@fluid-theme/core 0.4.3

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 (48) hide show
  1. package/AGENTS.md +32 -0
  2. package/CHANGELOG.md +159 -0
  3. package/CLAUDE.md +104 -0
  4. package/GEMINI.md +48 -0
  5. package/LICENSE +21 -0
  6. package/README.md +253 -0
  7. package/dist/fluid.min.css +2 -0
  8. package/fluid-agent-kit/README.md +57 -0
  9. package/fluid-agent-kit/skills/accessibility.md +41 -0
  10. package/fluid-agent-kit/skills/css-conventions.md +51 -0
  11. package/fluid-agent-kit/skills/image-optimization.md +115 -0
  12. package/fluid-agent-kit/skills/ux-rules.md +43 -0
  13. package/package.json +68 -0
  14. package/src/animations/scroll-reveal.css +224 -0
  15. package/src/components/accordion.css +250 -0
  16. package/src/components/alert.css +453 -0
  17. package/src/components/avatar.css +192 -0
  18. package/src/components/badge.css +182 -0
  19. package/src/components/button.css +387 -0
  20. package/src/components/card.css +650 -0
  21. package/src/components/chip.css +143 -0
  22. package/src/components/dropdown.css +335 -0
  23. package/src/components/empty-state.css +105 -0
  24. package/src/components/form.css +508 -0
  25. package/src/components/hero.css +293 -0
  26. package/src/components/indicator.css +455 -0
  27. package/src/components/loading.css +274 -0
  28. package/src/components/modal.css +364 -0
  29. package/src/components/nav.css +726 -0
  30. package/src/components/scroll-progress.css +104 -0
  31. package/src/components/search-input.css +125 -0
  32. package/src/components/settings-panel.css +603 -0
  33. package/src/components/step-indicator.css +188 -0
  34. package/src/components/table.css +350 -0
  35. package/src/components/themed-images.css +229 -0
  36. package/src/components/tooltip.css +247 -0
  37. package/src/components/version-badge.css +70 -0
  38. package/src/core/base.css +884 -0
  39. package/src/core/reset.css +159 -0
  40. package/src/core/tokens.css +2416 -0
  41. package/src/fluid.css +242 -0
  42. package/src/layouts/positioning.css +626 -0
  43. package/src/sections/cta.css +210 -0
  44. package/src/sections/features.css +356 -0
  45. package/src/sections/footer.css +283 -0
  46. package/src/sections/stats.css +234 -0
  47. package/src/sections/team.css +181 -0
  48. package/src/sections/testimonials.css +251 -0
