/* Folio · site stylesheet
   Tokens first (light, then dark), components after. Every colour goes through a token. */

:root {
  --bg: #FBFBFA;
  --surface: #FFFFFF;
  --ink: #2F3437;
  --ink-strong: #111111; --ink-rgb: 17 17 17;
  --muted: #787774;
  --hair: #EAEAEA;
  --hair-2: #D8D7D3;
  --accent: #1F6C9F;
  --accent-soft: #A9C8DE;
  --pale-blue: #E1F3FE;  --blue-t: #1F6C9F;
  --pale-green: #EDF3EC; --green-t: #346538;
  --pale-yellow: #FBF3DB; --yellow-t: #956400;
  --pale-red: #FDEBEC;   --red-t: #9F2F2D;
  --dye-cool: #2F7FBF;   --dye-warm: #6E56E0; /* fluid hero: two cool dyes, luminous enough to read as colour over black ink */
  --sumi-1: #3D82C4;     --sumi-2: #E0745A;     --sumi-3: #6FAE9C; /* sumi hero: indigo, vermilion, celadon, lifted so they read as ink over black type */
  --aside: #F6F6F4;
  --img-bg: #F3F8FB; --img-line: #BDDCEE;
  --nav-bg: rgba(251, 251, 250, 0.86);
  --btn-bg: #111111; --btn-fg: #FFFFFF; --btn-hover: #333333;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
  --shadow-2: 0 2px 8px rgba(0, 0, 0, 0.05);
  --lift: 0 24px 48px rgba(0, 0, 0, 0.12); /* card hover */
  --amb-1: rgba(220, 205, 170, 0.14);
  --amb-2: rgba(190, 205, 215, 0.10);
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --serif: 'Schibsted Grotesk', 'Helvetica Neue', Arial, sans-serif; /* display + long-form face (token name kept; was Newsreader until 2026-08-30) */
  --sans: 'Instrument Sans', 'Helvetica Neue', Arial, sans-serif; /* UI + labels (was Geist) */
  --mono: 'Geist Mono', 'SF Mono', Menlo, monospace;
  --measure: 44rem;
  --wide: 1280px;
  --case: 50rem; /* detail pages commit to this single frame (2026-09-01): head, text, figures, back/next bar and footer row all at 800; only the nav stays at --wide */
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #1B1B1A; --surface: #232322;
    --ink: #CFCFCC; --ink-strong: #F2F2EF; --ink-rgb: 242 242 239; --muted: #93928E;
    --hair: #32322F; --hair-2: #45443F;
    --accent: #77B7E2; --accent-soft: #3E6D8C;
    --pale-blue: #1D2A33;  --blue-t: #85C4EA;
    --pale-green: #1F2A20; --green-t: #8FC79A;
    --pale-yellow: #3A3115; --yellow-t: #E3B75B;
    --pale-red: #3B2020;   --red-t: #E08D8D;
    --dye-cool: #8FC5EC;   --dye-warm: #B9A7F5;
    --sumi-1: #85C4EA;     --sumi-2: #E8938A;     --sumi-3: #9FD3C2;
    --aside: #222221;
    --img-bg: #1D2A33; --img-line: #2F4C60;
    --nav-bg: rgba(27, 27, 26, 0.86);
    --btn-bg: #F2F2EF; --btn-fg: #111111; --btn-hover: #D9D9D5;
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-2: 0 2px 8px rgba(0, 0, 0, 0.4); --lift: 0 28px 56px rgba(0, 0, 0, 0.35);
    --amb-1: rgba(120, 105, 70, 0.10);
    --amb-2: rgba(70, 95, 115, 0.10);
  }
}
:root[data-theme="dark"] {
  --bg: #1B1B1A; --surface: #232322;
  --ink: #CFCFCC; --ink-strong: #F2F2EF; --ink-rgb: 242 242 239; --muted: #93928E;
  --hair: #32322F; --hair-2: #45443F;
  --accent: #77B7E2; --accent-soft: #3E6D8C;
  --pale-blue: #1D2A33;  --blue-t: #85C4EA;
  --pale-green: #1F2A20; --green-t: #8FC79A;
  --pale-yellow: #3A3115; --yellow-t: #E3B75B;
  --pale-red: #3B2020;   --red-t: #E08D8D;
  --dye-cool: #8FC5EC;   --dye-warm: #B9A7F5;
  --sumi-1: #85C4EA;     --sumi-2: #E8938A;     --sumi-3: #9FD3C2;
  --aside: #222221;
  --img-bg: #1D2A33; --img-line: #2F4C60;
  --nav-bg: rgba(27, 27, 26, 0.86);
  --btn-bg: #F2F2EF; --btn-fg: #111111; --btn-hover: #D9D9D5;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
  --shadow-2: 0 2px 8px rgba(0, 0, 0, 0.4); --lift: 0 28px 56px rgba(0, 0, 0, 0.35);
  --amb-1: rgba(120, 105, 70, 0.10);
  --amb-2: rgba(70, 95, 115, 0.10);
}

:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font-family: var(--sans); font-size: 16px; line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
::selection { background: var(--pale-yellow); }
a { color: inherit; }
a:focus-visible, button:focus-visible, input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }
img, svg, video { max-width: 100%; }
h1, h2, h3, h4, p, ul, ol, dl, figure, blockquote { margin: 0; }
button { font: inherit; color: inherit; }
.serif { font-family: var(--serif); }
.mono { font-family: var(--mono); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.wrap { max-width: var(--measure); margin: 0 auto; padding: 0 24px; }
.wide { max-width: var(--wide); margin: 0 auto; padding: 0 24px; }
body:is([data-page^="work"], [data-page="about"]) :is(.wide, .wrap) { max-width: var(--case); } /* the one detail-page frame; About shares it since 2026-09-01 so its h1 wraps in two lines, not four */

.ambient { position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(560px 340px at 76% 4%, var(--amb-1), transparent 70%),
    radial-gradient(700px 460px at 8% 60%, var(--amb-2), transparent 70%); }
main, .topnav, .site-foot { position: relative; z-index: 1; }

.kicker, .eyebrow { font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); font-weight: 500; }
.eyebrow { font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; font-weight: 400; }

.chip { display: inline-block; border-radius: 9999px; font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase; padding: 4px 12px; font-weight: 500; line-height: 1.4; }
.chip.blue { background: var(--pale-blue); color: var(--blue-t); }
.chip.green { background: var(--pale-green); color: var(--green-t); }
.chip.yellow { background: var(--pale-yellow); color: var(--yellow-t); }
.chip.red { background: var(--pale-red); color: var(--red-t); }

.btn { display: inline-block; background: var(--btn-bg); color: var(--btn-fg); text-decoration: none; font-size: 14.5px; font-weight: 500;
  padding: 12px 22px; border-radius: 6px; border: none; cursor: pointer; transition: background 200ms ease, transform 120ms ease; }
.btn:hover { background: var(--btn-hover); }
.btn:active { transform: scale(0.98); }
.btn[disabled] { opacity: 0.6; cursor: progress; }
.btn-ghost { background: transparent; border: 1px solid var(--hair-2); color: var(--ink); border-radius: 6px; font-size: 13px; font-weight: 500; padding: 8px 14px; cursor: pointer; transition: border-color 200ms ease, color 200ms ease; }
.btn-ghost:hover { border-color: var(--ink-strong); color: var(--ink-strong); }

/* ---------- nav ---------- */
.topnav { position: sticky; top: 0; z-index: 40; background: var(--nav-bg); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border-bottom: 1px solid var(--hair); }
.topnav .in { max-width: var(--wide); margin: 0 auto; padding: 16px 24px; display: flex; justify-content: space-between; align-items: baseline; gap: 16px; }
.topnav .name { font-weight: 600; font-size: 15px; color: var(--ink-strong); text-decoration: none; }
.topnav .links { display: flex; gap: 24px; font-size: 13.5px; }
.topnav .links a { text-decoration: none; color: var(--muted); transition: color 200ms ease; }
.topnav .links a:hover, .topnav .links a[aria-current="page"] { color: var(--ink-strong); }
@media (max-width: 560px) { .topnav .links { gap: 16px; } }
.topnav .links { align-items: center; }
/* theme switch: sun | moon pill, the thumb sits on the active mode */
.topnav .theme { position: relative; display: inline-flex; align-items: center; gap: 6px; width: 52px; height: 26px; padding: 2px; margin: 0; border-radius: 9999px; border: 1px solid var(--hair-2); background: var(--surface); cursor: pointer; flex: none; transition: border-color 200ms ease; }
.topnav .theme:hover { border-color: var(--muted); }
.topnav .theme .thumb { position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%; background: var(--btn-bg); transition: transform 260ms var(--ease); }
.topnav .theme[aria-checked="true"] .thumb { transform: translateX(26px); }
.topnav .theme svg { position: relative; z-index: 1; width: 20px; height: 20px; padding: 4px; flex: none; color: var(--muted); transition: color 200ms ease; }
.topnav .theme[aria-checked="false"] .sun, .topnav .theme[aria-checked="true"] .moon { color: var(--btn-fg); }

