@bongos/core 1.19.92 → 1.19.94

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,809 +0,0 @@
1
- /* ═══════════════════════════════════════════════════════════════════════
2
- Cloud Bongos — "space" scene (task 1721)
3
- The pannable, zoomable sky where every Cloud Bongos project floats as a
4
- drifting circle. Sits ABOVE the gate's cloud-temple world: click a circle
5
- to dive down into that project; press ESC to rise back up here.
6
-
7
- Theme is the locked Cloud Bongos palette (brand/cloud-bongos/tokens.json):
8
- sun #f97316, sky #38bdf8, coral #fb7185, gold #ffd98a, ink #2a1f17.
9
- The search bar reuses the gate's live-glass #disp-bar filter (defined in
10
- index.html) so it matches the terminal + search sprites exactly.
11
- ═══════════════════════════════════════════════════════════════════════ */
12
-
13
- :root{
14
- --cb-sun:#f97316; --cb-sun-lit:#fb923c; --cb-gold:#ffd98a; --cb-gold-soft:#f6c976;
15
- --cb-sky:#38bdf8; --cb-coral:#fb7185; --cb-ink:#2a1f17; --cb-ink-soft:#6b5d52;
16
- --cb-font-display:"Baloo 2",system-ui,sans-serif;
17
- --cb-font-mono:"Fira Code",ui-monospace,monospace;
18
- }
19
-
20
- /* ---- view switching: entry gate / space circles / download / detail (task 1722) ----
21
- entry + space share the space backdrop (#space); download is the temple-world
22
- .stage; detail is #detail. .stage is hidden unless we're on the download page. */
23
- #space{ display:none; }
24
- .stage{ display:none; }
25
- body.view-entry #space, body.view-space #space, body.view-table #space{ display:block; }
26
- body.view-download .stage{ display:block; }
27
- /* table view (task 1731) reuses the deep-space backdrop + starfield, but the
28
- pannable circle canvas is hidden and the surface is a plain reading pane. */
29
- body.view-table #space-canvas{ display:none; }
30
- body.view-table #space{ cursor:default; }
31
-
32
- /* ---- entry gate: the type-"bongos" terminal, set in space (task 1722) ---- */
33
- #entry{ display:none; z-index:6; transition:opacity .45s ease, transform .55s cubic-bezier(.4,0,.7,1); }
34
- body.view-entry #entry{ display:flex; }
35
- #entry.leaving{ opacity:0; transform:scale(1.14); pointer-events:none; }
36
- /* in the entry view the circles stay hidden behind the terminal (space.js also
37
- sets the canvas opacity to 0); the top-left mark + help belong to the circles view */
38
- body.view-entry .space-mark, body.view-entry .space-help{ display:none; }
39
- /* the entry gate leans on the gate's own terminal/enter CSS (index.html <style>);
40
- nudge the enter key a touch closer under the bar in this stacked layout */
41
- #entry .enter{ margin-top:2px; }
42
-
43
- /* ═══ deep space ═══ (task 1725: actually in space — no clouds up here) */
44
- #space{
45
- position:fixed; inset:0; overflow:hidden; z-index:1;
46
- background:
47
- radial-gradient(120% 85% at 50% -12%, #2b2456 0%, rgba(43,36,86,0) 55%),
48
- radial-gradient(70% 55% at 82% 112%, rgba(56,120,200,.16), transparent 62%),
49
- radial-gradient(58% 48% at 12% 6%, rgba(120,70,160,.14), transparent 60%),
50
- linear-gradient(180deg, #05060f 0%, #0a0c20 48%, #0d0f28 100%);
51
- cursor:grab; touch-action:none; user-select:none; -webkit-user-select:none;
52
- }
53
- /* the whole canvas is a pannable surface — grabbing on press, everywhere,
54
- including over the orbs (they still click-to-enter). */
55
- #space.panning, #space.grabbing{ cursor:grabbing; }
56
- #space.grabbing .circle{ cursor:grabbing; }
57
-
58
- /* starfield backdrop (generated in space.js). Fixed behind the canvas — a
59
- distant sky, so it does not pan with the circles. */
60
- .stars{ position:absolute; inset:0; z-index:0; pointer-events:none; overflow:hidden; transition:opacity .3s ease; }
61
- .star{ position:absolute; border-radius:50%; background:#fff; box-shadow:0 0 3px rgba(255,255,255,.5); }
62
- @keyframes twinkle{ 0%,100%{opacity:.22} 50%{opacity:.95} }
63
-
64
- /* ═══ space-time sheet ═══
65
- A blueprint grid that warps under the orbs' gravity (drawn in space.js). Sits
66
- between the distant starfield (z0) and the orb canvas (z2), so the orbs rest
67
- ON the sheet. Kept faint — a whisper zoomed out, legible zoomed in. It fades
68
- in with the circle sky and, like #space-canvas, is absent in table view. */
69
- #space-grid{
70
- position:absolute; inset:0; z-index:1; pointer-events:none;
71
- opacity:0; transition:opacity .55s ease;
72
- }
73
- body.view-space #space-grid{ opacity:1; }
74
- body.view-table #space-grid{ display:none; }
75
-
76
- /* ═══ the pannable / zoomable canvas ═══ */
77
- #space-canvas{
78
- position:absolute; inset:0; z-index:2; transform-origin:0 0; will-change:transform;
79
- }
80
-
81
- /* ═══ a project circle ═══
82
- .circle carries the drift offset (transform). Inside, .disc is the visible
83
- bubble and .label the name. Anchor lives in left/top (set by JS). */
84
- .circle{
85
- position:absolute; will-change:transform; cursor:grab; transition:opacity .35s ease;
86
- }
87
- .circle .disc{
88
- width:100%; height:100%; border-radius:50%; position:relative; overflow:hidden;
89
- background:
90
- radial-gradient(120% 120% at 50% 50%, var(--acc, #fb923c), color-mix(in srgb, var(--acc,#fb923c) 55%, #1b2b52) 100%);
91
- box-shadow:
92
- 0 0 0 1.5px rgba(255,255,255,.35) inset,
93
- 0 10px 34px rgba(20,16,40,.42),
94
- 0 0 42px var(--glow, rgba(251,146,60,.5));
95
- transition:transform .28s cubic-bezier(.2,.9,.3,1.2), box-shadow .28s ease, filter .28s ease;
96
- }
97
- /* the world image lives INSIDE the orb (added in makeCircle for real instances);
98
- hidden until hover, then it fades in to fill the sphere. */
99
- .circle .disc-world{
100
- position:absolute; inset:0; border-radius:50%; z-index:1; pointer-events:none;
101
- background-position:center; background-size:cover; background-repeat:no-repeat;
102
- opacity:0; transition:opacity .34s ease;
103
- }
104
- .circle:hover .disc-world{ opacity:1; }
105
- /* glassy shine as a ::after so it sits ON TOP of the world image — the orb keeps
106
- reading as a sphere even when filled with its world. */
107
- .circle .disc::after{
108
- content:''; position:absolute; inset:0; border-radius:50%; z-index:2; pointer-events:none;
109
- background:radial-gradient(38% 34% at 34% 28%, rgba(255,255,255,.9), rgba(255,255,255,0) 60%);
110
- }
111
- .circle .label{
112
- position:absolute; top:100%; left:50%; transform:translateX(-50%);
113
- margin-top:9px; text-align:center; pointer-events:none; width:max-content; max-width:190px;
114
- font-family:var(--cb-font-display); font-weight:700; color:#fff;
115
- text-shadow:0 2px 12px rgba(20,12,30,.7); line-height:1.05;
116
- }
117
- .circle .label .name{ display:block; font-size:15px; letter-spacing:.2px; }
118
- .circle .label .count{
119
- display:inline-block; margin-top:3px; font-family:var(--cb-font-mono); font-weight:500;
120
- font-size:10.5px; color:var(--cb-gold); text-shadow:0 1px 8px rgba(20,12,30,.8);
121
- }
122
- .circle:hover .disc{ transform:scale(1.06); box-shadow:0 0 0 1.5px rgba(255,255,255,.55) inset, 0 14px 40px rgba(20,16,40,.5), 0 0 60px var(--glow,rgba(251,146,60,.7)); }
123
- .circle.dim{ opacity:.16; }
124
- .circle.match .disc{ box-shadow:0 0 0 2px var(--cb-gold) inset, 0 14px 40px rgba(20,16,40,.5), 0 0 66px var(--cb-gold-soft); }
125
-
126
- /* ═══ search spotlight (task 1892) ═══
127
- Opening the in-view search darkens the whole sky — the starfield + gravity
128
- grid dip and every orb dims to a baseline — so the matching orbs (kept bright,
129
- gold-ringed, lifted) read as spotlit. Non-matches (.dim) sink further. The
130
- orb POSITION transform is set inline per-frame by space.js, so the match
131
- pop scales the inner .disc, never the .circle. */
132
- body.searching #starfield{ opacity:.3; }
133
- body.searching #space-grid{ opacity:.25; }
134
- body.searching .circle{ opacity:.4; }
135
- body.searching .circle .disc{ filter:saturate(.55) brightness(.72); }
136
- body.searching .circle.dim{ opacity:.1; }
137
- body.searching .circle.match{ opacity:1; z-index:6; }
138
- body.searching .circle.match .disc{ filter:none; transform:scale(1.1);
139
- box-shadow:0 0 0 2.5px var(--cb-gold) inset, 0 16px 48px rgba(20,16,40,.55), 0 0 92px var(--cb-gold-soft); }
140
- .circle.is-self .disc{ box-shadow:0 0 0 2px rgba(255,231,178,.85) inset, 0 12px 40px rgba(20,16,40,.5), 0 0 60px rgba(251,146,60,.75); }
141
- /* a provisional orb while the create panel is open (tasks 1909/1912): stationary,
142
- outside the sim, greyed/dim like the search state until it's named (or removed
143
- on cancel). */
144
- .circle.pending{ opacity:.5; }
145
- .circle.pending .disc{ filter:saturate(.35) brightness(.82);
146
- box-shadow:0 0 0 1.5px rgba(255,255,255,.3) inset, 0 10px 30px rgba(20,16,40,.4); }
147
- .circle.pending .label .name{ font-style:italic; opacity:.85; }
148
- .circle .self-badge{
149
- position:absolute; top:-8px; left:50%; transform:translateX(-50%);
150
- font-family:var(--cb-font-mono); font-size:9px; font-weight:500; letter-spacing:.6px;
151
- color:var(--cb-ink); background:var(--cb-gold); padding:2px 8px; border-radius:999px;
152
- box-shadow:0 2px 10px rgba(20,12,30,.4); white-space:nowrap; pointer-events:none;
153
- }
154
-
155
- /* ═══ hover info card ═══ */
156
- #hovercard{
157
- position:fixed; z-index:40; max-width:270px; padding:13px 15px; border-radius:14px;
158
- background:rgba(24,20,44,.82); -webkit-backdrop-filter:blur(9px) saturate(1.3); backdrop-filter:blur(9px) saturate(1.3);
159
- border:1px solid rgba(255,255,255,.16); box-shadow:0 14px 44px rgba(10,8,25,.5);
160
- color:#fff; font-family:var(--cb-font-display); pointer-events:none;
161
- opacity:0; transition:opacity .16s ease;
162
- }
163
- #hovercard.show{ opacity:1; }
164
- #hovercard .hc-name{ font-weight:700; font-size:16px; display:flex; align-items:center; gap:8px; }
165
- #hovercard .hc-dot{ width:10px; height:10px; border-radius:50%; background:var(--acc,#fb923c); box-shadow:0 0 10px var(--acc,#fb923c); flex:none; }
166
- #hovercard .hc-tag{ margin-top:3px; font-size:12.5px; color:#e7dcc9; }
167
- #hovercard .hc-meta{ margin-top:9px; display:flex; align-items:center; gap:8px; font-family:var(--cb-font-mono); font-size:11px; color:var(--cb-gold); }
168
- #hovercard .hc-meta .chip{ color:#cdbfae; }
169
- #hovercard .hc-go{ margin-top:9px; font-family:var(--cb-font-mono); font-size:11px; color:#9fe1cb; }
170
- #hovercard .hc-sample{ color:#f0997b; }
171
-
172
- /* ═══ toolbar / help affordances ═══ */
173
- .space-mark{
174
- position:fixed; top:20px; left:22px; z-index:30; white-space:nowrap;
175
- font-family:var(--cb-font-display); font-weight:700; font-size:19px; color:var(--cb-gold);
176
- text-shadow:0 2px 12px rgba(20,12,30,.6); pointer-events:none;
177
- }
178
- .space-mark b{ color:var(--cb-gold); font-weight:700; }
179
- /* the wordmark logo breathes a faint gold glow so it reads as alive (task 1894) */
180
- .space-mark{ animation:markGlow 3.4s ease-in-out infinite; }
181
- @keyframes markGlow{
182
- 0%,100%{ text-shadow:0 2px 12px rgba(20,12,30,.6), 0 0 14px rgba(246,201,118,.12); }
183
- 50%{ text-shadow:0 2px 12px rgba(20,12,30,.6), 0 0 24px rgba(246,201,118,.42); }
184
- }
185
- /* self-typing wordmark (task 1902): the lead word swaps "Cloud" for lowercase
186
- platform names and "bongos" re-types after it, with a terminal caret. Only
187
- the space-view logo animates; JS (mountLogoTerminal) drives the text. */
188
- /* two colours: the LLM/lead word is white, "bongos" keeps the brand gold (task 1905) */
189
- .mk-lead{ display:inline-block; transition:opacity .18s ease; color:#fff; }
190
- .mk-lead.swap{ opacity:0; }
191
- .mk-tail{ color:var(--cb-gold); font-weight:700; }
192
- /* each typed letter is its own popping span (the entry terminal's per-letter pop);
193
- white-space:pre keeps the leading word-gap space from collapsing (task 1910).
194
- transform-origin:left so the pop's scale-overshoot grows each new letter
195
- RIGHTWARD into empty space, never symmetrically over its already-settled left
196
- neighbour — that overlap was the only way a fast type-in could visually smear. */
197
- .mk-ch{ display:inline-block; white-space:pre; transform-origin:left center; animation:pop .22s cubic-bezier(.2,1.4,.4,1); }
198
- /* caret sits flush against the last typed/deleted letter — no gap (task 1907) */
199
- .mk-caret{ display:inline-block; width:9px; height:17px; margin-left:0; vertical-align:-3px;
200
- background:var(--cb-gold); box-shadow:0 0 5px rgba(246,201,118,.55); opacity:0; }
201
- .mk-caret.on{ animation:blink 1.05s steps(1) infinite; }
202
-
203
- /* ─── idle "create a project" ghost orb (task 1896) ─────────────────────────
204
- A faint dashed orb that follows the cursor over EMPTY sky only (never over an
205
- orb, never while panning or with an overlay open) — a light nudge toward the
206
- click-to-create gesture. space.js sets left/top + toggles .show; the .show
207
- transform/animation and the position are kept on different properties so they
208
- never fight. */
209
- #ghost-orb{
210
- position:fixed; top:0; left:0; z-index:20; pointer-events:none;
211
- width:74px; height:74px; margin:-37px 0 0 -37px; border-radius:50%;
212
- border:1.5px dashed rgba(255,217,138,.5);
213
- background:radial-gradient(circle at 50% 42%, rgba(255,217,138,.12), rgba(255,217,138,0) 68%);
214
- display:flex; align-items:center; justify-content:center;
215
- opacity:0; transform:scale(.7); transition:opacity .28s ease, transform .28s ease;
216
- }
217
- #ghost-orb.show{ opacity:.9; transform:scale(1); animation:ghostPulse 2.2s ease-in-out infinite; }
218
- #ghost-orb .ghost-plus{ font-family:var(--cb-font-display); font-weight:700; font-size:30px; line-height:1;
219
- color:var(--cb-gold); text-shadow:0 0 12px rgba(246,201,118,.6); }
220
- #ghost-orb .ghost-label{
221
- position:absolute; top:100%; left:50%; transform:translateX(-50%); margin-top:8px; white-space:nowrap;
222
- font-family:var(--cb-font-mono); font-size:11px; letter-spacing:.3px; color:rgba(255,246,235,.72);
223
- text-shadow:0 1px 8px rgba(20,12,30,.8); }
224
- @keyframes ghostPulse{ 0%,100%{ border-color:rgba(255,217,138,.34); } 50%{ border-color:rgba(255,217,138,.72); } }
225
- body:not(.view-space) #ghost-orb{ display:none; }
226
- @media (prefers-reduced-motion: reduce){ #ghost-orb.show{ animation:none; } }
227
-
228
- /* ─── minimap (task 1897) ─── a live cluster overview + viewport rect, bottom-right */
229
- #minimap{
230
- position:fixed; right:16px; bottom:16px; z-index:32; width:172px; height:120px;
231
- border-radius:12px; overflow:hidden; cursor:pointer;
232
- background:rgba(16,14,34,.52); border:1px solid rgba(255,255,255,.14);
233
- -webkit-backdrop-filter:blur(7px) saturate(1.2); backdrop-filter:blur(7px) saturate(1.2);
234
- box-shadow:0 8px 26px rgba(10,8,25,.42);
235
- opacity:.72; transition:opacity .25s ease;
236
- }
237
- #minimap:hover{ opacity:1; }
238
- #minimap canvas{ display:block; width:100%; height:100%; }
239
- body:not(.view-space) #minimap{ display:none; }
240
- @media (max-width:640px){ #minimap{ display:none; } }
241
-
242
- /* ─── space whale (task 1898) ─── flies orb→project on update, back on a module
243
- push. space.js sets the transform (position + flip) each frame; opacity fades
244
- it in/out. The default art faces LEFT, so a rightward flight is scaleX(-1). */
245
- #whale{
246
- position:fixed; top:0; left:0; z-index:18; pointer-events:none;
247
- opacity:0; transition:opacity .6s ease; will-change:transform, width;
248
- /* Size is normally set inline per-frame by space.js (worldW*zoom). These are
249
- the safety net: a sane default before the first flight, and a hard cap so a
250
- frame the JS hasn't sized yet (flight start, or rAF starved by heavy
251
- scroll-zoom) can never balloon to the image's intrinsic ~1280px width. */
252
- width:90px; max-width:240px;
253
- filter:drop-shadow(0 3px 7px rgba(10,8,25,.5));
254
- }
255
- #whale.show{ opacity:.96; }
256
- /* width is set per-frame by space.js (scaled to the orbs); height follows aspect */
257
- #whale img{ display:block; width:100%; height:auto; }
258
- body:not(.view-space) #whale{ display:none; }
259
- /* the target orb pings a gold ring as the whale arrives */
260
- .circle.pinged .disc{ animation:orbPing .9s ease-out; }
261
- @keyframes orbPing{
262
- 0%{ box-shadow:0 0 0 0 rgba(255,217,138,.75), 0 10px 34px rgba(20,16,40,.42); }
263
- 100%{ box-shadow:0 0 0 30px rgba(255,217,138,0), 0 10px 34px rgba(20,16,40,.42); }
264
- }
265
- @media (prefers-reduced-motion: reduce){ #whale{ display:none; } }
266
- @media (prefers-reduced-motion: reduce){
267
- .space-mark{ animation:none; }
268
- .mk-caret.on{ animation:none; opacity:0; }
269
- .mk-lead{ transition:none; }
270
- }
271
-
272
- .space-help{
273
- position:fixed; bottom:16px; left:50%; transform:translateX(-50%); z-index:30;
274
- display:flex; gap:16px; align-items:center; flex-wrap:wrap; justify-content:center;
275
- font-family:var(--cb-font-mono); font-size:11.5px; color:#f3ead9;
276
- background:rgba(24,20,44,.42); border:1px solid rgba(255,255,255,.14); border-radius:999px;
277
- padding:8px 18px; -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
278
- text-shadow:0 1px 6px rgba(20,12,30,.7); transition:opacity .3s ease; pointer-events:none;
279
- }
280
- .space-help kbd{
281
- font-family:var(--cb-font-mono); font-size:10.5px; color:var(--cb-ink); background:var(--cb-gold);
282
- border-radius:5px; padding:1px 7px; margin-right:5px; box-shadow:0 1px 4px rgba(20,12,30,.35);
283
- }
284
- .space-help .sep{ color:rgba(255,255,255,.28); }
285
- /* the /projects door (task 1002696) — same glass voice as the help strip */
286
- .space-projects{
287
- position:fixed; top:20px; right:22px; z-index:30;
288
- font-family:var(--cb-font-display); font-weight:700; font-size:13.5px; color:var(--cb-gold);
289
- text-decoration:none; text-shadow:0 1px 8px rgba(20,12,30,.8);
290
- background:rgba(255,255,255,.06); border:1.5px solid rgba(255,217,138,.45); border-radius:999px;
291
- padding:7px 15px; backdrop-filter:blur(4px);
292
- }
293
- .space-projects:hover{ border-color:var(--cb-gold); background:rgba(255,217,138,.1); }
294
- body:not(.view-space) .space-mark,
295
- body:not(.view-space) .space-help,
296
- body:not(.view-space) .space-projects{ display:none; }
297
-
298
- /* ═══ dive / rise transition ═══ */
299
- #space.diving #space-canvas{ transition:transform .72s cubic-bezier(.5,.03,.4,1), opacity .72s ease; }
300
- #space.diving{ pointer-events:none; }
301
- .dive-flash{
302
- position:fixed; inset:0; z-index:60; pointer-events:none; opacity:0;
303
- background:radial-gradient(40% 35% at var(--fx,50%) var(--fy,52%), rgba(255,240,205,.96), rgba(249,115,22,.4) 45%, transparent 74%);
304
- }
305
- .dive-flash.go{ animation:diveFlash .72s ease-out forwards; }
306
- @keyframes diveFlash{ 0%{opacity:0;transform:scale(.6)} 30%{opacity:.95} 100%{opacity:0;transform:scale(1.7)} }
307
-
308
- /* ═══ space-bar search overlay ═══ */
309
- #searchbar{
310
- position:fixed; top:16%; left:50%; transform:translate(-50%,-14px); z-index:50; width:min(560px,90vw);
311
- opacity:0; pointer-events:none; transition:opacity .22s ease, transform .22s cubic-bezier(.2,.9,.3,1.1);
312
- }
313
- #searchbar.show{ opacity:1; transform:translate(-50%,0); pointer-events:auto; }
314
- #searchbar .bar{
315
- position:relative; height:64px; border-radius:16px; display:flex; align-items:center; gap:12px; padding:0 18px;
316
- background:rgba(255,250,242,.16);
317
- -webkit-backdrop-filter:blur(3px) saturate(1.25) url(#disp-bar); backdrop-filter:blur(3px) saturate(1.25) url(#disp-bar);
318
- border:1px solid rgba(255,255,255,.35); box-shadow:0 18px 54px rgba(10,8,25,.5), 0 0 0 1px rgba(255,255,255,.1) inset;
319
- }
320
- #searchbar .mag{ width:20px; height:20px; flex:none; color:var(--cb-gold); }
321
- #searchbar input{
322
- flex:1; background:transparent; border:0; outline:0; color:#fff;
323
- font-family:var(--cb-font-mono); font-size:18px; letter-spacing:.3px;
324
- }
325
- #searchbar input::placeholder{ color:rgba(255,246,235,.6); }
326
- #searchbar .esc{ font-family:var(--cb-font-mono); font-size:10.5px; color:rgba(255,255,255,.7); flex:none; }
327
- #searchbar .esc kbd{ color:var(--cb-ink); background:var(--cb-gold); border-radius:5px; padding:1px 6px; }
328
- #searchbar .ctx{
329
- margin-top:10px; display:flex; align-items:center; gap:8px; padding:0 6px;
330
- font-family:var(--cb-font-mono); font-size:11.5px; color:#f3ead9; text-shadow:0 1px 8px rgba(20,12,30,.7);
331
- }
332
- #searchbar .ctx .dot{ width:7px; height:7px; border-radius:50%; background:#16a34a; box-shadow:0 0 9px #16a34a; animation:sbPulse 1.6s ease-in-out infinite; flex:none; }
333
- @keyframes sbPulse{ 0%,100%{opacity:.45} 50%{opacity:1} }
334
- #searchbar .ctx b{ color:var(--cb-gold); font-weight:500; }
335
- #searchbar .ai-soon{ color:#cdbfae; }
336
-
337
- /* ═══ create-a-project panel ═══
338
- No dim/blur (task 1909): the panel floats near the bottom so the live preview
339
- orb the click just dropped stays visible in the sky. The full-screen scrim is
340
- still the click-outside-to-cancel catcher. */
341
- .overlay-scrim{
342
- position:fixed; inset:0; z-index:70; display:none; align-items:flex-end; justify-content:center;
343
- background:transparent; padding-bottom:9vh;
344
- }
345
- .overlay-scrim.show{ display:flex; }
346
- #createpanel{
347
- width:min(420px,92vw); border-radius:18px; padding:24px 24px 22px;
348
- background:linear-gradient(180deg, rgba(38,30,60,.96), rgba(24,20,44,.96));
349
- border:1px solid rgba(255,255,255,.16); box-shadow:0 26px 70px rgba(6,4,20,.6);
350
- color:#fff; font-family:var(--cb-font-display); transform:translateY(10px) scale(.98); opacity:0;
351
- transition:opacity .24s ease, transform .24s cubic-bezier(.2,.9,.3,1.1);
352
- }
353
- .overlay-scrim.show #createpanel{ transform:none; opacity:1; }
354
- #createpanel h3{ font-weight:700; font-size:20px; display:flex; align-items:center; gap:10px; }
355
- #createpanel p.sub{ margin-top:6px; font-size:13px; color:#d9cebb; line-height:1.5; }
356
- #createpanel label{ display:block; margin-top:16px; font-family:var(--cb-font-mono); font-size:11px; letter-spacing:.5px; color:var(--cb-gold); text-transform:uppercase; }
357
- #createpanel input[type=text]{
358
- width:100%; margin-top:7px; height:44px; padding:0 14px; border-radius:11px;
359
- background:rgba(255,255,255,.08); border:1px solid rgba(255,255,255,.2); outline:0; color:#fff;
360
- font-family:var(--cb-font-display); font-size:15px;
361
- }
362
- #createpanel input[type=text]:focus{ border-color:var(--cb-gold); box-shadow:0 0 0 3px rgba(255,217,138,.22); }
363
- #createpanel .row{ margin-top:22px; display:flex; gap:10px; justify-content:flex-end; align-items:center; }
364
- #createpanel button{
365
- font-family:var(--cb-font-display); font-weight:700; font-size:14px; border-radius:11px; padding:11px 20px; cursor:pointer; border:0;
366
- }
367
- #createpanel .btn-ghost{ background:transparent; color:#d9cebb; border:1px solid rgba(255,255,255,.22); }
368
- #createpanel .btn-ghost:hover{ background:rgba(255,255,255,.06); }
369
- #createpanel .btn-go{ background:linear-gradient(180deg,#fdba74,#f97316); color:#3a1c07; box-shadow:0 8px 22px rgba(249,115,22,.45); }
370
- #createpanel .btn-go:hover{ filter:brightness(1.05); }
371
- #createpanel .note{ margin-top:14px; font-family:var(--cb-font-mono); font-size:10.5px; color:#9c8f7d; line-height:1.5; }
372
-
373
- /* handoff toast (task 2087) — a quiet beat between "orb joins the sky" and the
374
- /create build wizard taking over */
375
- #handoff-toast{
376
- position:fixed; left:50%; bottom:34px; transform:translate(-50%, 14px); z-index:60;
377
- padding:11px 20px; border-radius:999px; pointer-events:none; opacity:0;
378
- background:linear-gradient(180deg, rgba(38,30,60,.96), rgba(24,20,44,.96));
379
- border:1px solid rgba(255,255,255,.16); box-shadow:0 16px 44px rgba(6,4,20,.55);
380
- color:#f5edd9; font-family:var(--cb-font-display); font-weight:700; font-size:14px;
381
- transition:opacity .25s ease, transform .25s cubic-bezier(.2,.9,.3,1.1);
382
- }
383
- #handoff-toast.show{ opacity:1; transform:translate(-50%, 0); }
384
-
385
- /* ═══ non-self project "detail — coming soon" scene ═══ */
386
- #detail{
387
- position:fixed; inset:0; z-index:20; display:none; align-items:center; justify-content:center; padding:30px;
388
- background:
389
- radial-gradient(120% 90% at 50% 116%, rgba(255,221,138,.3), transparent 55%),
390
- linear-gradient(180deg, #141f3d 0%, #2c3c6e 45%, #6a74a6 78%, #e7b48c 100%);
391
- }
392
- body.view-detail #detail{ display:flex; }
393
- body.view-detail #space, body.view-detail .stage{ display:none; }
394
- #detail .card{
395
- max-width:520px; text-align:center; color:#fff; font-family:var(--cb-font-display);
396
- opacity:0; transform:translateY(24px) scale(.97); transition:opacity .7s ease .1s, transform .8s cubic-bezier(.2,.8,.2,1) .1s;
397
- }
398
- body.view-detail #detail .card{ opacity:1; transform:none; }
399
- #detail .halo{ width:120px; height:120px; border-radius:50%; margin:0 auto 22px;
400
- background:radial-gradient(38% 34% at 34% 28%, rgba(255,255,255,.9), transparent 60%), radial-gradient(120% 120% at 50% 50%, var(--acc,#38bdf8), color-mix(in srgb, var(--acc,#38bdf8) 55%, #141f3d) 100%);
401
- box-shadow:0 0 0 2px rgba(255,255,255,.4) inset, 0 0 70px var(--glow,rgba(56,189,248,.6)); }
402
- #detail h2{ font-weight:700; font-size:34px; letter-spacing:.3px; text-shadow:0 3px 18px rgba(10,8,25,.6); }
403
- #detail .tag{ margin-top:8px; font-size:16px; color:#e7dcc9; }
404
- #detail .desc{ margin-top:16px; font-size:14.5px; line-height:1.6; color:#cdbfae; }
405
- #detail .meta{ margin-top:18px; font-family:var(--cb-font-mono); font-size:12px; color:var(--cb-gold); }
406
- #detail .soon{ margin-top:26px; display:inline-block; font-family:var(--cb-font-mono); font-size:12px; color:#3a1c07;
407
- background:var(--cb-gold); padding:9px 18px; border-radius:999px; box-shadow:0 8px 22px rgba(20,12,30,.35); }
408
- #detail .actions{ margin-top:20px; display:flex; gap:12px; justify-content:center; align-items:center; }
409
- #detail a.visit{ font-family:var(--cb-font-display); font-weight:700; font-size:14px; text-decoration:none;
410
- color:#3a1c07; background:linear-gradient(180deg,#fdba74,#f97316); padding:11px 22px; border-radius:11px; box-shadow:0 8px 22px rgba(249,115,22,.45); }
411
- #detail .esc-hint{ position:fixed; bottom:22px; left:50%; transform:translateX(-50%); font-family:var(--cb-font-mono); font-size:11px; color:#f3ead9; }
412
- #detail .esc-hint kbd{ color:var(--cb-ink); background:var(--cb-gold); border-radius:5px; padding:1px 7px; }
413
-
414
- /* ═══════════════════════════════════════════════════════════════════════
415
- Dive cinematic (task 1729) — clicking the Cloud Bongos orb flies you from
416
- the space constellation, down through the clouds, into the Cloud Bongos
417
- world (the download page). space.js fills the star layers, adds #descent
418
- .playing on the self-orb click, then hands off to view-download under the
419
- flash and lifts the curtain (.done). Each layer runs its own timeline under
420
- `#descent.playing` (no nested camera transform to fight) with matched
421
- ease-in curves, so everything rushes the viewer together. `--descent` is the
422
- master duration; the cloud puffs reuse the gate's proven crush/flash motion.
423
- ═══════════════════════════════════════════════════════════════════════ */
424
- #descent{
425
- --descent:3.4s;
426
- position:fixed; inset:0; z-index:90; overflow:hidden; display:none; cursor:pointer;
427
- background:
428
- radial-gradient(120% 92% at 50% 122%, rgba(249,115,22,.20), transparent 56%),
429
- radial-gradient(120% 85% at 50% -12%, #2b2456 0%, rgba(43,36,86,0) 55%),
430
- linear-gradient(180deg, #05060f 0%, #0a0c20 46%, #0d0f28 100%);
431
- }
432
- #descent.playing{ display:block; }
433
- /* the reveal: once we're deep in the cloud, keep zooming — the cloud rushes
434
- past the camera (scales up) and dissolves, revealing the world behind it.
435
- A zoom-through crossfade, NOT a slide. */
436
- #descent.done{ pointer-events:none; opacity:0; transform:scale(1.42);
437
- transition:opacity .55s ease-in, transform .8s cubic-bezier(.3,0,.5,1); }
438
-
439
- /* two star layers → parallax depth. Near flies faster (closer); both fade as
440
- we enter the cloud bank. transform-origin biased low, toward the dive point. */
441
- .descent-stars{ position:absolute; inset:-22%; pointer-events:none; transform-origin:50% 56%; will-change:transform,opacity; }
442
- .descent-stars .star{ position:absolute; border-radius:50%; background:#fff; box-shadow:0 0 3px rgba(255,255,255,.5); }
443
- #descent.playing .descent-stars.far{ animation:descentStarsFar var(--descent) cubic-bezier(.5,0,.85,.5) forwards; }
444
- #descent.playing .descent-stars.near{ animation:descentStarsNear var(--descent) cubic-bezier(.45,0,.9,.45) forwards; }
445
- @keyframes descentStarsFar{ 0%{transform:scale(1);opacity:.85} 58%{opacity:.62} 100%{transform:scale(1.8);opacity:0} }
446
- @keyframes descentStarsNear{ 0%{transform:scale(1);opacity:1} 52%{opacity:.78} 100%{transform:scale(3.4);opacity:0} }
447
-
448
- /* the warm glow of the cloud bank, seen from space — grows + rises as we near it */
449
- .descent-glow{ position:absolute; left:50%; bottom:-12%; width:150%; height:72%; transform:translateX(-50%);
450
- background:radial-gradient(60% 60% at 50% 100%, rgba(255,214,150,.52), rgba(249,115,22,.18) 42%, transparent 72%);
451
- opacity:.3; pointer-events:none; will-change:transform,opacity; }
452
- #descent.playing .descent-glow{ animation:descentGlow var(--descent) ease-in forwards; }
453
- @keyframes descentGlow{ 0%{opacity:.26;transform:translateX(-50%) scale(.82) translateY(10%)} 70%{opacity:.72} 100%{opacity:.95;transform:translateX(-50%) scale(1.65) translateY(-12%)} }
454
-
455
- /* the Cloud Bongos sky-island — we fly straight INTO it: it stays centered and
456
- swells until it fills the whole screen (going soft + warm as we phase into the
457
- cloud). Much bigger now, so it dominates even on a wide monitor, then zooms
458
- past + dissolves with the crossfade reveal. */
459
- .descent-island{ position:absolute; left:50%; top:52%; width:40%; aspect-ratio:1/1; transform:translate(-50%,-50%);
460
- background:url("../world/assets/clouds/cloud-island-large.png") center/contain no-repeat; opacity:0;
461
- pointer-events:none; will-change:transform,opacity,filter; }
462
- /* zoom + haze are SEPARATE animations so the zoom (transform) has only two
463
- keyframes — a single continuous acceleration with no intermediate stops to
464
- stall on (the "hangs twice" bug was intermediate transform keyframes at
465
- 48%/78%, where the easing restarted). ease-in ends at full speed, carrying
466
- straight into the .done crossfade so the whole dive is one continuous motion. */
467
- #descent.playing .descent-island{
468
- animation:descentIslandZoom var(--descent) cubic-bezier(.42,0,1,1) forwards,
469
- descentIslandHaze var(--descent) ease-out forwards; }
470
- @keyframes descentIslandZoom{
471
- from{ transform:translate(-50%,-50%) scale(.34); }
472
- to{ transform:translate(-50%,-50%) scale(13); }
473
- }
474
- @keyframes descentIslandHaze{
475
- 0%{ opacity:0; filter:drop-shadow(0 20px 42px rgba(10,8,25,.5)) blur(0px) brightness(1); }
476
- 12%{ opacity:1; }
477
- 58%{ filter:drop-shadow(0 20px 42px rgba(10,8,25,.3)) blur(4px) brightness(1.16); }
478
- 100%{ opacity:1; filter:drop-shadow(0 20px 42px rgba(10,8,25,0)) blur(16px) brightness(1.5); }
479
- }
480
-
481
- /* the cloud deck we phase INTO — a full-bleed warm cloud that fills the screen
482
- as we enter (hiding the world behind it), so the phase-in is a full screen of
483
- cloud even on wide monitors. It dissolves with the zoom-through crossfade. */
484
- .descent-deck{ position:absolute; left:-8%; right:-8%; top:-10%; height:122%; opacity:0; pointer-events:none;
485
- background:
486
- radial-gradient(120% 66% at 50% 36%, #fff3d6, rgba(255,243,214,0) 62%),
487
- linear-gradient(180deg, #f7dab4 0%, #f2cd9e 68%, #ecc493 100%);
488
- will-change:opacity,transform; }
489
- #descent.playing .descent-deck{ animation:descentDeck var(--descent) ease-in forwards; }
490
- @keyframes descentDeck{ 0%{opacity:0} 46%{opacity:0} 74%{opacity:1} 100%{opacity:1} }
491
-
492
- /* the cloud bank we punch through — puffs sweep up past the camera (the gate's
493
- crush motion): each --x/--w placed, --s start-scale, --d dur, --del stagger. */
494
- .descent-clouds{ position:absolute; inset:0; pointer-events:none; }
495
- .ic{ position:absolute; bottom:-30%; left:var(--x); width:var(--w); aspect-ratio:720/401;
496
- background:url("../world/assets/clouds/cloud-puff.png") center/contain no-repeat; opacity:0;
497
- filter:drop-shadow(0 0 34px rgba(249,115,22,.4)) saturate(1.05); will-change:transform,opacity; }
498
- #descent.playing .ic{ animation:descentCloud var(--d,1.6s) cubic-bezier(.4,.05,.3,1) var(--del,0.9s) forwards; }
499
- @keyframes descentCloud{ 0%{transform:translateY(0) scale(var(--s,1));opacity:0}
500
- 15%{opacity:.97} 82%{opacity:.9}
501
- 100%{transform:translateY(-152vh) scale(calc(var(--s,1)*1.3));opacity:0} }
502
-
503
- /* a soft warm bloom as we hit the cloud — ambience now (the reveal is the
504
- cloud scroll, not a whiteout), so it stays gentle and fades before the scroll */
505
- .descent-flash{ position:absolute; inset:0; pointer-events:none; opacity:0;
506
- background:radial-gradient(50% 44% at 50% 46%, rgba(255,244,214,.85), rgba(249,115,22,.32) 46%, transparent 76%); }
507
- #descent.playing .descent-flash{ animation:descentFlash 1.0s ease-out 1.45s forwards; }
508
- @keyframes descentFlash{ 0%{opacity:0;transform:scale(.7)} 45%{opacity:.5} 100%{opacity:0;transform:scale(1.5)} }
509
-
510
- /* ═══════════════════════════════════════════════════════════════════════
511
- TABLE DIRECTORY + VIEW TOGGLE (task 1731)
512
- A scannable, searchable, sortable alternative to the circle sky. Sits over
513
- the same deep-space backdrop; the circle canvas is hidden while it's open.
514
- ═══════════════════════════════════════════════════════════════════════ */
515
-
516
- .cc-sr{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }
517
-
518
- /* ─── segmented Sky ⇄ Table toggle (top-right, shown only while browsing) ─── */
519
- /* top-left ESC button (task 1913): shown on the download + detail pages */
520
- #esc-btn{
521
- position:fixed; top:18px; left:20px; z-index:60; display:none; align-items:center; gap:7px;
522
- font-family:var(--cb-font-mono); font-size:12px; font-weight:500; letter-spacing:.3px; color:#fff; cursor:pointer;
523
- background:rgba(24,20,44,.5); border:1px solid rgba(255,255,255,.16); border-radius:999px; padding:7px 14px;
524
- -webkit-backdrop-filter:blur(8px) saturate(1.2); backdrop-filter:blur(8px) saturate(1.2);
525
- box-shadow:0 8px 26px rgba(10,8,25,.4); transition:background .2s ease, transform .2s ease;
526
- }
527
- #esc-btn:hover{ background:rgba(40,34,64,.72); transform:translateY(-1px); }
528
- #esc-btn kbd{ color:var(--cb-ink); background:var(--cb-gold); border-radius:5px; padding:1px 7px; font-family:inherit; }
529
- body.view-download #esc-btn, body.view-detail #esc-btn{ display:inline-flex; }
530
-
531
- /* Moved to the bottom-left (task 2094): the top-right corner now holds the
532
- GitHub identity chip (#cb-account), so the browse toggle steps out of its way. */
533
- #view-toggle{
534
- position:fixed; bottom:18px; left:20px; z-index:35; display:none; gap:2px; padding:3px;
535
- border-radius:999px; background:rgba(24,20,44,.5); border:1px solid rgba(255,255,255,.14);
536
- -webkit-backdrop-filter:blur(8px) saturate(1.2); backdrop-filter:blur(8px) saturate(1.2);
537
- box-shadow:0 8px 26px rgba(10,8,25,.4);
538
- }
539
- body.view-space #view-toggle, body.view-table #view-toggle{ display:flex; }
540
- #view-toggle .vt-btn{
541
- display:flex; align-items:center; gap:7px; border:0; cursor:pointer;
542
- font-family:var(--cb-font-mono); font-size:12px; font-weight:500; letter-spacing:.3px;
543
- color:#d9cebb; background:transparent; padding:7px 15px; border-radius:999px;
544
- transition:background .18s ease, color .18s ease;
545
- }
546
- #view-toggle .vt-btn svg{ width:14px; height:14px; flex:none; }
547
- #view-toggle .vt-btn:hover{ color:#fff; }
548
- #view-toggle .vt-btn.active{
549
- color:var(--cb-ink); background:linear-gradient(180deg,#fde3b4,var(--cb-gold));
550
- box-shadow:0 3px 12px rgba(246,201,118,.4);
551
- }
552
-
553
- /* ─── top-right cluster: enter builders' hall + GitHub identity chip ──────────
554
- A fixed top-right row shown on every post-entry view (orbs, table, download,
555
- detail), so "the way in" (the hall) and "who you are" (the account) always sit
556
- in the same corner. #view-toggle is bottom-left and #esc-btn is top-left, so
557
- the top-right is clear on every view. */
558
- #cb-topright{
559
- position:fixed; top:18px; right:20px; z-index:36; display:none;
560
- align-items:center; gap:10px;
561
- }
562
- body.view-space #cb-topright, body.view-table #cb-topright,
563
- body.view-download #cb-topright, body.view-detail #cb-topright{ display:flex; }
564
-
565
- /* the hall door — a glass pill, deliberately distinct from the gold "Sign in"
566
- chip so the action (enter the hall) and the identity (GitHub login) read as
567
- two separate things sitting side by side. */
568
- .cb-hall{
569
- display:inline-flex; align-items:center; gap:8px; cursor:pointer; text-decoration:none;
570
- font-family:var(--cb-font-mono); font-size:12.5px; font-weight:500; letter-spacing:.3px;
571
- color:#f3ead9; background:rgba(24,20,44,.5); border:1px solid rgba(255,255,255,.14);
572
- border-radius:999px; padding:8px 15px;
573
- -webkit-backdrop-filter:blur(8px) saturate(1.2); backdrop-filter:blur(8px) saturate(1.2);
574
- box-shadow:0 8px 26px rgba(10,8,25,.4);
575
- transition:background .18s ease, transform .16s ease, border-color .18s ease;
576
- }
577
- .cb-hall:hover{ background:rgba(40,34,64,.72); border-color:rgba(255,217,138,.5); transform:translateY(-1px); }
578
- .cb-hall svg{ width:15px; height:15px; flex:none; color:var(--cb-gold); }
579
-
580
- /* GitHub identity chip — the org-page account (task 2094). Now a flex child of
581
- #cb-topright (the fixed positioning moved to the wrapper). Signed out = a
582
- "Sign in with GitHub" button; signed in = the avatar + login with a quiet
583
- sign-out. Populated by space.js from /api/bongos/me. */
584
- #cb-account{
585
- display:flex; align-items:center;
586
- font-family:var(--cb-font-mono); font-size:12.5px; font-weight:500;
587
- }
588
- #cb-account .cb-signin{
589
- display:inline-flex; align-items:center; gap:8px; cursor:pointer; text-decoration:none;
590
- color:var(--cb-ink); background:linear-gradient(180deg,#fde3b4,var(--cb-gold));
591
- border:0; border-radius:999px; padding:8px 16px;
592
- font-family:var(--cb-font-display); font-weight:700; font-size:13px;
593
- box-shadow:0 3px 12px rgba(246,201,118,.42); transition:transform .16s ease, box-shadow .16s ease;
594
- }
595
- #cb-account .cb-signin:hover{ transform:translateY(-1px); box-shadow:0 6px 18px rgba(246,201,118,.5); }
596
- #cb-account .cb-signin svg{ width:15px; height:15px; }
597
- #cb-account .cb-me{
598
- display:inline-flex; align-items:center; gap:9px; padding:5px 12px 5px 6px; border-radius:999px;
599
- background:rgba(24,20,44,.5); border:1px solid rgba(255,255,255,.14); color:#f3ead9;
600
- -webkit-backdrop-filter:blur(8px) saturate(1.2); backdrop-filter:blur(8px) saturate(1.2);
601
- box-shadow:0 8px 26px rgba(10,8,25,.4);
602
- }
603
- #cb-account .cb-me img{ width:28px; height:28px; border-radius:50%; border:1.5px solid rgba(255,217,138,.6); display:block; }
604
- #cb-account .cb-me .cb-out{
605
- color:#b7a88f; text-decoration:none; font-size:11px; margin-left:2px; padding-left:9px;
606
- border-left:1px solid rgba(255,255,255,.16); transition:color .15s ease;
607
- }
608
- #cb-account .cb-me .cb-out:hover{ color:#fff; }
609
- /* Small screens: drop the login name + the hall label, keep the icon + avatar. */
610
- @media (max-width:520px){
611
- #cb-account .cb-name{ display:none; }
612
- .cb-hall__label{ display:none; }
613
- .cb-hall{ padding:8px 11px; }
614
- }
615
-
616
- /* Signed-out: the create-a-project affordances rest grayed + nudge sign-in first
617
- (task 2094). The ghost orb loses its gold glow + pulse; the table's create
618
- button dims. space.js relabels the ghost + routes the click to the sign-in
619
- prompt instead of the name field. */
620
- #ghost-orb.locked{
621
- border-color:rgba(255,255,255,.3);
622
- background:radial-gradient(circle at 50% 42%, rgba(255,255,255,.07), rgba(255,255,255,0) 68%);
623
- }
624
- #ghost-orb.locked .ghost-plus{ color:#b9ac97; text-shadow:none; }
625
- #ghost-orb.locked.show{ animation:none; }
626
- #table-view .tv-add.locked{ opacity:.5; }
627
-
628
- /* Signed-out create gate — the sign-in prompt shown when a signed-out visitor
629
- tries to create a project. Shares the create panel's look + the overlay-scrim
630
- entrance (task 2094). */
631
- #signinpanel{
632
- width:min(420px,92vw); border-radius:18px; padding:24px 24px 22px;
633
- background:linear-gradient(180deg, rgba(38,30,60,.96), rgba(24,20,44,.96));
634
- border:1px solid rgba(255,255,255,.16); box-shadow:0 26px 70px rgba(6,4,20,.6);
635
- color:#fff; font-family:var(--cb-font-display);
636
- transform:translateY(10px) scale(.98); opacity:0;
637
- transition:opacity .24s ease, transform .24s cubic-bezier(.2,.9,.3,1.1);
638
- }
639
- .overlay-scrim.show #signinpanel{ transform:none; opacity:1; }
640
- #signinpanel h3{ font-weight:700; font-size:20px; }
641
- #signinpanel p.sub{ margin-top:6px; font-size:13px; color:#d9cebb; line-height:1.5; }
642
- #signinpanel .signin-go{
643
- margin-top:20px; width:100%; display:inline-flex; align-items:center; justify-content:center; gap:9px;
644
- text-decoration:none; cursor:pointer; border:0; border-radius:12px; padding:13px 20px;
645
- font-family:var(--cb-font-display); font-weight:700; font-size:15px;
646
- color:var(--cb-ink); background:linear-gradient(180deg,#fde3b4,var(--cb-gold));
647
- box-shadow:0 8px 22px rgba(246,201,118,.45); transition:filter .16s ease, transform .16s ease;
648
- }
649
- #signinpanel .signin-go:hover{ filter:brightness(1.04); transform:translateY(-1px); }
650
- #signinpanel .signin-go svg{ width:18px; height:18px; }
651
- #signinpanel .signin-dismiss{
652
- margin-top:12px; width:100%; background:transparent; border:0; cursor:pointer;
653
- color:#9c8f7d; font-family:var(--cb-font-mono); font-size:12px; transition:color .15s ease;
654
- }
655
- #signinpanel .signin-dismiss:hover{ color:#d9cebb; }
656
-
657
- /* ─── the table pane ─── */
658
- #table-view{
659
- display:none; position:fixed; inset:0; z-index:15;
660
- flex-direction:column; align-items:center; padding:74px 24px 22px;
661
- }
662
- body.view-table #table-view{ display:flex; }
663
-
664
- #table-view .tv-head{
665
- width:min(1040px,94vw); display:flex; align-items:center; gap:16px; flex-wrap:wrap; margin-bottom:16px;
666
- }
667
- #table-view .tv-mark{
668
- display:flex; align-items:center; gap:10px; flex:none;
669
- font-family:var(--cb-font-display); font-weight:700; font-size:20px; color:var(--cb-gold);
670
- text-shadow:0 2px 12px rgba(20,12,30,.6);
671
- }
672
- #table-view .tv-mark b{ color:var(--cb-gold); }
673
- #table-view .tv-mark .tv-sub{ font-family:var(--cb-font-mono); font-weight:500; font-size:12px; color:#9c8f7d; margin-left:2px; }
674
-
675
- #table-view .tv-search{
676
- flex:1; min-width:210px; display:flex; align-items:center; gap:10px; height:46px; padding:0 16px;
677
- border-radius:13px; background:rgba(255,250,242,.1); border:1px solid rgba(255,255,255,.2);
678
- -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px); transition:border-color .18s ease, box-shadow .18s ease;
679
- }
680
- #table-view .tv-search:focus-within{ border-color:var(--cb-gold); box-shadow:0 0 0 3px rgba(255,217,138,.18); }
681
- #table-view .tv-search .mag{ width:18px; height:18px; color:var(--cb-gold); flex:none; }
682
- #table-view .tv-search input{
683
- flex:1; min-width:0; background:transparent; border:0; outline:0; color:#fff;
684
- font-family:var(--cb-font-mono); font-size:14.5px;
685
- }
686
- #table-view .tv-search input::placeholder{ color:rgba(255,246,235,.5); }
687
- #table-view .tv-count{ font-family:var(--cb-font-mono); font-size:11px; color:#9c8f7d; flex:none; white-space:nowrap; }
688
-
689
- #table-view .tv-add{
690
- flex:none; display:flex; align-items:center; gap:7px; height:46px; padding:0 16px; border-radius:12px; cursor:pointer;
691
- border:1px solid rgba(255,255,255,.2); background:rgba(255,255,255,.06); color:#f3ead9;
692
- font-family:var(--cb-font-display); font-weight:700; font-size:13px; transition:background .16s ease;
693
- }
694
- #table-view .tv-add:hover{ background:rgba(255,255,255,.12); }
695
- #table-view .tv-add .plus{ font-size:17px; line-height:1; color:var(--cb-gold); margin-top:-1px; }
696
-
697
- /* ─── scroll container: table scrolls inside its own pane, page never does ─── */
698
- #table-view .tv-scroll{
699
- width:min(1040px,94vw); flex:1 1 auto; min-height:0; overflow:auto;
700
- border-radius:16px; border:1px solid rgba(255,255,255,.1); background:rgba(18,15,38,.55);
701
- -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px); box-shadow:0 20px 60px rgba(8,6,22,.5);
702
- }
703
- #table-view table{ width:100%; border-collapse:collapse; min-width:620px; }
704
-
705
- #table-view thead th{
706
- position:sticky; top:0; z-index:2; text-align:left; padding:14px 18px;
707
- font-family:var(--cb-font-mono); font-size:11px; font-weight:500; letter-spacing:.6px; text-transform:uppercase; color:#9c8f7d;
708
- background:rgba(20,17,42,.94); -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
709
- border-bottom:1px solid rgba(255,255,255,.1); white-space:nowrap;
710
- }
711
- #table-view thead th.num{ text-align:right; }
712
- #table-view th.sortable{ cursor:pointer; user-select:none; transition:color .15s ease; }
713
- #table-view th.sortable:hover{ color:#f3ead9; }
714
- #table-view th.sorted{ color:var(--cb-gold); }
715
- #table-view th .sort-ind{ display:inline-block; width:10px; margin-left:5px; font-size:9px; }
716
-
717
- #table-view tbody td{ padding:12px 18px; border-bottom:1px solid rgba(255,255,255,.06); vertical-align:middle; }
718
- #table-view tbody tr:last-child td{ border-bottom:0; }
719
- #table-view .tv-row{ cursor:pointer; transition:background .14s ease; }
720
- #table-view .tv-row:hover{ background:rgba(255,255,255,.05); }
721
-
722
- #table-view .tv-proj{ display:flex; align-items:center; gap:12px; }
723
- #table-view .tv-dot{ width:12px; height:12px; border-radius:50%; flex:none;
724
- background:radial-gradient(circle at 34% 30%, rgba(255,255,255,.85), var(--acc,#fb923c) 72%);
725
- box-shadow:0 0 12px var(--acc,#fb923c); }
726
- #table-view .tv-proj-txt{ display:flex; flex-direction:column; min-width:0; }
727
- #table-view .tv-name{ font-family:var(--cb-font-display); font-weight:700; font-size:15px; color:#fff; display:flex; align-items:center; gap:8px; }
728
- #table-view .tv-self{ font-family:var(--cb-font-mono); font-size:9px; font-weight:500; letter-spacing:.4px;
729
- color:var(--cb-ink); background:var(--cb-gold); padding:2px 7px; border-radius:999px; white-space:nowrap; }
730
- #table-view .tv-tag{ font-size:12.5px; color:#b9ab98; margin-top:2px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:360px; }
731
-
732
- #table-view .tv-num{ text-align:right; font-family:var(--cb-font-mono); font-size:15px; font-weight:500; color:var(--cb-gold); }
733
- #table-view .tv-pill{ display:inline-block; font-family:var(--cb-font-mono); font-size:10.5px; font-weight:500; letter-spacing:.3px; padding:3px 10px; border-radius:999px; white-space:nowrap; }
734
- #table-view .tp-self{ color:#3a1c07; background:var(--cb-gold); }
735
- #table-view .tp-live{ color:#bfe9ff; background:rgba(56,189,248,.16); border:1px solid rgba(56,189,248,.4); }
736
- #table-view .tp-sample{ color:#d9cebb; background:rgba(255,255,255,.08); border:1px solid rgba(255,255,255,.16); }
737
-
738
- #table-view .tv-tags{ }
739
- #table-view .tv-tagwrap{ display:flex; flex-wrap:wrap; gap:5px; }
740
- #table-view .tv-chip{ font-family:var(--cb-font-mono); font-size:10px; color:#cdbfae; background:rgba(255,255,255,.06);
741
- border:1px solid rgba(255,255,255,.12); padding:2px 8px; border-radius:6px; white-space:nowrap; }
742
-
743
- #table-view .tv-act{ text-align:right; white-space:nowrap; }
744
- #table-view .tv-go{ font-family:var(--cb-font-mono); font-size:12px; color:var(--cb-gold); background:transparent;
745
- border:1px solid rgba(255,217,138,.4); border-radius:9px; padding:7px 13px; cursor:pointer; transition:background .15s ease, color .15s ease; }
746
- #table-view .tv-row:hover .tv-go{ background:var(--cb-gold); color:var(--cb-ink); }
747
-
748
- #table-view .tv-empty{ padding:34px 18px; text-align:center; font-family:var(--cb-font-mono); font-size:13px; color:#9c8f7d; }
749
- #table-view .tv-foot{ margin-top:13px; font-family:var(--cb-font-mono); font-size:11px; color:#8a7d6f; text-shadow:0 1px 6px rgba(20,12,30,.6); }
750
- #table-view .tv-foot kbd{ color:var(--cb-ink); background:var(--cb-gold); border-radius:5px; padding:1px 7px; }
751
-
752
- /* narrow screens: drop the tags + action columns so Project / Builders / Type
753
- fit without a horizontal scroll (a row tap still opens the project); let the
754
- table shrink to the container and tighten padding. */
755
- @media (max-width:760px){
756
- #table-view{ padding:70px 12px 18px; }
757
- #table-view .col-tags, #table-view .tv-tags,
758
- #table-view .col-act, #table-view .tv-act{ display:none; }
759
- #table-view table{ min-width:0; }
760
- #table-view thead th, #table-view tbody td{ padding-left:13px; padding-right:13px; }
761
- #table-view .tv-tag{ max-width:52vw; }
762
- #table-view .tv-head{ gap:12px; }
763
- #table-view .tv-mark .tv-sub{ display:none; }
764
- }
765
- /* very narrow phones: also drop the Type column so Project + the Builders stat
766
- sit flush with no horizontal scroll. */
767
- @media (max-width:560px){
768
- #table-view .col-type{ display:none; }
769
- }
770
-
771
- /* ── Bongo Buddha idle on the download page, above the search bar (task 1732,
772
- ADR 0088) — the shipped idle sprite floating on a THIN painterly cloud + a
773
- warm glow. The cloud is plate-clouds-near (the page's own wisp), not the
774
- bubbly cloud-puff, so the buddha's cloud reads on-theme. Scoped inside #land,
775
- which only renders in view-download; frames injected + cycled by space.js.
776
- It carries no .el/.mark class, so the stage drag script never grabs it. */
777
- #buddha{
778
- position:relative; width:250px; height:206px; margin-bottom:2px;
779
- pointer-events:none; animation:buddhaFloat 5.4s ease-in-out infinite;
780
- }
781
- #buddha .buddha-glow{
782
- position:absolute; left:50%; top:37%; width:245px; height:195px;
783
- transform:translate(-50%,-50%); pointer-events:none;
784
- background:radial-gradient(closest-side, rgba(255,206,112,.58), rgba(255,190,80,.16) 58%, transparent 75%);
785
- }
786
- #buddha .buddha-cloud{
787
- position:absolute; left:50%; bottom:2px; width:330px; transform:translateX(-50%);
788
- pointer-events:none; -webkit-user-drag:none; user-drag:none;
789
- filter:drop-shadow(0 4px 12px rgba(90,70,120,.3));
790
- }
791
- #buddha .buddha-fig{
792
- position:absolute; left:50%; top:0; width:205px; aspect-ratio:380/320;
793
- transform:translateX(-50%);
794
- }
795
- #buddha .buddha-fig img{
796
- position:absolute; inset:0; width:100%; height:100%; pointer-events:none;
797
- -webkit-user-drag:none; user-drag:none;
798
- filter:drop-shadow(0 8px 16px rgba(20,12,30,.42));
799
- }
800
- @keyframes buddhaFloat{ 0%,100%{transform:translateY(0)} 50%{transform:translateY(-6px)} }
801
-
802
- /* reduced-motion: keep everything usable, just calmer */
803
- @media (prefers-reduced-motion:reduce){
804
- .star{ animation:none !important; }
805
- #descent, #descent.playing{ display:none !important; }
806
- .descent-stars, .descent-glow, .descent-island, .descent-deck, .ic, .descent-flash{ animation:none !important; }
807
- #buddha{ animation:none !important; }
808
- #view-toggle .vt-btn, #table-view .tv-row, #table-view .tv-go, #table-view .tv-search{ transition:none; }
809
- }