/* Shared by every page. The per-page sheet that follows it may override these rules:
   css/home.css on the home page, css/legal.css on the legal pages and 404. */
/* Layout: one calm codex folio on parchment. A fine construction grid holds a single ink drawing per screen; text sits in a precise two-column grid beside it. Single committed light look: ink, parchment, one red-chalk accent. */
:root {
  --parch: #F4ECDC;
  --parch-2: #EADFC8;
  --ink: #2A2018;
  --ink-2: #574837;
  --rule: #CDBD9F;
  --red: #9E3B24;
  --on-ink: #F4ECDC;
  --chalk: #E9A58F;
  --display: "Cormorant Garamond", "Iowan Old Style", Garamond, Georgia, serif;
  --text: "Source Serif 4", "Iowan Old Style", Georgia, serif;
  --ease: cubic-bezier(.16, 1, .3, 1);
  --gutter: clamp(16px, 5vw, 72px);
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .35  0 0 0 0 .25  0 0 0 0 .12  0 0 0 .07 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  color-scheme: light;
}
* { box-sizing: border-box }
html { scroll-behavior: auto; background: var(--parch) }
body {
  margin: 0;
  background-color: var(--parch);
  background-image: var(--grain), radial-gradient(120% 90% at 50% 30%, transparent 60%, rgba(120, 90, 50, .10) 100%);
  color: var(--ink);
  font-family: var(--text);
  font-size: 18px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
a { color: inherit }
:focus-visible { outline: 2px solid var(--red); outline-offset: 3px }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; padding: 0 }
.wrap { max-width: 1240px; margin-inline: auto; padding-inline: var(--gutter) }
/* the shell the header, the hero band, the quotes, the founders and the contact band share,
   so their edges line up and the logo stands left of the Fix it button (#27) */
:root { --shell: 1600px }
.top .wrap, .hero-play, .hero-foot, #clients .wrap, #founders .wrap, #contact .wrap, footer .wrap { max-width: var(--shell) }
.label { font-family: var(--text); font-size: 14px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-2) }

/* header */
.top { position: absolute; inset: 0 0 auto 0; z-index: 20; padding-top: env(safe-area-inset-top, 0px) }
.top .wrap { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding-block: 20px }
.wordmark { display: flex; align-items: center; text-decoration: none; padding-block: 6px }
.wordmark svg { display: block; height: 26px; width: auto }
.top nav { display: flex; gap: 28px; align-items: center }
.top nav a { text-decoration: none; padding-block: 10px; font-size: 16px; font-weight: 600; letter-spacing: .04em }
.top nav a:hover { color: var(--red) }
.top nav .cta { padding: 9px 20px; border: 1px solid var(--ink); border-radius: 999px }
.top nav .cta:hover { border-color: var(--red) }

/* hero */
/* no 100svh floor: the stage is capped at the machine's own ratio, so a floor taller than what
   the hero holds would only leave a blank band under the caption on a narrow screen (#27) */
#hero.zooming { overflow: clip }
#hero { --live: 0; position: relative; display: grid; grid-template-rows: auto auto auto; align-content: start; padding-top: calc(80px + env(safe-area-inset-top, 0px)); padding-bottom: 8px }

h1 { margin: 0; font-family: var(--display); font-weight: 600; font-size: clamp(2.2rem, 4.6vw, 4.4rem); line-height: 1.02; letter-spacing: -.005em; text-wrap: balance }
h1 .l2 { display: block; font-style: italic; font-weight: 500; color: color-mix(in oklch, var(--red) calc(var(--live) * 100%), var(--ink-2)) }
/* every step holds its own place in the row from the press on and is only hidden until the repair
   reaches it, so a step arriving later moves nothing below it (#27) */
.step { display: grid; gap: 2px; min-width: 0; opacity: 0; visibility: hidden; transform: translateY(10px); transition: opacity .45s ease, transform .45s ease }
.step.on { opacity: 1; visibility: visible; transform: none }
.step b { font-family: var(--display); font-style: italic; font-weight: 600; font-size: clamp(16px, 1.3vw, 21px); line-height: 1.1; color: var(--red) }
.step .t { display: block; font-family: var(--display); font-weight: 600; font-size: clamp(13px, 1.05vw, 16px); line-height: 1.26; text-wrap: balance }
.step.is-fault .t { color: var(--red) }
.hero-head { display: grid; grid-template-columns: minmax(0, 1fr); align-items: start; gap: 24px; padding-top: clamp(8px, 3vh, 36px) }
/* a stated width, so the measured margin that puts the button on its label cannot widen a
   fit-content wrap and move the button with it */