/* ---------- home · hero ---------- */
.hero { padding: 0 0 36px; } /* halved (was 72px) 2026-08-31: tighter gap above Selected work */
#work.sect { padding-top: 48px; } /* halved from .sect's 96px, same request; About's sections keep 96 */
.stage { position: relative; min-height: clamp(480px, 72vh, 780px); display: grid; place-items: center; overflow: hidden; padding: 96px 24px 128px; } /* bottom hairline removed 2026-08-31 (Miki): no divider under the hero; taller + more padding 2026-08-31 (Miki): more air above and below the hero typography */
.stage-foot { position: absolute; left: 0; right: 0; bottom: 20px; display: flex; align-items: center; justify-content: center; gap: 14px; flex-wrap: wrap; padding: 0 24px; }
.stage-hint { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.intro { padding-top: 64px; }
.intro h1 { font-family: var(--serif); font-weight: 700; font-size: clamp(2.2rem, 5vw, 3.6rem); line-height: 1.12; letter-spacing: -0.025em; color: var(--ink-strong); margin-top: 22px; text-wrap: balance; }
.intro h1 em { font-style: italic; }
.intro .lede { margin-top: 26px; font-size: 17.5px; line-height: 1.65; max-width: 58ch; }
.facts { margin-top: 40px; display: flex; gap: 36px; flex-wrap: wrap; font-size: 13px; color: var(--muted); }
.facts b { display: block; color: var(--ink-strong); font-weight: 500; margin-top: 2px; }

/* hero · lab switcher (only with ?lab or data-lab) */
.hero-lab { position: fixed; right: 14px; bottom: 14px; z-index: 70; display: flex; gap: 6px; max-width: calc(100vw - 28px); overflow-x: auto; background: var(--surface); border: 1px solid var(--hair); border-radius: 9999px; padding: 5px; box-shadow: var(--shadow-2); }
.hero-lab button { border: none; background: transparent; border-radius: 9999px; padding: 6px 12px; font-size: 12px; color: var(--muted); cursor: pointer; white-space: nowrap; }
.hero-lab button b { font-family: var(--mono); font-weight: 500; font-size: 10px; margin-right: 5px; color: var(--accent); }
.hero-lab button.on { background: var(--btn-bg); color: var(--btn-fg); }
.hero-lab button.on b { color: var(--accent-soft); }

/* hero · 01 quote */
.qbox { text-align: center; max-width: 900px; }
.qtext { font-family: var(--serif); font-weight: 400; color: var(--ink-strong); font-size: clamp(2rem, 5.6vw, 4.2rem); line-height: 1.16; letter-spacing: -0.02em; text-wrap: balance; }
.qattr { margin-top: 26px; font-family: var(--mono); font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); opacity: 0; }
.qattr.show { animation: qattr 600ms var(--ease) 700ms forwards; }
@keyframes qattr { to { opacity: 1; } }
.qtext.cascade .w { display: inline-block; opacity: 0; transform: translateY(28px); filter: blur(7px); animation: qcas 750ms var(--ease) forwards; }
@keyframes qcas { to { opacity: 1; transform: none; filter: none; } }
.qtext .em { font-style: italic; background: linear-gradient(transparent 62%, var(--pale-yellow) 62%); padding: 0 0.06em; }
.qtext.rise .rl { display: inline-block; overflow: hidden; vertical-align: bottom; }
.qtext.rise .rli { display: inline-block; transform: translateY(112%); animation: qrise 850ms var(--ease) forwards; }
@keyframes qrise { to { transform: none; } }
.qtext.wave .wl { display: inline-block; white-space: pre; opacity: 0; animation: qfade 500ms ease forwards; }
@keyframes qfade { to { opacity: 1; } }

/* hero · 02 measured type */
.mwrap { width: min(1000px, 94%); }
.msvg { width: 100%; height: auto; display: block; overflow: visible; }
.msvg .mword { font-family: var(--serif); font-weight: 700; fill: var(--ink-strong); }
.msvg tspan { transition: fill 200ms ease; }
.msvg tspan.hi { fill: var(--accent); }
.msvg line { vector-effect: non-scaling-stroke; }
.msvg .cl { stroke: var(--hair-2); stroke-width: 1; stroke-dasharray: 14 5 2 5; }
.msvg .hl { stroke: var(--hair-2); stroke-width: 1; }
.msvg .dim { stroke: var(--accent); stroke-width: 1; }
.msvg .arw { fill: var(--accent); }
.msvg .dimtxt { font-family: var(--mono); font-size: 13px; fill: var(--accent); }
.msvg .linlbl { font-family: var(--mono); font-size: 11px; fill: var(--muted); letter-spacing: 0.1em; }
.msvg .hit { fill: transparent; cursor: crosshair; }
.msvg .pillr { fill: var(--surface); stroke: var(--hair); }
.msvg .pillt { font-family: var(--mono); font-size: 12.5px; fill: var(--ink-strong); }
.msvg .flagc { fill: var(--pale-red); stroke: var(--red-t); stroke-width: 1.4; }
.msvg .flagn { font-family: var(--mono); font-size: 12px; font-weight: 700; fill: var(--red-t); }
.msvg .flagl { stroke: var(--red-t); stroke-width: 1; }

