/* ==========================================================================
   Home: hero, essay chapters, generic-to-distinctive, why, work, contact
   ========================================================================== */

/* --- Hero: name + portrait coming through the paper ---------------------- */

.aura { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; transition: opacity 1.2s var(--ease); }
.aura.still { transition: none; }   /* until you scroll yourself: a refresh further down starts at the dimmed light, with no fade */
.aura i { position: absolute; border-radius: 50%; filter: blur(var(--light-blur, 70px)); }
.aura i:nth-child(1) { width: 46vw; height: 46vw; left: 8vw; top: 6vh; background: var(--light-1, var(--blue)); opacity: calc(.55 * var(--light-o, 1)); }
.aura i:nth-child(2) { width: 38vw; height: 38vw; right: 4vw; top: 30vh; background: var(--light-2, #f2dcc4); opacity: calc(.7 * var(--light-o, 1)); }
.aura i:nth-child(3) { width: 30vw; height: 30vw; left: 40vw; top: 52vh; background: var(--light-3, #c9def0); opacity: calc(.6 * var(--light-o, 1)); }

main, .footer { position: relative; z-index: 1; }

.hero { height: 100vh; position: relative; }   /* the intro plays on its own now, so no scroll track */
/* Until the fonts are in (see the script in index.html's head), the intro waits: hidden, its animations paused at the start */
html.intro-wait .hero-stage, html.intro-wait .nav { visibility: hidden; }
html.intro-wait .hero-stage, html.intro-wait .hero-stage * { animation-play-state: paused !important; }
.hero-stage { position: sticky; top: 0; height: 100vh; display: grid; place-items: center; overflow: hidden; }
.hero .eyebrow { position: absolute; top: 18vh; left: 50%; translate: -50% 0; opacity: 0; animation: fadeIn 1.4s var(--ease) 1.1s forwards; }

.name { display: flex; align-items: center; justify-content: center; gap: 2.4vw; font-family: var(--serif); font-weight: 400;
  font-size: clamp(64px, 11.5vw, 190px); line-height: .9; letter-spacing: -.035em; white-space: nowrap; }
.name .l { display: inline-block; opacity: 0; filter: blur(18px); translate: 0 .12em;
  animation: focusIn 1.6s var(--ease) forwards; animation-delay: calc(var(--i) * 55ms + 150ms); }
@keyframes focusIn { to { opacity: 1; filter: blur(0); translate: 0 0; } }
@keyframes fadeIn { to { opacity: 1; } }

/* The name lands as one; scrolling opens a slot between the words for the portrait (sized in JS) */
.portrait { --w: clamp(150px, 21vw, 340px); position: relative; z-index: 0; flex: none; perspective: 900px;
  width: 0; height: calc(var(--w) * 1.25); margin-inline: -1.2vw; }
.name > [data-letters] { position: relative; z-index: 1; }
.card { display: block; opacity: 0; position: absolute; left: 50%; top: 0; translate: -50% 0; width: var(--w); height: 100%; border-radius: 18px; overflow: hidden; transform-origin: 50% 60%; will-change: transform, filter; }
.card img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; }
.card::after { content: ""; position: absolute; inset: 0; background: var(--paper); opacity: var(--veil, .78); }

.hero .lede { position: absolute; bottom: 12vh; left: 50%; translate: -50% 0; width: max-content; max-width: calc(100% - 48px); white-space: nowrap; text-align: center;
  font-size: clamp(18px, 1.6vw, 22px); line-height: 1.45; opacity: 0; }

.cue { position: absolute; bottom: 6vh; left: 50%; translate: -50% 0; display: grid; justify-items: center; gap: 10px;
  font: 500 11px/1 var(--sans); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint); opacity: 0; animation: fadeIn 1.4s var(--ease) 1.8s forwards; transition: filter .4s ease-out; }
.cue.gone { filter: opacity(0); }   /* once you scroll it fades away (filter, as opacity is held by its entrance) */
.cue::after { content: ""; width: 1px; height: 36px; background: linear-gradient(var(--ink-faint), transparent); animation: cue 2.4s var(--ease) infinite; transform-origin: top; }
@keyframes cue { 0% { transform: scaleY(0); } 50% { transform: scaleY(1); } 100% { transform: scaleY(1); opacity: 0; } }

/* --- Hero B: portrait left, name stacked right and still ----------------- */

.hero-b .hero-b-grid { display: grid; grid-template-columns: auto auto; align-items: center; gap: clamp(32px, 6vw, 96px);
  width: min(1180px, 100% - var(--gutter) * 2); justify-content: center; }
.hero-b .portrait { width: var(--w); margin: 0; --w: clamp(170px, 24vw, 380px); }
.hero-b .hero-b-text { display: grid; gap: 4vh; justify-items: start; }
.hero-b .eyebrow, .hero-b .lede { position: static; translate: none; }
.hero-b .eyebrow { opacity: 0; }
/* The label above the name: one fact at a time, rolling on by itself (Designer → 13+ Yrs exp → Stockholm → Designer…) */
.hero .eyebrow { opacity: 1; animation: none; }
.hero .eyebrow .roll { display: inline-block; height: 1.2em; overflow: hidden; vertical-align: top; margin-top: -.1em;
  opacity: 0; animation: eyebrow-in 1.2s var(--ease) 1.1s forwards; }
.hero .eyebrow .track { display: block; animation: eyebrow-roll 7s cubic-bezier(.32,.72,0,1) 3.4s infinite; }   /* two facts, 3.5s each */
.hero .eyebrow .track > span { display: block; height: 1.2em; line-height: 1.2em; }
@keyframes eyebrow-in { from { opacity: 0; filter: blur(6px); translate: 0 .5em; } to { opacity: 1; filter: none; translate: 0 0; } }
/* Each fact holds, then rolls up to the next; the last row repeats the first, so the loop restarts without a jump */
@keyframes eyebrow-roll { 0%, 42% { translate: 0 0; } 50%, 92% { translate: 0 -1.2em; } 100% { translate: 0 -2.4em; } }
@media (prefers-reduced-motion: reduce) { .hero .eyebrow .track { animation: none; } }
.hero-b .name { flex-direction: column; align-items: flex-start; gap: 0; font-size: clamp(64px, 10.5vw, 176px); line-height: .88; }
.hero-b .lede { text-align: left; white-space: normal; width: auto; max-width: 22em; }

/* Intro line: hidden until the photo lands, then each word focuses in on a timeline */
.hero .lede { opacity: 1; }
.hero .lede .lw { display: inline-block; opacity: 0; filter: blur(14px); translate: 0 .3em;
  transition: opacity .25s var(--ease), filter .25s var(--ease), translate .25s var(--ease); }
.hero .lede.in .lw { opacity: 1; filter: blur(0); translate: 0 0;
  transition: opacity 1.2s var(--ease), filter 1.2s var(--ease), translate 1.2s var(--ease); transition-delay: calc(var(--i) * 70ms); }

/* --- Essay chapters ------------------------------------------------------ */

.chapter { padding: 22vh 0 6vh; }
/* Sidenote: "the basics" carries a small number, and the facts sit level with it in the right margin, like a well-set essay */
.prose:has(.sidenote) { position: relative; }
/* The dotted line under "the basics" draws in from the left once you reach it, then the 1 rolls in after it */
.sn-t { position: relative; }
/* (the dots are laid by home.js, one by one: each lands a little large and settles to size) */
.sn-t { position: relative; }
.sn-dots { position: absolute; left: 0; right: 0; bottom: .02em; height: 2px; display: flex; justify-content: space-between; pointer-events: none; }
.sn-dots i { width: 2px; height: 2px; border-radius: 50%; background: var(--ink-soft); opacity: 0; scale: 2.6;
  transition: opacity .25s, scale .55s cubic-bezier(.3,1.5,.5,1), background .3s; }
.sn.drawn .sn-dots i { opacity: 1; scale: 1; transition-delay: calc(var(--i) * 28ms); }
.sn sup { font: 500 .55em var(--sans); color: var(--blue-ink); margin-left: 1px; padding: 0 1px; border-radius: 3px;
  opacity: 0; translate: -.6em 0; filter: blur(3px); transition: background .3s, opacity .4s var(--ease), translate .7s cubic-bezier(.3,1.4,.5,1), filter .5s var(--ease); }
.sn.drawn sup { opacity: 1; translate: 0 0; filter: none; transition-delay: 0s, var(--sup-d, .65s), var(--sup-d, .65s), var(--sup-d, .65s); }
.sidenote { position: absolute; left: calc(100% + 32px); width: 200px;   /* left is refined in home.js: just past the paragraph's measure */
  font: 400 14px/1.55 var(--sans); color: var(--ink-soft); padding-top: 10px; }
/* Its entrance, once you've scrolled to it: the number in the text pings, a rule draws out from it,
   the note's 1 pops, then the three facts settle in one by one */
.sidenote::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: var(--rule); transform-origin: 0 50%; scale: 0 1;
  transition: scale .9s cubic-bezier(.32,.72,0,1) .15s, background .3s; }
.sidenote > * { opacity: 0; filter: blur(5px); translate: -10px 0; transition: opacity .6s var(--ease), filter .7s var(--ease), translate .8s cubic-bezier(.32,.72,0,1); }
.sidenote > b { display: inline-block; translate: 0 0; scale: .3; transition: opacity .3s, filter .3s, scale .55s cubic-bezier(.3,1.7,.5,1); }
.sidenote.shown::before { scale: 1 1; }
.sidenote.shown > * { opacity: 1; filter: none; translate: 0 0; transition-delay: calc(.45s + var(--i, 0) * 110ms); }
.sidenote.shown > b { scale: 1; transition-delay: .35s; }
.sidenote > span:nth-of-type(1) { --i: 1; } .sidenote > span:nth-of-type(2) { --i: 2; } .sidenote > span:nth-of-type(3) { --i: 3; }
.sn.ping sup { animation: sn-ping 1.1s cubic-bezier(.3,1.5,.5,1); }
@keyframes sn-ping { 0% { background: transparent; scale: 1; } 25% { background: var(--blue-soft); scale: 1.5; } 100% { background: transparent; scale: 1; } }
.sn sup { display: inline-block; }
.sidenote b { font-weight: 500; color: var(--blue-ink); margin-right: 4px; }
.sidenote > span { display: block; color: var(--ink); }
/* Point at either one and both light up */
.lit .sn-dots i { background: var(--blue-ink); }
.lit .sn sup { background: var(--blue-soft); }
.lit .sidenote::before { background: var(--blue-ink); }
@media (max-width: 1360px) { .sidenote { position: relative; width: auto; max-width: 31em; margin: -.3em 0 1.6em; } }
.chapter .kicker { margin-bottom: 5vh; }
.chapter .display { margin-bottom: 7vh; }
.pull { width: min(1100px, 100% - var(--gutter) * 2); margin: 16vh auto; }
.pull .display { max-width: 13em; }

.triad { font-family: var(--serif); font-size: clamp(64px, 12vw, 170px); line-height: .9; letter-spacing: -.035em; margin: 24vh 0 10vh; }
/* Taste: click to swap through five very different typefaces */
.triad .taste { cursor: pointer; width: max-content; outline: none; height: .9em; }   /* one line, always: no face (WordArt) can push Intuition down */
/* The word changes size per face, but never the height of its line */
.taste-in { display: inline-block; line-height: 0; vertical-align: baseline; white-space: nowrap; }
/* Swashy faces (Ballet) spill over Perspective: only Taste's own line takes the pointer, and it's never part of a text selection */
.triad .taste { user-select: none; -webkit-user-select: none; }
.taste-in { pointer-events: none; }
/* WordArt chrome: metallic gradient, outline and a drop shadow, upright (it needs a real line box for its gradient) */
.taste-in.wordart { line-height: 1.05; margin: -.1em 0; filter: drop-shadow(.07em .07em 0 rgba(60,64,72,.55)); }   /* the classic grey WordArt shadow */
/* The fill and outline go on the word layer itself (.w has its own filter layer, so a clip on the parent drifts off the glyphs) */
.taste-in.wordart .w, .taste-in.wordart:not(:has(.w)) { padding: 0 .06em; color: transparent; -webkit-text-stroke: .02em #222;
  background: linear-gradient(180deg, #fefefe 0%, #9aa3ad 46%, #2f3640 50%, #c6cdd5 70%, #fff 100%); -webkit-background-clip: text; background-clip: text; }
.triad .taste:focus-visible { box-shadow: 0 0 0 2px var(--blue-ink); border-radius: 8px; }

/* "Human" sits at the start of the line, uncovered left to right (H first) as Intuition slides right by --x */
.triad .intu { position: relative; --x: 0px; --xe: 0; }
.intu-h { position: absolute; left: 0; top: 0; white-space: nowrap; clip-path: inset(-.3em calc(100% - var(--x)) -.3em -.1em); }
.intu-h { --scene: none; }
.intu-h .w, .intu-h:not(:has(.w)) { background: var(--scene) 50% 50% / cover; -webkit-background-clip: text; background-clip: text; color: transparent; }
.intu-track { display: inline-block; white-space: nowrap; cursor: grab; touch-action: pan-y; translate: var(--x) 0; }
.intu-track.grabbing { cursor: grabbing; }
.triad > span { display: block; }
/* Letter by letter, like the name (home.js): the words are there at once, their letters focus in one after another */
.triad .w:has(.tl) { --ro: 1; transition: none; }
/* Hidden at once (no fade out: Perspective's letters may already be on screen when they're marked), then the
   entrance runs once its own class is on, with the delays set */
.tl { display: inline-block; opacity: 0; filter: blur(18px); translate: 0 .12em; }
.tl-on .tl { opacity: 1; filter: none; translate: 0 0;
  transition: opacity 1.6s var(--ease), filter 1.6s var(--ease), translate 1.6s var(--ease); transition-delay: var(--ld, 0ms); }
@media (hover: none), (max-width: 700px) { .tl { filter: none; } }   /* phones: fade and rise, no blur (as the words do, site.css) */
/* Perspective: select it to see its anatomy (letters to outline, boxes and the type's guides; drawn in home.js) */
.persp { position: relative; cursor: text; }
.persp .pl { display: inline-block; position: relative; }
.persp ::selection { background: transparent; color: var(--ink); }
.persp .pl.s::selection { color: transparent; }
.persp .pl.s::after { content: attr(data-c); position: absolute; left: 0; top: 0; color: transparent; -webkit-text-stroke: 1.2px var(--blue-ink); pointer-events: none; }
.persp-guides { user-select: none; -webkit-user-select: none; position: absolute; left: -20%; top: -40%; width: 140%; height: 180%; pointer-events: none; overflow: visible; }
.persp-guides line { stroke: var(--blue-ink); stroke-width: 1; }
.persp-guides rect { fill: rgba(156,198,236,.12); stroke: rgba(45,106,168,.35); stroke-width: 1; }
.persp-guides text { font: 500 11px "IBM Plex Mono", monospace; fill: var(--blue-ink); letter-spacing: 0; }

/* --- Generic to distinctive ---------------------------------------------- */

.gd { height: 450vh; position: relative; margin-top: -8vh; }   /* pulled up (the stage centres in a full screen); longer, as the prompt holds alone first (STEPS_FROM in home.js), then each step keeps its old length */
/* The words lead, the site supports */
.gd-stage { position: sticky; top: 0; height: 100vh; display: grid; grid-template-columns: minmax(280px, 420px) minmax(0, 640px); justify-content: center; gap: clamp(28px, 3.5vw, 56px); align-items: center;
  width: min(1280px, 100% - var(--gutter) * 2); margin: 0 auto; }
.gd .steps { list-style: none; display: grid; gap: 30px; }
.gd .steps li { transition: opacity .6s var(--ease), filter .6s var(--ease); opacity: .28; filter: blur(1.5px); }
.gd .steps li.on { opacity: 1; filter: none; }
.gd .steps button { all: unset; display: block; cursor: pointer; border-radius: 6px; }
.gd .steps button:focus-visible { outline: 2px solid var(--blue-ink); outline-offset: 6px; }
.gd .steps li:not(.on):hover { opacity: .6; filter: none; }
.gd .steps li.on span { color: var(--blue-ink); }
.gd .steps span { transition: color .3s; }
.gd .steps small { display: block; font: 500 12px/1 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 8px; }
.gd .steps span { font-family: var(--serif); font-size: clamp(34px, 3.4vw, 52px); line-height: 1; letter-spacing: -.02em; }
.gd .steps p { font-size: clamp(16px, 1.3vw, 18px); color: var(--ink-soft); margin-top: 10px; line-height: 1.45; max-width: 24em; }

.browser { border-radius: 14px; overflow: hidden; background: #fff; aspect-ratio: 16 / 10.4; max-height: 82vh;
  box-shadow: 0 0 0 1px rgba(0,0,0,.06), 0 30px 80px -30px rgba(40,35,30,.35); display: flex; flex-direction: column; }
.browser .bar { height: 36px; flex: none; display: flex; align-items: center; gap: 7px; padding: 0 14px; background: #f6f5f3; border-bottom: 1px solid #ebe8e3; }
.browser .bar i { width: 10px; height: 10px; border-radius: 50%; background: #dedbd5; }
.browser .bar { position: relative; }
.browser .bar span { position: absolute; left: 50%; translate: -50% 0;   /* centred on the whole bar, not the space after the dots */
  font: 12px var(--sans); color: var(--ink-faint); background: #fff; border-radius: 6px; padding: 3px 40px; }

.mock { --t: .9s; position: relative; flex: 1; overflow: hidden; font-family: Inter, system-ui, sans-serif; background: #fff;
  transition: background var(--t) var(--ease); container-type: inline-size; }
.mock * { transition: all var(--t) var(--ease); }
.mock .blob { position: absolute; inset: -20% -10% auto; height: 90%; filter: blur(40px); opacity: .55;
  background: radial-gradient(40% 50% at 30% 40%, #a78bfa, transparent 70%), radial-gradient(40% 50% at 70% 35%, #60a5fa, transparent 70%), radial-gradient(30% 40% at 50% 70%, #f0abfc, transparent 70%); }
.mock .mgrain { position: absolute; inset: 0; pointer-events: none; opacity: 0; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 .6 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"); }
.mock .mnav { position: relative; display: flex; align-items: center; gap: 4cqw; padding: 2.6cqw 4cqw; font-size: 1.35cqw; color: #475569; }
.mock .logo { font-weight: 700; color: #0f172a; font-size: 1.7cqw; display: flex; align-items: center; gap: .6cqw; margin-right: auto; }
.mock .logo i { width: 1.9cqw; height: 1.9cqw; border-radius: .5cqw; background: linear-gradient(135deg, #8b5cf6, #3b82f6); }
.mock .btn { border-radius: 999px; padding: .9cqw 1.8cqw; font-weight: 500; color: #fff; background: linear-gradient(135deg, #8b5cf6, #3b82f6); box-shadow: 0 .6cqw 1.6cqw -.6cqw rgba(99,102,241,.6); }
.mock .btn.ghost { background: #fff; color: #0f172a; box-shadow: 0 0 0 1px #e2e8f0; }
.mock .mhero { position: relative; height: 26cqw; }
.mock .h { position: absolute; left: 4cqw; right: 4cqw; top: 3cqw; }
.mock .h0 { text-align: center; }
.mock .h0 .pill { display: inline-block; font-size: 1.15cqw; color: #6d28d9; background: #ede9fe; border-radius: 999px; padding: .5cqw 1.2cqw; margin-bottom: 1.6cqw; }
.mock .h0 h3 { font-size: 4.6cqw; line-height: 1.08; font-weight: 700; letter-spacing: -.03em; color: #0f172a; }
.mock .h0 p { font-size: 1.5cqw; color: #64748b; margin: 1.4cqw auto 2cqw; max-width: 44cqw; }
.mock .h0 .ctas { display: flex; gap: 1cqw; justify-content: center; font-size: 1.35cqw; }
.mock .h2, .mock .h3 { font-family: var(--serif); color: var(--ink); opacity: 0; filter: blur(12px); transform: translateY(1.5cqw); }
.mock .h2 h3, .mock .h3 h3 { font-weight: 400; font-size: 8.4cqw; line-height: .93; letter-spacing: -.03em; }
.mock .h2 p, .mock .h3 p { font-family: var(--sans); font-size: 1.6cqw; color: var(--ink-soft); margin-top: 2cqw; max-width: 40cqw; }
.mock .h3 { right: 38cqw; }
.mock .h3 p { max-width: none; text-wrap: balance; }
.mock .cards { position: absolute; left: 4cqw; right: 4cqw; bottom: 4cqw; display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.6cqw; }
.mock .mcard { background: #fff; border-radius: 1.4cqw; padding: 1.8cqw; box-shadow: 0 0 0 1px #eef2f7, 0 1cqw 2.4cqw -1.2cqw rgba(15,23,42,.18); font-size: 1.2cqw; color: #64748b; }
.mock .mcard i { display: block; width: 3cqw; height: 3cqw; border-radius: .9cqw; margin-bottom: 1.2cqw; background: linear-gradient(135deg, #c4b5fd, #93c5fd); }
.mock .mcard b { display: block; color: #0f172a; font-size: 1.45cqw; margin-bottom: .4cqw; }
.mock .mphoto { position: absolute; right: 4cqw; top: 9cqw; width: 28cqw; aspect-ratio: 4/5; border-radius: 1.6cqw; overflow: hidden;
  opacity: 0; filter: blur(20px); transform: translateY(3cqw) rotate(2deg); }
.mock .mphoto img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; }
.mock .mtag { position: absolute; right: 4cqw; top: 46cqw; font-family: var(--sans); font-size: 1.15cqw; color: var(--ink); opacity: 0; display: flex; align-items: center; gap: .6cqw; }
.mock .index { position: absolute; left: 4cqw; right: 38cqw; bottom: 4cqw; display: grid; grid-template-columns: repeat(3, 1fr); gap: 2cqw;
  border-top: 1px solid rgba(22,21,20,.15); padding-top: 1.4cqw; opacity: 0; filter: blur(10px); transform: translateY(2cqw); }
.mock .index small { display: block; font: 500 .95cqw/1 var(--sans); letter-spacing: .1em; color: var(--ink-faint); margin-bottom: .8cqw; }
.mock .index span { font-family: var(--serif); font-size: 2.3cqw; line-height: 1; color: var(--ink); }

/* step 1: strip the defaults */
.mock:not([data-step="0"]) .blob { opacity: 0; transform: scale(.8); }
[data-step="1"] .btn, [data-step="1"] .logo i { background: #e5e5e5; color: #737373; box-shadow: none; }
[data-step="1"] .h0 .pill { background: #f0f0f0; color: #a3a3a3; }
[data-step="1"] .h0 h3, [data-step="1"] .logo, [data-step="1"] .mcard b { color: #a3a3a3; }
[data-step="1"] .mcard { box-shadow: 0 0 0 1px #ededed; }
[data-step="1"] .mcard i { background: #f0f0f0; }
/* step 2: find a voice */
[data-step="2"].mock, [data-step="3"].mock { background: var(--paper); }
[data-step="2"] .h0, [data-step="3"] .h0 { opacity: 0; filter: blur(14px); transform: translateY(-2cqw) scale(.96); }
[data-step="2"] .h2 { opacity: 1; filter: none; transform: none; }
[data-step="2"] .cards, [data-step="3"] .cards { opacity: 0; filter: blur(16px); transform: translateY(4cqw); }
/* The nav's button becomes an underlined link (a text underline, so nothing bulges as the pill's corners straighten);
   the hero's buttons just fade out as they were, rather than picking up the underline on the way */
.mock .mnav .btn { text-decoration: underline 1px transparent; text-underline-offset: .3em; }
[data-step="2"] .mnav .btn, [data-step="3"] .mnav .btn { background: transparent; box-shadow: none; color: var(--ink); padding: 0; border-radius: 0; text-decoration-color: currentColor; }
[data-step="2"] .h0 .btn, [data-step="3"] .h0 .btn { background: #e5e5e5; color: #737373; box-shadow: none; }
[data-step="2"] .logo i, [data-step="3"] .logo i { width: 0; margin-right: -.6cqw; }
[data-step="2"] .logo, [data-step="3"] .logo { font-family: var(--serif); font-weight: 446; font-variation-settings: "opsz" 144, "SOFT" 96, "WONK" 0; font-optical-sizing: none; letter-spacing: -.01em; font-size: 2.2cqw; color: var(--ink); }   /* styled like the real nav's name */
[data-step="2"] .mnav, [data-step="3"] .mnav { color: var(--ink-soft); font-family: var(--sans); }
[data-step="2"] .index, [data-step="3"] .index { opacity: 1; filter: none; transform: none; transition-delay: .15s; }
/* step 3: make it yours */
/* Step 04 is drawn by the .v4 takes below; the old step-04 pieces stay hidden */
[data-step="3"] .h3 { opacity: 0; }
[data-step="3"] .mgrain { opacity: .2; }
[data-step="3"] .index { opacity: 0; filter: blur(10px); }
[data-step="3"] .index { border-color: var(--blue-ink); }

/* --- Prompt: the request that "generates" the demo below ------------------ */

/* The prompt sits at the top of where the site will be, narrower than it; then it becomes the browser: one shape that
   widens (--ox, 0 → 1) and then drops open (--oy), each on its own spring (home.js). The prompt box follows exactly the
   same outline while its words blur away and its white melts into the page beneath, so it reads as one object changing.
   (--pi: the prompt's inset either side; --ph: its height) */
@property --bx { syntax: "<number>"; inherits: false; initial-value: 0; }   /* the browser's copy: not inherited, so its */
@property --by { syntax: "<number>"; inherits: false; initial-value: 0; }   /* many children aren't restyled every frame */
.gd-right { position: relative; --ph: 112px; --pi: 14%; }
.gd-right .prompt-status.gone { opacity: 0; filter: blur(6px); animation-play-state: paused; }   /* paused: a hidden shimmer would still repaint every frame */
/* The clip-path cuts off box-shadows, so the shadow comes from a drop-shadow on a wrapper and follows the opening shape */
.browser-shadow { filter: drop-shadow(0 18px 22px rgba(40,35,30,.13)) drop-shadow(0 3px 5px rgba(40,35,30,.06)); }
.gd .browser { clip-path: inset(0 calc((1 - var(--bx)) * var(--pi)) calc((1 - var(--by)) * (100% - var(--ph))) calc((1 - var(--bx)) * var(--pi)) round calc(24px - var(--by) * (24px - var(--tune-r-demo, 14px)))); }   /* opens to 14px, or the Parameter switcher's radius */
/* Once open, the frame is a plain rounded box (same look), so the switcher's corner smoothing can reach it too */
.gd .browser.opened { clip-path: none; border-radius: var(--tune-r-demo, 14px); }
:root[style*="--corner:"] .gd .browser.opened { corner-shape: var(--corner); }
.gd-right .prompt { --ox: 0; --oy: 0; position: absolute; top: 0; z-index: 4; pointer-events: none;
  left: calc(var(--pi) * (1 - var(--ox))); right: calc(var(--pi) * (1 - var(--ox)));
  min-height: 0; height: calc(var(--ph) + (100% - var(--ph)) * var(--oy)); border-radius: calc(24px - var(--oy) * 10px);
  /* the white surface melts away as it drops open, and its lift (shadow) hands over to the browser's */
  background: rgba(255,255,255, calc(1 - clamp(0, (var(--oy) - .12) * 2.6, 1)));
  box-shadow: 0 0 0 1px rgba(15,23,42, calc(.08 * (1 - var(--oy)))), 0 24px 60px -34px rgba(40,35,30, calc(.45 * (1 - var(--ox)))); }
.gd-right .prompt.sent { transition: none; }   /* (its values change every frame now: no easing on top) */
/* its words and button lift and blur away first, as it starts to widen */
.gd-right .prompt > * { opacity: calc(1 - var(--ox) * 3.2); filter: blur(calc(var(--ox) * 8px)); translate: 0 calc(var(--ox) * -8px); }
.gd-right .prompt-status { --ox: 0; --oy: 0; position: absolute; z-index: 4; margin: 0; transition: opacity .5s var(--ease), filter .5s var(--ease);
  left: calc(var(--pi) * (1 - var(--ox)) + 4px); top: calc((var(--ph) + 14px) * (1 - var(--oy)) + (100% + 14px) * var(--oy)); }

.prompt { display: flex; align-items: flex-end; gap: 14px; min-height: 112px; padding: 20px 18px 18px 24px; background: #fff; border-radius: 24px; corner-shape: var(--corner);
  box-shadow: 0 0 0 1px rgba(15,23,42,.08), 0 24px 60px -34px rgba(40,35,30,.45); font-family: Inter, system-ui, sans-serif; color: #0f172a;
  transition: box-shadow .4s var(--ease); }
.prompt.typing { box-shadow: 0 0 0 1.5px rgba(99,102,241,.55), 0 24px 60px -34px rgba(40,35,30,.45); }
.prompt-field { flex: 1; align-self: flex-start; font-size: clamp(17px, 1.6vw, 20px); line-height: 1.45; }
.prompt-ph { color: #9ca3af; }
.prompt.typing .prompt-ph, .prompt.sent .prompt-ph { display: none; }
.prompt-caret { display: inline-block; width: 2px; height: 1.15em; margin-left: 1px; vertical-align: -.2em; background: #6366f1; animation: caret 1s steps(1) infinite; }
.prompt.sent .prompt-caret { display: none; }
@keyframes caret { 50% { opacity: 0; } }
.prompt-send { flex: none; width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center; color: #fff; background: #e5e7eb;
  transition: background .3s var(--ease), scale .25s var(--ease); }
.prompt-send svg { width: 17px; height: 17px; }
.prompt.ready .prompt-send { background: #111827; }
.prompt.pressed .prompt-send { scale: .86; }
.prompt.sent .prompt-send { background: #e5e7eb; }
.prompt-status { margin-top: 14px; padding-left: 4px; min-height: 1.4em; font: 500 14px/1.4 var(--sans); color: var(--ink-soft); display: flex; align-items: center; gap: 10px; }
.prompt-status.working { background: linear-gradient(90deg, var(--ink-soft) 0%, var(--ink-faint) 40%, var(--ink-soft) 80%) 0 0 / 200% 100%; -webkit-background-clip: text; background-clip: text;
  color: transparent; animation: shimmer 1.4s linear infinite; }
@keyframes shimmer { to { background-position: -200% 0; } }

/* Generating: a skeleton of the page with a shimmer, then the content arrives */
.mock .mnav, .mock .mhero, .mock .cards, .mock .blob { transition: opacity .7s var(--ease), translate .9s var(--ease), filter .7s var(--ease); }
.mock.generating .mnav, .mock.generating .mhero, .mock.generating .cards, .mock.generating .blob { opacity: 0; translate: 0 1.2cqw; filter: blur(6px); }
.mock.arriving .mhero { transition-delay: .15s; }
.mock.arriving .cards { transition-delay: .32s; }
.mock.arriving .blob { transition-delay: .1s; }
.mock::before { content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none; opacity: 0; transition: opacity .5s var(--ease);
  background:
    linear-gradient(100deg, transparent 35%, rgba(255,255,255,.85) 50%, transparent 65%) 0 0 / 250% 100% no-repeat,
    linear-gradient(#eef0f3, #eef0f3) 4cqw 3cqw / 10cqw 2cqw no-repeat,
    linear-gradient(#eef0f3, #eef0f3) 70cqw 3cqw / 26cqw 2cqw no-repeat,
    linear-gradient(#e7eaee, #e7eaee) 50% 12cqw / 52cqw 4.2cqw no-repeat,
    linear-gradient(#e7eaee, #e7eaee) 50% 17.5cqw / 40cqw 4.2cqw no-repeat,
    linear-gradient(#eef0f3, #eef0f3) 50% 24cqw / 34cqw 1.6cqw no-repeat,
    linear-gradient(#eef0f3, #eef0f3) 4cqw calc(100% - 4cqw) / 28.5cqw 13cqw no-repeat,
    linear-gradient(#eef0f3, #eef0f3) 50% calc(100% - 4cqw) / 28.5cqw 13cqw no-repeat,
    linear-gradient(#eef0f3, #eef0f3) calc(100% - 4cqw) calc(100% - 4cqw) / 28.5cqw 13cqw no-repeat; }
.mock.generating::before { opacity: 1; animation: skel 1.3s linear infinite; }
@keyframes skel { from { background-position: 150% 0, 4cqw 3cqw, 70cqw 3cqw, 50% 12cqw, 50% 17.5cqw, 50% 24cqw, 4cqw calc(100% - 4cqw), 50% calc(100% - 4cqw), calc(100% - 4cqw) calc(100% - 4cqw); }
                  to   { background-position: -50% 0, 4cqw 3cqw, 70cqw 3cqw, 50% 12cqw, 50% 17.5cqw, 50% 24cqw, 4cqw calc(100% - 4cqw), 50% calc(100% - 4cqw), calc(100% - 4cqw) calc(100% - 4cqw); } }

/* Entrance for the steps: they cascade in as the prompt opens into the site (home.js adds .in) */
.gd .steps button { opacity: 0; translate: 0 28px; filter: blur(10px);
  transition: opacity 1.1s var(--ease), translate 1.1s var(--ease), filter 1.1s var(--ease); }
.gd .steps li:nth-child(2) button { transition-delay: .08s; }
.gd .steps li:nth-child(3) button { transition-delay: .16s; }
.gd .steps li:nth-child(4) button { transition-delay: .24s; }
.gd.in .steps button { opacity: 1; translate: 0 0; filter: none; }

/* --- Step 04: this page, by hand -------------------------------------------- */
.mock .mnav { z-index: 2; }
.v4 { position: absolute; inset: 0; z-index: 1; opacity: 0; visibility: hidden; transition: opacity .5s var(--ease), visibility 0s .5s; pointer-events: none; }
.mock[data-step="3"] .v4-7 { opacity: 1; visibility: visible; transition: opacity .3s var(--ease); }
.v4-aura i { position: absolute; border-radius: 50%; filter: blur(5cqw); opacity: 0; }
.v4-aura i:nth-child(1) { width: 46cqw; height: 46cqw; left: 4cqw; top: -6cqw; background: var(--blue); }
.v4-aura i:nth-child(2) { width: 40cqw; height: 40cqw; right: 2cqw; top: 18cqw; background: #f2dcc4; }
.v4-copy { position: absolute; left: 5cqw; top: 16cqw; z-index: 2; font-family: var(--sans); color: var(--ink); }
.v4-copy small { display: block; font: 500 1cqw/1 var(--sans); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); }
.v4-copy h3 { font: 400 7.6cqw/.93 var(--serif); letter-spacing: -.03em; margin-top: 2.8cqw; }   /* keeps the spot the label used to hold, so the traced line still sits under the paragraph */
.v4-copy h3 span { display: inline-block; }
.v4-copy p { font: 1.55cqw/1.45 var(--sans); margin-top: 4.2cqw; }
.v4-photo { position: absolute; left: 55cqw; top: 12cqw; width: 29cqw;   /* close in to the words, not off at the far edge */ aspect-ratio: 4/5; border-radius: 1.4cqw; corner-shape: var(--corner); overflow: hidden; z-index: 2; }
.v4-photo img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; display: block; }
.v4-ink { position: absolute; left: 0; top: 0; width: 100cqw; height: 60cqw; z-index: 3; overflow: visible; fill: none; stroke: var(--blue-ink); stroke-width: 3;
  stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.v4-ink path { stroke-dasharray: 1; stroke-dashoffset: 1; }

/* Louie's own pen marks, in blue ink: a line under the paragraph, then a moustache and goatee on the photo */
.v4-line, .v4-face { position: absolute; overflow: visible; fill: none; stroke: var(--blue-ink); stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
.v4-line { left: 0; top: 3cqw; width: 100cqw;   /* moves down with the copy */ height: 60cqw; z-index: 3; stroke-width: .34; stroke: var(--ink); }
/* Same ink as the drawable pen: black with a soft light halo */
.v4-line path { filter: drop-shadow(0 0 .8px rgba(255,255,255,.95)) drop-shadow(0 0 2.5px rgba(255,255,255,.55)); }
.v4-face { inset: 0; width: 100%; height: 100%; z-index: 1; stroke-width: 1.45; stroke: #fff; }   /* white ink on the photo */
.v4-line path, .v4-face path { stroke-dasharray: 1 2; stroke-dashoffset: 1; opacity: 0; }   /* hidden until drawn: round caps would otherwise show as dots */
/* The stroke draws on with the easing; the caps stay flat until there's a real line, so the start never shows as a round dot while the ease is still slow */
@keyframes v4-ink-on { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes v4-ink-cap { 0% { opacity: 0; stroke-linecap: butt; } .1% { opacity: 1; } 25% { stroke-linecap: butt; } 25.1%, 100% { opacity: 1; stroke-linecap: round; } }
[data-step="3"] .v4-7 .v4-line path { animation: v4-ink-on .95s cubic-bezier(.3,.55,.35,1) 2.5s both, v4-ink-cap .95s linear 2.5s both; }   /* sets off quickly, then eases into the end */
[data-step="3"] .v4-7 .v4-face path:nth-child(1) { animation: v4-ink-on .7s cubic-bezier(.45,.05,.35,1) 3.9s both, v4-ink-cap .7s linear 3.9s both; }
[data-step="3"] .v4-7 .v4-face path:nth-child(2) { animation: v4-ink-on .7s cubic-bezier(.45,.05,.35,1) 4.7s both, v4-ink-cap .7s linear 4.7s both; }
[data-step="3"] .v4-7 .v4-face path:nth-child(3) { animation: v4-ink-on .35s cubic-bezier(.45,.05,.35,1) 5.5s both, v4-ink-cap .35s linear 5.5s both; }
[data-step="3"] .v4-7 .v4-face path:nth-child(4) { animation: v4-ink-on .2s cubic-bezier(.45,.05,.35,1) 5.95s both, v4-ink-cap .2s linear 5.95s both; }

/* Take 7: the world of this page, then one stroke of the pen */
[data-v="7"][data-step="3"] .v4-7 .v4-aura i { animation: v4-aura 1.6s var(--ease) .2s both, v4-drift 9s ease-in-out 1.8s infinite alternate; }
[data-v="7"][data-step="3"] .v4-7 small { animation: v4-fade .8s var(--ease) .3s both; }
[data-v="7"][data-step="3"] .v4-7 h3 span { animation: v4-word 1.1s var(--ease) both; animation-delay: calc(.4s + var(--i) * 110ms); }
[data-v="7"][data-step="3"] .v4-7 p { animation: v4-word 1.2s var(--ease) 1.5s both; }
[data-v="7"][data-step="3"] .v4-7 .v4-photo { animation: v4-paper 1.6s var(--ease) .6s both; }
[data-v="7"][data-step="3"] .v4-7 .v4-ink path { animation: v4-draw 1.5s cubic-bezier(.45,.05,.35,1) 2.4s both; }
/* Blur can't animate on the GPU, so these get their own layers: the blur updates without repainting, and the text glides instead of snapping pixel to pixel */
[data-step="3"] .v4-7 h3 span, [data-step="3"] .v4-7 p { will-change: translate, opacity, filter; }
[data-step="3"] .v4-7 .v4-photo { will-change: transform, opacity, filter; }
@keyframes v4-aura { from { opacity: 0; } to { opacity: .7; } }
@keyframes v4-drift { to { translate: 4cqw -3cqw; scale: 1.1; } }
@keyframes v4-fade { from { opacity: 0; } }
@keyframes v4-word { from { opacity: 0; filter: blur(1.2cqw); translate: 0 .25em; } }
@keyframes v4-paper { from { opacity: 0; filter: blur(2cqw) saturate(.4); transform: perspective(60cqw) translateZ(-20cqw) rotate(-10deg) scale(.7); } }
@keyframes v4-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }


/* --- Pen: a nod to the Recap After Use pen. Opens once in view, then draws a smiley --- */

.pen-track { position: relative; margin-top: -22vh; }   /* closer to the examples above */
.pen-stage { position: relative; min-height: 100vh; display: grid; align-content: center; justify-items: center; gap: 14vh;
  width: min(1100px, 100% - var(--gutter) * 2); margin: 0 auto; }
.pen-head { justify-self: stretch; max-width: 13em; }
/* From the original vectors (same scale): pen 816x83, lid 287.75x99. Lid's right edge meets the barrel at x=258.8 */
.pen { --W: min(860px, 60vw); position: relative; width: var(--W); height: calc(var(--W) * 83 / 816); }
/* Original artwork, kept as-is: black fill, cream line */
.pen-art { position: absolute; top: 0; will-change: translate, rotate; }   /* their own layers, so slow moves glide instead of stepping pixel by pixel */
.pen-body { left: 0; width: 100%; }
.pen-lid { left: -3.1%; width: 35.26%; z-index: 3; }   /* over the pen, so it covers the nib when closed; a hair further on than the artwork lines up, so no gap shows at the barrel */
.pen-body { transform-origin: .25% 48%; z-index: 2; }   /* above the ink while it draws */   /* the nib tip, so tilting while drawing pivots on it */
/* No z-index on .pen: its parts share main's layer, so ink (z 1) lands over the paragraph but under the pen (z 2-3) */
/* Free drawing: ink sits under the pen and the type, across the whole section */
.doodles { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; overflow: visible;
  fill: none; stroke: var(--ink); stroke-width: 5; stroke-linecap: round; stroke-linejoin: round; }
.pen.grabbable .pen-body { cursor: pointer; }
/* The lid can be tugged and springs back */
.pen-lid { cursor: grab; touch-action: none; }
.pen-lid.grabbing { cursor: grabbing; }
.pen.capped .pen-art, .pen.shut .pen-art { cursor: pointer; }
.pen:not(.grabbable, .capped, .shut) .pen-art { cursor: default; }   /* still closed, waiting for the scroll: nothing to pick up yet */
/* Hover: a small hint that it can be picked up. The pen lifts a hair off the paper, its shadow softening out under it; the lid
   eases a few pixels towards coming off. (Properties the pen's script doesn't touch, so they add on top of wherever it has put things) */
.pen-art { transition: filter .35s var(--ease); -webkit-user-drag: none; user-select: none; -webkit-user-select: none; }
.pen-body, .pen > .nib-ink { transition: filter .35s var(--ease), transform .45s cubic-bezier(.34,1.5,.5,1), margin .45s cubic-bezier(.34,1.5,.5,1); }
.pen-lid:not(.grabbing) { transition: filter .35s var(--ease), margin .45s cubic-bezier(.34,1.5,.5,1); }
.pen:is(.capped, .shut) .pen-lid { transition: filter .35s var(--ease), margin .45s cubic-bezier(.34,1.5,.5,1); }   /* even while it's still in your hand from putting it back on */
@media (hover: hover) {
  /* open: the pen and the lid each answer on their own (not before it has opened: until then it's just a picture) */
  html:not(.pen-held) .pen.grabbable:not(.capped, .shut) .pen-body:hover + .nib-ink { transform: translateY(-2px); }   /* the coloured tip goes with it */
  html:not(.pen-held) .pen.grabbable:not(.capped, .shut) .pen-body:hover { transform: translateY(-2px); filter: drop-shadow(0 5px 6px rgba(40,35,30,.16)); }
  html:not(.pen-held) .pen.grabbable:not(.capped, .shut) .pen-lid:not(.grabbing):hover { margin: -1px 0 0 -4px; filter: drop-shadow(0 5px 6px rgba(40,35,30,.16)); }
  /* capped: it's one object, so the whole pen lifts together */
  /* (pen, tip and lid all move by the same property, on the same curve, so they can't drift apart) */
  html:not(.pen-held) .pen:is(.capped, .shut):hover :is(.pen-body, .nib-ink, .pen-lid) { margin-top: -2px; }
  /* the same shadow as the open pen's, cast by the barrel only: it runs the full length under the cap, so the cap doesn't need
     its own (which would fall across the barrel) */
  html:not(.pen-held) .pen:is(.capped, .shut):hover .pen-body { filter: drop-shadow(0 5px 6px rgba(40,35,30,.16)); }
}

/* Pen mode: the pen is the cursor, drawings live on a page-wide layer */
.pen-held, .pen-held * { cursor: none !important; user-select: none; -webkit-user-select: none; }
.pen-held .pen-bar, .pen-held .pen-bar * { cursor: pointer !important; }
.pen-held .pen-inks, .pen-held .pen-inks * { cursor: none !important; }
.pen-held.pen-drawing { touch-action: none; }
@media (pointer: coarse) { .pen-held, .pen-held body { touch-action: none; } }
.pen-cursor { position: fixed; left: 0; top: 0; z-index: 99;   /* just under the page's grain (100), so it looks the same in the hand as lying down */ pointer-events: none; opacity: 0; will-change: translate, rotate;
  transition: scale .18s var(--ease); }   /* tilt is eased per frame in home.js, not by a transition, so it never fights itself */
.pen-held .pen-cursor { opacity: 1; }
/* Depth: in the hand the pen hovers, casting a soft shadow down and away (offsets are in the pen's own tilted frame, so they
   land roughly straight down on screen); press to draw and it meets the paper, the shadow tightening in under the nib.
   It also keeps the nib readable over an ink of its own colour */
.pen-held .pen-cursor { filter: drop-shadow(8px 6px 7px rgba(40,35,30,.2)); transition: scale .18s var(--ease), filter .3s var(--ease); }
.pen-held.pen-drawing .pen-cursor { filter: drop-shadow(3px 2px 2.5px rgba(40,35,30,.27)); transition: scale .22s var(--ease), filter .18s var(--ease); }
.pen-cursor img { width: 100%; display: block; }
.pen-cursor.lifting { transition: translate .4s var(--ease), scale .4s var(--ease); }
.pen-cursor.returning { opacity: 1; transition: translate .6s var(--ease), rotate .6s var(--ease), scale .6s var(--ease); animation: pen-land .45s var(--ease) forwards; }
@keyframes pen-land { from { filter: drop-shadow(8px 6px 7px rgba(40,35,30,.2)); } to { filter: drop-shadow(0 0 0 rgba(40,35,30,0)); } }   /* settles onto the page */
.pen-held.over-bar .pen-cursor { opacity: 0; }   /* normal cursor over the bar */
.ink-layer, .ink-local { position: absolute; left: 0; top: 0; z-index: 1; pointer-events: none; overflow: visible;
  fill: none; stroke: var(--ink); stroke-width: 5; stroke-linecap: round; stroke-linejoin: round; }
.ink-local { width: 100%; height: 100%; z-index: 50; }
.ink-layer g path { vector-effect: non-scaling-stroke; }   /* doodles scale with the page; the line keeps its weight */
/* Ink with a soft light halo: invisible on the paper, but it lifts the line off dark photos, instantly, with no colour switching */
.ink-layer path, .ink-local path { filter: drop-shadow(0 0 .8px rgba(255,255,255,.95)) drop-shadow(0 0 2.5px rgba(255,255,255,.55)); }
/* The dock holds the bar and, beside it, the floating ink pots */
.pen-dock { --spring: cubic-bezier(.32,.72,0,1);   /* a native-feeling settle: quick out, long soft landing */
  position: fixed; left: 50%; top: 13px; z-index: 98;   /* above the nav, under the pen */ display: flex; align-items: center; gap: 14px; max-width: calc(100% - 32px);
  translate: -50% calc(-100% - 60px); transition: translate .6s var(--spring); pointer-events: none; }
.pen-held .pen-dock { translate: -50% 0; }
[data-bars="bottom"] .pen-dock { top: auto; bottom: 20px; translate: -50% calc(100% + 60px); }
[data-bars="bottom"].pen-held .pen-dock { translate: -50% 0; }
.pen-dock > * { pointer-events: auto; }
/* On a phone there isn't room for the bar and the open row of colours: the bar steps aside while you choose */
@media (max-width: 560px) { .pen-dock:has(.pen-inks.open) .pen-bar { display: none; } }
.pen-bar { display: flex; align-items: center; gap: 12px; min-width: 0;
  padding: 8px 8px 8px 16px; border-radius: 999px; background: rgba(22,21,20,.92); color: var(--paper); font: 500 13px/1 var(--sans);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); box-shadow: 0 14px 40px -16px rgba(0,0,0,.5); }
.pen-bar .pb-hint { color: rgba(243,240,234,.7); white-space: nowrap; }
.pen-bar button { all: unset; cursor: pointer; font: 500 12px/1 var(--sans); white-space: nowrap; padding: 8px 12px; border-radius: 999px; background: rgba(243,240,234,.12); color: var(--paper);
  transition: background .2s, scale .25s var(--ease); }
.pen-bar button:hover { background: rgba(243,240,234,.22); }
.pen-bar button:active { scale: .95; }
.pen-bar button:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
/* The inks: a small flower of six petals with the current colour at its heart; hover and they spring out into a row (springs in home.js) */
.pen-inks { position: relative; flex: none; width: 30px; height: 30px; opacity: 0; transition: opacity .3s var(--ease) .1s; }
.pen-held .pen-inks { opacity: 1; }
/* A steady hit area: closed, the petals don't take the pointer (they lean towards the pen), this circle does */
.pen-inks::before { content: ""; position: absolute; left: -6px; top: -6px; width: 42px; height: 42px; border-radius: 21px; }
/* Open, the hover area runs on past the last colour, so drifting a little right doesn't fold it away */
.pen-inks.open::before { width: calc(100% + 52px); }
.pen-inks:not(.open) .ink-dot { pointer-events: none; }
.ink-dot { all: unset; box-sizing: border-box; position: absolute; left: 0; top: 0; width: 30px; height: 30px; border-radius: 50%; cursor: none !important; background: var(--c);
  box-shadow: inset 0 0 0 1px rgba(22,21,20,.14), 0 2px 6px -2px rgba(22,21,20,.35); will-change: transform; }
.ink-dot::after { content: ""; position: absolute; inset: -3px; border-radius: 50%; box-shadow: 0 0 0 1.5px var(--ink);   /* close to its own dot, clear of the next */ opacity: 0; scale: .8; transition: opacity .2s, scale .3s var(--ease); }
.pen-inks.open .ink-dot.on::after { opacity: 1; scale: 1; }
/* The centre of the closed flower: a thin paper ring sets it apart from the petals */
.ink-dot.core { box-shadow: 0 0 0 4px var(--paper), 0 2px 6px -2px rgba(22,21,20,.35); }
@media (max-width: 700px) { .pen-bar .pb-hint { display: none; } }
.pen-tip { position: absolute; z-index: 3; font: 500 12px/1 var(--sans); color: var(--ink-soft); pointer-events: none; white-space: nowrap;
  opacity: 0; translate: 0 6px; transition: opacity .6s var(--ease), translate .6s var(--ease); }
.pen-tip.on { opacity: 1; translate: 0 0; }
/* The shortcut, as a small key */
/* A square key, the P centred in it (measured: the same space above and below) */
.pen-tip kbd { margin-left: 5px; display: inline-grid; place-items: center; box-sizing: border-box; width: 19px; height: 19px; padding: 0; font: 500 10px/1 var(--sans); color: var(--ink-soft); border-radius: 4px; border: 1px solid var(--rule); border-bottom-width: 2px; vertical-align: middle; }
/* Hidden, and sized to nothing, until the script has measured it and hidden its strokes: otherwise, for a moment on load, it
   shows at full width, fully drawn */
.smiley:not(.ready) { visibility: hidden; width: 0; height: 0; }
.smiley { position: absolute; z-index: 1; overflow: visible; fill: none; stroke: var(--ink); stroke-width: 18; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
.pen-copy { position: absolute; top: 50%; translate: -50% -50%; width: min(560px, 38vw); margin: 0;
  font-size: clamp(20px, 2.1vw, 25px); line-height: 1.5; color: var(--ink); opacity: 0; pointer-events: none; text-wrap: pretty; }
.tune-on .pen-copy { pointer-events: auto; }   /* (it lets clicks through to the pen, except in the Inspector, where it can be picked) */

/* --- Why a designer, now ------------------------------------------------- */

.why { width: min(1240px, 100% - var(--gutter) * 2); margin: 0 auto; padding: 22vh 0 10vh; }
.why .kicker { margin-bottom: 5vh; }
.why .display { max-width: 12em; margin-bottom: 12vh; }
.reasons { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(24px, 4vw, 56px); }
.reasons div { border-top: 1px solid var(--ink); padding-top: 22px; }
.reasons small { font: 500 12px/1 var(--sans); letter-spacing: .1em; color: var(--ink-faint); }
.reasons h3 { font-family: var(--serif); font-weight: 400; font-size: clamp(36px, 3.6vw, 52px); line-height: 1; margin: 14px 0 16px; }
.reasons p { color: var(--ink-soft); font-size: 17px; max-width: 22em; }

/* --- Selected work -------------------------------------------------------- */

.work { width: min(1240px, 100% - var(--gutter) * 2); margin: 0 auto; padding: 22vh 0 12vh; scroll-margin-top: 40px; }
.work-head { display: flex; justify-content: space-between; align-items: end; gap: 24px; margin-bottom: 8vh; flex-wrap: wrap; }

.work-head p { color: var(--ink-soft); max-width: 24em; }

.project { display: block; text-decoration: none; color: inherit; }
.grid3 > .reveal:nth-child(2) { transition-delay: .12s; }   /* the three arrive one after another, like the tools */
.grid3 > .reveal:nth-child(3) { transition-delay: .24s; }
.project .shot { border-radius: 16px; overflow: hidden; background: var(--paper-deep); aspect-ratio: 16 / 10; }
.project .shot img { width: 100%; height: 100%; object-fit: cover; transition: scale 1.2s var(--ease); }
.project:hover .shot img { scale: 1.025; }
.project .meta { display: grid; grid-template-columns: 1fr auto; gap: 6px 20px; padding-top: 20px; }
.project .cat { font: 500 12px/1 var(--sans); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint); grid-column: 1 / -1; }
.project h3 { font-family: var(--serif); font-weight: 400; font-size: clamp(28px, 2.5vw, 38px); line-height: 1.05; transition: color .3s; }
.project p { color: var(--ink-soft); font-size: 16px; max-width: 30em; grid-column: 1; }
.project .go { font-size: 22px; align-self: start; padding-top: 8px; transition: color .3s; }
.project .go i { font-style: normal; display: block; }
.project:hover h3, .project:hover .go { color: var(--blue-ink); }
/* Hover: the arrow leaves the way it points and a fresh one slides in behind it (up-right for links that open elsewhere) */
.project .go { overflow: hidden; }
.project .go i { --dx: 1.1em; --dy: 0em; text-shadow: calc(var(--dx) * -1) calc(var(--dy) * -1) currentColor; transition: translate .55s var(--ease); }
.project[target] .go i { --dy: -1.1em; }
.project:hover .go i { translate: var(--dx) var(--dy); }
@media (prefers-reduced-motion: reduce) { .project .go i { transition: none !important; } }

/* Logo tile: lighten blend drops the image's own dark box into the tile colour */
.project .shot.logo { background: #2b2b2b; position: relative; }
.project .shot.logo img { position: absolute; inset: 0; margin: auto; width: auto; height: 58%; object-fit: contain; mix-blend-mode: lighten; }
.grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9vh clamp(20px, 3vw, 40px); }

/* --- Contact -------------------------------------------------------------- */

.contact { width: min(1240px, 100% - var(--gutter) * 2); margin: 0 auto; padding: 16vh 0 22vh; text-align: center; scroll-margin-top: 40px; }
.contact .display { font-size: clamp(52px, 9vw, 140px); max-width: 10em; margin: 0 auto 8vh; }
/* The underline draws in from the left once the address has faded up */
.contact .mail { font-family: var(--serif); font-size: clamp(26px, 3vw, 40px); text-decoration: none; padding-bottom: 4px;
  background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat;
  transition: color .3s, opacity 1.1s var(--ease), translate 1.1s var(--ease), background-size .9s cubic-bezier(.6,0,.2,1) .5s; }
.contact .mail.in { background-size: 100% 1px; }
.contact .mail:hover { color: var(--blue-ink); }.contact .note { margin-top: 4vh; color: var(--ink-soft); font-size: 16px; }

/* --- Small screens --------------------------------------------------------- */

@media (max-width: 860px) {
  .gd-stage { grid-template-columns: 1fr; align-content: center; gap: 24px; }
  .gd .steps { grid-template-columns: repeat(4, 1fr); gap: 10px; }
  .gd .steps span { font-size: 16px; } .gd .steps p { display: none; }
  .reasons, .grid3 { grid-template-columns: 1fr; }
  .pen { --W: 78vw; }
  .pen-copy { top: calc(100% + 7vh); translate: -50% 0; width: calc(100vw - var(--gutter) * 2); }
}
/* Phone: the pen as a close-up, bigger than the screen. The nib end sits at the left margin and the rest runs off the
   right edge; opening, the lid slides off the left (home.js). The words line up with the heading */
@media (max-width: 560px) {
  .pen-track { overflow-x: clip; }
  .pen { --W: 165vw; justify-self: start; }
  .pen-copy { translate: 0 0; }
}
@media (max-width: 700px) {
  .name { flex-direction: column; gap: 3vh; }
  .portrait { --w: 46vw; width: var(--w); height: 0; margin: -1.5vh 0; }
  .hero .lede { white-space: normal; width: calc(100% - 48px); }

  /* Hero: portrait beside the name (like the desktop), the question full width underneath */
  .hero-b .hero-b-grid { grid-template-columns: 40vw 1fr; grid-template-rows: auto auto auto; align-items: end; gap: 0 18px; width: calc(100% - var(--gutter) * 2); }
  .hero-b .hero-b-text { display: contents; }
  .hero-b .portrait { --w: 40vw; grid-column: 1; grid-row: 1 / span 2; height: calc(var(--w) * 1.25); margin: 0; }
  .hero-b .eyebrow { grid-column: 2; grid-row: 1; align-self: end; margin-bottom: 12px; }
  .hero-b .name { grid-column: 2; grid-row: 2; font-size: clamp(48px, 24vw, 120px); }   /* big, like the desktop */
  .hero-b .lede { grid-column: 1 / -1; grid-row: 3; margin-top: 4.5vh; max-width: none; font-size: 19px; }
  .cue { bottom: 4vh; }

  /* Website demo: one step at a time, clearly labelled, with the browser full width */
  .gd-stage { gap: 20px; }
  .gd .steps { display: block; min-height: 4.6em; }
  .gd .steps li { display: none; }
  .gd .steps li.on { display: block; animation: stepIn .5s var(--ease); }
  .gd .steps:not(:has(.on)) li:first-child { display: block; }
  .gd .steps small { display: inline-block; margin: 0 8px 0 0; }
  .gd .steps span { font-size: 26px; }
  .gd .steps p { display: block; font-size: 15px; margin-top: 6px; max-width: 26em; }
  .gd .browser { margin: 0 calc(var(--gutter) * -.5); }
  .prompt { min-height: 96px; padding: 16px 14px 14px 18px; border-radius: 20px; }

  /* Pen: the stage's spacing is set in index.html */
  .pen-tip { white-space: nowrap; }

  /* The top edge on a small screen (see site.css): frosted behind the nav, fading out below */
  .edge { height: var(--edge-h, 120px); }
}
@keyframes stepIn { from { opacity: 0; translate: 0 6px; filter: blur(4px); } }



/* The tip of the held pen, in the current ink */
:root { --nib: var(--ink); }
.pen-cursor .nib-ink { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.pen > .nib-ink { position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: 2; pointer-events: none; transform-origin: .25% 48%; will-change: translate, rotate; }   /* a layer like the body's, so the two move in step */
.pen.capped > .nib-ink, .pen.shut > .nib-ink, .pen.lid-up > .nib-ink { z-index: 2; }
:is(.pen-cursor, .pen) .nib-ink path { fill: var(--nib); stroke: var(--nib); stroke-width: 2.6; transition: fill .25s, stroke .25s; }   /* stroked in the ink too, so it covers the drawn outline: just the colour */
:is(.pen-cursor, .pen) .nib-ink .nib-join { stroke: #0b0b0b; stroke-width: 1.6; }   /* a black line where the coloured tip meets the pen, joining its two outlines */
/* Near the lid the held pen moves into the page's layer, just under the lid */
.pen-cursor.by-lid { z-index: 4; }
.pen.lid-up .pen-lid { z-index: 5; }




/* Phones and touch screens: the background light stays still, drawn as soft gradients rather than live-blurred
   shapes, and the intro line focuses in without a blur (see the note in site.css) */
@media (hover: none), (max-width: 700px) {
  .aura i:nth-child(n) { filter: none; animation: none; will-change: auto; background: radial-gradient(closest-side, var(--c-aura), transparent); scale: 1.6; }
  .aura i:nth-child(1) { --c-aura: var(--light-1, var(--blue)); }
  .aura i:nth-child(2) { --c-aura: var(--light-2, #f2dcc4); }
  .aura i:nth-child(3) { --c-aura: var(--light-3, #c9def0); }
  .hero .lede .lw { filter: none; }
  .card { filter: none !important; }
}