.hero-play { display: grid; grid-template-columns: minmax(0, 1fr); align-items: start; gap: 18px; margin-top: 20px; width: 100% }
.hero-run { display: grid; grid-template-columns: minmax(0, 1fr); align-items: center }
/* one row of five under the drawing and as wide as the drawing itself, which home.js measures into
   --draw-w: the viewBox is letterboxed inside the stage, so a row on the stage's own edges would
   start far left of the machine. The floor keeps five columns readable where the drawing is
   narrower than the text needs; both are centred in the same box, so the row stays under it. The
   page gutter beats them both: the stage runs full bleed, the text must not (#27) */
.steps { list-style: none; margin: 12px auto 0; padding: 0; width: max(var(--draw-w, 100%), 720px); max-width: calc(100% - 2 * var(--gutter)); grid-template-columns: repeat(5, minmax(0, 1fr)); gap: clamp(10px, 1.4vw, 22px); align-items: start }
/* the button stands directly above the Stuck here label and left-aligned with it: both offsets
   are measured in home.js, since the label rides the SVG and moves with its scale (#27) */
.hero-go { position: relative; z-index: 1; margin: 0 }
/* the steps are off the page until Fix it plays the repair, then they stay (#27) */
#hero .steps { display: none }
#hero.fixed .steps { display: grid }
/* the backstop in the same scope: where motion is unwelcome the step is simply there */
.motion-off .step { transition: none }
@media (prefers-reduced-motion: reduce) { .step { transition: none } }

/* The stage keeps a floor, so the machine stays readable once the steps take the head's room. The
   width is stated and the minimum cleared, so the ratio only ever derives the height: the other way
   round the min-height made the stage wider than a phone screen and Chrome shrank the page to fit. */
/* --stage-h is measured: the viewport minus the fixed bar, the steps, the button and the
   bottom line. Without script the ratio still gives the height. */