/* hero · 03 magnetic serif (field · filings · ink share one engine; the stage becomes the page h1) */
.stage.magnet { cursor: crosshair; touch-action: pan-y; }
.mag { position: relative; z-index: 1; width: min(1140px, 100%); text-align: center; }
.mag-kick { font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); font-weight: 500; margin: 0 0 28px; opacity: 0; transition: opacity 700ms var(--ease) 300ms; }
.mag.in .mag-kick { opacity: 1; }
.gline { font-family: var(--serif); color: var(--ink-strong); font-size: clamp(2.5rem, 6.6vw, 6rem); line-height: 1.06; letter-spacing: -0.02em; text-wrap: balance; font-variation-settings: 'wght' 430; opacity: 0; transition: opacity 600ms var(--ease); }
.mag.in .gline { opacity: 1; }
.gline .gw { display: inline-block; white-space: nowrap; }
.gline .gl { display: inline-block; text-align: center; }
.gline .gl.it { font-style: italic; }
.stage.mag-field .gline .gl { will-change: transform; }
.mag-canvas { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.stage.magnet .stage-foot { z-index: 1; }
.stage.mag-ink .gline .gl { -webkit-text-stroke: 1px rgb(var(--ink-rgb) / calc(1 - var(--a, 0) * 0.85)); -webkit-text-fill-color: rgb(var(--ink-rgb) / var(--a, 0)); }
.stage.mag-fluid .gline, .stage.mag-sumi .gline { color: transparent; -webkit-text-fill-color: transparent; } /* the canvas draws this headline; the DOM copy keeps layout and a11y */
.hero--stage-h1 .intro { padding-top: 52px; }
.hero--stage-h1 .intro .lede { margin-top: 0; }

/* hero · 03f bezier warp (the canvas draws the headline; cursor bends the sheet) */
.stage.bez { cursor: crosshair; touch-action: pan-y; }
/* hero · 03g liquid distort (WebGL: the cursor's fluid field displaces the type per pixel) */
.stage.liq { cursor: crosshair; touch-action: pan-y; }
.stage.liq .stage-foot { flex-direction: column; gap: 12px; z-index: 3; }
/* hero cursor: the droplet (2026-09-01; four options were built, Miki picked the droplet and dropped the rest —
   roster in git + README "Hero cursor options"). Coarse pointers and reduced motion keep the native crosshair
   (data-cursor stays "cross" there, so cursor: none can never hide the pointer without a stand-in). */
.stage.liq[data-cursor]:not([data-cursor="cross"]) { cursor: none; }
.stage.liq .stage-foot { cursor: default; }
.liq-cursor { position: absolute; left: 0; top: 0; z-index: 2; pointer-events: none; opacity: 0; transition: opacity 160ms ease; color: var(--ink-strong); }
.liq-cursor i, .liq-cursor .w { position: absolute; display: block; }
.liq-cursor .rip { left: 0; top: 0; width: 44px; height: 44px; margin: -22px 0 0 -22px; border: 1px solid currentColor; border-radius: 50%; opacity: 0; }
.liq-cursor .rip.go { animation: liq-rip 520ms var(--ease) forwards; }
@keyframes liq-rip { from { transform: scale(0.25); opacity: 0.6; } to { transform: scale(2.1); opacity: 0; } }
/* the droplet: a soft drop that squashes with speed and sheds trailing beads */
.cur-drop .blob { width: 18px; height: 18px; margin: -9px 0 0 -9px; border-radius: 50%; border: 1px solid currentColor; border-color: color-mix(in srgb, currentColor 42%, transparent); background: color-mix(in srgb, currentColor 12%, transparent); } /* outline at 42% (2026-09-01, Miki: "outline can be less opacity"); the border shorthand line stays as the no-color-mix fallback */
.cur-drop .t1 { width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px; border-radius: 50%; background: currentColor; opacity: 0; }
.cur-drop .t2 { width: 4px; height: 4px; margin: -2px 0 0 -2px; border-radius: 50%; background: currentColor; opacity: 0; }
.liq-controls { display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap; }
.fx-btn { display: inline-flex; align-items: center; gap: 9px; border: 1px solid var(--hair-2); background: var(--surface); border-radius: 9999px; padding: 9px 16px; cursor: pointer; box-shadow: var(--shadow-2); transition: border-color 200ms ease; }
.fx-btn:hover { border-color: var(--muted); }
.fx-btn:active { transform: scale(0.98); }
.fx-btn span { font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.fx-btn b { font-size: 13px; font-weight: 600; color: var(--ink-strong); min-width: 46px; text-align: left; line-height: 1.2; }
.stage.liq .tpanel { padding: 9px 16px; gap: 10px; cursor: default; }
.stage.liq .tpanel .lbl { font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; }
.stage.liq .tpanel input[type=range] { width: min(150px, 26vw); height: 4px; border-radius: 2px; background: var(--hair); }
.stage.liq .tpanel input[type=range]::-webkit-slider-thumb { width: 16px; height: 16px; transition: transform 150ms ease; }
.stage.liq .tpanel input[type=range]::-webkit-slider-thumb:hover { transform: scale(1.15); }
.stage.liq .tpanel .val { min-width: 34px; font-size: 12.5px; }

/* hero · 04 tolerance */
.tword { font-family: var(--serif); font-weight: 600; color: var(--ink-strong); font-size: clamp(3rem, 11vw, 8.4rem); letter-spacing: 0.02em; line-height: 1; text-align: center; }
.tword .tl { display: inline-block; will-change: transform; }
.tpanel { display: flex; align-items: center; gap: 16px; background: var(--surface); border: 1px solid var(--hair); border-radius: 9999px; padding: 10px 20px; box-shadow: var(--shadow-2); }
.tpanel .lbl { font-family: var(--mono); font-size: 12px; color: var(--muted); white-space: nowrap; }
.tpanel .val { font-family: var(--mono); font-size: 13px; color: var(--ink-strong); min-width: 76px; }
.tpanel input[type=range] { -webkit-appearance: none; appearance: none; width: min(240px, 40vw); height: 3px; border-radius: 2px; background: linear-gradient(90deg, var(--green-t), var(--yellow-t), var(--red-t)); }
.tpanel input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 18px; height: 18px; border-radius: 50%; background: var(--ink-strong); border: 3px solid var(--surface); box-shadow: 0 1px 4px rgba(0,0,0,0.25); cursor: ew-resize; }
.tpanel input[type=range]::-moz-range-thumb { width: 14px; height: 14px; border-radius: 50%; background: var(--ink-strong); border: 3px solid var(--surface); box-shadow: 0 1px 4px rgba(0,0,0,0.25); cursor: ew-resize; }
.tpass { position: absolute; top: 18%; left: 50%; transform: translate(-50%, 0) rotate(-6deg) scale(0.6); opacity: 0; border: 2px solid var(--green-t); color: var(--green-t); background: var(--pale-green); border-radius: 8px; padding: 8px 18px; font-family: var(--mono); font-size: 14px; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase; transition: opacity 400ms var(--ease), transform 500ms var(--ease); pointer-events: none; }
.tpass.on { opacity: 1; transform: translate(-50%, 0) rotate(-6deg) scale(1); }

/* ---------- sections ---------- */
.sect { padding-top: 96px; }
.shead { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; flex-wrap: wrap; border-bottom: 1px solid var(--hair); padding-bottom: 14px; }
.shead h2 { font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); font-weight: 500; }
.shead span, .shead a { font-size: 13px; color: var(--muted); display: inline-flex; align-items: center; gap: 6px; }
.shead a { text-decoration: none; }
.shead a:hover { color: var(--ink-strong); }
.shead svg { width: 12px; height: 12px; }

/* ---------- home · work grid ---------- */
.grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 20px; margin-top: 40px; }
.card { --pop: cubic-bezier(.34, 1.56, .64, 1); grid-column: span 2; display: flex; flex-direction: column; text-decoration: none; color: inherit; background: var(--surface); border: 1px solid var(--hair); border-radius: 14px; overflow: hidden; box-shadow: var(--shadow); transition: box-shadow 550ms var(--ease), transform 550ms var(--pop), border-color 400ms ease; }
.card:hover { box-shadow: var(--shadow-2), var(--lift); transform: translateY(-6px); border-color: var(--hair-2); } /* Roll card (directions/work-index.html, 09), chosen 2026-08-30 */
.card.half { grid-column: span 3; }
.card.wide { grid-column: span 6; flex-direction: row; }
.card.wide .cover { flex: 0 0 58%; aspect-ratio: auto; min-height: 340px; border-right: 1px solid var(--hair); }
.card.wide .card-text { flex: 1; align-self: center; padding: 40px 36px; }
.cover { position: relative; aspect-ratio: 16 / 9; overflow: hidden; display: grid; place-items: center; padding: 24px; border-bottom: 1px solid var(--hair);
  background: var(--aside);
  background-image: linear-gradient(var(--hair) 1px, transparent 1px), linear-gradient(90deg, var(--hair) 1px, transparent 1px); background-size: 28px 28px; background-position: center; }
.card.third .cover { aspect-ratio: 16 / 9; padding: 20px; }
.cover.tint-blue { background-color: var(--pale-blue); }
.cover.tint-green { background-color: var(--pale-green); }
.cover.tint-yellow { background-color: var(--pale-yellow); }
.cover.tint-red { background-color: var(--pale-red); }
.card .cover.img, .card.third .cover.img, .card.wide .cover.img { padding: 0; display: block; background: var(--surface); } /* real thumbnail covers (live-site images); beats the per-size padding rules */
.card .cover.img img { display: block; width: 100%; height: 100%; object-fit: cover; }
.card .cover > * { transition: transform 800ms var(--ease); }
.card:hover .cover > * { transform: scale(1.05) translateY(-6px); } /* the mock or image lifts inside the clipped cover */
.card-text { padding: 22px 24px 22px; display: flex; flex-direction: column; gap: 6px; }
.card-text h3 { font-family: var(--serif); font-weight: 700; font-size: clamp(1.35rem, 2.1vw, 1.6rem); letter-spacing: -0.02em; line-height: 1.1; color: var(--ink-strong); text-wrap: pretty; }
.ttl .org { color: var(--ink-strong); }
.ttl .sep { color: var(--hair-2); font-weight: 400; margin: 0 .32em; position: relative; top: -0.04em; }
.ttl .proj { color: var(--ink-strong); opacity: .6; font-weight: 600; } /* Employer | Project: employer 700, project 600 at 60% */
.card.wide .card-text h3 { font-size: clamp(1.8rem, 3vw, 2.4rem); }
.card-text .standfirst { font-family: var(--serif); font-style: normal; color: var(--muted); font-size: .98rem; line-height: 1.5; text-wrap: pretty; }
.card.third .card-text .standfirst { font-size: 0.95rem; }
.card .roll { height: 1.5em; overflow: hidden; font-size: 12.5px; margin-top: 8px; } /* year at rest; rolls up to the CTA on hover */
.card .roll > span { display: block; line-height: 1.5em; color: var(--muted); transition: transform 500ms var(--ease); }
.card .roll > span + span { color: var(--ink-strong); font-weight: 500; }
.card .roll > span + span i { display: inline-block; font-style: normal; transform: translateX(-6px); opacity: 0; transition: transform 400ms var(--pop) 250ms, opacity 300ms 250ms; }
.card:hover .roll > span { transform: translateY(-100%); }
.card:hover .roll > span + span i { transform: none; opacity: 1; }
@media (prefers-reduced-motion: reduce) { .card, .card .cover > *, .card-text h3, .card .roll > span, .card .roll > span + span i { transition: none; } }
@media (max-width: 900px) {
  .card, .card.half, .card.third { grid-column: span 6; }
  .card.wide { flex-direction: column; }
  .card.wide .cover { flex: none; aspect-ratio: 16 / 10; min-height: 0; border-right: none; border-bottom: 1px solid var(--hair); }
  .card.wide .card-text { padding: 26px; }
  .card.wide .card-text h3 { font-size: clamp(1.6rem, 5vw, 2rem); }
}
@media (min-width: 901px) and (max-width: 1280px) { .card.third { grid-column: span 3; } .card.third:last-child { grid-column: 2 / span 3; } }

