b2-view-streaming.html
| 1 | <!DOCTYPE html> |
| 2 | <html lang="en" class="dark"> |
| 3 | <head> |
| 4 | <meta charset="utf-8"> |
| 5 | <title>Mockup B2 — Search view, streaming</title> |
| 6 | <link rel="preconnect" href="https://fonts.googleapis.com"> |
| 7 | <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght@20..24,400&family=JetBrains+Mono:wght@400;600&display=swap" rel="stylesheet"> |
| 8 | <style> |
| 9 | :root { |
| 10 | color-scheme: dark; |
| 11 | --bg: #0f1115; |
| 12 | --panel: #171a20; |
| 13 | --text: #e5e7eb; |
| 14 | --muted: #9ca3af; |
| 15 | --accent: #60a5fa; |
| 16 | --accent-hover: #3b82f6; |
| 17 | --accent-border: #79b5fc; |
| 18 | --danger: #f87171; |
| 19 | --danger-border: #fa8b8b; |
| 20 | --border: #2a2f3a; |
| 21 | --topbar-h: 48px; |
| 22 | --mark: color-mix(in srgb, var(--accent) 35%, transparent); |
| 23 | } |
| 24 | * { box-sizing: border-box; border-radius: 0; } |
| 25 | body { margin: 0; font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; background: var(--bg); color: var(--text); font-size: 15px; } |
| 26 | .material-symbols-rounded { font-family: 'Material Symbols Rounded'; font-weight: normal; font-style: normal; line-height: 1; letter-spacing: normal; text-transform: none; display: inline-block; white-space: nowrap; direction: ltr; font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24; } |
| 27 | mark { background: var(--mark); color: inherit; padding: 0 1px; } |
| 28 | |
| 29 | .layout { min-height: 100vh; display: flex; flex-direction: column; } |
| 30 | .topbar { flex: none; position: sticky; top: 0; z-index: 130; height: var(--topbar-h); display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 0 16px; background: var(--panel); border-bottom: 1px solid var(--border); } |
| 31 | .brand { display: flex; align-items: center; gap: 10px; font-weight: 700; white-space: nowrap; color: inherit; text-decoration: none; } |
| 32 | .logo { width: 26px; height: 26px; flex: none; display: block; } |
| 33 | |
| 34 | .body-row { flex: 1; display: flex; } |
| 35 | .sidebar { flex: none; width: 224px; background: var(--panel); border-right: 1px solid var(--border); padding: 14px 8px 16px; } |
| 36 | .nav-section-head { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); padding: 0 8px 6px; } |
| 37 | .nav-item { display: flex; align-items: center; gap: 9px; padding: 7px 8px; font-size: 14px; color: var(--text); text-decoration: none; } |
| 38 | .nav-item.active { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); } |
| 39 | .nav-item .material-symbols-rounded { font-size: 19px; color: var(--muted); } |
| 40 | .nav-item.active .material-symbols-rounded { color: var(--accent); } |
| 41 | |
| 42 | .content { flex: 1; padding: 18px 20px; max-width: 1020px; } |
| 43 | |
| 44 | /* query bar */ |
| 45 | .query-bar { display: flex; gap: 10px; align-items: stretch; margin-bottom: 6px; position: relative; } |
| 46 | .query-input { flex: 1; display: flex; align-items: center; gap: 10px; background: var(--panel); border: 1px solid var(--border); padding: 0 12px; height: 40px; } |
| 47 | .query-input:focus-within { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); } |
| 48 | .query-input .material-symbols-rounded { color: var(--muted); font-size: 20px; } |
| 49 | .query-input input { flex: 1; background: none; border: none; outline: none; color: var(--text); font-size: 15px; height: 100%; } |
| 50 | .seg { display: flex; border: 1px solid var(--border); background: var(--panel); } |
| 51 | .seg button { appearance: none; border: none; background: none; color: var(--muted); font-size: 13px; font-weight: 600; padding: 0 14px; cursor: pointer; border-right: 1px solid var(--border); } |
| 52 | .seg button:last-child { border-right: none; } |
| 53 | .seg button.on { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); box-shadow: inset 0 -2px 0 var(--accent); } |
| 54 | |
| 55 | /* roots multiselect */ |
| 56 | .ms { position: relative; } |
| 57 | .ms-btn { display: flex; align-items: center; gap: 8px; background: var(--panel); border: 1px solid var(--accent); color: var(--text); font-size: 13px; height: 40px; padding: 0 12px; cursor: pointer; min-width: 130px; justify-content: space-between; } |
| 58 | .ms-btn .material-symbols-rounded { font-size: 17px; color: var(--muted); } |
| 59 | .ms-drop { position: absolute; top: 44px; left: 0; width: 230px; background: var(--panel); border: 1px solid var(--border); box-shadow: 0 12px 32px rgba(0,0,0,.5); z-index: 40; padding: 6px 0; } |
| 60 | .ms-opt { display: flex; align-items: center; gap: 10px; padding: 7px 12px; font-size: 14px; cursor: pointer; } |
| 61 | .ms-opt:hover { background: color-mix(in srgb, var(--panel) 50%, var(--bg)); } |
| 62 | .ms-opt .box { width: 16px; height: 16px; border: 1px solid var(--muted); display: inline-flex; align-items: center; justify-content: center; flex: none; } |
| 63 | .ms-opt .box.on { background: var(--accent); border-color: var(--accent); } |
| 64 | .ms-opt .box .material-symbols-rounded { font-size: 13px; color: #fff; } |
| 65 | .ms-opt .rp { margin-left: auto; color: var(--muted); font-size: 12px; } |
| 66 | |
| 67 | /* stop button (visible while searching) */ |
| 68 | .btn-stop { display: inline-flex; align-items: center; gap: 7px; border: 1px solid var(--danger-border); color: var(--danger); background: color-mix(in srgb, var(--danger) 8%, var(--panel)); font-size: 13px; font-weight: 600; padding: 0 14px; height: 40px; cursor: pointer; } |
| 69 | .btn-stop .material-symbols-rounded { font-size: 17px; font-variation-settings: 'FILL' 1; } |
| 70 | .btn { display: inline-flex; align-items: center; gap: 7px; border: 1px solid var(--border); background: var(--panel); color: var(--text); font-size: 13px; font-weight: 600; padding: 0 14px; height: 40px; cursor: pointer; } |
| 71 | .btn .material-symbols-rounded { font-size: 17px; } |
| 72 | |
| 73 | /* live status line */ |
| 74 | .status-line { display: flex; align-items: center; gap: 8px; margin: 4px 2px 12px; font-size: 12.5px; color: var(--muted); } |
| 75 | .status-line .dot { width: 8px; height: 8px; background: var(--accent); animation: pulse 1.2s ease-in-out infinite; } |
| 76 | @keyframes pulse { 50% { opacity: .25; } } |
| 77 | .status-line .grow { flex: 1; } |
| 78 | .status-line .linkish { color: var(--muted); cursor: pointer; } |
| 79 | |
| 80 | /* result groups */ |
| 81 | .group-label { display: flex; align-items: center; gap: 7px; margin: 16px 2px 8px; font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); } |
| 82 | .group-label .material-symbols-rounded { font-size: 15px; } |
| 83 | .group-label .n { font-weight: 400; letter-spacing: 0; text-transform: none; } |
| 84 | .group-label .grow { flex: 1; } |
| 85 | .collapse-all { appearance: none; border: none; background: none; color: var(--muted); font-size: 12px; display: inline-flex; align-items: center; gap: 4px; cursor: pointer; padding: 2px 4px; } |
| 86 | .collapse-all:hover { color: var(--text); } |
| 87 | .collapse-all .material-symbols-rounded { font-size: 15px; } |
| 88 | |
| 89 | .entries-list { background: var(--panel); border: 1px solid var(--border); overflow: hidden; } |
| 90 | .srow { display: grid; grid-template-columns: 28px minmax(0,1fr) 240px 90px; gap: 12px; align-items: center; padding: 9px 14px; border-bottom: 1px solid var(--border); font-size: 14px; cursor: pointer; } |
| 91 | .srow:last-child { border-bottom: none; } |
| 92 | .srow:hover { background: color-mix(in srgb, var(--panel) 50%, var(--bg)); } |
| 93 | .srow .material-symbols-rounded { font-size: 20px; color: var(--muted); } |
| 94 | .spath { color: var(--muted); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } |
| 95 | .ssize { color: var(--muted); font-size: 13px; text-align: right; } |
| 96 | .more-row { display: flex; justify-content: center; gap: 8px; padding: 7px; color: var(--muted); font-size: 13px; border-top: 1px solid var(--border); } |
| 97 | |
| 98 | /* content match cards — match lines only */ |
| 99 | .match-card { background: var(--panel); border: 1px solid var(--border); margin-bottom: 10px; } |
| 100 | .match-head { display: grid; grid-template-columns: 28px minmax(0,1fr) 70px 90px 34px; gap: 12px; align-items: center; padding: 9px 10px 9px 14px; font-size: 14px; } |
| 101 | .match-head .material-symbols-rounded.mi { font-size: 20px; color: var(--muted); } |
| 102 | .match-head b { font-weight: 600; } |
| 103 | .match-head .mpath { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } |
| 104 | .match-head .mcount { color: var(--accent); font-size: 12px; font-weight: 600; text-align: right; } |
| 105 | .match-head .msize { color: var(--muted); font-size: 13px; text-align: right; } |
| 106 | .chev { appearance: none; border: 1px solid transparent; background: none; color: var(--muted); cursor: pointer; padding: 5px; display: inline-flex; align-items: center; justify-content: center; } |
| 107 | .chev:hover { border-color: var(--border); background: var(--bg); color: var(--text); } |
| 108 | .chev .material-symbols-rounded { font-size: 18px; } |
| 109 | .match-lines { border-top: 1px solid var(--border); background: color-mix(in srgb, var(--bg) 60%, var(--panel)); padding: 6px 0; } |
| 110 | .mline { display: grid; grid-template-columns: 52px minmax(0,1fr); gap: 12px; padding: 3px 14px 3px 10px; font-family: "JetBrains Mono", monospace; font-size: 12.5px; line-height: 1.5; cursor: pointer; } |
| 111 | .mline:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); } |
| 112 | .mline .ln { color: var(--muted); text-align: right; user-select: none; } |
| 113 | .mline .tx { white-space: pre; overflow: hidden; text-overflow: ellipsis; } |
| 114 | </style> |
| 115 | </head> |
| 116 | <body> |
| 117 | <div class="layout"> |
| 118 | <header class="topbar"> |
| 119 | <a class="brand" href="#"> |
| 120 | <svg class="logo" viewBox="0 0 32 32"><rect width="32" height="32" fill="#2563eb"/><path d="M6 8h7l3 4h10v14H6z" fill="#fff"/><path d="M11.5 17.5 16 22l4.5-4.5" fill="none" stroke="#2563eb" stroke-width="3"/></svg> |
| 121 | <span>filebrowser-ng</span> |
| 122 | </a> |
| 123 | </header> |
| 124 | |
| 125 | <div class="body-row"> |
| 126 | <aside class="sidebar"> |
| 127 | <div class="nav-section-head">Files</div> |
| 128 | <div class="nav-item active"><span class="material-symbols-rounded">search</span> Search</div> |
| 129 | <div class="nav-item"><span class="material-symbols-rounded">folder</span> Documents</div> |
| 130 | <div class="nav-item"><span class="material-symbols-rounded">folder</span> Projects</div> |
| 131 | <div class="nav-section-head" style="margin-top:14px">Manage</div> |
| 132 | <div class="nav-item"><span class="material-symbols-rounded">link</span> Shares</div> |
| 133 | <div class="nav-item"><span class="material-symbols-rounded">settings</span> Settings</div> |
| 134 | </aside> |
| 135 | |
| 136 | <main class="content"> |
| 137 | <div class="query-bar"> |
| 138 | <div class="query-input"> |
| 139 | <span class="material-symbols-rounded">search</span> |
| 140 | <input value="invoice 2025" spellcheck="false"> |
| 141 | </div> |
| 142 | <div class="seg"> |
| 143 | <button>Name</button> |
| 144 | <button>Content</button> |
| 145 | <button class="on">Both</button> |
| 146 | </div> |
| 147 | <div class="ms"> |
| 148 | <button class="ms-btn"><span>2 roots</span><span class="material-symbols-rounded">expand_more</span></button> |
| 149 | <div class="ms-drop"> |
| 150 | <div class="ms-opt"><span class="box on"><span class="material-symbols-rounded">check</span></span> Documents <span class="rp">612 files</span></div> |
| 151 | <div class="ms-opt"><span class="box on"><span class="material-symbols-rounded">check</span></span> Projects <span class="rp">588 files</span></div> |
| 152 | </div> |
| 153 | </div> |
| 154 | <button class="btn-stop"><span class="material-symbols-rounded">stop</span> Stop</button> |
| 155 | </div> |
| 156 | |
| 157 | <div class="status-line"> |
| 158 | <span class="dot"></span> |
| 159 | <span>searching… scanned 412 files, 5 name matches, 14 content matches</span> |
| 160 | <span class="grow"></span> |
| 161 | </div> |
| 162 | |
| 163 | <div class="group-label"><span class="material-symbols-rounded">description</span> Files <span class="n">· 5</span></div> |
| 164 | <div class="entries-list"> |
| 165 | <div class="srow"><span class="material-symbols-rounded">description</span><span><mark>invoice</mark>_2025-11_final.pdf</span><span class="spath">Documents / finance / 2025</span><span class="ssize">182 KB</span></div> |
| 166 | <div class="srow"><span class="material-symbols-rounded">description</span><span><mark>invoice</mark>_2025-08_draeger.pdf</span><span class="spath">Documents / finance / 2025</span><span class="ssize">164 KB</span></div> |
| 167 | <div class="srow"><span class="material-symbols-rounded">folder</span><span><mark>invoices</mark>-2025</span><span class="spath">Projects / shop</span><span class="ssize">—</span></div> |
| 168 | <div class="srow"><span class="material-symbols-rounded">grid_on</span><span>export_2025_Q3.<mark>xlsx</mark></span><span class="spath">Documents / finance</span><span class="ssize">58 KB</span></div> |
| 169 | </div> |
| 170 | <div class="more-row"><span class="material-symbols-rounded" style="font-size:16px">more_horiz</span> 1 more…</div> |
| 171 | |
| 172 | <div class="group-label"> |
| 173 | <span class="material-symbols-rounded">text_snippet</span> Content <span class="n">· 14 matches in 4 files</span> |
| 174 | <span class="grow"></span> |
| 175 | <button class="collapse-all"><span class="material-symbols-rounded">unfold_less</span> Collapse all</button> |
| 176 | </div> |
| 177 | |
| 178 | <div class="match-card"> |
| 179 | <div class="match-head"> |
| 180 | <span class="material-symbols-rounded mi">code</span> |
| 181 | <span class="mpath">Projects / billing / <b>generate_2025.rs</b></span> |
| 182 | <span class="msize">14 KB</span> |
| 183 | <span class="mcount">6 matches</span> |
| 184 | <button class="chev" title="Collapse"><span class="material-symbols-rounded">expand_more</span></button> |
| 185 | </div> |
| 186 | <div class="match-lines"> |
| 187 | <div class="mline"><span class="ln">42</span><span class="tx">let template = load("<mark>invoice</mark>-<mark>2025</mark>-layout");</span></div> |
| 188 | <div class="mline"><span class="ln">58</span><span class="tx">stamp(&mut pdf, "<mark>INVOICE</mark>-<mark>2025</mark>-…");</span></div> |
| 189 | <div class="mline"><span class="ln">87</span><span class="tx">// <mark>2025</mark>-11: VAT rate changed mid-run</span></div> |
| 190 | <div class="mline"><span class="ln">91</span><span class="tx">fn total_2025(rows: &[Line]) -> Money { … }</span></div> |
| 191 | </div> |
| 192 | </div> |
| 193 | |
| 194 | <div class="match-card"> |
| 195 | <div class="match-head"> |
| 196 | <span class="material-symbols-rounded mi">description</span> |
| 197 | <span class="mpath">Documents / finance / <b>2025_summary.md</b></span> |
| 198 | <span class="msize">6 KB</span> |
| 199 | <span class="mcount">5 matches</span> |
| 200 | <button class="chev" title="Collapse"><span class="material-symbols-rounded">expand_more</span></button> |
| 201 | </div> |
| 202 | <div class="match-lines"> |
| 203 | <div class="mline"><span class="ln">3</span><span class="tx">## <mark>Invoice</mark> totals <mark>2025</mark></span></div> |
| 204 | <div class="mline"><span class="ln">11</span><span class="tx">| <mark>2025</mark>-11 | 4,120.00 | paid |</span></div> |
| 205 | <div class="mline"><span class="ln">12</span><span class="tx">| <mark>2025</mark>-12 | 3,807.50 | open |</span></div> |
| 206 | </div> |
| 207 | </div> |
| 208 | |
| 209 | <div class="match-card"> |
| 210 | <div class="match-head"> |
| 211 | <span class="material-symbols-rounded mi">grid_on</span> |
| 212 | <span class="mpath">Documents / finance / <b>export_2025_Q3.csv</b></span> |
| 213 | <span class="msize">210 KB</span> |
| 214 | <span class="mcount">3 matches</span> |
| 215 | <button class="chev" title="Expand"><span class="material-symbols-rounded">expand_less</span></button> |
| 216 | </div> |
| 217 | </div> |
| 218 | </main> |
| 219 | </div> |
| 220 | </div> |
| 221 | </body> |
| 222 | </html> |
| 223 |