stagecraft 0.1.0

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.
Files changed (133) hide show
  1. package/AGENT.md +792 -0
  2. package/LICENSE +21 -0
  3. package/README.md +210 -0
  4. package/bin/cli.js +51 -0
  5. package/bin/export.js +137 -0
  6. package/bin/init.js +52 -0
  7. package/bin/lib/edit-ops.js +405 -0
  8. package/bin/serve.js +278 -0
  9. package/dist/stagecraft.bundle.css +4443 -0
  10. package/dist/stagecraft.bundle.js +7621 -0
  11. package/dist/themes/brand.bundle.css +5262 -0
  12. package/dist/themes/neon.bundle.css +5289 -0
  13. package/dist/themes/paper.bundle.css +5276 -0
  14. package/dist/themes/phosphor.bundle.css +4443 -0
  15. package/dist/themes/shopware.bundle.css +5850 -0
  16. package/examples/closing-card.js +74 -0
  17. package/examples/orchestration-graph.js +156 -0
  18. package/examples/terminal-log.js +109 -0
  19. package/examples/token-stream.js +96 -0
  20. package/examples/whoami.js +90 -0
  21. package/package.json +41 -0
  22. package/src/components/activity-list.js +75 -0
  23. package/src/components/agenda.js +79 -0
  24. package/src/components/bar-chart.js +162 -0
  25. package/src/components/before-after.js +135 -0
  26. package/src/components/bento.js +73 -0
  27. package/src/components/big-number.js +87 -0
  28. package/src/components/callout.js +75 -0
  29. package/src/components/checklist.js +81 -0
  30. package/src/components/code-block.js +141 -0
  31. package/src/components/code-diff.js +98 -0
  32. package/src/components/compare.js +85 -0
  33. package/src/components/counter.js +80 -0
  34. package/src/components/cta.js +69 -0
  35. package/src/components/cycle.js +146 -0
  36. package/src/components/definition.js +96 -0
  37. package/src/components/donut-chart.js +179 -0
  38. package/src/components/full-image.js +82 -0
  39. package/src/components/funnel.js +111 -0
  40. package/src/components/gauge.js +147 -0
  41. package/src/components/heatmap.js +141 -0
  42. package/src/components/image-grid.js +80 -0
  43. package/src/components/image-text.js +96 -0
  44. package/src/components/kinetic-text.js +72 -0
  45. package/src/components/kpi.js +106 -0
  46. package/src/components/line-chart.js +215 -0
  47. package/src/components/manifesto.js +104 -0
  48. package/src/components/marquee.js +63 -0
  49. package/src/components/matrix2x2.js +151 -0
  50. package/src/components/pillars.js +80 -0
  51. package/src/components/pricing.js +90 -0
  52. package/src/components/process-flow.js +133 -0
  53. package/src/components/progress.js +136 -0
  54. package/src/components/punchline.js +82 -0
  55. package/src/components/pyramid.js +107 -0
  56. package/src/components/qanda.js +60 -0
  57. package/src/components/quote.js +70 -0
  58. package/src/components/roadmap.js +130 -0
  59. package/src/components/section-card.js +45 -0
  60. package/src/components/shift-arrow.js +41 -0
  61. package/src/components/spark-line.js +147 -0
  62. package/src/components/spotlight.js +85 -0
  63. package/src/components/statement.js +106 -0
  64. package/src/components/stats.js +91 -0
  65. package/src/components/steps.js +83 -0
  66. package/src/components/swot.js +110 -0
  67. package/src/components/team-grid.js +87 -0
  68. package/src/components/testimonial.js +99 -0
  69. package/src/components/timeline.js +91 -0
  70. package/src/components/tip.js +63 -0
  71. package/src/components/venn.js +198 -0
  72. package/src/edit-mode.js +1256 -0
  73. package/src/engine.js +823 -0
  74. package/src/helpers.js +169 -0
  75. package/src/transitions.js +101 -0
  76. package/starter/index.html +40 -0
  77. package/starter/slides/00-title.js +12 -0
  78. package/starter/stagecraft.config.js +8 -0
  79. package/themes/brand/base.css +4 -0
  80. package/themes/brand/components-business.css +173 -0
  81. package/themes/brand/components-chart.css +65 -0
  82. package/themes/brand/components-content.css +126 -0
  83. package/themes/brand/components-data.css +162 -0
  84. package/themes/brand/components-diagram.css +115 -0
  85. package/themes/brand/components-layout.css +112 -0
  86. package/themes/brand/components.css +46 -0
  87. package/themes/brand/manifest.json +20 -0
  88. package/themes/brand/tokens.css +20 -0
  89. package/themes/brand/transitions.css +4 -0
  90. package/themes/neon/base.css +10 -0
  91. package/themes/neon/components-business.css +189 -0
  92. package/themes/neon/components-chart.css +70 -0
  93. package/themes/neon/components-content.css +112 -0
  94. package/themes/neon/components-data.css +160 -0
  95. package/themes/neon/components-diagram.css +109 -0
  96. package/themes/neon/components-layout.css +87 -0
  97. package/themes/neon/components.css +87 -0
  98. package/themes/neon/manifest.json +21 -0
  99. package/themes/neon/tokens.css +17 -0
  100. package/themes/neon/transitions.css +13 -0
  101. package/themes/paper/base.css +9 -0
  102. package/themes/paper/components-business.css +196 -0
  103. package/themes/paper/components-chart.css +74 -0
  104. package/themes/paper/components-content.css +108 -0
  105. package/themes/paper/components-data.css +168 -0
  106. package/themes/paper/components-diagram.css +89 -0
  107. package/themes/paper/components-layout.css +105 -0
  108. package/themes/paper/components.css +60 -0
  109. package/themes/paper/manifest.json +10 -0
  110. package/themes/paper/tokens.css +21 -0
  111. package/themes/paper/transitions.css +11 -0
  112. package/themes/phosphor/base.css +511 -0
  113. package/themes/phosphor/components-business.css +818 -0
  114. package/themes/phosphor/components-chart.css +415 -0
  115. package/themes/phosphor/components-content.css +530 -0
  116. package/themes/phosphor/components-data.css +824 -0
  117. package/themes/phosphor/components-diagram.css +427 -0
  118. package/themes/phosphor/components-layout.css +450 -0
  119. package/themes/phosphor/components.css +223 -0
  120. package/themes/phosphor/manifest.json +11 -0
  121. package/themes/phosphor/tokens.css +17 -0
  122. package/themes/phosphor/transitions.css +213 -0
  123. package/themes/shopware/base.css +94 -0
  124. package/themes/shopware/components-business.css +344 -0
  125. package/themes/shopware/components-chart.css +121 -0
  126. package/themes/shopware/components-content.css +169 -0
  127. package/themes/shopware/components-data.css +219 -0
  128. package/themes/shopware/components-diagram.css +129 -0
  129. package/themes/shopware/components-layout.css +166 -0
  130. package/themes/shopware/components.css +83 -0
  131. package/themes/shopware/manifest.json +21 -0
  132. package/themes/shopware/tokens.css +68 -0
  133. package/themes/shopware/transitions.css +22 -0