/* mini product mocks inside covers (shared chrome) */
.mock { width: 100%; max-width: 560px; background: var(--surface); border: 1px solid var(--hair); border-radius: 10px; overflow: hidden; box-shadow: var(--shadow-2); font-size: 11.5px; line-height: 1.4; color: var(--ink); }
.mock .chrome { display: flex; align-items: center; gap: 7px; padding: 8px 12px; border-bottom: 1px solid var(--hair); background: var(--aside); }
.mock .chrome i { width: 8px; height: 8px; border-radius: 50%; background: var(--hair-2); }
.mock .chrome span { margin-left: 6px; font-size: 10.5px; color: var(--muted); font-family: var(--mono); }
.mock .chrome .url { margin-left: 8px; flex: 1; background: var(--surface); border: 1px solid var(--hair); border-radius: 5px; padding: 2px 8px; font-family: var(--mono); font-size: 10px; color: var(--muted); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.mock h5 { margin: 0 0 8px; font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); font-weight: 500; }
.mock .app { display: grid; grid-template-columns: 150px 1fr 130px; min-height: 230px; }
.mock .col { border-right: 1px solid var(--hair); padding: 12px; }
.mock .col:last-child { border-right: none; }
.mock .cl-row { display: flex; align-items: center; gap: 7px; padding: 5px 7px; border-radius: 5px; }
.mock .cl-row.on { background: var(--pale-blue); color: var(--blue-t); font-weight: 500; }
.mock .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--hair-2); flex: none; }
.mock .dot.ok { background: var(--green-t); }
.mock .dot.warn { background: var(--yellow-t); }
.mock .canvas { position: relative; background-image: linear-gradient(var(--hair) 1px, transparent 1px), linear-gradient(90deg, var(--hair) 1px, transparent 1px); background-size: 22px 22px; background-position: center; }
.mock .canvas svg { position: absolute; inset: 0; margin: auto; width: 80%; height: 80%; }
.mock .canvas .drw { stroke: var(--ink); fill: none; stroke-width: 1.3; }
.mock .canvas .drw.acc { stroke: var(--accent); stroke-width: 1.8; }
.mock .canvas .tag { position: absolute; top: 12%; right: 8%; background: var(--surface); border: 1px solid var(--accent); color: var(--accent); border-radius: 5px; padding: 3px 7px; font-family: var(--mono); font-size: 9.5px; }
.mock .check { display: flex; align-items: flex-start; gap: 7px; padding: 5px 0; border-bottom: 1px solid var(--hair); }
.mock .check:last-child { border-bottom: none; }
.mock .check .box { width: 11px; height: 11px; border: 1.5px solid var(--hair-2); border-radius: 3px; flex: none; margin-top: 2px; position: relative; }
.mock .check.done .box { background: var(--ink-strong); border-color: var(--ink-strong); }
.mock .check.done .box::after { content: ""; position: absolute; inset: 2px 2px 3px; border-left: 2px solid var(--surface); border-bottom: 2px solid var(--surface); transform: rotate(-45deg); }
.mock .check.done { color: var(--muted); text-decoration: line-through; }
@media (max-width: 560px) { .mock .app { grid-template-columns: 1fr 1fr; } .mock .app .col:last-child { display: none; } }

/* prototype mock: code + rendered */
.mock.proto .split { display: grid; grid-template-columns: 1fr 1fr; min-height: 170px; }
/* Process card cover: the loading-experiment screenshot (1600x1000) as a floating browser window; the window hugs the image's own ratio so the full page shows, no crop (Miki, 2026-08-30) */
.cover .mock.pg { width: auto; height: 100%; aspect-ratio: 1.42; max-width: 100%; display: flex; flex-direction: column; } /* fallback: aspect-ratio needs width: auto to beat .mock's width: 100% */
.mock.pg .chrome { height: 28px; box-sizing: border-box; }
.mock.pg .chrome .url { text-align: center; }
.mock.pg .pgs { flex: 1; min-height: 0; background: var(--surface); }
.mock.pg .pgs img { display: block; width: 100%; height: 100%; object-fit: contain; }
@supports (width: 1cqh) { /* exact fit: window = chrome + the 16:10 shot, so the image meets the window edges, no side margins, no crop */
  .cover.pgc { container-type: size; }
  .cover.pgc .mock.pg { width: calc((100cqh - 28px) * 1.6); height: auto; aspect-ratio: auto; }
  .cover.pgc .mock.pg .pgs { flex: none; }
  .cover.pgc .mock.pg .pgs img { height: auto; object-fit: fill; }
}
.mock.proto .code { padding: 12px; border-right: 1px solid var(--hair); font-family: var(--mono); font-size: 9.5px; color: var(--muted); line-height: 1.7; }
.mock.proto .code b { color: var(--accent); font-weight: 500; }
.mock.proto .code em { color: var(--green-t); font-style: normal; }
.mock.proto .render { padding: 14px; display: flex; flex-direction: column; gap: 10px; justify-content: center; align-items: flex-start; background: var(--aside); }
.mock.proto .render .lbl { font-size: 9.5px; color: var(--muted); font-family: var(--mono); }
.mock.proto .pbtn { background: var(--btn-bg); color: var(--btn-fg); border-radius: 5px; padding: 6px 12px; font-size: 11px; font-weight: 500; }
.mock.proto .pbtn.sec { background: transparent; color: var(--ink); border: 1px solid var(--hair-2); }
.mock.proto .pr { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--hair); background: var(--surface); border-radius: 9999px; padding: 3px 9px; font-size: 9.5px; color: var(--muted); }
.mock.proto .pr i { width: 7px; height: 7px; border-radius: 50%; background: var(--green-t); }
/* the process mock in a third-width card (grid re-flows to wide + 3 thirds when work is hidden): tighter so it fits a 16:9 cover uncropped */
.card.third .mock.proto .split { min-height: 0; }
.card.third .mock.proto .code { font-size: 8.5px; line-height: 1.6; padding: 10px; }
.card.third .mock.proto .render { padding: 10px 12px; gap: 7px; }

/* cashback mock: phone with status */
.phone { width: 200px; background: var(--surface); border: 1px solid var(--hair); border-radius: 22px; padding: 14px 14px 18px; box-shadow: var(--shadow-2); font-size: 11px; color: var(--ink); }
.phone .bal { font-size: 9.5px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; }
.phone .amt { font-family: var(--serif); font-size: 26px; color: var(--ink-strong); letter-spacing: -0.02em; margin: 2px 0 14px; font-variant-numeric: tabular-nums; }
.phone .steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; position: relative; }
.phone .steps::before { content: ""; position: absolute; top: 6px; left: 12%; right: 12%; height: 1.5px; background: var(--hair-2); }
.phone .step { position: relative; text-align: center; font-size: 8.5px; color: var(--muted); line-height: 1.3; }
.phone .step i { display: block; width: 13px; height: 13px; border-radius: 50%; background: var(--surface); border: 1.5px solid var(--hair-2); margin: 0 auto 6px; position: relative; }
.phone .step.done i { background: var(--green-t); border-color: var(--green-t); }
.phone .step.now i { border-color: var(--accent); background: var(--pale-blue); }
.phone .step.now { color: var(--accent); font-weight: 500; }
.phone .row { display: flex; justify-content: space-between; gap: 8px; padding: 8px 0; border-top: 1px solid var(--hair); margin-top: 12px; }
.phone .row b { font-weight: 500; color: var(--ink-strong); }
.phone .row .st { font-size: 9.5px; padding: 1px 7px; border-radius: 9999px; background: var(--pale-yellow); color: var(--yellow-t); white-space: nowrap; }
.phone .row .st.paid { background: var(--pale-green); color: var(--green-t); }

