/* Frostyh portfolio, 2026-10-26: dark #0C0C0C, Kanit, giant gradient headings, a 3D player built from his skin,
   a scroll-driven marquee, a letter-by-letter about text, a white services sheet and sticky project
   cards that stack. Plain CSS; motion is driven by pf.js. */

@font-face { font-family: Kanit; font-weight: 300; font-display: swap; src: url(/assets/fonts/kanit-300-latin.woff2) format('woff2'); }
@font-face { font-family: Kanit; font-weight: 400; font-display: swap; src: url(/assets/fonts/kanit-400-latin.woff2) format('woff2'); }
@font-face { font-family: Kanit; font-weight: 500; font-display: swap; src: url(/assets/fonts/kanit-500-latin.woff2) format('woff2'); }
@font-face { font-family: Kanit; font-weight: 700; font-display: swap; src: url(/assets/fonts/kanit-700-latin.woff2) format('woff2'); }
@font-face { font-family: Kanit; font-weight: 900; font-display: swap; src: url(/assets/fonts/kanit-900-latin.woff2) format('woff2'); }
/* v8: a serif for the bright lines and titles, a condensed face for spines and labels, a mono for the
   card backs and a hand for the footer notes. All self-hosted (no Google Fonts requests). */
@font-face { font-family: Gloock; font-weight: 400; font-display: swap; src: url(/assets/fonts/gloock.woff2) format('woff2'); }
@font-face { font-family: 'Barlow Condensed'; font-weight: 600; font-display: swap; src: url(/assets/fonts/barlow-condensed-600.woff2) format('woff2'); }
@font-face { font-family: 'IBM Plex Mono'; font-weight: 400; font-display: swap; src: url(/assets/fonts/ibm-plex-mono-400.woff2) format('woff2'); }
@font-face { font-family: 'IBM Plex Mono'; font-weight: 500; font-display: swap; src: url(/assets/fonts/ibm-plex-mono-500.woff2) format('woff2'); }
@font-face { font-family: Caveat; font-weight: 400 700; font-display: swap; src: url(/assets/fonts/caveat.woff2) format('woff2'); }

