|
1 | | -:root { color-scheme: light; --accent: #FF4801; --accent-hover: #FF7038; --accent-soft: rgba(255, 72, 1, 0.08); --text: #521000; --muted: rgba(82, 16, 0, 0.7); --page: #F5F1EB; --surface: #FFFBF5; --surface-2: #FFFDFB; --surface-3: #FEF7ED; --hairline: #EBD5C1; --hairline-soft: rgba(235, 213, 193, 0.5); --header-veil: rgba(245, 241, 235, 0.82); --header-veil-0: rgba(245, 241, 235, 0); --header-veil-solid: rgba(245, 241, 235, 0.95); --figure-paper: #F5F1EB; --space-1: .5rem; --space-2: .75rem; --space-3: 1rem; --space-4: 1.5rem; --space-5: 2rem; --space-6: 3rem; } |
| 1 | +:root { color-scheme: light; --accent: #FF4801; --accent-hover: #FF7038; --accent-soft: rgba(255, 72, 1, 0.08); --text: #521000; --muted: rgba(82, 16, 0, 0.7); --page: #F5F1EB; --surface: #FFFBF5; --surface-2: #FFFDFB; --surface-3: #FEF7ED; --hairline: #EBD5C1; --hairline-soft: rgba(235, 213, 193, 0.5); --header-veil: rgba(245, 241, 235, 0.82); --header-veil-0: rgba(245, 241, 235, 0); --header-veil-solid: rgba(245, 241, 235, 0.95); --figure-paper: #F5F1EB; --terminal-bg: #0b1020; --terminal-ink: #f9fafb; --space-1: .5rem; --space-2: .75rem; --space-3: 1rem; --space-4: 1.5rem; --space-5: 2rem; --space-6: 3rem; } |
2 | 2 | * { box-sizing: border-box; } |
3 | 3 | html { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; } |
4 | | - body { max-width: 1040px; margin: 0 auto; padding: var(--space-4); color: var(--text); font: 16px/1.6 FT Kunst Grotesk, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif; background: radial-gradient(circle at top left, rgba(255, 72, 1, 0.10), transparent 34rem), var(--page); } |
| 4 | + body { max-width: 1040px; margin: 0 auto; padding: var(--space-4); color: var(--text); font: 100%/1.6 FT Kunst Grotesk, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif; background: radial-gradient(circle at top left, rgba(255, 72, 1, 0.10), transparent 34rem), var(--page); } |
5 | 5 | header { position: sticky; top: 0; z-index: 2; margin: 0 calc(-1 * var(--space-4)) var(--space-5); padding: var(--space-2) var(--space-4); backdrop-filter: blur(16px); background: var(--header-veil); } |
6 | 6 | .skip-link { position: absolute; left: -9999px; } |
7 | 7 | .skip-link:focus { position: fixed; left: var(--space-3); top: var(--space-3); z-index: 10; padding: .6rem 1rem; border: 1px solid var(--accent); border-radius: .5rem; background: var(--surface); color: var(--text); } |
|
13 | 13 | h1 { font-size: clamp(2.4rem, 4.5vw, 3.75rem); margin: 0 0 1rem; } |
14 | 14 | h2 { margin-top: 0; } |
15 | 15 | p, li { text-wrap: pretty; } |
16 | | - pre { overflow: auto; padding: 1rem; border-radius: 1rem; background: #0b1020; color: #f9fafb; box-shadow: 0 1px 1px rgba(0,0,0,.12), 0 12px 42px rgba(0,0,0,.18); } |
| 16 | + pre { overflow: auto; padding: 1rem; border-radius: 1rem; background: var(--terminal-bg); color: var(--terminal-ink); box-shadow: 0 1px 1px rgba(0,0,0,.12), 0 12px 42px rgba(0,0,0,.18); } |
17 | 17 | textarea { box-sizing: border-box; width: 100%; height: auto; min-height: 18rem; padding: 0; overflow: hidden; resize: vertical; border: 0; outline: 0; background: transparent; color: var(--text); font: 14px/1.5 Apercu Mono Pro, SF Mono, Fira Code, Consolas, monospace; tab-size: 4; transition-property: box-shadow; transition-duration: 150ms; transition-timing-function: cubic-bezier(0, 0, 0.2, 1); } |
18 | 18 | textarea:focus { box-shadow: 0 0 0 3px rgba(255, 72, 1, 0.18); } |
19 | 19 | .textarea-fallback[hidden] { display: none; } |
|
28 | 28 | .cm-selectionBackground, .cm-focused .cm-selectionBackground { background: rgba(255, 72, 1, 0.18) !important; } |
29 | 29 | code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-variant-numeric: tabular-nums; } |
30 | 30 | .syntax-inline { padding: .08rem .25rem; border-radius: .25rem; background: var(--accent-soft); color: var(--text); font-size: .94em; } |
31 | | - .brand { font-weight: 800; } |
| 31 | + /* Nav tap targets: block padding grows the hit area to ~43px while |
| 32 | + the negative margin cancels the layout growth. */ |
| 33 | + .brand { font-weight: 800; padding-block: .55rem; margin-block: -.55rem; } |
32 | 34 | .nav-links { display: flex; gap: .35rem; } |
33 | | - .nav-links a { padding: 0 .9rem; color: var(--muted); } |
| 35 | + .nav-links a { padding: .55rem .9rem; margin-block: -.55rem; color: var(--muted); } |
34 | 36 | .hero { overflow: hidden; border: 1px solid var(--hairline); border-radius: 1rem; padding: clamp(1.25rem, 3.5vw, 2.5rem); margin-bottom: 1.25rem; background: linear-gradient(135deg, var(--surface), var(--surface-3)); box-shadow: 0 1px 3px rgba(82, 16, 0, 0.04), 0 4px 12px rgba(82, 16, 0, 0.02); transform-origin: top left; } |
35 | 37 | .hero h1 { font-size: clamp(2rem, 4vw, 3rem); margin-bottom: var(--space-3); transform-origin: top left; } |
36 | 38 | .hero p { max-width: 60ch; color: var(--muted); font-size: 1rem; } |
|
40 | 42 | .hero h1 { animation: hero-h1-morph linear forwards; animation-timeline: scroll(root); animation-range: 0 240px; } |
41 | 43 | .hero p { animation: hero-p-fade linear forwards; animation-timeline: scroll(root); animation-range: 0 140px; } |
42 | 44 | body:has(.hero) { padding-top: var(--space-2); } |
43 | | - body:has(.hero) header { opacity: 0; background: var(--header-veil-0); box-shadow: none; margin-bottom: var(--space-2); animation: header-emerge linear forwards; animation-timeline: scroll(root); animation-range: 40px 240px; } |
| 45 | + /* The brand blurs in on scroll, but the header (and its nav) |
| 46 | + stays readable from first paint — hiding the primary nav on |
| 47 | + landing fails the "where can I go?" test. The emerging veil |
| 48 | + lives on a pseudo-element and animates opacity only, which |
| 49 | + the compositor can do without repainting every scroll frame. */ |
| 50 | + body:has(.hero) header { background: transparent; box-shadow: none; margin-bottom: var(--space-2); } |
| 51 | + body:has(.hero) header::before { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--header-veil-solid); box-shadow: 0 1px 8px rgba(82, 16, 0, 0.06); opacity: 0; animation: header-veil-emerge linear forwards; animation-timeline: scroll(root); animation-range: 40px 240px; } |
44 | 52 | body:has(.hero) header .brand { filter: blur(4px); transform: scale(0.88); animation: brand-focus linear forwards; animation-timeline: scroll(root); animation-range: 80px 240px; } |
45 | 53 | } |
46 | 54 | } |
|
56 | 64 | @keyframes brand-focus { |
57 | 65 | to { filter: blur(0); transform: scale(1); } |
58 | 66 | } |
59 | | - @keyframes header-emerge { |
60 | | - to { opacity: 1; background: var(--header-veil-solid); box-shadow: 0 1px 8px rgba(82, 16, 0, 0.06); } |
| 67 | + @keyframes header-veil-emerge { |
| 68 | + to { opacity: 1; } |
61 | 69 | } |
62 | 70 | .site-search { position: relative; max-width: 44rem; margin: 0 0 var(--space-5); } |
63 | 71 | .site-search input { width: 100%; min-height: 44px; padding: .6rem 1rem; border: 1px solid var(--hairline); border-radius: .75rem; background: var(--surface-2); color: var(--text); font: inherit; transition: border-color 160ms cubic-bezier(0.2, 0, 0, 1), box-shadow 160ms cubic-bezier(0.2, 0, 0, 1); } |
|
74 | 82 | .home-section .eyebrow { margin: 0 0 var(--space-2); } |
75 | 83 | .card { display: block; min-height: 10rem; border: 1px solid var(--hairline); border-radius: .75rem; padding: var(--space-3); background: var(--surface-2); color: inherit; text-decoration: none; box-shadow: 0 1px 3px rgba(82, 16, 0, 0.04), 0 4px 12px rgba(82, 16, 0, 0.02); transition-property: transform, background-color, border-color; transition-duration: 200ms; transition-timing-function: cubic-bezier(0, 0, 0.2, 1); } |
76 | 84 | .card:hover { transform: translateY(-2px); background: var(--surface-3); border-color: var(--accent); } |
| 85 | + .card:active { transform: translateY(0) scale(0.99); } |
77 | 86 | .card h2 { text-decoration: underline; text-decoration-color: var(--hairline); text-underline-offset: .18em; } |
78 | 87 | .card:hover h2 { text-decoration-color: var(--accent); } |
79 | 88 | .button { min-height: 40px; border: 1px solid var(--accent); border-radius: 9999px; padding: .72rem 1rem; background: var(--accent); color: white; cursor: pointer; font-weight: 650; box-shadow: 0 1px 3px rgba(82, 16, 0, 0.04), 0 4px 12px rgba(82, 16, 0, 0.02); transition-property: transform, opacity, border-style; transition-duration: 150ms; transition-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94); } |
|
234 | 243 | .button { color: #FFF7EF; } |
235 | 244 | .shiki, .shiki span { color: var(--shiki-dark) !important; } |
236 | 245 | } |
| 246 | + /* Non-motion accessibility signals. Reduced motion is handled by |
| 247 | + the transition kill switch and no-preference gates above; these |
| 248 | + cover the other two: solid chrome when translucency is reduced, |
| 249 | + defined borders and full-contrast prose when contrast is raised. */ |
| 250 | + @media (prefers-reduced-transparency: reduce) { |
| 251 | + header, body:has(.hero) header { background: var(--page); backdrop-filter: none; box-shadow: 0 1px 0 var(--hairline); } |
| 252 | + body:has(.hero) header::before { content: none; } |
| 253 | + .search-results { background: var(--surface); } |
| 254 | + } |
| 255 | + @media (prefers-contrast: more) { |
| 256 | + header, body:has(.hero) header { background: var(--page); backdrop-filter: none; box-shadow: 0 1px 0 var(--text); } |
| 257 | + body:has(.hero) header::before { content: none; } |
| 258 | + .card, .runner-panel, .site-search input, .copy-button, .tool-button { border-color: var(--text); } |
| 259 | + .meta, .lp-prose p, .lesson-step p, .nav-links a { color: var(--text); } |
| 260 | + } |
0 commit comments