/* one klarna mock: checkout */
.checkout { width: 100%; max-width: 300px; background: var(--surface); border: 1px solid var(--hair); border-radius: 10px; padding: 16px; box-shadow: var(--shadow-2); font-size: 11px; }
.checkout .line { display: flex; justify-content: space-between; color: var(--muted); padding: 4px 0; }
.checkout .line b { color: var(--ink-strong); font-weight: 500; }
.checkout .old { display: grid; gap: 5px; margin: 10px 0; opacity: 0.45; }
.checkout .old span { border: 1px dashed var(--hair-2); border-radius: 5px; padding: 5px 8px; text-decoration: line-through; font-size: 10px; }
.checkout .one { background: var(--btn-bg); color: var(--btn-fg); border-radius: 6px; padding: 9px 12px; text-align: center; font-weight: 500; margin-top: 8px; }
.checkout .note { text-align: center; font-size: 9.5px; color: var(--muted); margin-top: 8px; font-family: var(--mono); }

/* pollen8 mock: funnel */
.funnel { width: 100%; max-width: 300px; display: grid; gap: 6px; font-size: 10.5px; }
.funnel .stg { display: grid; grid-template-columns: 74px 1fr 34px; align-items: center; gap: 8px; color: var(--muted); }
.funnel .stg b { font-weight: 500; color: var(--ink); }
.funnel .bar { height: 14px; border-radius: 4px; background: var(--pale-green); position: relative; overflow: hidden; }
.funnel .bar i { position: absolute; inset: 0; right: auto; background: var(--green-t); opacity: 0.55; border-radius: 4px; }
.funnel .stg .n { font-family: var(--mono); font-size: 10px; text-align: right; font-variant-numeric: tabular-nums; }

/* campus mock: app frame with channels */
.campus { display: flex; gap: 14px; align-items: center; }
.campus .phone { width: 150px; padding: 12px; border-radius: 18px; }
.campus .ch { display: flex; align-items: center; gap: 7px; padding: 6px 7px; border-radius: 6px; font-size: 10px; }
.campus .ch i { width: 16px; height: 16px; border-radius: 5px; background: var(--pale-red); flex: none; }
.campus .ch.on { background: var(--aside); font-weight: 500; }
.campus .ch small { margin-left: auto; color: var(--muted); font-family: var(--mono); font-size: 9px; }
.campus .desk { width: 170px; background: var(--surface); border: 1px solid var(--hair); border-radius: 8px; box-shadow: var(--shadow-2); overflow: hidden; }
.campus .desk .bar { height: 14px; background: var(--aside); border-bottom: 1px solid var(--hair); }
.campus .desk .body { display: grid; grid-template-columns: 46px 1fr; min-height: 96px; }
.campus .desk .side { border-right: 1px solid var(--hair); padding: 8px 6px; display: grid; gap: 5px; align-content: start; }
.campus .desk .side i { height: 5px; border-radius: 3px; background: var(--hair-2); }
.campus .desk .side i:first-child { background: var(--red-t); opacity: 0.6; }
.campus .desk .main { padding: 8px; display: grid; gap: 6px; align-content: start; }
.campus .desk .main i { height: 5px; border-radius: 3px; background: var(--hair); }
.campus .desk .main i.w { width: 60%; }
@media (max-width: 400px) { .campus .desk { display: none; } }

/* ---------- pull quote ---------- */
.pull-sect { padding-top: 110px; text-align: center; }
.pull-sect blockquote { font-family: var(--serif); font-style: italic; font-weight: 400; font-size: clamp(1.5rem, 3.2vw, 2.3rem); line-height: 1.3; letter-spacing: -0.015em; color: var(--ink-strong); max-width: 28ch; margin: 0 auto; text-wrap: balance; }
.pull-sect .who { margin-top: 20px; font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }

/* ---------- notes bento ---------- */
.bento { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 40px; }
.bcard { background: var(--surface); border: 1px solid var(--hair); border-radius: 12px; padding: 32px 28px; transition: box-shadow 200ms ease; text-decoration: none; display: block; color: inherit; }
.bcard:hover { box-shadow: var(--shadow-2); }
.bcard .glyph { width: 34px; height: 34px; border-radius: 8px; display: grid; place-items: center; margin-bottom: 18px; }
.bcard .glyph svg { width: 17px; height: 17px; }
.bcard h3 { font-size: 16px; font-weight: 600; color: var(--ink-strong); }
.bcard p { margin-top: 8px; font-size: 14px; color: var(--muted); line-height: 1.6; }
.bcard .more { display: inline-block; margin-top: 14px; font-size: 13px; font-weight: 500; color: var(--ink-strong); }
@media (max-width: 820px) { .bento { grid-template-columns: 1fr; } }

/* ---------- about ---------- */
.about-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 56px; padding-top: 40px; }
.about-grid p { max-width: 58ch; }
.about-grid p + p { margin-top: 16px; }
.about-side { display: grid; gap: 26px; align-content: start; }
.about-side .portrait { display: block; width: 100%; max-width: 420px; height: auto; border-radius: 14px; border: 1px solid var(--hair); box-shadow: var(--shadow); }
.facts-dl { font-size: 14px; }
.facts-dl div { display: grid; grid-template-columns: 110px 1fr; padding: 12px 0; border-bottom: 1px solid var(--hair); }
.facts-dl dt { color: var(--muted); }
.facts-dl dd { color: var(--ink-strong); font-weight: 500; }
.facts-dl dd a { text-decoration: none; }
.facts-dl dd a:hover { color: var(--accent); }
@media (max-width: 760px) { .about-grid { grid-template-columns: 1fr; gap: 32px; } }
.page-head { padding-top: 88px; }
.page-head h1 { font-family: var(--serif); font-weight: 700; font-size: clamp(2rem, 4.5vw, 3rem); line-height: 1.12; letter-spacing: -0.025em; color: var(--ink-strong); margin-top: 20px; text-wrap: balance; } /* 48px cap (2026-09-01, Miki), scales down on small screens */
.page-head .lede { margin-top: 24px; font-size: 17.5px; line-height: 1.65; max-width: 58ch; }
.timeline { margin-top: 36px; } /* top hairline removed 2026-08-30: it doubled the .shead underline right above it */
.timeline .row { display: grid; grid-template-columns: 150px 1fr 1fr; gap: 20px; padding: 18px 0; border-bottom: 1px solid var(--hair); font-size: 14.5px; align-items: baseline; }
.timeline .when { font-family: var(--mono); font-size: 12px; color: var(--muted); letter-spacing: 0.04em; font-variant-numeric: tabular-nums; }
.timeline .where { color: var(--ink-strong); font-weight: 500; }
.timeline .where small { display: block; color: var(--muted); font-weight: 400; font-size: 13px; margin-top: 2px; }
.timeline .what { color: var(--ink); }
.timeline .what a { text-decoration: none; border-bottom: 1px solid var(--hair-2); }
.timeline .what a:hover { border-color: var(--ink-strong); }
.timeline .what b { display: block; color: var(--ink-strong); font-weight: 500; } /* role on its own level, mirroring the company cell */
.timeline .what small { display: block; color: var(--muted); font-size: 13px; font-weight: 400; margin-top: 2px; line-height: 1.55; }
@media (max-width: 640px) { .timeline .row { grid-template-columns: 1fr; gap: 6px; } }