@@ -0,0 +1,530 @@
1
+ /* Stagecraft — Phosphor theme: content/typography components. */
2
+
3
+ /* ---------------------------------------------------------------------------
4
+ * Statement
5
+ * ------------------------------------------------------------------------- */
6
+ .statement-host {
7
+ padding: clamp(2rem, 5vw, 4rem);
8
+ }
9
+ .statement {
10
+ width: min(1500px, 92vw);
11
+ text-align: center;
12
+ }
13
+ .statement-text {
14
+ margin: 0;
15
+ font-size: clamp(3rem, 9vw, 9rem);
16
+ font-weight: 500;
17
+ letter-spacing: -0.04em;
18
+ line-height: 1.02;
19
+ color: var(--fg);
20
+ /* word spans need to be inline-block so transform works */
21
+ }
22
+ .statement .st-word {
23
+ display: inline-block;
24
+ opacity: 0;
25
+ transform: translateY(14px);
26
+ filter: blur(6px);
27
+ transition:
28
+ opacity 600ms ease-out,
29
+ transform 700ms cubic-bezier(0.16, 1, 0.3, 1),
30
+ filter 600ms ease-out;
31
+ }
32
+ .statement .st-word.in {
33
+ opacity: 1;
34
+ transform: translateY(0);
35
+ filter: blur(0);
36
+ }
37
+ .statement .st-em {
38
+ color: var(--accent);
39
+ text-shadow: 0 0 30px var(--accent-glow);
40
+ }
41
+ .statement .st-em--amber { color: var(--amber); text-shadow: 0 0 22px rgba(255, 180, 84, 0.35); }
42
+ .statement .st-em--blue { color: var(--blue); text-shadow: 0 0 24px rgba(24, 158, 255, 0.4); }
43
+
44
+ /* ---------------------------------------------------------------------------
45
+ * QandA
46
+ * ------------------------------------------------------------------------- */
47
+ .qanda {
48
+ width: min(1200px, 92vw);
49
+ display: flex;
50
+ flex-direction: column;
51
+ align-items: center;
52
+ text-align: center;
53
+ gap: clamp(1.5rem, 4vw, 3rem);
54
+ }
55
+ .qa-q {
56
+ font-size: clamp(1.6rem, 3.5vw, 2.6rem);
57
+ font-style: italic;
58
+ font-weight: 400;
59
+ color: var(--amber);
60
+ letter-spacing: -0.01em;
61
+ line-height: 1.25;
62
+ max-width: 28ch;
63
+ opacity: 0;
64
+ transform: translateY(12px);
65
+ transition: opacity 800ms ease-out, transform 900ms cubic-bezier(0.16, 1, 0.3, 1);
66
+ }
67
+ .qa-q::before { content: '? '; color: var(--dim-2); font-style: normal; }
68
+ .qa-q.in { opacity: 1; transform: translateY(0); }
69
+
70
+ .qa-a {
71
+ font-size: clamp(2.5rem, 6.5vw, 5.5rem);
72
+ font-weight: 500;
73
+ color: var(--accent);
74
+ letter-spacing: -0.03em;
75
+ line-height: 1.05;
76
+ text-shadow: 0 0 40px var(--accent-glow);
77
+ max-width: 22ch;
78
+ opacity: 0;
79
+ transform: translateY(20px) scale(0.98);
80
+ transition: opacity 900ms ease-out, transform 1100ms cubic-bezier(0.16, 1, 0.3, 1);
81
+ }
82
+ .qa-a.in { opacity: 1; transform: translateY(0) scale(1); }
83
+
84
+ .qa-attr {
85
+ font-size: clamp(0.85rem, 1.1vw, 1rem);
86
+ color: var(--dim);
87
+ letter-spacing: 0.08em;
88
+ text-transform: uppercase;
89
+ opacity: 0;
90
+ transition: opacity 800ms ease-out;
91
+ }
92
+ .qa-attr.in { opacity: 1; }
93
+
94
+ /* ---------------------------------------------------------------------------
95
+ * Manifesto
96
+ * ------------------------------------------------------------------------- */
97
+ .manifesto {
98
+ width: min(1300px, 92vw);
99
+ display: flex;
100
+ flex-direction: column;
101
+ gap: clamp(1rem, 2.5vw, 2rem);
102
+ }
103
+ .mf-intro {
104
+ font-size: clamp(0.95rem, 1.3vw, 1.15rem);
105
+ color: var(--dim);
106
+ letter-spacing: 0.1em;
107
+ text-transform: uppercase;
108
+ opacity: 0;
109
+ transform: translateY(6px);
110
+ transition: opacity 700ms ease-out, transform 800ms ease-out;
111
+ }
112
+ .mf-intro.in { opacity: 1; transform: translateY(0); }
113
+
114
+ .mf-list {
115
+ list-style: none;
116
+ margin: 0;
117
+ padding: 0;
118
+ display: flex;
119
+ flex-direction: column;
120
+ gap: clamp(0.8rem, 1.6vw, 1.4rem);
121
+ }
122
+ .mf-item {
123
+ display: grid;
124
+ grid-template-columns: clamp(3rem, 6vw, 5rem) 1fr;
125
+ align-items: baseline;
126
+ gap: clamp(1rem, 2.5vw, 2rem);
127
+ padding-bottom: clamp(0.6rem, 1.4vw, 1.1rem);
128
+ border-bottom: 1px solid var(--dim-2);
129
+ opacity: 0;
130
+ transform: translateX(-14px);
131
+ transition: opacity 700ms ease-out, transform 800ms cubic-bezier(0.16, 1, 0.3, 1), border-color 600ms ease;
132
+ }
133
+ .mf-item:last-child { border-bottom: none; }
134
+ .mf-item.in { opacity: 1; transform: translateX(0); }
135
+ .mf-item.in { border-color: var(--dim-2); }
136
+
137
+ .mf-num {
138
+ font-size: clamp(1.5rem, 2.8vw, 2.2rem);
139
+ font-weight: 300;
140
+ color: var(--accent);
141
+ font-variant-numeric: tabular-nums;
142
+ letter-spacing: -0.02em;
143
+ text-shadow: 0 0 18px var(--accent-glow);
144
+ }
145
+ .mf-text {
146
+ font-size: clamp(1.4rem, 2.6vw, 2.2rem);
147
+ color: var(--fg);
148
+ font-weight: 400;
149
+ line-height: 1.25;
150
+ letter-spacing: -0.015em;
151
+ }
152
+ .mf-text .mf-em {
153
+ color: var(--accent);
154
+ font-weight: 500;
155
+ }
156
+
157
+ /* ---------------------------------------------------------------------------
158
+ * Punchline
159
+ * ------------------------------------------------------------------------- */
160
+ .punchline {
161
+ width: min(1300px, 92vw);
162
+ display: flex;
163
+ flex-direction: column;
164
+ align-items: center;
165
+ text-align: center;
166
+ gap: clamp(2rem, 5vw, 4rem);
167
+ }
168
+ .pl-buildup {
169
+ display: flex;
170
+ flex-direction: column;
171
+ gap: clamp(0.6rem, 1.4vw, 1.1rem);
172
+ }
173
+ .pl-line {
174
+ font-size: clamp(1.1rem, 1.8vw, 1.5rem);
175
+ color: var(--dim);
176
+ letter-spacing: -0.01em;
177
+ line-height: 1.4;
178
+ opacity: 0;
179
+ transform: translateY(8px);
180
+ transition: opacity 700ms ease-out, transform 800ms cubic-bezier(0.16, 1, 0.3, 1);
181
+ }
182
+ .pl-line.in { opacity: 1; transform: translateY(0); }
183
+
184
+ .pl-payoff {
185
+ font-size: clamp(3rem, 8vw, 7rem);
186
+ font-weight: 500;
187
+ color: var(--accent);
188
+ letter-spacing: -0.04em;
189
+ line-height: 1.05;
190
+ text-shadow: 0 0 50px var(--accent-glow);
191
+ max-width: 22ch;
192
+ opacity: 0;
193
+ transform: translateY(24px) scale(0.97);
194
+ filter: blur(8px);
195
+ transition:
196
+ opacity 900ms ease-out,
197
+ transform 1200ms cubic-bezier(0.16, 1, 0.3, 1),
198
+ filter 800ms ease-out;
199
+ }
200
+ .pl-payoff.in { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); }
201
+
202
+ /* ---------------------------------------------------------------------------
203
+ * Definition
204
+ * ------------------------------------------------------------------------- */
205
+ .definition {
206
+ width: min(1100px, 92vw);
207
+ display: flex;
208
+ flex-direction: column;
209
+ gap: clamp(1rem, 2vw, 1.6rem);
210
+ }
211
+ .df-head {
212
+ display: flex;
213
+ align-items: baseline;
214
+ gap: 0.6rem;
215
+ border-bottom: 1px solid var(--dim-2);
216
+ padding-bottom: clamp(0.6rem, 1.2vw, 1rem);
217
+ }
218
+ .df-term {
219
+ margin: 0;
220
+ font-size: clamp(4rem, 11vw, 9rem);
221
+ font-weight: 500;
222
+ letter-spacing: -0.04em;
223
+ line-height: 1;
224
+ color: var(--fg);
225
+ opacity: 0;
226
+ transform: translateY(14px);
227
+ transition: opacity 800ms ease-out, transform 900ms cubic-bezier(0.16, 1, 0.3, 1);
228
+ }
229
+ .df-term.in { opacity: 1; transform: translateY(0); }
230
+ .df-pos {
231
+ font-size: clamp(1rem, 1.6vw, 1.3rem);
232
+ color: var(--dim);
233
+ font-style: italic;
234
+ letter-spacing: 0.04em;
235
+ opacity: 0;
236
+ transition: opacity 800ms ease-out;
237
+ }
238
+ .df-pos.in { opacity: 1; }
239
+
240
+ .df-def {
241
+ margin: 0;
242
+ font-size: clamp(1.4rem, 2.4vw, 2rem);
243
+ font-weight: 400;
244
+ color: var(--fg);
245
+ line-height: 1.35;
246
+ letter-spacing: -0.01em;
247
+ opacity: 0;
248
+ transform: translateY(10px);
249
+ transition: opacity 800ms ease-out, transform 900ms ease-out;
250
+ }
251
+ .df-def.in { opacity: 1; transform: translateY(0); }
252
+ .df-def::before {
253
+ content: '1. ';
254
+ color: var(--accent);
255
+ font-weight: 500;
256
+ }
257
+
258
+ .df-ety {
259
+ margin: 0;
260
+ font-size: clamp(0.95rem, 1.3vw, 1.15rem);
261
+ font-style: italic;
262
+ color: var(--dim);
263
+ line-height: 1.4;
264
+ letter-spacing: 0.01em;
265
+ opacity: 0;
266
+ transition: opacity 800ms ease-out;
267
+ }
268
+ .df-ety::before { content: 'origin · '; color: var(--dim-2); font-style: normal; letter-spacing: 0.08em; text-transform: uppercase; }
269
+ .df-ety.in { opacity: 1; }
270
+
271
+ .df-examples {
272
+ margin: clamp(0.6rem, 1.5vw, 1.2rem) 0 0;
273
+ padding: 0;
274
+ list-style: none;
275
+ display: flex;
276
+ flex-direction: column;
277
+ gap: 0.7rem;
278
+ border-top: 1px dashed var(--dim-2);
279
+ padding-top: clamp(0.8rem, 1.6vw, 1.2rem);
280
+ }
281
+ .df-ex {
282
+ font-size: clamp(1rem, 1.5vw, 1.25rem);
283
+ color: var(--dim);
284
+ font-style: italic;
285
+ line-height: 1.4;
286
+ opacity: 0;
287
+ transform: translateY(6px);
288
+ transition: opacity 700ms ease-out, transform 800ms ease-out;
289
+ }
290
+ .df-ex.in { opacity: 1; transform: translateY(0); }
291
+ .df-ex::before { content: '“'; color: var(--dim-2); font-style: normal; }
292
+ .df-ex::after { content: '”'; color: var(--dim-2); font-style: normal; }
293
+ .df-mark {
294
+ color: var(--accent);
295
+ font-style: normal;
296
+ font-weight: 500;
297
+ background: var(--accent-soft);
298
+ padding: 0 0.2em;
299
+ }
300
+
301
+ /* ---------------------------------------------------------------------------
302
+ * ImageGrid
303
+ * ------------------------------------------------------------------------- */
304
+ .image-grid {
305
+ display: grid;
306
+ gap: clamp(1rem, 2vw, 1.8rem);
307
+ width: min(1500px, 94vw);
308
+ }
309
+ .image-grid.ig-cols-2 { grid-template-columns: repeat(2, 1fr); }
310
+ .image-grid.ig-cols-3 { grid-template-columns: repeat(3, 1fr); }
311
+ .image-grid.ig-cols-4 { grid-template-columns: repeat(4, 1fr); }
312
+
313
+ .ig-cell {
314
+ margin: 0;
315
+ display: flex;
316
+ flex-direction: column;
317
+ gap: 0.6rem;
318
+ opacity: 0;
319
+ transform: translateY(20px);
320
+ transition:
321
+ opacity 700ms ease-out,
322
+ transform 900ms cubic-bezier(0.16, 1, 0.3, 1);
323
+ }
324
+ .ig-cell.in { opacity: 1; transform: translateY(0) rotate(0); }
325
+
326
+ /* cascade: each cell falls in with a small rotation that resolves to zero */
327
+ .image-grid.ig--cascade .ig-cell {
328
+ transform: translateY(-30px) rotate(-3deg);
329
+ }
330
+ .image-grid.ig--cascade .ig-cell:nth-child(even) {
331
+ transform: translateY(-30px) rotate(3deg);
332
+ }
333
+ .image-grid.ig--cascade .ig-cell.in {
334
+ transform: translateY(0) rotate(0);
335
+ }
336
+
337
+ .ig-frame {
338
+ position: relative;
339
+ aspect-ratio: 3 / 2;
340
+ overflow: hidden;
341
+ background: var(--bg-elevated);
342
+ border: 1px solid var(--dim-2);
343
+ }
344
+ .ig-frame::after {
345
+ content: '';
346
+ position: absolute;
347
+ inset: 0;
348
+ pointer-events: none;
349
+ box-shadow:
350
+ inset 0 0 0 1px rgba(0,0,0,0.4),
351
+ 0 20px 50px -20px rgba(0,0,0,0.7);
352
+ }
353
+ .ig-img {
354
+ width: 100%;
355
+ height: 100%;
356
+ object-fit: cover;
357
+ display: block;
358
+ filter: saturate(0.92) contrast(1.04);
359
+ transition: transform 800ms ease-out, filter 600ms ease-out;
360
+ }
361
+ .ig-cell:hover .ig-img {
362
+ transform: scale(1.03);
363
+ filter: saturate(1) contrast(1.06);
364
+ }
365
+ .ig-cap {
366
+ font-size: clamp(0.85rem, 1.1vw, 1rem);
367
+ color: var(--dim);
368
+ letter-spacing: 0.06em;
369
+ text-transform: uppercase;
370
+ line-height: 1.4;
371
+ }
372
+
373
+ @media (max-width: 900px) {
374
+ .image-grid.ig-cols-4 { grid-template-columns: repeat(2, 1fr); }
375
+ .image-grid.ig-cols-3 { grid-template-columns: repeat(2, 1fr); }
376
+ }
377
+ @media (max-width: 540px) {
378
+ .image-grid.ig-cols-2,
379
+ .image-grid.ig-cols-3,
380
+ .image-grid.ig-cols-4 { grid-template-columns: 1fr; }
381
+ }
382
+
383
+ /* ---------------------------------------------------------------------------
384
+ * Spotlight
385
+ * ------------------------------------------------------------------------- */
386
+ .spotlight {
387
+ width: min(1300px, 92vw);
388
+ display: flex;
389
+ flex-direction: column;
390
+ align-items: center;
391
+ gap: clamp(2rem, 4vw, 3.5rem);
392
+ }
393
+ .sp-focus {
394
+ display: flex;
395
+ align-items: center;
396
+ gap: clamp(1rem, 2.5vw, 2rem);
397
+ padding: clamp(1.5rem, 3vw, 2.5rem) clamp(2rem, 4vw, 3.5rem);
398
+ background: var(--bg-elevated);
399
+ border: 1px solid var(--accent);
400
+ box-shadow:
401
+ 0 0 0 1px var(--accent-soft),
402
+ 0 0 60px -10px var(--accent-glow),
403
+ 0 30px 80px -30px rgba(0,0,0,0.7);
404
+ max-width: 56rem;
405
+ opacity: 0;
406
+ transform: translateY(20px) scale(0.97);
407
+ transition: opacity 800ms ease-out, transform 1000ms cubic-bezier(0.16, 1, 0.3, 1);
408
+ }
409
+ .sp-focus.in { opacity: 1; transform: translateY(0) scale(1); }
410
+
411
+ .sp-icon {
412
+ font-size: clamp(3rem, 5vw, 4.5rem);
413
+ color: var(--accent);
414
+ text-shadow: 0 0 30px var(--accent-glow);
415
+ line-height: 1;
416
+ }
417
+ .sp-focus-text {
418
+ display: flex;
419
+ flex-direction: column;
420
+ gap: 0.4rem;
421
+ }
422
+ .sp-heading {
423
+ font-size: clamp(2rem, 4.5vw, 3.4rem);
424
+ font-weight: 500;
425
+ letter-spacing: -0.03em;
426
+ line-height: 1.05;
427
+ color: var(--accent);
428
+ }
429
+ .sp-body {
430
+ font-size: clamp(1rem, 1.5vw, 1.25rem);
431
+ color: var(--fg);
432
+ line-height: 1.4;
433
+ max-width: 38ch;
434
+ }
435
+
436
+ .sp-context {
437
+ display: flex;
438
+ flex-wrap: wrap;
439
+ justify-content: center;
440
+ gap: clamp(1rem, 2.5vw, 2rem) clamp(1.4rem, 3vw, 2.6rem);
441
+ padding-top: clamp(1rem, 2vw, 1.6rem);
442
+ border-top: 1px solid var(--dim-2);
443
+ width: 100%;
444
+ }
445
+ .sp-ctx-item {
446
+ font-size: clamp(0.95rem, 1.4vw, 1.2rem);
447
+ color: var(--dim);
448
+ letter-spacing: 0.08em;
449
+ text-transform: uppercase;
450
+ opacity: 0;
451
+ transform: translateY(6px);
452
+ transition: opacity 600ms ease-out, transform 700ms ease-out, color 400ms ease;
453
+ }
454
+ .sp-ctx-item.in { opacity: 1; transform: translateY(0); }
455
+ .sp-ctx-item:hover { color: var(--fg); }
456
+
457
+ @media (max-width: 700px) {
458
+ .sp-focus { flex-direction: column; text-align: center; }
459
+ }
460
+
461
+ /* ---------------------------------------------------------------------------
462
+ * Marquee
463
+ * ------------------------------------------------------------------------- */
464
+ .marquee-host {
465
+ padding: 0 !important;
466
+ display: block !important;
467
+ width: 100vw;
468
+ height: auto;
469
+ align-self: center;
470
+ }
471
+ .marquee {
472
+ --mq-duration: 28s;
473
+ position: relative;
474
+ width: 100vw;
475
+ overflow: hidden;
476
+ display: flex;
477
+ flex-direction: column;
478
+ gap: clamp(0.6rem, 1.5vw, 1.4rem);
479
+ padding: clamp(2rem, 6vw, 5rem) 0;
480
+ mask-image: linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%);
481
+ }
482
+ .marquee.mq--slow { --mq-duration: 42s; }
483
+ .marquee.mq--medium { --mq-duration: 26s; }
484
+ .marquee.mq--fast { --mq-duration: 16s; }
485
+
486
+ .mq-track {
487
+ width: 100%;
488
+ overflow: hidden;
489
+ border-block: 1px solid var(--dim-2);
490
+ padding: clamp(0.6rem, 1.2vw, 1rem) 0;
491
+ }
492
+ .mq-row {
493
+ display: inline-flex;
494
+ align-items: center;
495
+ gap: clamp(1rem, 2vw, 1.6rem);
496
+ white-space: nowrap;
497
+ will-change: transform;
498
+ animation: mq-scroll var(--mq-duration) linear infinite;
499
+ }
500
+ .marquee.mq--right .mq-row { animation-direction: reverse; }
501
+ .mq-track--rev .mq-row { animation-direction: reverse; }
502
+ .marquee.mq--right .mq-track--rev .mq-row { animation-direction: normal; }
503
+
504
+ .marquee:hover .mq-row { animation-play-state: paused; }
505
+
506
+ .mq-item {
507
+ font-size: clamp(2rem, 5vw, 4.2rem);
508
+ font-weight: 500;
509
+ letter-spacing: -0.03em;
510
+ color: var(--fg);
511
+ line-height: 1;
512
+ text-transform: lowercase;
513
+ }
514
+ .mq-track--b .mq-item {
515
+ color: var(--accent);
516
+ text-shadow: 0 0 24px var(--accent-glow);
517
+ font-style: italic;
518
+ font-weight: 400;
519
+ }
520
+ .mq-sep {
521
+ font-size: clamp(2rem, 5vw, 4.2rem);
522
+ color: var(--dim-2);
523
+ line-height: 1;
524
+ user-select: none;
525
+ }
526
+
527
+ @keyframes mq-scroll {
528
+ from { transform: translateX(0); }
529
+ to { transform: translateX(-50%); }
530
+ }