:root {
  --bg: #0C0C0C;
  --ink: #D7E2EA;
  --bright: #F7F5F2;
  --muted: #AAA7AA;
  --paper: #FFFFFF;
  --shelf: #EDEBE6;
  --line: rgba(12, 12, 12, .15);
  --ease: cubic-bezier(.25, .1, .25, 1);
  --e-out: cubic-bezier(.22, 1, .36, 1);
  --e-slide: cubic-bezier(.2, .8, .2, 1);
  --serif: Gloock, 'Times New Roman', Times, serif;
  --cond: 'Barlow Condensed', 'Arial Narrow', sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, Consolas, monospace;
  --hand: Caveat, 'Segoe Print', cursive;
  color-scheme: dark;
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { background: var(--bg); }
body {
  font-family: 'Kanit', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
main { background: var(--bg); overflow-x: clip; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; border-radius: 6px; }
.skip { position: absolute; left: 16px; top: -60px; z-index: 50; background: var(--ink); color: var(--bg); padding: 10px 16px; border-radius: 10px; font-weight: 500; }
.skip:focus { top: 16px; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.hero-heading {
  background: linear-gradient(180deg, #646973 0%, #BBCCD7 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}

/* Reveal once, when 50px from the screen. v8: no opacity fades. A block slides up while a clip opens
   from its top edge (the prompts' mask language); the final clip is far outside the box so hover
   lifts and shadows are never cut. Only hidden when the script runs and motion is allowed. */
html.anim .fi {
  clip-path: inset(0 0 100% 0);
  transform: translate3d(var(--fx, 0), var(--fy, 30px), 0);
  transition: clip-path var(--fdur, .95s) var(--e-out) var(--fd, 0s), transform var(--fdur, .95s) var(--e-out) var(--fd, 0s);
}
html.anim .fi.in { clip-path: inset(-30vmax); transform: none; }
html.anim .fi.done { clip-path: none; transition: none; }

/* Line masks: the inner span rises out of its own line. */
.mrise { display: block; overflow: hidden; padding-bottom: .09em; margin-bottom: -.09em; }
.mrise > span { display: block; }
html.anim .mrise > span { transform: translate3d(0, 108%, 0); transition: transform 1s var(--e-out) var(--md, 0s); }
html.anim .mrise.in > span { transform: none; }

/* Glass pills, from the hero cards: thin rim, dark fill, a top highlight. Blur only where a pill sits
   over a picture; elsewhere the fill alone carries it. */
.gp {
  display: inline-flex; align-items: center; gap: 7px; min-height: 22px; padding: 0 9px; border-radius: 999px;
  border: 1px solid rgba(137, 158, 210, .3); background: rgba(10, 12, 18, .55);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12);
  color: var(--bright); font-size: 12px; line-height: 20px; font-weight: 500; white-space: nowrap;
}
.sd { flex: none; width: 7px; height: 7px; border-radius: 50%; background: #7adcc0; box-shadow: 0 0 8px currentColor; color: #7adcc0; }
.sd-g { background: #7adcc0; color: #7adcc0; } .sd-y { background: #ffd462; color: #ffd462; } .sd-v { background: #c69ff7; color: #c69ff7; }
@keyframes pulse { 0%, 18%, 100% { opacity: 1; transform: scale(1); } 42%, 62% { opacity: .22; transform: scale(.72); } 78% { transform: scale(1.08); } }
/* pulses run only while their section is on screen (pf.js toggles .live) */
html.anim .live .pulse { animation: pulse 1.55s var(--ease) infinite; }

/* ---------- buttons ---------- */
/* v8: the old magenta gradient pill became a quiet light one, so every button speaks the same language. */
.cbtn, .vbtn {
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px; border: 0;
  background: linear-gradient(180deg, #FFFFFF, #E4E9EE);
  box-shadow: inset 0 1px 0 #fff, inset 0 -2px 0 rgba(12, 12, 12, .12), 0 8px 24px -10px rgba(134, 204, 255, .45);
  color: #0C0C0C; font-weight: 500; text-transform: uppercase; letter-spacing: .1em;
  padding: 12px 30px; font-size: .75rem; white-space: nowrap; cursor: pointer;
  transition: transform .45s var(--e-out), box-shadow .45s var(--e-out);
}
.cbtn:hover, .vbtn:hover { transform: translateY(-2px); box-shadow: inset 0 1px 0 #fff, inset 0 -2px 0 rgba(12, 12, 12, .12), 0 14px 30px -12px rgba(134, 204, 255, .6); }
.cbtn:active, .vbtn:active { transform: translateY(0) scale(.97); }
.cbtn:focus-visible, .vbtn:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
/* round glass arrow buttons (shelf, sheet, gallery) */
.rbtn {
  flex: none; display: inline-grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; cursor: pointer;
  color: inherit; background: rgba(215, 226, 234, .05); border: 1px solid rgba(215, 226, 234, .2);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08); transition: transform .45s var(--e-out), background-color .2s;
}
.rbtn:hover { background: rgba(215, 226, 234, .12); transform: translateY(-1px); }
.rbtn:active { transform: scale(.94); }
.gbtn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5em;
  border-radius: 999px; border: 2px solid var(--ink); color: var(--ink);
  font-weight: 500; text-transform: uppercase; letter-spacing: .1em; white-space: nowrap;
  padding: 12px 32px; font-size: .875rem; transition: background-color .2s;
}
.gbtn:hover { background-color: rgba(215, 226, 234, .1); }
@media (min-width: 640px) {
  .cbtn { padding: 14px 40px; font-size: .875rem; }
  .gbtn { padding: 14px 40px; font-size: 1rem; }
}
@media (min-width: 768px) { .cbtn { padding: 16px 48px; font-size: 1rem; } }

/* section titles (v9: the hero, marquee, About and the old Services list are gone; see the v9 block at the end) */
.sec-h {
  font-weight: 900; text-transform: uppercase; line-height: 1; letter-spacing: -.025em; text-align: center;
  font-size: clamp(3rem, 12vw, 160px);
}

/* ---------- 5. projects: six tiles (the grid itself lives in suit.css, 2026-10-31) ---------- */
.projects {
  position: relative; z-index: 10; background: var(--bg);
  border-radius: 40px 40px 0 0; margin-top: -40px; padding: 80px 16px 40px;
}
.projects .sec-h { margin-bottom: 32px; }
.shelf, .vc, .cube { -webkit-tap-highlight-color: transparent; }
@media (min-width: 640px) {
  .projects { border-radius: 50px 50px 0 0; margin-top: -48px; padding: 96px 32px 48px; }
}
@media (min-width: 768px) {
  .projects { border-radius: 60px 60px 0 0; margin-top: -56px; padding: 128px 40px 64px; }
  .projects .sec-h { margin-bottom: 40px; }
}

/* ---------- 5b. plugins: the shelf ---------- */
.shelf-sec { padding: 40px 16px 0; }
.shelf-sheet {
  position: relative; max-width: 120rem; margin: 0 auto; overflow: hidden; isolation: isolate;
  background: var(--shelf); color: var(--bg); border-radius: 40px; padding: 56px 0 44px;
  display: flex; flex-direction: column; align-items: center;
}
/* paper grain: one still SVG noise tile under the colour's own layer (a pseudo-element layer
   went missing behind the 3D shelf). Drawn once, never animated. */
.shelf-sheet { background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .45 0 0 0 0 .42 0 0 0 0 .38 0 0 0 .2 0'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E"), var(--shelf); }
.shelf-sheet .sec-h { color: var(--bg); }
.shelf-sheet > .goal-k { margin-bottom: 12px; }
.tabs { position: relative; display: inline-flex; flex-wrap: wrap; justify-content: center; margin: 32px 16px 0; border: 1px solid var(--bg); }
.tab {
  position: relative; z-index: 1; height: 30px; padding: 0 14px; border: 0; border-left: 1px solid var(--bg); background: none; cursor: pointer;
  font-family: var(--cond); font-weight: 600; font-size: 13px; letter-spacing: .09em; text-transform: uppercase; color: var(--bg);
  transition: color .45s var(--e-slide);
}
.tab:first-of-type { border-left: 0; }
.tab[aria-selected="true"] { color: var(--shelf); }
.tab:focus-visible { outline: 2px solid var(--bg); outline-offset: 2px; border-radius: 0; }
.tab-hl { position: absolute; z-index: 0; left: 0; top: 0; bottom: 0; width: 0; background: var(--bg); transform: translateX(0); transition: width .6s var(--e-slide), transform .6s var(--e-slide); }

.shelf {
  --H: min(52vh, 31vw, 520px);
  --ws: calc(var(--H) * 142 / 840); --d: calc(var(--H) * 474 / 900); --gap: calc(var(--H) * .03);
  position: relative; width: 100%; height: calc(var(--H) * 1.3); margin: 8px 0 calc(var(--H) * .13);
  /* v11: the eye sits above the row, so every lid and the board show */
  perspective: 1700px; perspective-origin: 50% -14%; touch-action: pan-y; user-select: none; -webkit-user-select: none; outline: none;
}
.shelf:focus-visible::after { content: ''; position: absolute; left: 50%; bottom: 2px; width: 40px; height: 3px; margin-left: -20px; background: var(--bg); border-radius: 2px; }
.shelf-track { position: absolute; left: 50%; top: 52%; width: 0; height: 0; transform-style: preserve-3d; }
.bx { position: absolute; left: 0; top: 0; width: 0; height: 0; transform-style: preserve-3d; --o: 0; }
.bx.far, .shelf.off .bx { display: none; }
.bx-sp, .bx-cv { position: absolute; top: calc(var(--H) / -2); height: var(--H); backface-visibility: hidden; -webkit-backface-visibility: hidden; overflow: hidden; }
.bx-sp::after, .bx-cv::after { content: ''; position: absolute; inset: 0; pointer-events: none; background: #000; }
.bx-sp::after { opacity: calc(var(--o) * .55); }
.bx-cv::after { opacity: calc(.5 - var(--o) * .5); }

/* 2026-11-02 (second pass), owner: no game texture on the books, but no gloss either. Clean books that
   fit the page: one solid, muted colour per plugin (--lt, mixed from its accent), a darker label plate,
   two thin cream bands, cream page edges on top and down the open side, all drawn as crisp 1 px lines.
   No grain, no gradients, no shine. The shelf is a plain pale board. */
.bx { --lt: color-mix(in srgb, var(--a) 30%, #2e2a26); --dk: color-mix(in srgb, var(--a) 16%, #1d1a17); --cream: #E4DCCB; }
.bx-sp {
  left: calc(var(--ws) / -2); width: var(--ws); transform: translateZ(calc(var(--d) / 2)); cursor: pointer;
  background: var(--lt); border-radius: 3px 3px 2px 2px;
  box-shadow: inset 1px 0 0 rgba(255, 255, 255, .14), inset -1px 0 0 rgba(0, 0, 0, .3);
  display: flex; flex-direction: column; align-items: center;
}
.bx-sp::before { content: none; }
.sp-top {
  flex: none; width: 72%; aspect-ratio: 1; margin-top: 14%; display: grid; place-items: center;
  background: var(--dk); border-radius: 2px; box-shadow: inset 0 0 0 1px rgba(228, 220, 203, .14);
}
.sp-top img { width: 62%; height: auto; image-rendering: pixelated; }
.sp-name {
  flex: 1; min-height: 0; writing-mode: vertical-rl; transform: rotate(180deg); padding: 10% 0;
  font-family: var(--cond); font-weight: 600; text-transform: uppercase; letter-spacing: .05em; white-space: nowrap;
  font-size: calc(var(--ws) * .4); line-height: 1; color: var(--cream); text-align: center;
}
.sp-foot { flex: none; padding-bottom: 12%; font-family: var(--cond); font-weight: 600; font-size: calc(var(--ws) * .16); letter-spacing: .12em; color: rgba(228, 220, 203, .5); text-transform: uppercase; writing-mode: vertical-rl; transform: rotate(180deg); }
/* two thin cream bands across the spine, like the ones on a cloth binding */
.sp-band { flex: none; width: 100%; height: 5px; margin: 10% 0 0; border-top: 1px solid rgba(228, 220, 203, .5); border-bottom: 1px solid rgba(228, 220, 203, .5); }

/* the lid: the top edge of a book, the two boards and the cream pages between them */
.bx-tp, .bx-bk { position: absolute; backface-visibility: hidden; -webkit-backface-visibility: hidden; pointer-events: none; }
.bx-tp {
  left: calc(var(--ws) / -2); top: calc(var(--d) / -2); width: var(--ws); height: var(--d); transform: rotateX(90deg) translateZ(calc(var(--H) / 2));
  background: var(--cream); border-radius: 2px; box-shadow: inset 3px 0 0 var(--lt), inset -3px 0 0 var(--lt), inset 0 -3px 0 var(--lt);
}
/* the back board: the same colour, a shade darker */
.bx-bk {
  left: calc(var(--d) / -2); top: calc(var(--H) / -2); width: var(--d); height: var(--H); transform: rotateY(-90deg) translateZ(calc(var(--ws) / 2));
  background: var(--dk); border-radius: 3px;
}

/* the board: a plain pale shelf, a soft contact shadow where the books stand and a deeper one under the
   book that turns to you (it always turns at the centre) */
.board {
  position: absolute; left: -150vw; width: 300vw; top: calc(var(--d) * -.72); height: calc(var(--d) * 1.44); pointer-events: none;
  transform: translateY(calc(var(--H) / 2)) rotateX(90deg);
  background:
    radial-gradient(calc(var(--d) * .7) calc(var(--ws) * 1.5) at 50% calc(50% + var(--H) * .2), rgba(40, 26, 14, .32), rgba(40, 26, 14, 0)),
    linear-gradient(180deg, rgba(40, 26, 14, .26) 0, rgba(40, 26, 14, .1) 40%, rgba(40, 26, 14, .14) 82%, rgba(40, 26, 14, .3) 85.5%, rgba(40, 26, 14, 0) 92%),
    #D9CCB6;
}
.board-lip {
  position: absolute; left: -150vw; width: 300vw; top: calc(var(--H) / 2); height: calc(var(--H) * .05); pointer-events: none;
  transform: translateZ(calc(var(--d) * .72));
  background: #BFAE92; box-shadow: inset 0 1px 0 #EEE4D2, 0 calc(var(--H) * .03) calc(var(--H) * .05) rgba(30, 20, 10, .2);
}
.shelf.off .board, .shelf.off .board-lip { display: none; }

/* the front cover: the book's front board in the same colour, the cream page edge down the open side,
   the plugin cover set in with a thin line, catalogue tags around it */
.bx-cv {
  left: calc(var(--d) / -2); width: var(--d); transform: rotateY(90deg) translateZ(calc(var(--ws) / 2));
  border-radius: 3px; color: var(--cream); display: flex; flex-direction: column; padding: calc(var(--H) * .035) calc(var(--H) * .045) calc(var(--H) * .035) calc(var(--H) * .035);
  background: color-mix(in srgb, var(--lt) 72%, #141210);
  box-shadow: inset -5px 0 0 var(--cream), inset -6px 0 0 rgba(0, 0, 0, .25), inset 1px 0 0 rgba(255, 255, 255, .1);
}
.bx-cv::before { content: none; }
.cv-tags, .cv-foot { display: flex; gap: 4px; flex-wrap: wrap; }
.cv-tags { justify-content: space-between; }
.tg {
  display: inline-flex; align-items: center; height: calc(var(--H) * .04); padding: 0 .55em; border: 1px solid currentColor;
  font-family: var(--cond); font-weight: 600; font-size: calc(var(--H) * .022); letter-spacing: .09em; text-transform: uppercase; line-height: 1; white-space: nowrap;
}
.cv-pic { position: relative; margin-top: calc(var(--H) * .07); box-shadow: 0 0 0 1px rgba(228, 220, 203, .16); }
.cv-pic img { display: block; width: 100%; height: auto; aspect-ratio: 2 / 1; background: #1b1916; }
/* "Coming soon" sits over the price badge baked into covers of plugins that are not on sale yet */
.soon { position: absolute; left: 1.2%; top: 3.5%; width: 19%; height: 16%; display: grid; place-items: center; background: #F7F5F2; color: #0C0C0C; font-family: var(--cond); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; font-size: calc(var(--H) * .017); line-height: 1; text-align: center; }
.cv-name { margin-top: calc(var(--H) * .05); font-family: var(--cond); font-weight: 600; text-transform: uppercase; font-size: calc(var(--H) * .074); line-height: .95; letter-spacing: .01em; color: #F2ECDF; }
.cv-name::after { content: ''; display: block; width: 2.2em; height: 2px; margin-top: .3em; background: rgba(228, 220, 203, .55); }
.cv-t { margin-top: calc(var(--H) * .025); font-weight: 300; font-size: calc(var(--H) * .026); line-height: 1.45; color: rgba(228, 220, 203, .75); display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
.cv-foot { margin-top: auto; color: rgba(228, 220, 203, .8); }
.cv-foot .tg:last-child { margin-left: auto; color: #F2ECDF; }

/* the ring cursor (fine pointers, inside the shelf only) */
.ring { position: absolute; left: 0; top: 0; z-index: 500; width: 0; height: 0; pointer-events: none; display: none; }
.ring::before { content: ''; position: absolute; left: -18px; top: -18px; width: 36px; height: 36px; border-radius: 50%; border: 1.5px solid var(--bg); transition: transform .35s var(--e-out), background-color .35s var(--e-out); }
.ring b { position: absolute; left: -40px; top: -40px; width: 80px; height: 80px; display: grid; place-items: center; font-family: var(--cond); font-weight: 600; font-size: 13px; letter-spacing: .12em; text-transform: uppercase; color: var(--shelf); transform: scale(0); transition: transform .35s var(--e-out); }
.shelf.cursor { cursor: none; }
.shelf.cursor .bx-sp { cursor: none; }
.shelf.cursor .ring.seen { display: block; }
.ring.sp::before { transform: scale(.45); background: var(--bg); }
.ring.cv::before { transform: scale(2.2); background: var(--bg); border-color: var(--bg); }
.ring.cv b { transform: scale(1); }

.shelf-ui { display: flex; align-items: center; justify-content: center; gap: 20px; width: 100%; max-width: 40rem; padding: 0 16px; margin-top: 6px; }
.shelf-ui .rbtn { border-color: rgba(12, 12, 12, .3); background: rgba(12, 12, 12, .03); }
.shelf-ui .rbtn:hover { background: rgba(12, 12, 12, .08); }
.shelf-cap { flex: 1; min-width: 0; text-align: center; }
.sc-name { font-family: var(--serif); font-size: clamp(1.7rem, 3vw, 2.4rem); line-height: 1.1; letter-spacing: -.02em; }
.sc-meta { margin-top: 6px; font-family: var(--cond); font-weight: 600; font-size: 13px; letter-spacing: .1em; text-transform: uppercase; color: rgba(12, 12, 12, .6); }
.shelf-open { margin-top: 14px; border: 0; background: none; cursor: pointer; font: 500 .72rem/1 Kanit, sans-serif; letter-spacing: .12em; text-transform: uppercase; color: var(--bg); text-decoration: underline; text-underline-offset: 4px; padding: 8px; }
.shelf-list { list-style: none; width: 100%; max-width: 64rem; padding: 32px 20px 0; display: grid; gap: 0 32px; }
.shelf-list li { padding: 12px 0; border-top: 1px solid var(--line); font-weight: 300; font-size: .92rem; line-height: 1.5; }
.shelf-list a { font-weight: 500; text-transform: uppercase; letter-spacing: .04em; text-decoration: underline; text-underline-offset: 3px; margin-right: 6px; }
.shelf-sheet.on .shelf-list { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); padding: 0; }
.shelf-foot { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 32px; padding: 0 16px; }
.shelf-foot .gbtn, .gbtn-dark { border-color: var(--bg); color: var(--bg); font-size: .8rem; padding: 11px 22px; }
.shelf-foot .gbtn:hover, .gbtn-dark:hover { background-color: rgba(12, 12, 12, .06); }
@media (min-width: 640px) {
  .shelf-sec { padding: 48px 32px 0; }
  .shelf-sheet { border-radius: 50px; padding: 72px 0 56px; }
  .shelf-list { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 768px) {
  .shelf-sec { padding: 64px 40px 0; }
  .shelf-sheet { border-radius: 60px; padding: 96px 0 64px; }
  .tab { height: 32px; padding: 0 18px; }
}
@media (max-width: 699px) { .shelf { --H: min(54svh, 86vw, 440px); } .tabs { margin-top: 24px; flex-wrap: nowrap; } .tab { padding: 0 10px; font-size: 12px; } }
@media (max-width: 420px) { .tab .tl { display: none; } .tab { padding: 0 9px; } }

/* the sheet a cover opens into (v13): dark and immersive but still one calm page. The cover's own
   colours, blurred, light the room; the cover floats in front, leans toward the pointer and casts a
   glow in the plugin's colour (--a, set by shelf.js); the facts sit in three small glass panels. */
.sheet { --a: #9FD4FF; --am: color-mix(in srgb, var(--a) 40%, #CFC8BA); position: fixed; inset: 0; z-index: 100; background: #0B0B0C; color: var(--bright); overflow-y: auto; overscroll-behavior: contain; transform-origin: 0 0; isolation: isolate; }
.sheet[hidden] { display: none; }
.sheet.opening .sh-in, .sheet.opening .sh-x { visibility: hidden; }
.sh-bg { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; opacity: 0; transition: opacity 1s var(--ease); }
.sheet.ink .sh-bg { opacity: 1; }
.sh-bg img { position: absolute; left: -20%; top: -20%; width: 140%; height: 140%; max-width: none; object-fit: cover; filter: blur(72px) saturate(.8); opacity: .36; }
.sh-bg::after {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(60% 55% at 30% 46%, color-mix(in srgb, var(--am) 12%, transparent), rgba(11, 11, 12, 0) 70%), linear-gradient(180deg, rgba(11, 11, 12, .15), rgba(11, 11, 12, .5) 62%, rgba(11, 11, 12, .9));
}
.sh-x {
  position: fixed; z-index: 3; top: 16px; right: 16px; width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center; cursor: pointer;
  border: 1px solid rgba(247, 245, 242, .22); background: rgba(20, 20, 22, .55); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); color: var(--bright);
  transition: transform .45s var(--e-out), background-color .2s;
}
.sh-x:hover { transform: rotate(90deg); background: rgba(44, 44, 48, .7); }
.sh-x:focus-visible { outline: 2px solid var(--bright); outline-offset: 3px; }
.sh-in { position: relative; min-height: 100%; max-width: 76rem; margin: 0 auto; padding: 80px 20px 40px; display: grid; gap: 32px; align-content: center; }
.sh-pic { position: relative; margin: 0; transform: perspective(1400px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); transition: transform 1s var(--e-out); }
.sh-pic img { position: relative; width: 100%; height: auto; aspect-ratio: 2 / 1; display: block; border-radius: 14px; background: #1b1916; }
/* the glow under it and the glass edge over it, once the ink has spread */
.sh-pic::before { content: ''; position: absolute; inset: 10% 6% -4%; z-index: -1; border-radius: 24px; background: var(--a); filter: blur(56px); opacity: 0; transition: opacity 1.2s var(--ease) .3s; }
.sh-pic::after { content: ''; position: absolute; inset: 0; z-index: 1; border-radius: 14px; pointer-events: none; opacity: 0; transition: opacity 1s var(--ease) .5s; background: linear-gradient(125deg, rgba(255, 255, 255, .16), rgba(255, 255, 255, 0) 38%); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .12); }
.sheet.ink .sh-pic::before { opacity: .14; }
.sheet.ink .sh-pic::after { opacity: 1; }
/* "Coming soon" sits over the price badge baked into covers of plugins not on sale yet */
.sh-soon { position: absolute; z-index: 2; left: 1.2%; top: 3.5%; width: 19%; height: 16%; display: grid; place-items: center; background: #F7F5F2; color: #0C0C0C; font-family: var(--cond); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; line-height: 1; text-align: center; border-radius: 4px; font-size: clamp(.55rem, 1.2vw, .9rem); }
.sh-soon[hidden] { display: none; }
/* the picture bleeds in from three ink drops */
html.anim .sheet .sh-pic img { -webkit-mask: radial-gradient(circle at 22% 30%, #000 var(--r1), transparent calc(var(--r1) + 1px)), radial-gradient(circle at 70% 62%, #000 var(--r2), transparent calc(var(--r2) + 1px)), radial-gradient(circle at 46% 90%, #000 var(--r3), transparent calc(var(--r3) + 1px)); mask: radial-gradient(circle at 22% 30%, #000 var(--r1), transparent calc(var(--r1) + 1px)), radial-gradient(circle at 70% 62%, #000 var(--r2), transparent calc(var(--r2) + 1px)), radial-gradient(circle at 46% 90%, #000 var(--r3), transparent calc(var(--r3) + 1px)); }
.sh-b { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
.sh-ic {
  display: grid; place-items: center; width: 52px; height: 52px; border-radius: 14px; margin-bottom: 4px;
  background: color-mix(in srgb, var(--a) 18%, #1f1a15); border-radius: 0;
  box-shadow: inset 3px 3px 0 rgba(0, 0, 0, .4), inset -3px -3px 0 rgba(255, 255, 255, .1);
}
/* 16 px items at whole device pixels per texel: 32 css px is 2 or 3 device px per texel at 1x and 1.5x,
   at 1.25x it would be 2.5, so it steps up to 3 there (38.4 css px) */
@media (min-resolution: 1.2dppx) and (max-resolution: 1.3dppx) { .sh-ic img { width: 38.4px !important; height: 38.4px !important; } }
.sh-ic img { width: 32px; height: 32px; image-rendering: pixelated; filter: drop-shadow(2px 2px 0 rgba(0, 0, 0, .45)); }
.sh-k { font-family: var(--cond); font-weight: 600; font-size: 13px; letter-spacing: .14em; text-transform: uppercase; color: var(--am); }
.sh-name { font-family: var(--serif); font-weight: 400; font-size: clamp(2.6rem, 6vw, 4.8rem); line-height: 1; letter-spacing: -.03em; color: #fff; }
.sh-t { font-weight: 300; font-size: clamp(1rem, 1.5vw, 1.2rem); line-height: 1.6; color: rgba(247, 245, 242, .74); max-width: 34rem; }
.sh-spec { margin-top: 10px; width: 100%; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.sh-spec div {
  display: flex; flex-direction: column; gap: 6px; padding: 12px 14px; border-radius: 14px; overflow: hidden; min-width: 0;
  background: rgba(255, 255, 255, .045); border: 1px solid rgba(255, 255, 255, .09); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.sh-spec div:nth-child(2) { grid-column: 1 / -1; grid-row: 2; }
.sh-spec dt { font-family: var(--cond); font-weight: 600; font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: rgba(247, 245, 242, .5); }
.sh-spec dd { font-weight: 500; font-size: 1rem; line-height: 1.25; }
.sh-price { font-weight: 700 !important; color: #F2ECDF; }
html.anim .sh-spec dt, html.anim .sh-spec dd { transform: translate3d(0, 110%, 0); transition: transform .9s var(--e-out) var(--md, 0s); }
html.anim .sh-spec div.in dt, html.anim .sh-spec div.in dd { transform: none; }
.sh-go { margin-top: 12px; }
/* .sh-go is also a .mrise line mask (overflow hidden): room inside it for the button's glow, taken
   back with negative margins, so the glow is no longer cut into a rectangle (2026-11-02) */
.sh-go.mrise { padding: 0 36px 40px; margin: 12px -36px -40px; }
.sh-go > span { display: flex; flex-wrap: wrap; gap: 12px; }
.sh-go .vbtn { background: #F2ECDF; color: #0C0C0C; box-shadow: inset 0 1px 0 rgba(255, 255, 255, .45); }
.sh-go .vbtn:hover { background: #fff; }
.sh-go .gbtn { border-color: rgba(247, 245, 242, .45); color: var(--bright); font-size: .8rem; padding: 11px 24px; }
.sh-go .gbtn:hover { background-color: rgba(247, 245, 242, .08); }
/* not on sale yet: no buy button, and the docs take its place as the main one */
.sh-go [hidden] { display: none; }
.sh-go .sh-buy[hidden] + .sh-docs { border-color: #F2ECDF; background: #F2ECDF; color: #0C0C0C; }
.sh-nav { display: flex; align-items: center; gap: 14px; margin-top: 18px; padding-top: 18px; border-top: 1px solid rgba(247, 245, 242, .1); width: 100%; }
.sh-n { font-family: var(--mono); font-size: .8rem; color: rgba(247, 245, 242, .5); letter-spacing: .04em; min-width: 5.4em; text-align: center; }
.sh-n b { color: var(--bright); font-weight: 500; }
@media (min-width: 900px) {
  .sh-in { grid-template-columns: 1.15fr 1fr; gap: 64px; align-items: center; padding: 72px 56px; }
  .sh-x { top: 24px; right: 24px; }
  .sh-spec { grid-template-columns: .8fr 1.6fr .9fr; }
  .sh-spec div:nth-child(2) { grid-column: auto; grid-row: auto; }
}
html.lock, html.lock body { overflow: hidden; }

/* ---------- 6. off screen: the desk, then what I do away from it ---------- */
.me { padding: 120px 16px 40px; display: flex; flex-direction: column; align-items: center; gap: 40px; }
.me-lead { max-width: 600px; text-align: center; font-weight: 300; font-size: clamp(1rem, 1.8vw, 1.25rem); line-height: 1.6; }
.me-lead a { text-decoration: underline; text-underline-offset: 3px; font-weight: 500; }
/* v10: one big photo and a catalog of the others (gallery.js). Each slide is the photo whole (contain)
   over a blurred, darkened copy of itself, so portrait and landscape shots share one frame. */
.gal { width: 100%; max-width: 80rem; display: flex; flex-direction: column; gap: 14px; }
.gal-stage {
  position: relative; aspect-ratio: 1 / 1; border-radius: 24px; overflow: hidden; background: #111315;
  touch-action: pan-y; cursor: pointer; -webkit-user-select: none; user-select: none; isolation: isolate;
}
.gal-slide {
  position: absolute; inset: 0; margin: 0; opacity: 0; visibility: hidden;
  transform: translate3d(calc(var(--dir, 1) * 2.2%), 0, 0) scale(1.015);
  transition: opacity .7s var(--e-out), transform .9s var(--e-out), visibility 0s linear .9s;
}
.gal-slide.on { opacity: 1; visibility: visible; transform: none; transition: opacity .7s var(--e-out), transform .9s var(--e-out), visibility 0s; z-index: 1; }
.gal-bg { position: absolute; inset: -6%; width: 112%; height: 112%; max-width: none; object-fit: cover; filter: blur(34px) brightness(.5) saturate(1.1); }
.gal-fg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; -webkit-user-drag: none; }
.gal-ui { display: flex; align-items: center; gap: 12px; }
.gal-thumbs { display: flex; gap: 8px; flex: 1; min-width: 0; overflow-x: auto; scrollbar-width: none; padding: 3px; margin: -3px; }
.gal-thumbs::-webkit-scrollbar { display: none; }
.gal-th {
  flex: none; width: 64px; aspect-ratio: 4 / 3; border-radius: 12px; overflow: hidden; padding: 0; cursor: pointer;
  border: 1px solid rgba(215, 226, 234, .16); background: #16181b; opacity: .5;
  transition: opacity .3s var(--ease), border-color .3s var(--ease), transform .45s var(--e-out);
}
.gal-th img { width: 100%; height: 100%; object-fit: cover; }
.gal-th:hover { opacity: .85; }
.gal-th[aria-current="true"] { opacity: 1; border-color: var(--ice); box-shadow: 0 0 0 1px var(--ice); }
.gal-n { flex: none; font-family: var(--mono); font-size: 12px; letter-spacing: .08em; opacity: .6; }
.gal-n b { font-weight: 500; opacity: 1; color: var(--bright); }
.gal-nav { flex: none; display: flex; gap: 8px; }
html:not(.js) .gal-ui { display: none; }
@media (max-width: 479px) { .gal-n { display: none; } .gal-th { width: 54px; } .gal-nav .rbtn { width: 40px; height: 40px; } }
@media (min-width: 640px) {
  .gal-stage { aspect-ratio: 4 / 3; border-radius: 40px; }
  .gal-th { width: 84px; border-radius: 14px; }
}
@media (min-width: 1024px) { .gal-stage { aspect-ratio: 16 / 10; border-radius: 60px; } .gal-th { width: 104px; } }
.me-list { list-style: none; width: 100%; max-width: 64rem; display: grid; grid-template-columns: 1fr 1fr; gap: 0 24px; }
.me-list li { padding: 20px 0; border-top: 1px solid rgba(215, 226, 234, .15); display: flex; flex-direction: column; gap: 6px; }
.me-list h3 { font-weight: 500; text-transform: uppercase; letter-spacing: .02em; font-size: clamp(1rem, 2vw, 1.6rem); line-height: 1.1; }
.me-list p { font-weight: 300; opacity: .6; font-size: clamp(.85rem, 1.2vw, 1rem); line-height: 1.5; }
@media (min-width: 640px) {
  .me { padding: 140px 32px 48px; }
}
@media (min-width: 768px) {
  .me { padding: 160px 40px 64px; gap: 56px; }
  .me-list { grid-template-columns: repeat(4, 1fr); gap: 0 32px; }
}

/* ---------- 7. the goal: a white sheet, so the black bike reads ---------- */
.goal { padding: 40px 16px 0; }
.goal-sheet {
  max-width: 80rem; margin: 0 auto; background: var(--paper); color: var(--bg);
  border-radius: 40px; padding: 56px 20px 40px;
  display: flex; flex-direction: column; align-items: center;
}
.goal-k { font-size: clamp(.75rem, 1.2vw, 1rem); text-transform: uppercase; letter-spacing: .12em; opacity: .55; margin-bottom: 12px; }
.goal .sec-h { color: var(--bg); }
.goal-bike { width: min(100%, 1100px); margin: 24px 0 8px; position: relative; }
/* multiply: the photo's near-white backdrop melts into the sheet instead of showing its edge */
.goal-bike img { width: 100%; height: auto; mix-blend-mode: multiply; transition: transform .8s var(--ease); }
.goal-bike figcaption { text-align: right; font-size: .7rem; letter-spacing: .08em; text-transform: uppercase; opacity: .4; }
@media (hover: hover) { .goal-bike:hover img { transform: translateX(10px); } }
.goal-body { width: 100%; max-width: 64rem; display: grid; gap: 32px; margin-top: 16px; }
.goal-t { display: flex; flex-direction: column; align-items: flex-start; gap: 16px; }
.goal-t h3 { font-weight: 500; text-transform: uppercase; font-size: clamp(1.25rem, 2.6vw, 2.4rem); line-height: 1.1; }
.goal-t p { font-weight: 300; line-height: 1.6; font-size: clamp(.95rem, 1.4vw, 1.15rem); opacity: .7; max-width: 34rem; }
.goal .gbtn { border-color: var(--bg); color: var(--bg); }
.goal .gbtn:hover { background-color: rgba(12, 12, 12, .06); }
.goal-spec div { display: flex; justify-content: space-between; gap: 16px; padding: 12px 0; border-top: 1px solid var(--line); }
.goal-spec div:last-child { border-bottom: 1px solid var(--line); }
.goal-spec dt { text-transform: uppercase; letter-spacing: .1em; font-size: .75rem; opacity: .55; padding-top: .2em; flex: none; }
.goal-spec dd { font-weight: 500; text-align: right; font-size: clamp(.9rem, 1.3vw, 1.05rem); }
.goal-spec div:last-child dd { font-weight: 900; font-size: clamp(1.4rem, 2.6vw, 2.2rem); line-height: 1; }
@media (min-width: 640px) {
  .goal { padding: 48px 32px 0; }
  .goal-sheet { border-radius: 50px; padding: 72px 40px 48px; }
}
@media (min-width: 768px) {
  .goal { padding: 64px 40px 0; }
  .goal-sheet { border-radius: 60px; padding: 96px 56px 64px; }
  .goal-body { grid-template-columns: 1fr 1fr; gap: 56px; align-items: start; }
}

/* ---------- 8. wishlist: the same white sheet as the goal. Light cards for what I'm saving up for
   (phones swipe them, tablets get two columns, desktops three), then a dark panel for the dream cars. ---------- */
.wish .goal-sheet { padding-bottom: 20px; }
@media (min-width: 640px) { .wish .goal-sheet { padding-bottom: 40px; } }
@media (min-width: 768px) { .wish .goal-sheet { padding-bottom: 56px; } }
.wish-lead { max-width: 36rem; text-align: center; font-weight: 300; line-height: 1.6; font-size: clamp(.95rem, 1.4vw, 1.15rem); opacity: .7; margin-top: 20px; }
.wish-head {
  width: 100%; max-width: 72rem; display: flex; justify-content: space-between; align-items: baseline; gap: 8px 24px; flex-wrap: wrap;
  margin: 48px 0 18px; padding-bottom: 14px; border-bottom: 1px solid var(--line);
}
.wish-head h3 { font-weight: 500; text-transform: uppercase; letter-spacing: .02em; line-height: 1.1; font-size: clamp(1.1rem, 2vw, 1.6rem); }
.wish-head p { font-size: .72rem; text-transform: uppercase; letter-spacing: .12em; opacity: .5; }
.wish-grid {
  list-style: none; width: calc(100% + 40px); margin: 0 -20px; padding: 2px 20px 10px;
  display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding: 0 20px;
  scrollbar-width: none; overscroll-behavior-x: contain;
}
.wish-grid::-webkit-scrollbar { display: none; }
.wc {
  flex: 0 0 84%; scroll-snap-align: start; min-width: 0;
  display: flex; flex-direction: column; border-radius: 28px; background: #F2F3F4; overflow: hidden;
}
/* swiped cards are already on screen: no fade for them on phones */
@media (max-width: 639px) { html.anim .wish-grid .wc.fi { clip-path: none; transform: none; transition: none; } }
/* overflow hidden: an aspect-ratio box with visible overflow grows to fit a tall photo */
.wc-pic { position: relative; aspect-ratio: 16 / 10; overflow: hidden; padding: 28px 22px 10px; display: flex; align-items: center; justify-content: center; }
/* multiply: any white box around a product photo melts into the card */
.wc-pic img { width: 100%; height: 100%; object-fit: contain; mix-blend-mode: multiply; transition: transform .8s var(--ease); }
@media (hover: hover) { .wc:hover .wc-pic img { transform: scale(1.04); } }
.wc-pic figcaption, .car-pic figcaption {
  position: absolute; top: 14px; right: 18px; font-size: .6rem; letter-spacing: .1em; text-transform: uppercase; opacity: .4;
}
.wc-b { flex: 1; display: flex; flex-direction: column; gap: 10px; padding: 6px 22px 22px; }
.wc-k { font-size: .68rem; text-transform: uppercase; letter-spacing: .14em; opacity: .5; font-weight: 500; }
.wc-b h4, .car-b h4 { font-weight: 500; text-transform: uppercase; line-height: 1.1; font-size: clamp(1.15rem, 1.6vw, 1.45rem); margin-top: -4px; }
.wc-t { font-weight: 300; line-height: 1.55; font-size: .92rem; opacity: .72; }
.wc-spec { margin-top: 4px; }
.wc-spec div { display: flex; justify-content: space-between; gap: 12px; padding: 8px 0; border-top: 1px solid var(--line); }
.wc-spec dt { flex: none; font-size: .66rem; text-transform: uppercase; letter-spacing: .1em; opacity: .55; padding-top: .25em; }
.wc-spec dd { text-align: right; font-weight: 500; font-size: .86rem; line-height: 1.35; }
.wc-alt { font-size: .82rem; line-height: 1.5; font-weight: 300; opacity: .8; padding: 10px 12px; border-radius: 14px; background: rgba(12, 12, 12, .045); }
.wc-alt a { font-weight: 500; text-decoration: underline; text-underline-offset: 3px; }
.wc-foot { margin-top: auto; padding-top: 12px; display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px 12px; border-top: 1px solid var(--line); }
.wc-price { font-weight: 900; line-height: 1; font-size: clamp(1.45rem, 2.1vw, 1.85rem); letter-spacing: -.01em; white-space: nowrap; }
.wc-from { font-weight: 400; font-size: .7rem; text-transform: uppercase; letter-spacing: .12em; opacity: .55; margin-right: 6px; vertical-align: .25em; }
.wc-price--quiet { font-weight: 500; font-size: clamp(1rem, 1.4vw, 1.2rem); text-transform: uppercase; letter-spacing: .04em; }
.wc-note { font-size: .7rem; line-height: 1.45; opacity: .5; margin-top: -2px; }
.wc-go {
  flex: none; display: inline-flex; align-items: center; gap: 6px; padding: 9px 14px 9px 16px; border-radius: 999px;
  border: 1.5px solid currentColor; font-weight: 500; text-transform: uppercase; letter-spacing: .1em; font-size: .7rem; line-height: 1; white-space: nowrap;
  transition: background-color .2s, color .2s;
}
.wc-go svg { transition: transform .3s var(--ease); }
.wc-go:hover { background-color: var(--bg); color: var(--paper); }
.wc-go:hover svg { transform: translate(2px, -2px); }

/* the dream cars: one dark panel inside the sheet */
.cars {
  width: 100%; max-width: 72rem; margin-top: 40px; background: var(--bg); color: var(--ink);
  border-radius: 28px; padding: 6px 16px 16px;
}
.wish-head--dark { margin: 18px 4px 16px; width: auto; max-width: none; border-bottom-color: rgba(215, 226, 234, .14); }
.cars-row { list-style: none; display: grid; gap: 12px; }
.car { display: flex; flex-direction: column; border-radius: 20px; overflow: hidden; background: #151617; border: 1px solid rgba(215, 226, 234, .08); }
/* Each car photo is an inspector (assets/js/cars.js + veyra-scene.js). The figure is the image plane:
   hotspots and points are placed in percent of it, and the photo, its zoom and the detail photo all
   live inside one framed envelope, so nothing moves out of register. */
.car-pic { position: relative; aspect-ratio: 16 / 9; margin: 10px 10px 0; isolation: isolate; }
.vs-env { position: absolute; inset: 0; overflow: hidden; border-radius: 14px; background: #151617; box-shadow: 0 0 0 3px rgba(247, 245, 242, .92); pointer-events: none; user-select: none; -webkit-user-select: none; }
.vs-visual, .vs-detail { position: absolute; inset: 0; overflow: hidden; }
.vs-visual { transition: transform 1.5s cubic-bezier(.65, 0, .25, 1); }
.vs-phase-entering .vs-visual, .vs-phase-detail .vs-visual { transform: scale(var(--vs-zoom, 1.5)); }
.car-pic .vs-visual img { width: 100%; height: 100%; object-fit: cover; }
.vs-detail { opacity: 0; transition: opacity .85s ease; background: #151617; }
.vs-detail.vs-detail-none { visibility: hidden; }
.vs-detail img { width: 100%; height: 100%; object-fit: cover; transform: scale(1.08); transition: transform 1.3s cubic-bezier(.22, 1, .36, 1); }
.vs-detail.shown { opacity: 1; }
.vs-detail.shown img { transform: none; }
.car-pic figcaption { z-index: 4; color: #fff; opacity: .8; top: 12px; right: 12px; padding: 4px 8px; border-radius: 6px; background: rgba(12, 12, 12, .45); pointer-events: none; }
/* the GT3 is cut out: it stands on a soft pool of light instead of a photo (the pool zooms with it) */
.car-pic--cut .vs-visual { display: flex; align-items: center; justify-content: center; padding: 6% 7% 4%;
  background: radial-gradient(60% 46% at 50% 72%, rgba(215, 226, 234, .13), transparent 72%), #151617; }
.car-pic--cut .vs-visual img { height: auto; object-fit: contain; filter: drop-shadow(0 18px 18px rgba(0, 0, 0, .55)); }

/* hotspots: a 48 px target, a small light disc with a plus, a label on hover or keyboard focus */
.vs-hotspots, .vs-points { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.vs-hotspots[hidden], .vs-points[hidden] { display: none; }
.vs-hot, .vs-point { position: absolute; transform: translate(-50%, -50%); display: grid; place-items: center; width: 48px; height: 48px; padding: 0; border: 0; border-radius: 50%; background: none; color: #0C0C0C; cursor: pointer; pointer-events: auto; -webkit-tap-highlight-color: transparent; font: inherit; }
.vs-ring { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; background: var(--bright); box-shadow: 0 0 0 5px rgba(247, 245, 242, .16), 0 4px 14px rgba(0, 0, 0, .35); transition: transform .18s var(--ease), box-shadow .18s var(--ease); }
.vs-hot:hover .vs-ring, .vs-hot.active .vs-ring { transform: scale(1.08); box-shadow: 0 0 0 7px rgba(247, 245, 242, .24), 0 4px 14px rgba(0, 0, 0, .35); }
.vs-hot:disabled { opacity: .28; cursor: default; pointer-events: none; }
.vs-label, .vs-point-label {
  position: absolute; bottom: calc(100% - 2px); left: 50%; transform: translate(-50%, 4px); opacity: 0; display: flex; gap: 8px; align-items: center; white-space: nowrap;
  padding: 8px 11px; border-radius: 7px; background: var(--bright); color: #0C0C0C; font-weight: 500; font-size: .82rem; line-height: 1.2; letter-spacing: .01em;
  pointer-events: none; transition: opacity .18s var(--ease), transform .24s var(--e-out);
}
.vs-edge-l .vs-label, .vs-edge-l .vs-point-label { left: 8px; transform: translate(0, 4px); }
.vs-edge-r .vs-label, .vs-edge-r .vs-point-label { left: auto; right: 8px; transform: translate(0, 4px); }
.vs-hot.active .vs-label, .vs-hot:focus-visible .vs-label { opacity: 1; transform: translate(-50%, 0); }
.vs-edge-l.vs-hot.active .vs-label, .vs-edge-l.vs-hot:focus-visible .vs-label, .vs-edge-r.vs-hot.active .vs-label, .vs-edge-r.vs-hot:focus-visible .vs-label { transform: none; }
.vs-hot:focus-visible, .vs-point:focus-visible, .vs-back:focus-visible, .car-copy button:focus-visible { outline: 2px solid var(--bright); outline-offset: 3px; }
/* numbered points in the detail view */
.vs-point > span:first-child { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--bright); font-weight: 500; font-size: .74rem; letter-spacing: .02em; box-shadow: 0 4px 14px rgba(0, 0, 0, .35); transition: box-shadow .18s var(--ease); }
.vs-point.open > span:first-child { box-shadow: 0 0 0 5px rgba(247, 245, 242, .3), 0 4px 14px rgba(0, 0, 0, .35); }
.vs-point:hover .vs-point-label, .vs-point:focus-visible .vs-point-label, .vs-point.open .vs-point-label { opacity: 1; transform: translate(-50%, 0); }
.vs-edge-l.vs-point:hover .vs-point-label, .vs-edge-l.vs-point:focus-visible .vs-point-label, .vs-edge-l.vs-point.open .vs-point-label,
.vs-edge-r.vs-point:hover .vs-point-label, .vs-edge-r.vs-point:focus-visible .vs-point-label, .vs-edge-r.vs-point.open .vs-point-label { transform: none; }
/* the lens: that part of the photo, lifted a little, in a ring */
.vs-lens { position: absolute; z-index: 2; border-radius: 50%; background-repeat: no-repeat; background-color: #151617; pointer-events: none; opacity: 0; transform: scale(.92);
  box-shadow: 0 0 0 1.5px rgba(247, 245, 242, .85), 0 0 0 7px rgba(247, 245, 242, .1), 0 18px 40px rgba(0, 0, 0, .5); transition: opacity .2s var(--ease), transform .3s var(--e-out); }
.vs-lens.on { opacity: 1; transform: none; }
.vs-back { position: absolute; z-index: 5; left: 12px; top: 12px; display: inline-flex; align-items: center; gap: 8px; min-height: 40px; padding: 8px 12px; border: 0; border-radius: 7px; background: var(--bright); color: #0C0C0C; font: inherit; font-weight: 500; font-size: .82rem; cursor: pointer; }
.vs-back[hidden] { display: none; }
.vs-back:disabled { opacity: .7; cursor: default; }
.vs-back kbd { font: inherit; font-size: .7rem; opacity: .6; padding-left: 8px; margin-left: 2px; border-left: 1px solid rgba(12, 12, 12, .25); }
/* smaller where the photo is small, so it stays off part point 01 (Rear lid) at the top left (2026-11-02);
   the button keeps its aria-label */
@media (max-width: 1100px) { .vs-back kbd { display: none; } }
@media (max-width: 640px) { .vs-back { min-width: 40px; padding: 8px; justify-content: center; } .vs-back > span { display: none; } }
.vs-status { position: absolute; z-index: 4; left: 50%; bottom: 12px; transform: translateX(-50%); display: flex; align-items: center; gap: 8px; padding: 6px 10px; border-radius: 6px; background: rgba(12, 12, 12, .6); color: var(--ink); font-size: .74rem; white-space: nowrap; pointer-events: none; }
.vs-status[hidden] { display: none; }
.vs-status i { width: 5px; height: 5px; border-radius: 50%; background: var(--bright); }
.vs-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

/* the card text and the detail text share one grid cell, so the card never jumps */
.car-stack { flex: 1; display: grid; }
.car-stack > * { grid-area: 1 / 1; min-width: 0; }
.car-b { flex: 1; display: flex; flex-direction: column; gap: 10px; padding: 18px 20px 20px; transition: opacity .35s var(--ease); }
.car-tip { display: none; font-size: .74rem; letter-spacing: .02em; opacity: .5; margin-top: -2px; }
.vs-ready .car-tip { display: block; }
/* hidden, the detail text takes no room; shown, the card grows only if the text is longer than the card's own */
.car-copy { position: absolute; left: 0; right: 0; top: 0; padding: 18px 20px 20px; opacity: 0; visibility: hidden; transform: translateY(12px); transition: opacity .3s var(--ease), transform .7s var(--e-out), visibility 0s .3s; }
.car-copy.shown { position: relative; opacity: 1; visibility: visible; transform: none; transition: opacity .5s var(--ease) .15s, transform .7s var(--e-out) .15s, visibility 0s; }
.car-stack { position: relative; }
.vs-hot.active, .vs-hot:focus-visible, .vs-point.open, .vs-point:hover, .vs-point:focus-visible { z-index: 2; }
.vs-phase-detail .car-b, .vs-phase-entering .car-b { opacity: 0; visibility: hidden; }
.vs-eyebrow { font-size: .68rem; text-transform: uppercase; letter-spacing: .14em; opacity: .5; font-weight: 500; }
.vs-title { font-weight: 500; text-transform: uppercase; line-height: 1.1; font-size: clamp(1.15rem, 1.6vw, 1.45rem); margin-top: 6px; }
.vs-desc { font-weight: 300; line-height: 1.55; font-size: .9rem; opacity: .75; margin-top: 10px; }
.vs-parts { margin-top: 14px; border-top: 1px solid rgba(215, 226, 234, .12); }
.vs-parts button { display: block; width: 100%; min-height: 48px; padding: 13px 0; border: 0; border-bottom: 1px solid rgba(215, 226, 234, .12); background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; transition: color .18s var(--ease); }
.vs-part-row { display: flex; align-items: center; gap: 12px; font-weight: 500; font-size: .9rem; }
.vs-part-row small { font-size: .7rem; opacity: .5; font-weight: 400; min-width: 1.6em; }
.vs-part-row svg { margin-left: auto; flex: none; transition: transform .24s var(--e-out); }
.vs-parts button.selected svg { transform: rotate(45deg); }
.vs-parts button:hover, .vs-parts button.selected { color: var(--bright); }
.vs-part-text { display: block; padding: 8px 0 2px calc(1.6em + 12px); font-weight: 300; font-size: .86rem; line-height: 1.5; opacity: .8; }
.vs-part-text[hidden] { display: none; }
.vs-credit { margin-top: 12px; font-size: .62rem; text-transform: uppercase; letter-spacing: .1em; opacity: .4; }
@media (max-width: 639px) { .vs-back kbd { display: none; } .vs-label, .vs-point-label { font-size: .76rem; padding: 7px 9px; } .vs-ring { width: 24px; height: 24px; } }
@media (hover: none) { .vs-back kbd { display: none; } }
/* reduced motion: every state is instant (the zoom stays, so the points still sit on their parts) */
.vs-reduced .vs-visual, .vs-reduced .vs-detail, .vs-reduced .vs-detail img, .vs-reduced .vs-lens, .vs-reduced .car-copy, .vs-reduced .car-b, .vs-reduced .vs-label, .vs-reduced .vs-point-label, .vs-reduced .vs-ring { transition: none; }
.car .wc-spec div, .car .wc-foot { border-color: rgba(215, 226, 234, .12); }
.car .wc-go:hover { background-color: var(--ink); color: var(--bg); }

@media (min-width: 640px) {
  .wish-head { margin-top: 56px; }
  .wish-grid {
    width: 100%; margin: 0; padding: 0; overflow: visible; scroll-snap-type: none;
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; max-width: 72rem;
  }
  .wc { border-radius: 32px; }
  .cars { border-radius: 36px; padding: 8px 20px 20px; }
  .cars-row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
  .car { border-radius: 24px; }
}
@media (min-width: 768px) {
  .cars { margin-top: 56px; padding: 12px 28px 28px; border-radius: 40px; }
  .wish-head--dark { margin: 24px 4px 20px; }
}
@media (min-width: 1100px) {
  .wish-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
  .wc-pic { padding: 32px 26px 12px; }
  .wc-b { padding: 6px 26px 26px; }
}

/* ---------- 9. bike shortlists: small cards, so the TUES above stays the big one. Downhill sits inside the goal
   sheet, enduro gets its own sheet. Phones swipe, tablets two columns, desktops four (downhill) or three (enduro). ---------- */
.bk-grid {
  list-style: none; width: calc(100% + 40px); margin: 0 -20px; padding: 2px 20px 10px;
  display: flex; gap: 10px; overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding: 0 20px;
  scrollbar-width: none; overscroll-behavior-x: contain;
}
.bk-grid::-webkit-scrollbar { display: none; }
.bk {
  flex: 0 0 66%; scroll-snap-align: start; min-width: 0; position: relative;
  display: flex; flex-direction: column; border-radius: 22px; background: #F2F3F4; overflow: hidden;
}
@media (max-width: 639px) { html.anim .bk-grid .bk.fi { clip-path: none; transform: none; transition: none; } }
.bk-pic { position: relative; aspect-ratio: 16 / 10; overflow: hidden; padding: 22px 16px 4px; display: flex; align-items: center; justify-content: center; }
.bk-pic img { width: 100%; height: 100%; object-fit: contain; mix-blend-mode: multiply; transition: transform .8s var(--ease); }
@media (hover: hover) { .bk:hover .bk-pic img { transform: translateX(6px); } }
.bk-pic figcaption { position: absolute; top: 11px; right: 14px; font-size: .55rem; letter-spacing: .1em; text-transform: uppercase; opacity: .4; }
.bk-b { flex: 1; display: flex; flex-direction: column; gap: 6px; padding: 4px 16px 16px; }
.bk-b h4 { font-weight: 500; text-transform: uppercase; line-height: 1.1; font-size: clamp(1rem, 1.3vw, 1.15rem); }
.bk-s { font-size: .78rem; line-height: 1.45; opacity: .62; }
.bk-foot { margin-top: auto; padding-top: 10px; display: flex; justify-content: space-between; align-items: center; gap: 8px; border-top: 1px solid var(--line); }
.bk-price { font-weight: 900; line-height: 1; font-size: clamp(1.1rem, 1.5vw, 1.3rem); white-space: nowrap; }
.bk-price .wc-from { font-size: .6rem; margin-right: 4px; }
/* the arrow is the link; the whole card is clickable through its ::after */
.bk-go {
  flex: none; display: grid; place-items: center; width: 32px; height: 32px; border-radius: 10px;
  border: 1.5px solid currentColor; transition: background-color .2s, color .2s;
}
.bk-go::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.bk-go svg { transition: transform .3s var(--ease); }
.bk:hover .bk-go { background-color: var(--bg); color: var(--paper); }
.bk:hover .bk-go svg { transform: translate(2px, -2px); }
/* the TUES: dark, so the goal stands out among the alternatives */
.bk--goal { background: var(--bg); color: var(--ink); }
.bk--goal .bk-pic { background: #E9ECEE; margin: 8px 8px 0; border-radius: 16px; }
.bk--goal .bk-tag { background: var(--ink); color: var(--bg); }
.bk--goal .bk-foot { border-color: rgba(215, 226, 234, .16); }
.bk--goal:hover .bk-go { background-color: var(--ink); color: var(--bg); }
.bk-tag {
  position: absolute; top: 18px; left: 18px; z-index: 1; padding: 5px 9px; border-radius: 8px;
  background: var(--bg); color: var(--ink); font-size: .58rem; font-weight: 500; letter-spacing: .12em; text-transform: uppercase;
}
.bk-tag--soft { background: rgba(12, 12, 12, .08); color: var(--bg); }
.bk-was { font-weight: 400; font-size: .72rem; opacity: .5; margin-left: 7px; vertical-align: .2em; }
.bk-note { width: 100%; max-width: 72rem; font-size: .7rem; line-height: 1.5; opacity: .5; margin-top: 10px; }
.bikes .goal-sheet { padding-bottom: 28px; }
@media (min-width: 640px) {
  .bk-grid {
    width: 100%; margin: 0; padding: 0; overflow: visible; scroll-snap-type: none;
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; max-width: 72rem;
  }
  .bk { border-radius: 26px; }
  .bikes .goal-sheet { padding-bottom: 48px; }
}
@media (min-width: 1100px) {
  .bk-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
  .bk-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---------- contact ---------- */
.contact { padding: 120px 20px 96px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 40px; }
.contact > p { max-width: 560px; font-weight: 300; font-size: clamp(1rem, 1.8vw, 1.25rem); line-height: 1.6; }
.links { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; max-width: 900px; }
.links .gbtn { font-size: .8rem; padding: 10px 22px; }
@media (min-width: 768px) { .contact { padding: 160px 40px 128px; } }

/* ---------- footer: a white sheet, two cards, a fitted watermark ---------- */
.kf { position: relative; background: var(--paper); color: var(--bg); border-radius: 40px 40px 0 0; padding: 64px 16px 0; overflow: hidden; }
.kf-in { max-width: 1150px; margin: 0 auto; display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; }
.kf-l {
  position: relative; isolation: isolate; min-height: 340px; border-radius: 28px; padding: 28px; overflow: hidden;
  display: flex; flex-direction: column; color: #fff; background: #0f1a24;
  box-shadow: 0 30px 60px -28px rgba(40, 110, 200, .55);
}
.kf-v { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; object-fit: cover; object-position: 50% 8%; }
/* the still of my desk: kept dark behind the white lines, the lamp and slats left to show at the top */
.kf-l::after { content: ''; position: absolute; inset: 0; z-index: -1; background: linear-gradient(180deg, rgba(6, 10, 16, .5) 0%, rgba(6, 10, 16, .2) 26%, rgba(6, 10, 16, .62) 50%, rgba(6, 10, 16, .9) 100%); }
.kf-logo { display: inline-flex; align-items: center; gap: 12px; align-self: flex-start; font-weight: 700; font-size: 22px; letter-spacing: .06em; text-transform: uppercase; line-height: 1; }
.kf-logo img { width: 36px; height: 36px; }
.kf-tag { margin-top: auto; padding-top: 72px; font-size: 19px; line-height: 1.4; font-weight: 400; }
.kf-tag span { color: rgba(255, 255, 255, .65); }
.kf-social { margin-top: 20px; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 14px; }
.hand { font-family: var(--hand); font-weight: 600; }
.kf-social .hand { font-size: 21px; line-height: 1; }
.kf-tiles { display: flex; gap: 8px; }
.kf-tile { width: 38px; height: 38px; border-radius: 11px; display: grid; place-items: center; background: #0d0e10; color: #fff; box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12); transition: transform .45s var(--e-out), background-color .2s; }
.kf-tile:hover { transform: translateY(-2px); background: #1a1c20; }
.kf-tile svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

.kf-r { position: relative; background: #f0f1f5; border-radius: 28px; padding: 92px 24px 24px; display: flex; flex-direction: column; gap: 32px; }
.lucky { position: absolute; top: -30px; right: 24px; display: flex; align-items: center; gap: 4px; }
.cube { order: 3; width: 96px; height: 96px; padding: 0; border: 0; background: none; cursor: pointer; transform: rotate(-10deg); filter: drop-shadow(0 16px 18px rgba(30, 80, 160, .38)); transition: transform .6s var(--e-out); }
.cube img { width: 96px; height: 96px; transform: rotate(10deg) rotate(-10deg); }
.cube:hover, .cube:focus-visible { transform: rotate(-3deg) translateY(-4px) scale(1.04); }
.cube:active { transform: rotate(-3deg) scale(.96); }
.cube:focus-visible { outline: 2px solid var(--bg); outline-offset: 4px; border-radius: 24px; }
.lucky-arrow { order: 2; width: 58px; height: 36px; margin-top: 30px; fill: none; stroke: var(--bg); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; transform: scaleX(-1) rotate(14deg); }
.lucky-t { order: 1; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; margin-top: 54px; transform: rotate(-4deg); }
.lucky-t .hand { font-size: 22px; line-height: 1; white-space: nowrap; }
.lucky-t code { font-family: var(--mono); font-size: 11px; color: rgba(12, 12, 12, .55); }
.kf-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.kf-cols nav { display: flex; flex-direction: column; align-items: flex-start; gap: 11px; }
.kf-h { font-size: 24px; color: #8b9099; line-height: 1; margin-bottom: 6px; }
.kf-cols a { font-weight: 500; font-size: 14px; line-height: 1.2; transition: color .2s, transform .45s var(--e-out); }
.kf-cols a:hover { color: #2d7fd8; transform: translateX(3px); }
.kf-bot { margin-top: auto; display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-end; gap: 20px 24px; padding-top: 22px; border-top: 1px solid rgba(12, 12, 12, .08); }
.kf-copy { font-size: 12.5px; color: rgba(12, 12, 12, .5); max-width: 22rem; line-height: 1.5; }
.kf-cta { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; }
.kf-cta p { font-size: 14px; line-height: 1.35; color: rgba(12, 12, 12, .7); }
.kf-cta b { color: var(--bg); font-weight: 600; }
.kf-btn { display: inline-flex; align-items: center; height: 44px; padding: 0 22px; border-radius: 999px; background: var(--bg); color: #fff; font-weight: 500; font-size: 13px; letter-spacing: .08em; text-transform: uppercase; white-space: nowrap; transition: transform .45s var(--e-out), background-color .2s; }
.kf-btn:hover { transform: translateY(-2px); background: #1d2a38; }
.kf-wm { display: block; width: 100%; max-width: 1150px; height: auto; margin: 28px auto 0; overflow: visible; }
.kf-wm text { font-family: Kanit, sans-serif; font-weight: 900; font-size: 200px; letter-spacing: -6px; fill: rgba(0, 0, 0, .05); }
@media (min-width: 560px) {
  .kf-l { padding: 32px; }
  .kf-r { padding: 72px 40px 32px; }
  .lucky { right: 40px; top: -36px; }
}
@media (min-width: 640px) { .kf { border-radius: 50px 50px 0 0; padding-top: 80px; } }
@media (min-width: 860px) {
  .kf { border-radius: 60px 60px 0 0; padding: 96px 40px 0; }
  .kf-in { grid-template-columns: 350px minmax(0, 1fr); }
  .kf-r { padding: 40px; }
  .kf-cols { max-width: 360px; }
}
/* until the columns leave room beside it, the plugins note needs its own space above them: it lay on
   the Elsewhere heading (and on Navigation below 960px) (2026-11-02) */
@media (min-width: 860px) and (max-width: 1239px) { .kf-r { padding-top: 84px; } }
@media (max-width: 400px) { .lucky-arrow { display: none; } .cube, .cube img { width: 76px; height: 76px; } .lucky { top: -24px; } .lucky-t { margin-top: 40px; } }

/* the sheet's ink drops grow through registered lengths */
@property --r1 { syntax: '<length-percentage>'; inherits: false; initial-value: 0%; }
@property --r2 { syntax: '<length-percentage>'; inherits: false; initial-value: 0%; }
@property --r3 { syntax: '<length-percentage>'; inherits: false; initial-value: 0%; }
html.anim .sheet .sh-pic img { transition: --r1 1.1s var(--e-out) .15s, --r2 1.2s var(--e-out) .3s, --r3 1.1s var(--e-out) .42s; }
html.anim .sheet.ink .sh-pic img { --r1: 75%; --r2: 75%; --r3: 75%; }

/* Reduced motion: everything is still; transitions take a millisecond, nothing loops. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 1ms !important; transition-delay: 0s !important; animation: none !important; }
}

/* ======================================================================================
   v9 (2026-10-29): the owner's two scroll prompts. (2026-10-31: the climb hero was replaced by the
   suit-up hero in suit.css and its rules removed; the top bar, What I've made and Services stay.)
   Originally: a camera climb was the first screen,
   then the cloud-coloured "What I've shipped", then Services as giant letters behind me
   with a strip of cards in the dark ground. scrub.js drives both clips. The base rules
   below are the stacked page (reduced motion, no script); html.anim adds the scrub layout.
   ====================================================================================== */
@font-face { font-family: Unbounded; font-weight: 800; font-display: swap; src: url(/assets/fonts/unbounded-800-latin.woff2) format('woff2'); }
@font-face { font-family: Anton; font-weight: 400; font-display: swap; src: url(/assets/fonts/anton-400.woff2) format('woff2'); }
:root {
  --ice: #86ccff; --cream: #F7F5EF; --cloud: #e2dedd; --band: #111111; --ink2: #141516;
  --wide: Unbounded, 'Arial Black', sans-serif; --tall: Anton, Impact, 'Arial Narrow', sans-serif;
  --shadow-t: 0 1px 2px rgba(0, 0, 0, .35), 0 2px 18px rgba(0, 0, 0, .35);
}

/* ---------- the top bar: over the first screen, it scrolls away with it ---------- */
.bar {
  position: absolute; z-index: 40; left: 0; right: 0; top: 0;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 16px;
  padding: 16px 16px 0;
}
.mark {
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--bright); font-weight: 700; text-transform: uppercase; letter-spacing: .1em; font-size: .9rem; line-height: 1;
  text-shadow: var(--shadow-t);
}
.mark img { width: 28px; height: 28px; transition: transform .6s var(--e-out); filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .35)); }
@media (hover: hover) { .mark:hover img { transform: rotate(-8deg) scale(1.06); } }
.nav {
  display: flex; align-items: center; gap: 2px; padding: 4px; border-radius: 999px;
  background: rgba(8, 10, 14, .42); border: 1px solid rgba(215, 226, 234, .18); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08);
  -webkit-backdrop-filter: blur(10px) saturate(140%); backdrop-filter: blur(10px) saturate(140%);
}
.nav a {
  padding: 9px 9px; border-radius: 999px; line-height: 1;
  color: rgba(247, 245, 239, .86); font-weight: 500; text-transform: uppercase; letter-spacing: .08em; font-size: .68rem;
  transition: color .2s, background-color .2s;
}
.nav a:hover { color: #fff; background-color: rgba(215, 226, 234, .12); }
@media (max-width: 639px) { .nav { width: 100%; justify-content: space-between; } }
/* v10: six links do not fit a phone; Price (the BuiltByBit bundle) stays in the plugin shelf there */
/* 2026-11-02: Websites joined the bar (seven links); phones also leave Setup to the footer */
@media (max-width: 767px) { .nav a[href$="#wishlist"] { display: none; } }
@media (max-width: 479px) { .nav a[href="/setup/"] { display: none; } .nav a { padding: 9px 7px; letter-spacing: .05em; } }
.nav a[aria-current="page"] { color: #fff; background-color: rgba(215, 226, 234, .14); }
@media (max-width: 360px) { .nav a { padding: 9px 5px; font-size: .62rem; letter-spacing: .05em; } }
@media (min-width: 640px) { .bar { padding: 22px 32px 0; } .nav a { padding: 10px 16px; font-size: .74rem; } }
@media (min-width: 1100px) { .bar { padding: 28px 48px 0; } .mark { font-size: 1rem; } .nav a { padding: 11px 20px; font-size: .8rem; } }


/* ---------- after the clouds: what I've shipped ---------- */
.shipped {
  position: relative; z-index: 3; color: var(--ink2);
  background: linear-gradient(180deg, var(--cloud) 0, var(--cloud) calc(100% - 180px), #fff 100%);
  padding: 96px 0 180px;
}
.shp-wrap { max-width: 1120px; margin: 0 auto; padding: 0 20px; }
.shp-head { display: grid; gap: 22px; align-items: end; padding-bottom: 40px; }
.shp-t { font-family: var(--wide); font-weight: 800; text-transform: uppercase; font-size: clamp(30px, 6.2vw, 72px); line-height: 1.04; letter-spacing: -.015em; }
.shp-t span { display: block; }
.shp-t span:last-child { color: #8f8b8a; }
.shp-note { font-size: 13px; line-height: 1.55; color: rgba(20, 21, 22, .7); max-width: 300px; }
.shp-rows { list-style: none; }
.shp-row { display: grid; gap: 14px; padding: 34px 0; border-top: 1px solid rgba(20, 21, 22, .14); }
.shp-row:last-child { border-bottom: 1px solid rgba(20, 21, 22, .14); }
.shp-who { display: flex; flex-direction: column; gap: 4px; }
.shp-who b { font-weight: 600; font-size: 16px; letter-spacing: .01em; }
.shp-who span { font-size: 13px; color: rgba(20, 21, 22, .58); }
.shp-big { font-weight: 300; font-size: clamp(20px, 2.5vw, 32px); line-height: 1.3; letter-spacing: -.012em; }
.shp-big a { font-weight: 400; white-space: nowrap; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .18em; text-decoration-color: rgba(20, 21, 22, .35); transition: text-decoration-color .2s; }
.shp-big a:hover { text-decoration-color: currentColor; }
.shp-q { margin: 0; }
.shp-q figcaption { margin-top: 16px; font-size: 13px; line-height: 1.55; color: rgba(20, 21, 22, .62); }
.shp-q figcaption a { text-decoration: underline; text-underline-offset: 3px; color: var(--ink2); }
@media (min-width: 760px) {
  .shp-wrap { padding: 0 64px; }
  .shp-head { grid-template-columns: minmax(0, 1fr) 300px; padding-bottom: 56px; }
  .shp-row { grid-template-columns: 260px minmax(0, 1fr); gap: 24px; padding: 44px 0; }
}

/* ---------- B. Services (stacked by default: the last frame, the letters, then the cards) ---------- */
.sv { position: relative; z-index: 3; background: #fff; }
.sv-stage { position: relative; isolation: isolate; overflow: hidden; background: #fff; color: #fff; }
.sv-ground, .sv-video, .sv-speed { display: none; }
.sv-still { position: relative; z-index: 0; display: block; width: 100%; height: auto; }
.sv-letters {
  position: absolute; z-index: 2; left: 50%; top: calc(100vw * 9 / 16 * .448); transform: translate(-50%, -100%); font-size: 18vw;
  margin: 0; font-family: var(--tall); font-weight: 400; text-transform: uppercase; color: #e9e9e9; mix-blend-mode: darken;
  white-space: nowrap; pointer-events: none; line-height: .8; letter-spacing: .005em;
}
.sv-band { position: relative; z-index: 3; background: var(--band); padding: 48px 20px 64px; }
.sv-strip { display: grid; gap: 44px; max-width: 1240px; margin: 0 auto; }
.sv-lead { display: grid; gap: 22px; }
.sv-h { font-family: var(--tall); font-weight: 400; text-transform: uppercase; font-size: clamp(42px, 6vw, 64px); line-height: .98; letter-spacing: .005em; color: #fff; }
.sv-h span { display: block; white-space: nowrap; }
.sv-h .ice { color: var(--ice); }
.sv-ps { display: grid; gap: 12px; max-width: 360px; }
.sv-ps p { font-size: 14px; line-height: 1.55; color: rgba(255, 255, 255, .62); }
.sv-card { padding: 22px 0 0; border-top: 1px solid rgba(255, 255, 255, .12); }
.sv-i { display: block; width: 38px; height: 38px; fill: none; stroke: #fff; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
.sv-tx h3 { margin-top: 18px; font-weight: 600; font-size: 24px; line-height: 1.06; letter-spacing: -.005em; color: #fff; }
.sv-tx p { margin-top: 12px; font-size: 14px; line-height: 1.55; color: rgba(255, 255, 255, .78); }
.sv-tx a { text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(255, 255, 255, .4); }
.sv-pill {
  display: table; margin: 48px auto 0; padding: 13px 26px; border-radius: 999px; border: 1px solid rgba(255, 255, 255, .55);
  color: #fff; font-weight: 500; text-transform: uppercase; letter-spacing: .12em; font-size: 12px; line-height: 1; white-space: nowrap;
  transition: background-color .25s, color .25s, border-color .25s;
}
.sv-pill:hover { background: #fff; color: var(--band); border-color: #fff; }
@media (min-width: 700px) { .sv-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); } .sv-lead { grid-column: 1 / -1; grid-template-columns: auto minmax(0, 360px); align-items: end; column-gap: 48px; } }
@media (min-width: 1100px) { .sv-strip { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 44px 32px; } }

/* the scrub layout: one sticky screen; u = min(vw / 1440, vh / 960) */
html.anim .sv-track { height: 600vh; }
html.anim .sv-stage { --u: min(calc(100vw / 1440), calc(100vh / 960)); position: sticky; top: 0; height: 100vh; height: 100lvh; --edge-px: 55vh; }
html.anim .sv-still { display: none; }
html.anim .sv-ground { display: block; position: absolute; z-index: 0; left: 0; right: 0; bottom: 0; top: var(--edge-px); background: var(--band); }
html.anim .sv-video { display: block; position: absolute; z-index: 1; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; background: #fff; }
html.anim .sv-letters {
  left: 0; top: auto; bottom: calc(100% - var(--edge-px)); font-size: calc(330 * var(--u));
  transform: translate3d(100vw, 0, 0); will-change: transform;
}
html.anim .sv-speed {
  display: block; position: absolute; z-index: 4; left: calc(48 * var(--u)); top: calc(40 * var(--u)); margin: 0;
  font-family: var(--mono); font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--band);
  opacity: 0; transition: opacity .4s var(--ease);
}
html.anim .sv-speed b { font-weight: 500; display: inline-block; min-width: 2ch; }
html.anim .sv-stage.settled .sv-speed { opacity: 1; }
html.anim .sv-band { position: absolute; left: 0; right: 0; bottom: 0; top: var(--edge-px); padding: 0; background: none; }
html.anim .sv-strip {
  position: absolute; left: 0; top: calc(76 * var(--u)); display: flex; align-items: flex-start; gap: calc(120 * var(--u));
  max-width: none; margin: 0; transform: translate3d(100vw, 0, 0); will-change: transform;
}
html.anim .sv-lead { display: flex; align-items: flex-start; gap: calc(44 * var(--u)); flex: none; }
html.anim .sv-h { font-size: calc(64 * var(--u)); }
html.anim .sv-ps { width: calc(250 * var(--u)); flex: none; gap: calc(12 * var(--u)); padding-top: calc(6 * var(--u)); }
html.anim .sv-ps p { font-size: max(12px, calc(13 * var(--u))); }
html.anim .sv-card { flex: none; width: calc(270 * var(--u)); padding: 0 calc(30 * var(--u)); border-top: 0; border-left: 1px solid rgba(255, 255, 255, .12); --s: -40%; }
html.anim .sv-lead + .sv-card { border-left: 0; }
html.anim .sv-i { width: calc(38 * var(--u)); height: calc(38 * var(--u)); opacity: clamp(0, calc((var(--s) + 30%) / 60%), 1); }
html.anim .sv-tx {
  background: linear-gradient(90deg, #fff calc(var(--s) - 34%), var(--ice) calc(var(--s) - 6%), rgba(134, 204, 255, 0) calc(var(--s) + 26%));
  -webkit-background-clip: text; background-clip: text;
}
html.anim .sv-tx h3, html.anim .sv-tx p, html.anim .sv-tx a { color: transparent; }
html.anim .sv-tx h3 { margin-top: calc(22 * var(--u)); font-size: calc(26 * var(--u)); }
html.anim .sv-tx p { margin-top: calc(12 * var(--u)); font-size: max(12.5px, calc(12.4 * var(--u))); }
html.anim .sv-pill { position: absolute; left: 50%; bottom: calc(36 * var(--u)); margin: 0; transform: translate(-50%, 24px); opacity: 0; pointer-events: none; transition: transform .7s var(--e-out), opacity .5s var(--ease), background-color .25s, color .25s, border-color .25s; }
html.anim .sv-stage.settled .sv-pill { transform: translate(-50%, 0); opacity: 1; pointer-events: auto; }
/* the Projects panel slides over the stage's foot by its negative top margin (40 / 48 / 56px), so the
   pill sits that much higher, else Projects covered up to 31 of its 40px (2026-11-02) */
html.anim .sv-pill { bottom: calc(36 * var(--u) + 44px); }
@media (min-width: 640px) { html.anim .sv-pill { bottom: calc(36 * var(--u) + 52px); } }
@media (min-width: 768px) { html.anim .sv-pill { bottom: calc(36 * var(--u) + 60px); } }
/* phones and portrait screens: the clip is 155vw wide, its band edge at 36% of the screen */
@media (max-width: 767px), (orientation: portrait) {
  html.anim .sv-stage { --u: min(calc(100vw / 430), 1.4px); }
  /* max-width: none, or the global video rule caps it at 100vw: the clip was squeezed and stopped at 72.5% */
  html.anim .sv-video { left: -27.5vw; width: 155vw; max-width: none; height: calc(155vw * 9 / 16); object-fit: fill; }
  html.anim .sv-strip { top: calc(44 * var(--u)); gap: calc(56 * var(--u)); padding-left: 22px; }
  html.anim .sv-lead { flex-direction: column; gap: calc(18 * var(--u)); }
  html.anim .sv-h { font-size: calc(46 * var(--u)); }
  html.anim .sv-ps { width: calc(300 * var(--u)); }
  html.anim .sv-ps p { font-size: max(12.5px, calc(13 * var(--u))); }
  html.anim .sv-card { width: calc(250 * var(--u)); }
  html.anim .sv-speed { left: 20px; top: 22px; font-size: 11px; }
}
/* ======================================================================================
   v10 (2026-10-30): the setup page (/setup/). A dark head with the desk catalog, then the same white
   sheets as the goal, holding product cards: the maker's packshot on a white plate, name, one line and a
   link that shows where it goes. Phones get a picture-left row, then 2, 3 and 4 columns.
   ====================================================================================== */
.su-head { padding: 140px 16px 24px; display: flex; flex-direction: column; align-items: center; gap: 28px; }
.su-k { font-size: clamp(.75rem, 1.2vw, 1rem); text-transform: uppercase; letter-spacing: .12em; opacity: .55; margin-bottom: -12px; }
.su-lead { max-width: 40rem; text-align: center; font-weight: 300; font-size: clamp(1rem, 1.6vw, 1.2rem); line-height: 1.6; opacity: .85; }
.su-head .gal { margin-top: 12px; }
.su-sec + .su-sec { padding-top: 16px; }
.su-sec .goal-sheet { padding-bottom: 28px; }
.su-grid { list-style: none; width: 100%; max-width: 72rem; margin-top: 32px; display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; }
.su {
  position: relative; min-width: 0; display: grid; grid-template-columns: 42% minmax(0, 1fr); align-items: center;
  border-radius: 22px; background: #F2F3F4; padding: 8px; gap: 4px;
}
.su-pic { position: relative; margin: 0; aspect-ratio: 4 / 3; border-radius: 16px; overflow: hidden; background: #fff; }
.su-pic img { width: 100%; height: 100%; object-fit: contain; transition: transform .8s var(--ease); }
.su-pic figcaption { position: absolute; left: 8px; bottom: 2px; font-size: .45rem; letter-spacing: .1em; text-transform: uppercase; color: var(--bg); opacity: .42; }
@media (hover: hover) { .su:hover .su-pic img { transform: scale(1.04); } }
.su-b { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; padding: 6px 8px 6px 10px; min-width: 0; }
.su-b h3 { font-weight: 500; text-transform: uppercase; line-height: 1.12; font-size: clamp(.95rem, 1.25vw, 1.1rem); overflow-wrap: anywhere; }
.su-t { font-size: .8rem; line-height: 1.45; opacity: .66; }
/* the link: it names the site it goes to; the whole card is clickable through its ::after */
.su-go {
  margin-top: 4px; display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px; border-radius: 9px;
  border: 1.5px solid currentColor; font-size: .66rem; font-weight: 500; letter-spacing: .06em; text-transform: lowercase; line-height: 1;
  transition: background-color .2s, color .2s;
}
.su-go::after { content: ""; position: absolute; inset: 0; border-radius: 22px; }
.su-go svg { transition: transform .3s var(--ease); }
.su:hover .su-go { background-color: var(--bg); color: var(--paper); }
.su:hover .su-go svg { transform: translate(2px, -2px); }
/* a card without a photo (IKEA, Windows): dark, so it reads as a note, not a missing picture */
.su--note { grid-template-columns: minmax(0, 1fr); background: var(--bg); color: var(--ink); align-items: end; }
.su--note .su-b { padding: 16px 14px 14px; }
.su--note .su-b h3 { font-size: clamp(1.3rem, 2vw, 1.8rem); }
.su--note:hover .su-go { background-color: var(--ink); color: var(--bg); }
@media (max-width: 519px) { html.anim .su-grid .su.fi { --fd: 0s; } }
@media (min-width: 520px) {
  .su-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .su { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto 1fr; align-items: stretch; padding: 8px 8px 0; border-radius: 24px; }
  .su--note { grid-template-rows: 1fr; }
  .su-pic figcaption { left: 10px; bottom: 7px; font-size: .5rem; }
  .su-b { padding: 10px 8px 16px; flex: 1; }
  .su-b .su-go { margin-top: auto; }
  .su-t { margin-bottom: 8px; }
  .su--note { padding: 8px; }
  .su--note .su-b { justify-content: flex-end; padding: 22px 14px 14px; }
}
@media (min-width: 640px) { .su-head { padding: 170px 32px 32px; } .su-sec .goal-sheet { padding-bottom: 48px; } }
@media (min-width: 900px) { .su-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 48px; } }
@media (min-width: 1180px) { .su-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; } .su { border-radius: 26px; } }
/* ---------- v11: My setup (home page). Since 2026-11-02 the desk photo with markers and a list: more.css 7. ---------- */
.kit { padding: 96px 16px 40px; display: flex; flex-direction: column; align-items: center; gap: 28px; text-align: center; }
.kit-k { text-transform: uppercase; letter-spacing: .12em; font-size: clamp(.75rem, 1.2vw, 1rem); opacity: .55; margin-bottom: -12px; }
.kit-lead { max-width: 36rem; font-weight: 300; font-size: clamp(1rem, 1.6vw, 1.2rem); line-height: 1.6; opacity: .85; }
@media (min-width: 640px) { .kit { padding: 112px 32px 48px; } }
@media (min-width: 900px) { .kit { padding: 128px 40px 56px; gap: 36px; } }

/* ---------- v13: privacy and terms. The site's own header and footer; a row of four plain facts on the
   dark page, then the full text on the white sheet with a small index beside it on wide screens. ---------- */
.lg-head { padding: 140px 16px 32px; display: flex; flex-direction: column; align-items: center; gap: 24px; text-align: center; }
.lg-facts { list-style: none; width: 100%; max-width: 64rem; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 8px; }
.lg-facts li { text-align: left; padding: 18px 18px 16px; border-radius: 22px; background: rgba(215, 226, 234, .05); border: 1px solid rgba(215, 226, 234, .12); display: flex; flex-direction: column; gap: 6px; }
.lg-facts b { font-weight: 500; text-transform: uppercase; letter-spacing: .02em; font-size: clamp(1rem, 1.8vw, 1.3rem); line-height: 1.1; color: var(--bright); }
.lg-facts span { font-weight: 300; font-size: .85rem; line-height: 1.45; opacity: .66; }
.lg-date { font-family: var(--mono); font-size: .75rem; letter-spacing: .06em; opacity: .5; }
.lg-sheet { display: grid; gap: 28px; align-items: start; text-align: left; }
.lg-toc { display: flex; flex-wrap: wrap; gap: 8px; }
.lg-toc a { padding: 9px 14px; border-radius: 10px; border: 1px solid var(--line); font-weight: 500; font-size: .75rem; text-transform: uppercase; letter-spacing: .1em; transition: background-color .2s; }
.lg-toc a:hover { background-color: rgba(12, 12, 12, .05); }
.lg-body { max-width: 44rem; min-width: 0; }
.lg-body h2 { font-family: var(--serif); font-weight: 400; font-size: clamp(2.2rem, 4vw, 3.2rem); line-height: 1; letter-spacing: -.02em; margin: 4px 0 20px; scroll-margin-top: 24px; }
.lg-body h2:not(:first-child) { margin-top: 48px; padding-top: 40px; border-top: 1px solid var(--line); }
.lg-body p { font-weight: 300; font-size: clamp(1rem, 1.3vw, 1.08rem); line-height: 1.75; color: rgba(12, 12, 12, .8); }
.lg-body p + p { margin-top: 16px; }
.lg-body a { font-weight: 500; color: var(--bg); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(12, 12, 12, .3); transition: text-decoration-color .2s; }
.lg-body a:hover { text-decoration-color: currentColor; }
.lg-terms { list-style: none; counter-reset: t; }
/* the number hangs in the left padding, not in a grid column: as a grid every text run and link of the
   item became its own cell, and a link fell into the number column one word per line (2026-11-02) */
.lg-terms li { counter-increment: t; position: relative; padding: 15px 0 15px calc(2.6em + 8px); border-top: 1px solid var(--line); font-weight: 300; font-size: clamp(1rem, 1.3vw, 1.08rem); line-height: 1.65; color: rgba(12, 12, 12, .8); }
.lg-terms li::before { content: counter(t, decimal-leading-zero); position: absolute; left: 0; top: 15px; font-family: var(--mono); font-size: .78rem; padding-top: .35em; color: rgba(12, 12, 12, .42); }
.lg-terms li:last-child { border-bottom: 1px solid var(--line); }
.lg-sec { padding-bottom: 8px; }
@media (min-width: 640px) { .lg-head { padding: 170px 32px 40px; } .lg-facts { gap: 12px; } }
@media (min-width: 900px) {
  .lg-facts { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
  .lg-sheet { grid-template-columns: 180px minmax(0, 44rem); justify-content: center; gap: 72px; padding: 88px 56px 80px; }
  .lg-toc { position: sticky; top: 32px; flex-direction: column; align-items: flex-start; }
}