.stage { position: relative; width: 100%; min-width: 0; margin-top: 14px; isolation: isolate; aspect-ratio: 1200 / 640; height: var(--stage-h, auto); min-height: 150px; max-height: var(--stage-h, 70svh) }
.stage::before { content: ""; position: absolute; inset: 0 var(--gutter); z-index: -1; pointer-events: none;
  background-image:
    linear-gradient(rgba(42, 32, 24, .085) 1px, transparent 1px),
    linear-gradient(90deg, rgba(42, 32, 24, .085) 1px, transparent 1px),
    linear-gradient(rgba(42, 32, 24, .04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(42, 32, 24, .04) 1px, transparent 1px);
  background-size: 120px 120px, 120px 120px, 24px 24px, 24px 24px;
  background-position: center;
  -webkit-mask-image: radial-gradient(70% 75% at 50% 50%, #000 40%, transparent 100%);
  mask-image: radial-gradient(70% 75% at 50% 50%, #000 40%, transparent 100%) }
#machine { display: block; width: 100%; height: 100%; overflow: visible }
.ln { fill: none; stroke: var(--ink); stroke-width: 2; stroke-linecap: round }
.cons { fill: none; stroke: var(--ink); stroke-opacity: .28; stroke-width: 1; stroke-dasharray: 6 5 }
.hair { fill: none; stroke: var(--ink); stroke-opacity: .22; stroke-width: 1 }
.teeth { fill: var(--ink); fill-rule: evenodd; stroke: none }
.rot { filter: url(#wobble) }
.hz { fill: url(#hatch); stroke: none; opacity: .55 }
.fault .ln { stroke: var(--red) }
.fault .teeth { fill: var(--red) }
.fault .hz { fill: url(#hatch-red); opacity: .8 }
.qdisc { fill: var(--ink) }
/* --u is the drawing's fit, so 14.5px * --u holds a label at 14.5px on screen however small the
   machine is drawn. The labels sit at fixed points of the viewBox, so past 52 of its units two of
   them touch — "Q core: the part we build" reaches "Work in" — whatever the screen: 46 units is the
   ceiling, and on a short phone the labels give up screen size rather than room (#40). */
.lbl { font-family: var(--text); font-weight: 600; font-size: max(19px, min(calc(14.5px * var(--u, 1)), 46px)); fill: var(--ink) }
.lbl.red { fill: var(--red) }
.lbl.sub { font-weight: 400; font-style: italic; fill: var(--ink-2) }
.leader { fill: none; stroke: var(--ink-2); stroke-width: 1.2; stroke-dasharray: 2 5; stroke-linecap: round }
.leader.red { stroke: var(--red) }
.belt { fill: none; stroke: var(--ink); stroke-width: 2 }
.paper rect { fill: var(--parch); stroke: var(--ink); stroke-width: 1.6 }
.paper line { stroke: var(--ink-2); stroke-width: 1.4 }
.paper.stuck rect { stroke: var(--red); stroke-width: 2.4 }
.lamp { fill: var(--red) }
.hero-foot { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding-block: 12px 20px; color: var(--ink-2); font-size: 15px }
.hero-foot .fig { font-style: italic }
.motion { margin-left: auto; padding: 6px 14px; border: 1px solid var(--ink); border-radius: 999px; background: none; color: inherit; font: inherit; font-weight: 600; cursor: pointer }
.motion:hover { border-color: var(--red); color: var(--red) }
.motion:focus-visible { outline: 2px solid var(--red); outline-offset: 3px }

/* sections */
section.block { padding-block: clamp(80px, 11vw, 140px) }
h2 { margin: 0; font-family: var(--display); font-weight: 600; font-size: clamp(2.3rem, 4.6vw, 3.8rem); line-height: 1.04; text-wrap: balance }
h2 em { color: var(--red); font-weight: 500 }
.lede { color: var(--ink-2); max-width: 58ch; margin: 16px 0 0; text-wrap: pretty }

/* work */
.group { margin-top: 52px }
.group h3 { margin: 0 0 16px; display: flex; align-items: center; gap: 14px }
.group h3::after { content: ""; flex: 1; height: 1px; background: var(--rule) }
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); gap: 28px }
.tile { position: relative; z-index: 1; text-decoration: none; color: inherit; display: flex; flex-direction: column; width: 100%; background: var(--parch); border: 1px solid var(--rule); transition: transform .5s var(--ease), box-shadow .4s, border-color .3s }
.tile .pic { position: relative; aspect-ratio: 16 / 10; max-width: 100%; border-bottom: 1px solid var(--rule); overflow: hidden; display: grid; place-items: center;
  background-image: linear-gradient(rgba(42, 32, 24, .05) 1px, transparent 1px), linear-gradient(90deg, rgba(42, 32, 24, .05) 1px, transparent 1px); background-size: 24px 24px }
.tile .sketch { width: 62%; height: auto; transition: opacity .25s; filter: url(#wobble) }
.tile .sketch path { fill: none; stroke: var(--ink); stroke-width: 1.6; stroke-linecap: round }
.tile .sketch .hot { stroke: var(--red) }
.tile .chip { position: absolute; top: 12px; left: 14px; z-index: 2; font-size: 14px; font-style: italic; color: var(--red) }
.tile .meta { display: grid; grid-template-columns: minmax(0, 1fr) auto }
.tile .meta-l { display: grid; gap: 4px; padding: 16px 18px; border-right: 1px solid var(--rule); min-width: 0 }
.tile .name { font-family: var(--display); font-weight: 600; font-size: 28px; line-height: 1.1 }
.tile .client { color: var(--ink-2); font-size: 15px; font-weight: 600; letter-spacing: .02em }
.tile .line { color: var(--ink-2); font-size: 16px }
.tile .code { padding: 16px 18px; font-family: var(--display); font-style: italic; font-size: 20px; color: var(--ink-2) }
.tile .open { font-size: 15px; font-weight: 600; color: var(--red); opacity: 0; transition: opacity .25s .1s }
.app { position: absolute; inset: 12px; display: flex; flex-direction: column; background: var(--parch); color: var(--ink); font-family: var(--text); font-size: 12px; line-height: 1.3; border: 1px solid var(--ink); opacity: 0; transform: scale(.96); transition: opacity .3s .08s, transform .5s var(--ease) }
.app .bar { display: flex; justify-content: space-between; padding: 5px 8px; background: var(--ink); color: var(--on-ink); font-size: 11.5px; letter-spacing: .06em }
.app .bar em { font-style: italic }
.app .body { flex: 1; display: grid; min-height: 0 }
.app .col { padding: 8px; display: flex; flex-direction: column; gap: 5px; min-width: 0 }
.app .pill { padding: 3px 6px; background: var(--parch-2); font-weight: 600 }
.app .pill.on { background: var(--ink); color: var(--on-ink) }
.app .pill.next { background: transparent; border: 1px dashed var(--red); color: var(--red) }
.app .row { height: 6px; background: var(--rule) }
.app .go { margin-top: auto; align-self: flex-end; padding: 4px 8px; background: var(--red); color: var(--on-ink); font-weight: 600 }
.app .kv { display: flex; justify-content: space-between; gap: 8px }
.app .kv i { display: block; background: var(--rule) }
.app .ask { border: 1px solid var(--ink); padding: 4px 6px; color: var(--ink-2) }
@media (hover: hover) {
  .tile:hover, .tile:focus-visible { transform: translateY(-4px) scale(1.04); z-index: 40; border-color: var(--ink); box-shadow: 0 24px 50px rgba(60, 40, 20, .18) }
  .tile:hover .sketch, .tile:focus-visible .sketch { opacity: 0 }
  .tile:hover .app, .tile:focus-visible .app { opacity: 1; transform: none }
  .tile:hover .open, .tile:focus-visible .open { opacity: 1 }
}
@media (hover: none) { .tile .open { opacity: 1 } }

/* project page */
dialog#project { position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; background: var(--parch); color: var(--ink); overflow-y: auto; overscroll-behavior: contain }
dialog#project::backdrop { background: transparent }
.pp { padding-block: calc(28px + env(safe-area-inset-top, 0px)) 80px }
.pp-top { display: flex; justify-content: space-between; align-items: center; gap: 16px }
.pp-back { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; font-size: 16px; font-weight: 600 }
.pp-back:hover { color: var(--red) }
.pp h2 { font-size: clamp(2.8rem, 7vw, 5.6rem); margin-top: 36px }
.pp .one { font-size: clamp(19px, 2vw, 22px); color: var(--ink-2); margin: 12px 0 0; font-style: italic }
.pp-client, .pp-owner { margin: 10px 0 0; color: var(--ink-2); font-size: 17px }
.pp-client strong, .pp-owner strong { color: var(--ink); font-weight: 600 }
/* a class that sets `display` beats the browser's own [hidden] rule, and an empty bordered row or an
   unbacked demo box would stay on the page */
.pp-about[hidden], .pp-grid[hidden], .pp-demo[hidden], .pp-about > div[hidden] { display: none }
.pp-media[hidden], .pp-thumbs[hidden] { display: none }
.pp-about { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr)); column-gap: clamp(0px, 3vw, 34px); margin-top: 44px; border-top: 1px solid var(--ink) }
.pp-about > div { padding: clamp(20px, 2.6vw, 30px) 0; border-bottom: 1px solid var(--rule); min-width: 0 }
.pp-about h3 { margin: 0 0 10px }
.pp-text { margin: 0; color: var(--ink-2); font-size: clamp(17px, 1.6vw, 19px); line-height: 1.6; text-wrap: pretty }
.pp-list { margin: 0; padding-left: 1.1em; color: var(--ink-2); font-size: clamp(17px, 1.6vw, 19px); line-height: 1.6 }
.pp-list li { margin-bottom: 8px; text-wrap: pretty }
.pp-list li::marker { color: var(--red) }
.pp-tag { display: inline-block; padding: 4px 14px; border: 1px solid var(--rule); border-radius: 999px; background: var(--parch-2); color: var(--ink); font-size: 16px }
.pp-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); margin-top: 44px; border-top: 1px solid var(--ink) }
.pp-grid > div { padding: clamp(22px, 3vw, 34px) 0; border-bottom: 1px solid var(--rule); min-width: 0 }
.pp-grid > div + div { padding-left: clamp(0px, 3vw, 34px) }
.pp-grid h3 { margin: 0 0 12px }
.pp-quote { font-family: var(--display); font-weight: 500; font-size: clamp(22px, 2.4vw, 28px); line-height: 1.35; margin: 0 }
.pp-demo { position: relative; aspect-ratio: 16 / 9; max-width: 100%; border: 1px solid var(--rule); margin-top: 28px; display: grid; place-items: center; background: var(--parch-2) }
.pp-demo button { width: 84px; height: 84px; border: 1px solid var(--ink); border-radius: 50%; display: grid; place-items: center; background: var(--parch) }
.pp-demo span { position: absolute; left: 14px; bottom: 12px; color: var(--ink-2); font-size: 15px }
.pp-result { font-family: var(--display); font-weight: 600; font-size: clamp(56px, 8vw, 96px); line-height: 1; color: var(--red) }
/* the product's own screens: one large, the rest as thumbnails that swap into it */
.pp-media { margin-top: 44px; padding-top: clamp(22px, 3vw, 34px); border-top: 1px solid var(--ink) }
.pp-media h3 { margin: 0 0 14px }
.pp-shot { margin: 0 }
.pp-stage { border: 1px solid var(--rule); background: var(--parch-2); line-height: 0 }
.pp-stage img, .pp-stage video { display: block; width: 100%; height: auto; max-width: 100% }
/* a phone screen is taller than it is wide: cap it and centre it, never stretch it across the page */
.pp-stage img.portrait { width: auto; max-height: 70vh; margin-inline: auto }
.pp-shot figcaption { margin: 10px 0 0; color: var(--ink-2); font-size: 16px; line-height: 1.5; text-wrap: pretty }
.pp-thumbs { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 16px }
.pp-thumb { width: clamp(96px, 18vw, 150px); padding: 0; border: 1px solid var(--rule); background: var(--parch-2); cursor: pointer; line-height: 0; transition: border-color .2s }
.pp-thumb img { display: block; width: 100%; height: auto; max-height: 160px; object-fit: cover; object-position: top }
.pp-thumb:hover { border-color: var(--ink) }
.pp-thumb[aria-pressed="true"] { border-color: var(--red); box-shadow: 0 0 0 1px var(--red) }
.pp-next { margin-top: 28px; padding: clamp(24px, 4vw, 44px); background: var(--ink); color: var(--on-ink); display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 20px }
.pp-next p { margin: 0; font-family: var(--display); font-weight: 600; font-size: clamp(26px, 3vw, 38px); line-height: 1.1 }

/* buttons */
.btn { display: inline-flex; align-items: center; gap: 10px; min-height: 52px; padding: 0 28px; font-size: 17px; font-weight: 600; letter-spacing: .03em; text-decoration: none; border-radius: 999px; transition: background-color .2s, color .2s }
.btn.accent { background: var(--red); color: var(--on-ink) }
.btn.accent:hover { background: #82301C }

/* results */
/* the whole section reads down the middle; only the rules run the full width */
#clients .wrap { text-align: center }
.carousel { margin-top: 48px; border-top: 1px solid var(--ink); border-bottom: 1px solid var(--rule); overflow: hidden }
.track { display: flex; transition: transform .9s cubic-bezier(.7, 0, .2, 1) }
.slide { flex: 0 0 100%; min-width: 0; min-height: 300px; padding: clamp(24px, 5vw, 56px) 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; align-items: center; justify-items: center; text-align: center }
.slide .quote { margin: 0 auto; max-width: 66ch; font-family: var(--display); font-style: italic; font-weight: 500; font-size: clamp(22px, 2.3vw, 29px); line-height: 1.32; text-wrap: pretty }
/* the author reads in the hand of the drawing’s own labels, the red of "Stuck here" */
.slide .who { margin-top: 18px; font-family: var(--text); font-weight: 600; font-size: 19px; color: var(--red) }
.ctrl { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 12px 24px; margin-top: 14px }
.dots { display: flex }
.dots button { width: 44px; height: 44px; display: grid; place-items: center }
.dots button i { display: block; width: 9px; height: 9px; border-radius: 50%; border: 1px solid var(--ink-2); transition: background-color .3s }
.dots button[aria-current="true"] i { background: var(--red); border-color: var(--red) }
#pause { width: 44px; height: 44px; display: grid; place-items: center; border: 1px solid var(--rule); border-radius: 50%; font-size: 13px; line-height: 1 }
#pause:hover { border-color: var(--ink) }

/* who + talk */
.who-grid { display: grid; grid-template-columns: minmax(0, 1fr); justify-items: center; text-align: center; gap: clamp(24px, 3vw, 36px) }
.who-grid p { margin: 0 auto; font-size: clamp(19px, 1.8vw, 23px); line-height: 1.6; max-width: 66ch; text-wrap: pretty }
/* four portraits shot in four studios: one tone, one frame and one size make them one row */
.team { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px 24px; width: min(100%, 720px) }
@media (max-width: 560px) { .team { grid-template-columns: repeat(2, minmax(0, 1fr)) } }
.team li { display: grid; gap: 10px; justify-items: center; align-content: start; text-align: center }
.team li a { display: grid; gap: 10px; justify-items: center; color: inherit; text-decoration: none }
.team li a:hover .name { color: var(--red) }
.team li a:focus-visible { outline: 2px solid var(--red); outline-offset: 4px }
.team img {
  /* a grid item stretches by default, which would draw the circle as an ellipse */
  align-self: start; width: 100%; max-width: 116px; height: auto; aspect-ratio: 1; border-radius: 50%; object-fit: cover;
  background: var(--parch-2); border: 1px solid var(--rule);
  filter: grayscale(1) sepia(.34) contrast(1.06) brightness(1.04);
}
.team .name { font-family: var(--display); font-size: clamp(17px, 1.4vw, 20px); font-weight: 600; line-height: 1.25 }
.xp { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; min-width: 0; padding-top: 22px; border-top: 1px solid var(--rule) }
/* the label and the strip stay in the source and render nowhere: a class beats [hidden] on its own (#27) */
.xp[hidden] { display: none }
.xp-label { margin: 0; font-family: var(--text); font-size: 15px; font-weight: 600; letter-spacing: .04em; color: var(--ink-2) }
/* the strip runs on transform only, and the edges fade so a name never ends mid-letter against the page */
.xp-run { display: flex; width: 100%; max-width: 100%; min-width: 0; overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent) }
.xp-names { list-style: none; margin: 0; padding: 0; display: flex; flex: 0 0 auto; align-items: baseline; white-space: nowrap; font-size: 17px; line-height: 1.5; will-change: transform; animation: xp-run 44s linear infinite }
.xp-names li::after { content: '·' / ''; color: var(--rule); padding-inline: .55em }
.xp-run:hover .xp-names { animation-play-state: paused }
@keyframes xp-run { to { transform: translateX(-100%) } }
/* still and wrapped where motion is unwelcome, with the loop's second copy out of the way */
.motion-off .xp-run { overflow: visible; -webkit-mask-image: none; mask-image: none }
.motion-off .xp-names { flex: 0 1 auto; flex-wrap: wrap; white-space: normal; animation: none }
.motion-off .xp-copy { display: none }
.motion-off .xp-names li:last-child::after { content: none }
@media (prefers-reduced-motion: reduce) {
  .xp-run { overflow: visible; -webkit-mask-image: none; mask-image: none }
  .xp-names { flex: 0 1 auto; flex-wrap: wrap; white-space: normal; animation: none }
  .xp-copy { display: none }
  .xp-names li:last-child::after { content: none }
}
#contact { background: var(--ink); color: var(--on-ink); padding-block: clamp(64px, 9vw, 110px) }
/* centred like the quotes and the Founders above it; the fields keep a left edge to read down (#27) */
#contact .wrap { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 28px; text-align: center }
#contact h2 em { color: var(--on-ink) }
#contact .mail { font-size: 19px; margin: 12px 0 0; user-select: all }
#contact .reply { margin: 4px 0 0; font-size: 16px; opacity: .75 }
.topic { display: flex; flex: 1; justify-content: space-between; align-items: baseline; gap: 16px; padding-block: 14px; text-decoration: none }
.topic:hover, .topic:focus-visible { color: var(--red) }
.topic:hover span, .topic:focus-visible span { color: var(--red) }
.talk { flex: 1 1 100%; max-width: 820px; margin-inline: auto; text-align: left; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 28px; margin-top: 40px; padding-top: 32px; border-top: 1px solid rgba(244, 236, 220, .25) }
.talk[hidden] { display: none }
.talk .full { grid-column: 1 / -1 }
.talk label { display: grid; gap: 6px; font-size: 15px; font-weight: 600; letter-spacing: .03em }
.talk input, .talk select, .talk textarea { font: 400 17px/1.4 var(--text); color: var(--on-ink); background: rgba(244, 236, 220, .06); border: 1px solid rgba(244, 236, 220, .35); border-radius: 4px; padding: 12px 14px; min-height: 48px; width: 100%; min-width: 0 }
.talk select option { color: var(--ink); background: var(--parch) }
.talk :focus-visible { outline: 2px solid var(--parch); outline-offset: 2px }
.talk [aria-invalid="true"] { border-color: #E08A6E }
.talk .hint { margin: -6px 0 0; font-style: italic; opacity: .8 }
.talk .send { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 20px }
.talk .sent { margin: 0; font-size: 16px }
.talk > .hint:last-child { text-align: center }
@media (max-width: 760px) { .talk { grid-template-columns: minmax(0, 1fr) } }
footer { padding-block: 28px calc(28px + env(safe-area-inset-bottom, 0px)) }
footer .wrap { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 16px; color: var(--ink-2); font-size: 16px }
footer nav { display: flex; flex-wrap: wrap; gap: 24px }
.foot-co { flex: 1 0 100%; order: 3; margin: 0; font-size: 14px; color: var(--ink-2) }
footer nav a { padding-block: 10px; text-decoration: none }
footer nav a:hover { color: var(--red) }

@media (max-width: 760px) {
  .hero-head { gap: 16px }
  .pp-grid > div + div { padding-left: 0 }
  .top nav .hide-sm { display: none }
  .hero-foot .fig { display: none }
  /* a phone has no room for five columns: a compact list, numeral beside the line it numbers,
     its edges on the drawing's own, with a little air so no letter touches the screen */
  .steps { width: var(--draw-w, auto); padding-inline: 8px; grid-template-columns: minmax(0, 1fr); gap: 7px }
  .step { grid-template-columns: 22px minmax(0, 1fr); gap: 8px; align-items: baseline }
  .step b { font-size: 17px }
  .step .t { font-size: 14px; line-height: 1.3; text-wrap: initial }
}
/* a laptop screen that is short rather than narrow has the same problem: the row is five columns
   wide and the machine needs its height, so the type tightens before either gives way (#27) */
@media (min-width: 761px) and (max-height: 800px) {
  .steps { margin-top: 8px }
  .step .t { font-size: 13px; line-height: 1.2 }
  .step b { font-size: 15px }
  .hero-foot { padding-block: 8px 14px }
}
/* a short phone screen still has to hold the whole block: the rhythm tightens, rather than the
   machine shrinking further or a step going unread (#27) */
@media (max-width: 760px) and (max-height: 720px) {
  .hero-head { padding-top: 8px; gap: 12px }
  .hero-play { margin-top: 12px }
  .stage { margin-top: 8px }
  .steps { margin-top: 8px; gap: 5px }
  .step .t { font-size: 13px; line-height: 1.26 }
  .hero-foot { padding-block: 8px 12px }
}
.motion-off :is(.tile, .tile .app, .tile .sketch, .track) { transition: none }
/* the quotes still take their turns, they just do not slide (#27) */
@media (prefers-reduced-motion: reduce) { .track { transition: none } }

/* Variant L: B's codex on the blueprint grid, with the arcane machine of J. */
:root { --hex: #19B6DA; --hex-hi: #EAFFFF; --hex-ink: #0A6F8C; --run: var(--red); --page: var(--parch); --soft: #CC8A63; --strong: #B4471F }
h1 { font-size: clamp(2.5rem, 5vw, 4.8rem) }
/* a turbulence filter on a wheel that turns every frame is re-rendered every frame: the wheels go without it */
.rot { filter: none }
h1 .l2 { --final: 0; font-size: .86em; color: color-mix(in oklch, var(--strong) calc(var(--final) * 100%), var(--soft)); text-shadow: 0 0 calc(var(--final) * 22px) rgba(180, 71, 31, calc(var(--final) * .3)) }
.step .t { margin-top: 2px }
/* the power-up look Robert kept (#27); the glow moves by transform and opacity only, so the
   compositor runs it without repainting the page */
.solve { position: relative; isolation: isolate; display: inline-flex; align-items: center; gap: 8px; min-height: 42px; padding: 0 20px 0 16px; margin-bottom: 2px; border: 0; border-radius: 999px; font-family: var(--display); font-weight: 700; font-size: 19px; letter-spacing: .03em; color: #EAFFFF; background: linear-gradient(100deg, #083247 0%, #0A6F8C 40%, #0A6F8C 60%, #083247 100%); box-shadow: 0 0 0 1px #0A6F8C, 0 0 18px rgba(25, 182, 218, .5); text-shadow: 0 0 8px rgba(127, 243, 255, .9); cursor: pointer; transition: transform .2s }
.solve::after { content: ""; position: absolute; inset: 0; z-index: -2; border-radius: inherit; box-shadow: 0 0 0 1px #19B6DA, 0 0 36px rgba(25, 182, 218, .9), inset 0 0 6px rgba(234, 255, 255, .6); opacity: 0; will-change: opacity; animation: hum 1.5s ease-in-out infinite }
.solve .sheen { position: absolute; inset: 0; z-index: -1; border-radius: inherit; overflow: hidden; pointer-events: none }
.solve .sheen::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 70%; background: linear-gradient(100deg, rgba(127, 243, 255, 0), rgba(127, 243, 255, .85) 50%, rgba(127, 243, 255, 0)); transform: translateX(-100%); will-change: transform; animation: surge 2.2s linear infinite }
.solve svg { filter: drop-shadow(0 0 5px #7FF3FF) }
.solve:hover { transform: translateY(-2px) }
.solve:focus-visible { outline: 2px solid var(--red); outline-offset: 4px }
@keyframes surge { from { transform: translateX(-100%) } to { transform: translateX(150%) } }
@keyframes hum { 50% { opacity: 1 } }
/* the button keeps its colours when motion is unwelcome; only the glow and the sheen hold still */
.motion-off .solve::after, .motion-off .solve .sheen::before { animation: none }
@media (prefers-reduced-motion: reduce) {
  .solve::after, .solve .sheen::before { animation: none }
}
.fx { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 2 }
.qbody { transform-box: fill-box; transform-origin: center; opacity: 0 }
.qgear .housing { fill: url(#housing) }
.qgear .coils rect { fill: url(#copper); stroke: #2A1606; stroke-width: .8 }
.qgear .teeth { fill: var(--ink) }
.qgear .ln { stroke: var(--ink) }
.qgear .core { opacity: 0 }
.corering { fill: none; stroke: var(--hex-hi); stroke-width: 2.4 }
/* a blur filter next to wheels that turn every frame is re-run every frame: the glow is stacked strokes */
.core .glow { fill: none; stroke: var(--hex); stroke-linejoin: round }
.core .g1 { stroke-width: 9; stroke-opacity: .22 }
.core .g2 { stroke-width: 5; stroke-opacity: .4 }
#tagStuck .arrow { fill: none; stroke: var(--red); stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round }
#tagJam .lbl { transition: fill .3s }
#tagJam.hot .lbl { fill: var(--red) }
#tagJam.hot .leader { stroke: var(--red) }
.lbl.q { fill: var(--hex-ink) }
.top { position: fixed; --on: 0; background: rgba(244, 236, 220, .96); border-bottom: 1px solid rgba(205, 189, 159, .6) }
.top .wrap { padding-block: 14px }
/* the logo stays ink; once the machine runs, the call to talk takes the orange of the solved line */
.wordmark { color: var(--ink) }
.top nav .cta { border-color: color-mix(in oklch, var(--strong) calc(var(--on) * 100%), var(--ink)); color: color-mix(in oklch, var(--strong) calc(var(--on) * 100%), var(--ink)) }
section.block, #contact { scroll-margin-top: 76px }
.wordmark svg.inline { height: 38px; width: auto; overflow: visible }
.wordmark svg use, .foot-mark use, .qfix use { fill: currentColor }
#hero { padding-top: calc(88px + env(safe-area-inset-top, 0px)) }
.qfix { position: fixed; z-index: 30; color: var(--ink); line-height: 0 }
.qfix svg { display: block; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 0 5px var(--parch)) drop-shadow(0 0 2px var(--parch)) }
.qfix::before { content: ""; position: absolute; inset: -10px -16px; z-index: -1; border-radius: 8px; background: var(--parch); opacity: .94 }
.qfix.on-dark::before { background: var(--ink) }
.qfix.on-dark { color: var(--on-ink) }
.qfix.on-dark svg { filter: none }
section.block { position: relative; --qgap: 18px }
section.block::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px; background: linear-gradient(to right, var(--rule) calc(50% - var(--qgap)), transparent 0 calc(50% + var(--qgap)), var(--rule) 0) }
section.block::after { content: ""; position: absolute; top: -11.5px; left: 50%; width: 24px; height: 24px; transform: translateX(-50%); background: var(--hex-ink); filter: drop-shadow(0 0 5px var(--hex)); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath fill-rule='evenodd' d='M2%202%20H40%20V28%20L28%2040%20H2%20Z%20M14%2014%20V28%20H28%20V14%20Z%20M34%2046%20L46%2034%20V46%20Z'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cpath fill-rule='evenodd' d='M2%202%20H40%20V28%20L28%2040%20H2%20Z%20M14%2014%20V28%20H28%20V14%20Z%20M34%2046%20L46%2034%20V46%20Z'/%3E%3C/svg%3E") center / contain no-repeat }
.foot-mark { display: flex; align-items: center; gap: 20px; color: var(--ink) }
.foot-mark svg { height: 34px; width: auto; overflow: visible }
@media (max-width: 760px) { .wordmark svg.inline { height: 32px } #hero { padding-top: calc(80px + env(safe-area-inset-top, 0px)) } }

.talk .consent { grid-template-columns: auto 1fr; align-items: start; gap: 12px; font-weight: 400; letter-spacing: 0; line-height: 1.5 }
/* the tick is a box, not a field: the 48px field floor would drop it below its own sentence */
.talk .consent input { width: 20px; height: 20px; min-height: 0; margin-top: 2px; padding: 0; accent-color: var(--red) }
.talk .consent a { color: inherit }
/* the check reserves its height, so a challenge appearing does not shove Send down */
.talk .check { min-height: 68px; display: flex; align-items: center; justify-content: center }
.talk .check:empty { min-height: 0 }