/* ---------- case study pages ---------- */
/* type retune 2026-08-30 for Schibsted + Instrument Sans, layout unchanged: title tighter and lower-leaded, standfirst in ink (not muted) so it reads as a second voice rather than a paler title, body 17px/1.6 on 62ch, h3 600 sits above the pull at 500, stat numbers move to the display face with proportional figures */
/* spacing retune 2026-09-01: everything on an 8px scale with proximity doing the grouping — 16 paragraph · 40/12 sub-head · 64/16 section head · 40 figures and pulls · 56 breakouts · 96 case-next; tapers under 640px */
.case-head { padding-top: 80px; }
.case-head .crumb { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; font-size: 13px; color: var(--muted); margin-bottom: 48px; }
.case-head .crumb:hover { color: var(--ink-strong); }
.case-head h1 { font-family: var(--serif); font-weight: 700; font-size: clamp(2rem, 4.5vw, 3rem); letter-spacing: -0.03em; line-height: 1.04; color: var(--ink-strong); margin-top: 12px; text-wrap: balance; } /* 48px cap (2026-09-01, Miki) */
.case-head .standfirst { font-family: var(--serif); font-style: normal; color: var(--ink); font-size: clamp(1.15rem, 1.8vw, 1.3rem); line-height: 1.45; margin-top: 24px; text-wrap: pretty; }
.rolebar { display: flex; gap: 8px 32px; flex-wrap: wrap; margin-top: 40px; padding: 14px 0; border-top: 1px solid var(--hair); border-bottom: 1px solid var(--hair); }
.rolebar span { font-size: 12.5px; color: var(--muted); }
.rolebar b { color: var(--ink-strong); font-weight: 500; }

.prose { padding-top: 0; }
.prose h2 { font-family: var(--sans); font-weight: 600; font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); margin: 64px 0 16px; }
.prose h2:first-child { margin-top: 40px; }
.prose p, .prose ul, .prose ol { font-family: var(--serif); font-size: 1.0625rem; line-height: 1.6; margin: 0 0 16px; text-wrap: pretty; } /* fills the --case frame (2026-09-01, Miki: one width for the whole detail page) */
.prose ul, .prose ol { padding-left: 22px; }
.prose li { margin-bottom: 6px; }
.prose strong { color: var(--ink-strong); font-weight: 600; }
.prose p > strong:only-child { font-weight: 500; } /* a paragraph that is entirely bold (Drawing Review's overview lede) reads as a lede at 500; 600 across a whole paragraph is too heavy */
.prose a { color: var(--ink-strong); text-decoration: none; border-bottom: 1px solid var(--hair-2); transition: border-color 200ms ease; }
.prose a:hover { border-color: var(--ink-strong); }
.prose .pull { border-left: 2px solid var(--ink-strong); padding: 3px 0 3px 20px; margin: 40px 0; font-size: 1.45rem; line-height: 1.35; letter-spacing: -0.015em; color: var(--ink-strong); font-style: normal; font-weight: 500; text-wrap: balance; }
.prose .stats { display: flex; flex-wrap: wrap; gap: 10px; margin: 24px 0 32px; }
.stat { flex: 1 1 150px; min-width: 140px; background: var(--surface); border: 1px solid var(--hair); border-radius: 8px; padding: 14px 16px 13px; }
.stat .n { font-family: var(--serif); font-weight: 600; font-size: 1.75rem; letter-spacing: -0.025em; line-height: 1.1; color: var(--ink-strong); font-variant-numeric: proportional-nums; } /* proportional: Schibsted's tabular period is a full digit wide and "3.1M" read as monospaced */
.stat .l { font-family: var(--sans); font-size: 12px; color: var(--muted); margin-top: 4px; line-height: 1.4; }
.stat.fill { background: var(--pale-yellow); border: 1px dashed var(--yellow-t); }
.stat.fill .n { color: var(--yellow-t); font-size: 1.05rem; padding-top: 4px; }
.stat.fill .l { color: var(--yellow-t); opacity: 0.85; }

/* image slots: designed as frames so the page reads as image-led even before images land */
figure.slot { margin: 40px 0; }
figure.slot.breakout { margin-top: 56px; margin-bottom: 56px; } /* one-frame system: a breakout is now frame-width like everything else; the extra air marks the moment */
figure.slot .frame { position: relative; aspect-ratio: 16 / 9; background: var(--img-bg); border: 1px dashed var(--img-line); border-radius: 24px; display: grid; place-items: center; overflow: hidden; }
figure.slot .frame > span { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--blue-t); opacity: 0.85; }
figure.slot .frame img, figure.slot .frame video { width: 100%; height: 100%; object-fit: cover; display: block; }
figure.slot figcaption { font-family: var(--sans); font-size: 13px; color: var(--muted); line-height: 1.5; margin-top: 12px; text-wrap: pretty; }
figure.slot figcaption b { color: var(--blue-t); font-weight: 500; font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; margin-right: 8px; }

mark { border-radius: 4px; padding: 1px 6px; font-family: var(--sans); font-size: 0.82em; font-weight: 500; }
mark.ph { background: var(--pale-yellow); color: var(--yellow-t); }
mark.vf { background: var(--pale-red); color: var(--red-t); }
mark b { font-family: var(--mono); font-size: 0.85em; letter-spacing: 0.06em; font-weight: 500; }

