b2-view-streaming.html
⎇
Raw
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; }
25body { 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; }
27mark { 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(&amp;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: &amp;[Line]) -&gt; 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