@@ -0,0 +1,884 @@
1
+ /**
2
+ * Fluid Framework - Base Element Styles
3
+ * @layer base
4
+ *
5
+ * Default styles for native HTML elements.
6
+ * These establish the rhythm and feel without requiring classes.
7
+ * Every element should feel intentional, refined, unhurried.
8
+ */
9
+
10
+ @layer base {
11
+ /* ========================================
12
+ DOCUMENT
13
+ ======================================== */
14
+
15
+ body {
16
+ font-family: var(--font-body, var(--font-system));
17
+ font-size: var(--font-size-base);
18
+ line-height: var(--leading-normal);
19
+ color: var(--color-text);
20
+ background-color: var(--color-background);
21
+ }
22
+
23
+ ::selection {
24
+ background-color: var(--color-selection);
25
+ color: var(--color-text);
26
+ }
27
+
28
+
29
+ /* ========================================
30
+ TYPOGRAPHY - Headings
31
+ Confident but not aggressive
32
+ ======================================== */
33
+
34
+ h1, h2, h3, h4, h5, h6 {
35
+ font-family: var(--font-heading, var(--font-system));
36
+ color: var(--color-text);
37
+ font-weight: var(--weight-semibold);
38
+ line-height: var(--leading-tight);
39
+ letter-spacing: var(--tracking-tight);
40
+ margin-block-start: 0;
41
+ margin-block-end: var(--space-4);
42
+ }
43
+
44
+ h1 {
45
+ font-size: var(--font-size-4xl);
46
+ font-weight: var(--weight-bold);
47
+ letter-spacing: -0.03em;
48
+ }
49
+
50
+ h2 {
51
+ font-size: var(--font-size-3xl);
52
+ letter-spacing: -0.02em;
53
+ }
54
+
55
+ h3 {
56
+ font-size: var(--font-size-2xl);
57
+ letter-spacing: -0.015em;
58
+ }
59
+
60
+ h4 {
61
+ font-size: var(--font-size-xl);
62
+ letter-spacing: var(--tracking-tight);
63
+ }
64
+
65
+ h5 {
66
+ font-size: var(--font-size-lg);
67
+ font-weight: var(--weight-medium);
68
+ letter-spacing: var(--tracking-normal);
69
+ }
70
+
71
+ h6 {
72
+ font-size: var(--font-size-base);
73
+ font-weight: var(--weight-medium);
74
+ letter-spacing: var(--tracking-normal);
75
+ }
76
+
77
+ /* Subheadings following main headings */
78
+ :is(h1, h2, h3) + :is(h2, h3, h4) {
79
+ margin-block-start: var(--space-2);
80
+ }
81
+
82
+
83
+ /* ========================================
84
+ TYPOGRAPHY - Body Text
85
+ Room to breathe
86
+ ======================================== */
87
+
88
+ p {
89
+ margin-block-end: var(--space-5);
90
+ max-inline-size: var(--container-prose);
91
+ }
92
+
93
+ /* Last child shouldn't add extra space */
94
+ p:last-child {
95
+ margin-block-end: 0;
96
+ }
97
+
98
+ strong, b {
99
+ font-weight: var(--weight-semibold);
100
+ }
101
+
102
+ em, i {
103
+ font-style: italic;
104
+ }
105
+
106
+ small {
107
+ font-size: var(--font-size-sm);
108
+ color: var(--color-text-muted);
109
+ }
110
+
111
+ /* Subscript and superscript */
112
+ sub, sup {
113
+ font-size: 75%;
114
+ line-height: 0;
115
+ position: relative;
116
+ vertical-align: baseline;
117
+ }
118
+
119
+ sup {
120
+ inset-block-start: -0.5em;
121
+ }
122
+
123
+ sub {
124
+ inset-block-end: -0.25em;
125
+ }
126
+
127
+
128
+ /* ========================================
129
+ LINKS
130
+ Subtle, inviting interaction
131
+ ======================================== */
132
+
133
+ a {
134
+ color: var(--accent);
135
+ text-decoration: underline;
136
+ text-decoration-thickness: 1px;
137
+ text-underline-offset: 0.15em;
138
+ transition:
139
+ color var(--duration-normal) var(--ease-fluid),
140
+ text-decoration-color var(--duration-normal) var(--ease-fluid);
141
+ }
142
+
143
+ a:hover {
144
+ color: var(--accent-hover);
145
+ text-decoration-thickness: 2px;
146
+ }
147
+
148
+ /* Links that look like text but reveal on hover */
149
+ a[data-subtle] {
150
+ color: inherit;
151
+ text-decoration: none;
152
+ }
153
+
154
+ a[data-subtle]:hover {
155
+ color: var(--accent);
156
+ text-decoration: underline;
157
+ }
158
+
159
+
160
+ /* ========================================
161
+ LISTS
162
+ Structured with breathing room
163
+ Theme-specific list markers
164
+ ======================================== */
165
+
166
+ ul, ol {
167
+ padding-inline-start: var(--space-6);
168
+ margin-block-end: var(--space-5);
169
+ }
170
+
171
+ li {
172
+ margin-block-end: var(--space-2);
173
+ }
174
+
175
+ li:last-child {
176
+ margin-block-end: 0;
177
+ }
178
+
179
+ /* Nested lists */
180
+ li > ul,
181
+ li > ol {
182
+ margin-block-start: var(--space-2);
183
+ margin-block-end: 0;
184
+ }
185
+
186
+ /* === Themed list markers ===
187
+ Each child theme gets a distinctive marker
188
+ Note: Uses :not([class]) to avoid overriding nav dropdowns and other styled lists */
189
+
190
+ /* Still: Clean disc (default - minimal) */
191
+ [data-motion="still"] ul:not([class]) {
192
+ list-style-type: disc;
193
+ }
194
+
195
+ /* Serene: Open circle - elegant, understated */
196
+ [data-motion="serene"] ul:not([class]) {
197
+ list-style-type: circle;
198
+ }
199
+
200
+ /* Stream: Dash - modern, horizontal emphasis */
201
+ [data-motion="stream"] ul:not([class]) {
202
+ list-style-type: none;
203
+ padding-inline-start: var(--space-5);
204
+ }
205
+ [data-motion="stream"] ul:not([class]) > li {
206
+ position: relative;
207
+ }
208
+ [data-motion="stream"] ul:not([class]) > li::before {
209
+ content: "—";
210
+ position: absolute;
211
+ inset-inline-start: calc(var(--space-5) * -1);
212
+ color: var(--accent);
213
+ font-weight: var(--weight-bold);
214
+ }
215
+
216
+ /* Cascade: Filled circle - friendly, rounded */
217
+ [data-motion="cascade"] ul:not([class]) {
218
+ list-style-type: none;
219
+ padding-inline-start: var(--space-6);
220
+ }
221
+ [data-motion="cascade"] ul:not([class]) > li {
222
+ position: relative;
223
+ }
224
+ [data-motion="cascade"] ul:not([class]) > li::before {
225
+ content: "";
226
+ position: absolute;
227
+ inset-inline-start: calc(var(--space-6) * -1);
228
+ inset-block-start: 0.55em;
229
+ inline-size: 0.5em;
230
+ block-size: 0.5em;
231
+ background: var(--accent);
232
+ border-radius: var(--radius-full);
233
+ }
234
+
235
+ /* Rapids: Chevron - energetic, forward motion */
236
+ [data-motion="rapids"] ul:not([class]) {
237
+ list-style-type: none;
238
+ padding-inline-start: var(--space-6);
239
+ }
240
+ [data-motion="rapids"] ul:not([class]) > li {
241
+ position: relative;
242
+ }
243
+ [data-motion="rapids"] ul:not([class]) > li::before {
244
+ content: "";
245
+ position: absolute;
246
+ inset-inline-start: calc(var(--space-6) * -1);
247
+ inset-block-start: 0.4em;
248
+ inline-size: 0;
249
+ block-size: 0;
250
+ border-block-start: 0.35em solid transparent;
251
+ border-block-end: 0.35em solid transparent;
252
+ border-inline-start: 0.5em solid var(--accent);
253
+ }
254
+
255
+ /* Tsunami: Square - bold, impactful */
256
+ [data-motion="tsunami"] ul:not([class]) {
257
+ list-style-type: none;
258
+ padding-inline-start: var(--space-6);
259
+ }
260
+ [data-motion="tsunami"] ul:not([class]) > li {
261
+ position: relative;
262
+ }
263
+ [data-motion="tsunami"] ul:not([class]) > li::before {
264
+ content: "";
265
+ position: absolute;
266
+ inset-inline-start: calc(var(--space-6) * -1);
267
+ inset-block-start: 0.5em;
268
+ inline-size: 0.5em;
269
+ block-size: 0.5em;
270
+ background: var(--accent);
271
+ }
272
+
273
+ /* Definition lists */
274
+ dl {
275
+ margin-block-end: var(--space-5);
276
+ }
277
+
278
+ dt {
279
+ font-weight: var(--weight-semibold);
280
+ margin-block-end: var(--space-1);
281
+ }
282
+
283
+ dd {
284
+ margin-inline-start: var(--space-6);
285
+ margin-block-end: var(--space-4);
286
+ color: var(--color-text-muted);
287
+ }
288
+
289
+
290
+ /* ========================================
291
+ BLOCKQUOTES
292
+ Thoughtful, set apart
293
+ ======================================== */
294
+
295
+ blockquote {
296
+ position: relative;
297
+ padding-inline-start: var(--space-6);
298
+ margin-block: var(--space-6);
299
+ border-inline-start: 3px solid var(--color-border);
300
+ color: var(--color-text-muted);
301
+ font-style: italic;
302
+ }
303
+
304
+ blockquote::before {
305
+ content: none; /* No decorative quotes - let content speak */
306
+ }
307
+
308
+ blockquote cite {
309
+ display: block;
310
+ margin-block-start: var(--space-3);
311
+ font-size: var(--font-size-sm);
312
+ font-style: normal;
313
+ color: var(--color-text-subtle);
314
+ }
315
+
316
+ blockquote cite::before {
317
+ content: "— ";
318
+ }
319
+
320
+
321
+ /* ========================================
322
+ CODE
323
+ Technical but approachable
324
+ ======================================== */
325
+
326
+ code {
327
+ font-family: var(--font-mono);
328
+ font-size: 0.9em;
329
+ background-color: var(--color-surface);
330
+ padding-inline: var(--space-1-5);
331
+ padding-block: var(--space-0-5);
332
+ border-radius: var(--radius-sm);
333
+ }
334
+
335
+ pre {
336
+ font-family: var(--font-mono);
337
+ font-size: var(--font-size-sm);
338
+ line-height: var(--leading-relaxed);
339
+ background-color: var(--color-surface);
340
+ padding: var(--space-5);
341
+ border-radius: var(--radius-lg);
342
+ overflow-x: auto;
343
+ margin-block-end: var(--space-5);
344
+ tab-size: 2;
345
+ }
346
+
347
+ pre code {
348
+ background: none;
349
+ padding: 0;
350
+ font-size: inherit;
351
+ border-radius: 0;
352
+ }
353
+
354
+ kbd {
355
+ font-family: var(--font-mono);
356
+ font-size: 0.875em;
357
+ background-color: var(--color-surface-raised);
358
+ border: 1px solid var(--color-border);
359
+ border-radius: var(--radius-sm);
360
+ padding-inline: var(--space-1-5);
361
+ padding-block: var(--space-0-5);
362
+ box-shadow: var(--shadow-xs);
363
+ }
364
+
365
+ samp {
366
+ font-family: var(--font-mono);
367
+ }
368
+
369
+ var {
370
+ font-style: italic;
371
+ font-weight: var(--weight-medium);
372
+ }
373
+
374
+
375
+ /* ========================================
376
+ HORIZONTAL RULES
377
+ Quiet separation
378
+ ======================================== */
379
+
380
+ hr {
381
+ border: none;
382
+ border-block-start: 1px solid var(--color-border-subtle);
383
+ margin-block: var(--space-10);
384
+ }
385
+
386
+
387
+ /* ========================================
388
+ MEDIA
389
+ Graceful presentation
390
+ ======================================== */
391
+
392
+ figure {
393
+ margin-block: var(--space-6);
394
+ }
395
+
396
+ figcaption {
397
+ margin-block-start: var(--space-3);
398
+ font-size: var(--font-size-sm);
399
+ color: var(--color-text-muted);
400
+ text-align: center;
401
+ }
402
+
403
+
404
+ /* ========================================
405
+ TABLES
406
+ Clean, readable data
407
+ ======================================== */
408
+
409
+ table {
410
+ inline-size: 100%;
411
+ margin-block-end: var(--space-5);
412
+ border-collapse: collapse;
413
+ font-variant-numeric: tabular-nums;
414
+ }
415
+
416
+ th, td {
417
+ padding: var(--space-3) var(--space-4);
418
+ text-align: start;
419
+ border-block-end: 1px solid var(--color-border-subtle);
420
+ }
421
+
422
+ th {
423
+ font-weight: var(--weight-semibold);
424
+ color: var(--color-text);
425
+ background-color: var(--color-surface);
426
+ }
427
+
428
+ /* Striped rows - subtle */
429
+ tbody tr:nth-child(even) {
430
+ background-color: oklch(from var(--shadow-color) l c h / 0.02);
431
+ }
432
+
433
+ /* Hover state - gentle highlight */
434
+ tbody tr {
435
+ transition: background-color var(--duration-normal) var(--ease-fluid);
436
+ }
437
+
438
+ tbody tr:hover {
439
+ background-color: oklch(from var(--shadow-color) l c h / 0.04);
440
+ }
441
+
442
+
443
+ /* ========================================
444
+ FORMS - Inputs
445
+ Inviting, not intimidating
446
+ ======================================== */
447
+
448
+ label {
449
+ display: block;
450
+ font-size: var(--font-size-sm);
451
+ font-weight: var(--weight-medium);
452
+ margin-block-end: var(--space-2);
453
+ color: var(--color-text);
454
+ }
455
+
456
+ input,
457
+ textarea,
458
+ select {
459
+ inline-size: 100%;
460
+ padding: var(--space-3) var(--space-4);
461
+ font-size: var(--font-size-base);
462
+ line-height: var(--leading-normal);
463
+ color: var(--color-text);
464
+ background-color: var(--color-background);
465
+ border: 1px solid var(--color-border);
466
+ border-radius: var(--radius-input, var(--radius-md));
467
+ /* Subtle 3D effect - layered shadows create depth */
468
+ box-shadow:
469
+ inset 0 1px 2px oklch(from var(--shadow-color) l c h / 0.04),
470
+ 0 1px 0 oklch(from var(--theme-light) l c h / 0.6);
471
+ transition:
472
+ border-color var(--duration-normal) var(--ease-fluid),
473
+ box-shadow var(--duration-normal) var(--ease-fluid),
474
+ background-color var(--duration-normal) var(--ease-fluid);
475
+ }
476
+
477
+ input:hover,
478
+ textarea:hover,
479
+ select:hover {
480
+ border-color: var(--color-text-subtle);
481
+ }
482
+
483
+ input:focus,
484
+ textarea:focus,
485
+ select:focus {
486
+ outline: 2px solid transparent;
487
+ border-color: var(--accent);
488
+ /* Focus: glow ring + maintain subtle 3D */
489
+ box-shadow:
490
+ var(--shadow-glow),
491
+ inset 0 1px 2px oklch(from var(--shadow-color) l c h / 0.03);
492
+ /* Soft focus background - subtle tint */
493
+ background-color: color-mix(in oklch, var(--accent) 8%, var(--color-background));
494
+ }
495
+
496
+ /* Dark mode: stronger tint needed for visibility */
497
+ @media (prefers-color-scheme: dark) {
498
+ input:focus,
499
+ textarea:focus,
500
+ select:focus {
501
+ background-color: color-mix(in oklch, var(--accent) 15%, var(--color-background));
502
+ }
503
+ }
504
+
505
+ [data-theme="dark"] input:focus,
506
+ [data-theme="dark"] textarea:focus,
507
+ [data-theme="dark"] select:focus {
508
+ background-color: color-mix(in oklch, var(--accent) 15%, var(--color-background));
509
+ }
510
+
511
+ input::placeholder,
512
+ textarea::placeholder {
513
+ color: var(--color-text-subtle);
514
+ opacity: 1;
515
+ }
516
+
517
+ /* Disabled state */
518
+ input:disabled,
519
+ textarea:disabled,
520
+ select:disabled {
521
+ opacity: 0.6;
522
+ cursor: not-allowed;
523
+ background-color: var(--color-surface);
524
+ }
525
+
526
+ textarea {
527
+ min-block-size: 8rem;
528
+ resize: vertical;
529
+ }
530
+
531
+
532
+ /* ========================================
533
+ FORMS - Buttons
534
+ Clear call to action, never garish
535
+ ======================================== */
536
+
537
+ button {
538
+ display: inline-flex;
539
+ align-items: center;
540
+ justify-content: center;
541
+ gap: var(--space-2);
542
+ padding: var(--space-3) var(--space-5);
543
+ font-size: var(--font-size-base);
544
+ font-weight: var(--weight-medium);
545
+ line-height: var(--leading-none);
546
+ color: var(--white);
547
+ background-color: var(--accent);
548
+ border: none;
549
+ border-radius: var(--radius-md);
550
+ cursor: pointer;
551
+ transition:
552
+ background-color var(--duration-normal) var(--ease-fluid),
553
+ transform var(--duration-fast) var(--ease-settle),
554
+ box-shadow var(--duration-normal) var(--ease-fluid);
555
+ }
556
+
557
+ button:hover {
558
+ background-color: var(--accent-hover);
559
+ box-shadow: var(--shadow-sm);
560
+ }
561
+
562
+ button:active {
563
+ transform: scale(0.98);
564
+ box-shadow: none;
565
+ }
566
+
567
+ button:disabled {
568
+ opacity: 0.6;
569
+ cursor: not-allowed;
570
+ }
571
+
572
+ button:disabled:hover {
573
+ background-color: var(--accent);
574
+ box-shadow: none;
575
+ transform: none;
576
+ }
577
+
578
+
579
+ /* ========================================
580
+ INTERACTIVE ELEMENTS
581
+ Native HTML interactivity
582
+ ======================================== */
583
+
584
+ details {
585
+ margin-block-end: var(--space-4);
586
+ border: 1px solid var(--color-border-subtle);
587
+ border-radius: var(--radius-md);
588
+ padding: var(--space-4);
589
+ }
590
+
591
+ summary {
592
+ font-weight: var(--weight-medium);
593
+ cursor: pointer;
594
+ padding: var(--space-2);
595
+ margin: calc(var(--space-4) * -1);
596
+ margin-block-end: 0;
597
+ border-radius: var(--radius-md);
598
+ transition: background-color var(--duration-normal) var(--ease-fluid);
599
+ }
600
+
601
+ summary:hover {
602
+ background-color: var(--color-surface);
603
+ }
604
+
605
+ details[open] summary {
606
+ margin-block-end: var(--space-4);
607
+ border-block-end: 1px solid var(--color-border-subtle);
608
+ border-end-start-radius: 0;
609
+ border-end-end-radius: 0;
610
+ }
611
+
612
+ /* Hide default marker in webkit */
613
+ summary::-webkit-details-marker {
614
+ display: none;
615
+ }
616
+
617
+ summary::marker {
618
+ content: "";
619
+ }
620
+
621
+ summary::before {
622
+ content: "▸";
623
+ display: inline-block;
624
+ margin-inline-end: var(--space-2);
625
+ transition: transform var(--duration-normal) var(--ease-settle);
626
+ }
627
+
628
+ details[open] summary::before {
629
+ transform: rotate(90deg);
630
+ }
631
+
632
+
633
+ /* ========================================
634
+ SEMANTIC ELEMENTS
635
+ Meaningful markup, meaningful styles
636
+ ======================================== */
637
+
638
+ mark {
639
+ background-color: oklch(90% 0.08 90);
640
+ padding-inline: var(--space-1);
641
+ border-radius: var(--radius-sm);
642
+ }
643
+
644
+ @media (prefers-color-scheme: dark) {
645
+ mark {
646
+ background-color: oklch(40% 0.08 90);
647
+ color: oklch(95% 0.02 90);
648
+ }
649
+ }
650
+
651
+ abbr[title] {
652
+ text-decoration: underline dotted;
653
+ cursor: help;
654
+ }
655
+
656
+ address {
657
+ font-style: normal;
658
+ margin-block-end: var(--space-5);
659
+ }
660
+
661
+ time {
662
+ font-variant-numeric: tabular-nums;
663
+ }
664
+
665
+
666
+ /* ========================================
667
+ METER & PROGRESS
668
+ Visual feedback with viewport animation
669
+ ======================================== */
670
+
671
+ meter,
672
+ progress {
673
+ inline-size: 100%;
674
+ block-size: var(--space-2);
675
+ border-radius: var(--radius-full);
676
+ overflow: hidden;
677
+ }
678
+
679
+ progress {
680
+ appearance: none;
681
+ background-color: var(--color-surface);
682
+ }
683
+
684
+ progress::-webkit-progress-bar {
685
+ background-color: var(--color-surface);
686
+ border-radius: var(--radius-full);
687
+ }
688
+
689
+ progress::-webkit-progress-value {
690
+ background-color: var(--accent);
691
+ border-radius: var(--radius-full);
692
+ /* Animate to draw attention when visible */
693
+ transition: inline-size var(--duration-slow) var(--ease-fluid);
694
+ }
695
+
696
+ progress::-moz-progress-bar {
697
+ background-color: var(--accent);
698
+ border-radius: var(--radius-full);
699
+ transition: inline-size var(--duration-slow) var(--ease-fluid);
700
+ }
701
+
702
+ /* Animated progress - starts at 0 and fills to value when in viewport */
703
+ progress[data-animate] {
704
+ --progress-value: 73; /* Default: NSW easter egg */
705
+ }
706
+
707
+ progress[data-animate]::-webkit-progress-value {
708
+ animation: progress-fill var(--duration-slower) var(--ease-fluid) forwards;
709
+ animation-play-state: paused;
710
+ }
711
+
712
+ progress[data-animate][data-visible]::-webkit-progress-value {
713
+ animation-play-state: running;
714
+ }
715
+
716
+ @keyframes progress-fill {
717
+ from { inline-size: 0; }
718
+ to { inline-size: 100%; }
719
+ }
720
+
721
+ @media (prefers-reduced-motion: reduce) {
722
+ progress[data-animate]::-webkit-progress-value {
723
+ animation: none;
724
+ }
725
+ }
726
+
727
+
728
+ /* ========================================
729
+ DIALOG
730
+ Modal overlay styling
731
+ ======================================== */
732
+
733
+ dialog {
734
+ max-inline-size: min(90vw, var(--container-sm));
735
+ padding: var(--space-6);
736
+ border: 1px solid var(--color-border-subtle);
737
+ border-radius: var(--radius-xl);
738
+ box-shadow: var(--shadow-xl);
739
+ background-color: var(--color-background);
740
+ }
741
+
742
+ dialog::backdrop {
743
+ background-color: oklch(from var(--shadow-color) l c h / 0.5);
744
+ backdrop-filter: blur(4px);
745
+ }
746
+
747
+
748
+ /* ========================================
749
+ SKIP LINK
750
+ Accessibility: Jump to main content
751
+ Hidden until focused for keyboard users
752
+ ======================================== */
753
+
754
+ .skip-link {
755
+ position: absolute;
756
+ inset-block-start: var(--space-4);
757
+ inset-inline-start: var(--space-4);
758
+ z-index: var(--z-max);
759
+ padding: var(--space-3) var(--space-5);
760
+ background-color: var(--accent);
761
+ color: var(--white);
762
+ font-weight: var(--weight-medium);
763
+ text-decoration: none;
764
+ border-radius: var(--radius-md);
765
+ box-shadow: var(--shadow-lg);
766
+ transform: translateY(-200%);
767
+ transition: transform var(--duration-fast) var(--ease-fluid);
768
+ }
769
+
770
+ .skip-link:focus {
771
+ transform: translateY(0);
772
+ outline: 2px solid transparent;
773
+ box-shadow:
774
+ var(--shadow-lg),
775
+ 0 0 0 3px var(--color-background),
776
+ 0 0 0 5px var(--accent);
777
+ }
778
+
779
+
780
+ /* ========================================
781
+ THEME-SPECIFIC TYPOGRAPHY
782
+ Motion styles affect text presentation
783
+ ======================================== */
784
+
785
+ /* Still: Clean, precise, Swiss-style typography */
786
+ [data-motion="still"] h1,
787
+ [data-motion="still"] h2,
788
+ [data-motion="still"] h3 {
789
+ font-weight: var(--weight-medium);
790
+ letter-spacing: 0.02em;
791
+ text-transform: uppercase;
792
+ }
793
+
794
+ /* Serene: Elegant, classical typography */
795
+ [data-motion="serene"] h1,
796
+ [data-motion="serene"] h2 {
797
+ font-weight: var(--weight-normal);
798
+ letter-spacing: 0;
799
+ font-style: italic;
800
+ }
801
+
802
+ /* Rapids: Bold, italic, aggressive sports feel */
803
+ [data-motion="rapids"] h1,
804
+ [data-motion="rapids"] h2,
805
+ [data-motion="rapids"] h3 {
806
+ font-weight: 900;
807
+ font-style: italic;
808
+ text-transform: uppercase;
809
+ letter-spacing: -0.02em;
810
+ line-height: 0.95;
811
+ }
812
+ [data-motion="rapids"] h1 {
813
+ font-size: clamp(var(--font-size-3xl), 8vw, var(--font-size-5xl));
814
+ }
815
+
816
+ /* Tsunami: Maximum impact, dramatic typography */
817
+ [data-motion="tsunami"] h1,
818
+ [data-motion="tsunami"] h2 {
819
+ font-weight: 900;
820
+ text-transform: uppercase;
821
+ letter-spacing: -0.03em;
822
+ line-height: 0.9;
823
+ }
824
+ [data-motion="tsunami"] h1 {
825
+ font-size: clamp(var(--font-size-4xl), 10vw, 6rem);
826
+ }
827
+
828
+
829
+ /* ========================================
830
+ PRINT STYLES
831
+ Clean output for paper
832
+ ======================================== */
833
+
834
+ @media print {
835
+ body {
836
+ font-size: 12pt;
837
+ line-height: 1.5;
838
+ }
839
+
840
+ h1, h2, h3, h4, h5, h6 {
841
+ page-break-after: avoid;
842
+ break-after: avoid;
843
+ }
844
+
845
+ p, blockquote, ul, ol, table {
846
+ page-break-inside: avoid;
847
+ break-inside: avoid;
848
+ }
849
+
850
+ a {
851
+ color: inherit;
852
+ text-decoration: underline;
853
+ }
854
+
855
+ /* Show URLs for external links */
856
+ a[href^="http"]::after {
857
+ content: " (" attr(href) ")";
858
+ font-size: 0.8em;
859
+ color: var(--color-text-muted);
860
+ }
861
+
862
+ pre, code {
863
+ background-color: var(--color-surface-raised, #f5f5f5);
864
+ }
865
+
866
+ /* Hide overlays and fixed UI on print */
867
+ .modal,
868
+ .toast-container,
869
+ .settings-fab,
870
+ .settings-drawer,
871
+ .scroll-progress,
872
+ .nav {
873
+ display: none !important;
874
+ }
875
+
876
+ /* Preserve badge/alert colors on print */
877
+ .badge,
878
+ .alert {
879
+ -webkit-print-color-adjust: exact;
880
+ print-color-adjust: exact;
881
+ border: 1px solid currentColor;
882
+ }
883
+ }
884
+ }