.case-next { position: relative; margin-top: 96px; padding-top: 32px; display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap; align-items: baseline; } /* Back and Next share one anatomy (label + title), so their titles sit on one baseline */
.case-next::before { content: ""; position: absolute; top: 0; left: 24px; right: 24px; height: 1px; background: var(--hair); } /* hairline inset to the content edges, so it lines up with the text and the footer base rule (a border would span the .wide padding box and overhang 24px each side) */
.case-next a { text-decoration: none; }
.case-next .prv { text-align: left; }
.case-next .nxt { text-align: right; }
.case-next .prv small, .case-next .nxt small { display: block; font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.case-next .prv b, .case-next .nxt b { font-family: var(--serif); font-weight: 700; font-size: 1.5rem; letter-spacing: -0.02em; color: var(--muted); } /* 2026-09-01 (Miki): grey at rest, full ink on hover; the accent hover read oddly in dark mode. Back mirrors Next since the same day (previous case, not All work) */
.case-next .prv:hover b, .case-next .nxt:hover b { color: var(--ink-strong); }

/* the rhythm tapers on small screens: the same hierarchy, about three quarters of the air */
@media (max-width: 640px) {
  .case-head { padding-top: 64px; }
  .case-head .crumb { margin-bottom: 36px; }
  .prose h2 { margin-top: 48px; }
  .prose h2:first-child { margin-top: 32px; }
  .prose .pull { margin: 32px 0; }
  figure.slot, figure.fig { margin: 32px 0; }
  figure.slot.breakout, figure.fig.breakout { margin-top: 40px; margin-bottom: 40px; }
  .case-next { margin-top: 72px; }
}

/* ---------- gate ---------- */
.gate { padding-top: 40px; transition: opacity 240ms var(--ease), transform 240ms var(--ease); }
.gate[data-state="checking"] { opacity: 0; pointer-events: none; }
.gate.leaving { opacity: 0; transform: translateY(-6px); pointer-events: none; transition: opacity 200ms var(--ease-exit), transform 200ms var(--ease-exit); } /* the card leaves quietly (Jakub: exits subtler than enters), then the story enters */
.gate-card { background: var(--surface); border: 1px solid var(--hair); border-radius: 14px; padding: 40px 36px; box-shadow: var(--shadow); }
.gate-card h2 { font-family: var(--serif); font-weight: 600; font-size: 1.3rem; letter-spacing: -0.012em; line-height: 1.3; color: var(--ink-strong); margin-top: 12px; text-wrap: balance; } /* 2026-09-01 (Miki: "title is too big"): h3 scale, not a page title; the card is a notice, the story is the headline */
.gate-card p { margin-top: 14px; max-width: 56ch; font-size: 15px; }
.gate-form { display: flex; gap: 10px; margin-top: 24px; max-width: 440px; }
.gate-form input { flex: 1; min-width: 0; font-family: var(--mono); font-size: 14px; padding: 11px 14px; border-radius: 6px; border: 1px solid var(--hair-2); background: var(--bg); color: var(--ink-strong); }
.gate-form input::placeholder { color: var(--muted); }
.gate-form.shake { animation: shake 400ms var(--ease); }
@keyframes shake { 20% { transform: translateX(-6px); } 40% { transform: translateX(5px); } 60% { transform: translateX(-3px); } 80% { transform: translateX(2px); } }
.gate-msg { min-height: 1.4em; margin-top: 12px !important; font-size: 13.5px !important; color: var(--red-t); }
.gate[data-state="busy"] .gate-msg { color: var(--muted); }
.gate-alt { font-size: 13.5px !important; color: var(--muted); }
.gate-alt a { color: var(--ink); }
.case-body[hidden] { display: none; }
.case-body { opacity: 0; transform: translateY(10px); transition: opacity 500ms var(--ease), transform 500ms var(--ease); }
.case-body.open { opacity: 1; transform: none; }
@media (max-width: 560px) { .gate-card { padding: 28px 22px; } .gate-form { flex-direction: column; } }

/* ---------- footer ---------- */
.site-foot { margin-top: 120px; border-top: 1px solid var(--hair); padding: 80px 0 48px; }
.site-foot h2 { font-family: var(--serif); font-weight: 700; font-size: clamp(1.8rem, 4vw, 2.8rem); line-height: 1.1; letter-spacing: -0.02em; color: var(--ink-strong); text-wrap: balance; }
.site-foot .btn { margin-top: 28px; }
.site-foot .alt { margin-top: 14px; font-size: 13.5px; color: var(--muted); }
.site-foot .alt a { color: var(--ink); }
.site-foot .base { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-top: 72px; padding-top: 20px; border-top: 1px solid var(--hair); font-size: 12.5px; color: var(--muted); }
.site-foot .base .l a { text-decoration: none; margin-left: 20px; }
.site-foot .base .l a:hover { color: var(--ink-strong); }
/* work pages carry no contact CTA (the case-next bar closes the page), so the footer is just the base row */
body[data-page^="work"] .site-foot { margin-top: 0; padding: 64px 0 48px; border-top: 0; }
body[data-page^="work"] .site-foot .base { margin-top: 0; }

/* ---------- reveal ----------
   Motion tiers (2026-09-01, after kylezantos/design-motion-principles; Jakub-weighted, Emil's frequency gate):
   .rv          base fade-up, the home page's reveal (600ms, 12px)                      .rv-line   small lines: crumb, eyebrow, kicker, section heads (450ms, 8px)
   .rv-title    the page h1 only: fade-up + blur→sharp, the one blur on a page (750ms)   .rv-rule   the rolebar wipes in along its hairlines, left→right (mask)
   .rv-pull     pull quotes wipe down along their left rule (mask)                  .rv-media  figures + portrait materialise: fade + scale .98→1, no blur on big images (750ms)
   .rv-row      tiles and rows count in (400ms, 6px, 40ms stagger); triggered by their .rvg group, not one by one
   Body copy (h2 labels, paragraphs, lists) has no entrance: it is read once and should be there when the eye arrives.
   Stagger: --i × --stagger (80ms; page/case heads and the About grid use 60ms so the opener finishes inside ~0.9s).
   .skip = arrived without motion (gate open marks what is already in view). No JS → the <noscript> style in base.html shows everything. */
:root { --ease-wipe: cubic-bezier(0.77, 0, 0.175, 1); --ease-exit: cubic-bezier(0.4, 0, 1, 1); }
.rv { opacity: 0; transform: translateY(12px); transition: opacity 600ms var(--ease), transform 600ms var(--ease); transition-delay: calc(var(--i, 0) * var(--stagger, 80ms)); }
.case-head .rv, .page-head .rv, .about-grid .rv { --stagger: 60ms; }
.rv.rv-line { transform: translateY(8px); transition-duration: 450ms; }
.rv.rv-title { transition: none; }
.rv.rv-title.in { animation: rv-title 750ms var(--ease) calc(var(--i, 0) * var(--stagger, 80ms)) backwards; }
@keyframes rv-title { from { opacity: 0; transform: translateY(12px); filter: blur(6px); } to { opacity: 1; transform: none; filter: blur(0); } }
/* wipes use an animated mask, not clip-path: Chrome's IntersectionObserver treats a fully clipped element as not intersecting, so a clip-path'd .rv would never reveal.
   The mask is 3× the element with a soft edge in its middle third: at 60% the element sits in the clear part (hidden), at 0 in the solid part (shown), and the edge sweeps the whole element in between */
.rv.rv-rule, .rv.rv-pull { opacity: 1; transform: none; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; }
.rv.rv-rule { -webkit-mask-image: linear-gradient(to right, #000 34%, transparent 37%); mask-image: linear-gradient(to right, #000 34%, transparent 37%); -webkit-mask-size: 300% 100%; mask-size: 300% 100%; -webkit-mask-position: 60% 0; mask-position: 60% 0; transition: -webkit-mask-position 650ms var(--ease-wipe), mask-position 650ms var(--ease-wipe); }
.rv.rv-pull { -webkit-mask-image: linear-gradient(to bottom, #000 34%, transparent 37%); mask-image: linear-gradient(to bottom, #000 34%, transparent 37%); -webkit-mask-size: 100% 300%; mask-size: 100% 300%; -webkit-mask-position: 0 60%; mask-position: 0 60%; transition: -webkit-mask-position 550ms var(--ease-wipe), mask-position 550ms var(--ease-wipe); }
.rv.rv-media { transform: scale(0.98); transition: opacity 750ms var(--ease), transform 750ms var(--ease); }
.rv.rv-row { transform: translateY(6px); transition-duration: 400ms; transition-delay: calc(var(--i, 0) * 40ms); }
.rv.in, .rv.rv-media.in, .rv.rv-row.in { opacity: 1; transform: none; }
.rv.rv-rule.in, .rv.rv-pull.in { -webkit-mask-position: 0 0; mask-position: 0 0; }
.rv.skip { transition-duration: 0s !important; transition-delay: 0s !important; animation-duration: 0s !important; animation-delay: 0s !important; }
#app { transition: opacity 160ms var(--ease-exit); } /* single-file preview: the old route fades before the next mounts */
#app.leaving { opacity: 0; }

/* page-to-page (Chrome 126+, Safari 18.2+; other browsers navigate as before): the nav stays put, the page crossfades, the old page leaves faster than the new one arrives */
@view-transition { navigation: auto; }
.topnav { view-transition-name: topnav; }
::view-transition-old(root) { animation-duration: 160ms; animation-timing-function: var(--ease-exit); }
::view-transition-new(root) { animation-duration: 260ms; }

/* ---------- dev chip (preview / dev builds only) ---------- */
.devchip { position: fixed; left: 14px; bottom: 14px; z-index: 70; background: var(--surface); border: 1px solid var(--hair); color: var(--muted); font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; padding: 6px 10px; border-radius: 6px; max-width: min(60vw, 420px); }
.devchip b { color: var(--yellow-t); font-weight: 500; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .rv, .rv.rv-line, .rv.rv-title, .rv.rv-rule, .rv.rv-pull, .rv.rv-media, .rv.rv-row { opacity: 1; transform: none; transition: none; -webkit-mask-image: none; mask-image: none; filter: none; }
  .rv.rv-title.in { animation: none; }
  .case-body, .gate, #app { opacity: 1; transform: none; transition: none; }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
  .card, .card:hover { transform: none; transition: none; }
  .qtext.cascade .w, .qtext.rise .rli, .qtext.wave .wl { animation-duration: 1ms; }
  .qattr.show { animation-duration: 1ms; animation-delay: 0ms; }
  .gline .gl { transition: font-variation-settings 400ms ease; }
  .topnav .theme .thumb { transition: none; }
  .gline .gl:hover { font-variation-settings: 'wght' 760 !important; }
  .stage.mag-ink .gline .gl { --a: 1; }
}

/* late additions */
main { overflow-x: clip; }
[id] { scroll-margin-top: 76px; }

/* real media figures (filled slots) */
figure.fig { margin: 40px 0; }
figure.fig.breakout { margin-top: 56px; margin-bottom: 56px; }
figure.fig img { display: block; width: 100%; height: auto; border-radius: 24px; border: 1px solid var(--hair); background: var(--surface); }
figure.fig > img { width: auto; max-width: 100%; margin-left: auto; margin-right: auto; } /* a lone image never upscales past its pixels */
figure.fig .imgs { display: grid; grid-template-columns: repeat(var(--cols, 2), 1fr); gap: 12px; align-items: start; }
figure.fig .imgs.c3 { --cols: 3; }
figure.fig.narrow img, figure.fig .imgs .tall { max-width: 360px; margin: 0 auto; }
figure.fig figcaption { font-family: var(--sans); font-size: 13px; color: var(--muted); line-height: 1.5; margin-top: 12px; text-wrap: pretty; }
figure.fig figcaption b { color: var(--ink-strong); font-weight: 600; }
figure.fig .poster { position: relative; display: block; }
figure.fig .poster i { position: absolute; left: 10px; bottom: 10px; font-family: var(--mono); font-style: normal; font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; background: var(--surface); color: var(--muted); border: 1px solid var(--hair); border-radius: 9999px; padding: 6px 10px; }
@media (max-width: 700px) { figure.fig .imgs, figure.fig .imgs.c3 { grid-template-columns: 1fr; } }

/* case-study structure v2 (2026-08-30, piloted on Cashback): sub-heads, accountability ledger, initiatives index */
.prose h3 { font-family: var(--serif); font-weight: 600; font-size: 1.2rem; letter-spacing: -0.012em; line-height: 1.3; color: var(--ink-strong); margin: 40px 0 12px; max-width: 30em; text-wrap: balance; }
.prose h2 + h3 { margin-top: 16px; }
.prose .ledger { margin: 16px 0 32px; max-width: none; border-top: 1px solid var(--hair); }
.ledger > div { display: grid; grid-template-columns: 150px 1fr; gap: 20px; padding: 16px 0; border-bottom: 1px solid var(--hair); }
.ledger dt { font-family: var(--sans); font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); padding-top: 5px; }
.ledger dd { font-family: var(--serif); font-size: 1rem; line-height: 1.55; color: var(--ink); margin: 0; }
.prose .initiatives { list-style: none; padding: 0; margin: 16px 0 32px; max-width: none; border-top: 1px solid var(--hair); }
.initiatives li { display: grid; grid-template-columns: 150px 1fr; gap: 20px; padding: 20px 0; border-bottom: 1px solid var(--hair); }
.initiatives .num { font-family: var(--mono); font-size: 12px; letter-spacing: 0.04em; color: var(--muted); padding-top: 4px; font-variant-numeric: tabular-nums; }
.prose .initiatives h3 { margin: 0 0 4px; font-size: 1.125rem; }
.prose .initiatives p { font-size: 1rem; line-height: 1.55; margin: 0; }
.initiatives .res { font-family: var(--sans); font-size: 12.5px; color: var(--muted); margin-top: 8px; line-height: 1.5; }
.initiatives .res b { color: var(--ink); font-weight: 500; margin-right: 6px; }
.initiatives .tag { display: inline-block; vertical-align: 0.25em; margin-left: 10px; font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); border: 1px solid var(--hair-2); border-radius: 4px; padding: 1px 6px; white-space: nowrap; } /* neutral since 2026-09-01 (Miki: the blue "Focus of this page" chip was out of style); was --blue-t on --pale-blue */
/* framed ledger (2026-09-01, Miki, prototype page: "frame these 3 points and bring it together, title and description can be continuation of same line"):
   one bordered panel, a serif title column and the description on the same line; the last row closes the frame without a hairline */
.prose .ledger.framed { border: 1px solid var(--hair); border-radius: 12px; background: var(--surface); padding: 0 20px; margin: 24px 0 40px; }
.ledger.framed > div { grid-template-columns: 168px 1fr; gap: 24px; padding: 18px 0; }
.ledger.framed > div:last-child { border-bottom: 0; }
.ledger.framed dt { font-family: var(--serif); font-size: 1.0625rem; font-weight: 600; letter-spacing: -0.005em; text-transform: none; color: var(--ink-strong); line-height: 1.55; padding-top: 0; }
.ledger.framed dd { font-size: 1.0625rem; }
@media (max-width: 640px) { .ledger > div, .initiatives li { grid-template-columns: 1fr; gap: 6px; } .initiatives .num, .ledger dt { padding-top: 0; } }

/* before/after compare (2026-08-30, v2): two same-size images layered, the "before" clipped to the left of --pos; a transparent full-size range input is the control (mouse, touch, keyboard). --p is --pos as a 0..1 number (set by JS) for opacity maths. Line, knob and chips are frosted/translucent because they sit on the image, not the page. */
figure.fig .cmp { position: relative; overflow: hidden; aspect-ratio: 16 / 9; border-radius: 24px; border: 1px solid var(--hair); background: var(--surface); --pos: 50%; --p: 0.5; user-select: none; -webkit-user-select: none; touch-action: pan-y; cursor: grab; }
.cmp.dragging { cursor: grabbing; }
figure.fig .cmp img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; margin: 0; border: 0; border-radius: 0; display: block; }
figure.fig .cmp img.before { clip-path: inset(0 calc(100% - var(--pos)) 0 0); }
.cmp-handle { position: absolute; top: 0; bottom: 0; left: var(--pos); width: 0; pointer-events: none; z-index: 1; }
.cmp-handle::before { content: ""; position: absolute; top: 0; bottom: 0; left: -0.5px; width: 1px; background: rgba(255, 255, 255, 0.82); box-shadow: 0 0 10px rgba(0, 0, 0, 0.45); transition: background 200ms ease; }
.cmp.dragging .cmp-handle::before { background: #FFFFFF; }
.cmp-knob { position: absolute; top: 50%; left: clamp(24px, var(--pos), calc(100% - 24px)); width: 44px; height: 44px; transform: translate(-50%, -50%); border-radius: 50%; color: rgba(255, 255, 255, 0.92); background: rgba(255, 255, 255, 0.12); border: 1px solid rgba(255, 255, 255, 0.42); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35); -webkit-backdrop-filter: blur(14px) saturate(140%); backdrop-filter: blur(14px) saturate(140%); display: grid; place-items: center; pointer-events: none; z-index: 1; transition: transform 240ms var(--ease), background 240ms ease, border-color 240ms ease; }
.cmp:hover .cmp-knob { background: rgba(255, 255, 255, 0.18); }
.cmp.dragging .cmp-knob { transform: translate(-50%, -50%) scale(1.08); background: rgba(255, 255, 255, 0.26); border-color: rgba(255, 255, 255, 0.75); }
.cmp-knob svg { width: 18px; height: 18px; }
.cmp.snap img.before, .cmp.snap .cmp-handle { transition: clip-path 520ms var(--ease), left 520ms var(--ease); }
.cmp.snap .cmp-knob { transition: left 520ms var(--ease), transform 240ms var(--ease), background 240ms ease, border-color 240ms ease; }
.cmp-range { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; opacity: 0; cursor: inherit; -webkit-appearance: none; appearance: none; background: transparent; z-index: 2; }
.cmp-range::-webkit-slider-thumb { -webkit-appearance: none; width: 44px; height: 44px; }
.cmp:has(.cmp-range:focus-visible) .cmp-knob { outline: 2px solid var(--accent); outline-offset: 3px; }
.cmp-chip { position: absolute; bottom: 14px; z-index: 3; font-family: var(--mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; line-height: 1; color: rgba(255, 255, 255, 0.88); background: rgba(12, 10, 20, 0.38); border: 1px solid rgba(255, 255, 255, 0.16); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); border-radius: 9999px; padding: 7px 11px; cursor: pointer; transition: opacity 240ms ease, background 200ms ease, color 200ms ease; }
.cmp-chip.before { left: 14px; opacity: calc(0.4 + 0.6 * var(--p)); }
.cmp-chip.after { right: 14px; opacity: calc(1 - 0.6 * var(--p)); }
.cmp-chip:hover, .cmp-chip:focus-visible { opacity: 1; color: #FFFFFF; background: rgba(255, 255, 255, 0.16); }
@media (max-width: 640px) { .cmp-knob { width: 38px; height: 38px; } .cmp-chip { bottom: 10px; padding: 6px 9px; } .cmp-chip.before { left: 10px; } .cmp-chip.after { right: 10px; } }
@media (prefers-reduced-motion: reduce) { .cmp.snap img.before, .cmp.snap .cmp-handle, .cmp.snap .cmp-knob, .cmp-knob, .cmp-chip, .cmp-handle::before { transition: none; } }

/* chapter title inside a case page (2026-08-30): a serif opener for the deep-dive, sitting between the small-caps h2 labels */
.prose h2.chapter { font-family: var(--serif); font-weight: 700; font-size: clamp(1.7rem, 3.2vw, 2.25rem); letter-spacing: -0.028em; line-height: 1.1; text-transform: none; color: var(--ink-strong); margin: 80px 0 8px; padding-top: 32px; border-top: 1px solid var(--hair); max-width: 24em; text-wrap: balance; }
.prose h2.chapter + h3 { margin-top: 32px; }
.case-head .standfirst strong { color: var(--ink-strong); font-weight: 500; }
.prose .initiatives + h2.chapter { border-top: 0; padding-top: 0; margin-top: 72px; }
.prose .stats .break { flex-basis: 100%; height: 0; margin: 0; padding: 0; } /* forces a row break between stat tiles */
.prose .stats.solo .stat { flex: 0 1 auto; min-width: 220px; } /* a single stat tile (Drawing Review's ~70% target) should not stretch across the column */
