/* ============================================================
   site.css — the 2026 redesign (Claude Design handoff, 2026-10-09)

   Every value below the token block is a token. The handoff is high
   fidelity, so the tokens carry its exact values rather than values
   snapped to a scale: the reference is explicit, so there is no
   "question" for the snap-to-Untitled-UI rule to settle.

   Where the handoff gave the same thing two values, one was chosen and
   the choice is commented at the token. styles.css is the PREVIOUS
   design; it stays only because the gate's request-access and contact
   pages still load it. Migrate those, then delete it.
   ============================================================ */

:root {
  /* ---- Color: chrome ---------------------------------------- */
  --paper:         #FFFFFF;
  --ink:           #0F1B2D;
  --ink-soft:      #1C2A3D;   /* problem paragraph, craft rows */
  --body:          #41505F;
  --muted:         #5B6B7E;
  --accent:        #0E7C86;
  --accent-hover:  #0A5E66;
  --surface:       #F4F7F9;   /* the gray band and screen panels */
  --line:          #E2E9EF;   /* hairlines */
  /* Frames and tiles. The handoff draws frames in #DBE3EA and tiles in
     #DCE3E9 — one unit apart in two channels, the same intent twice.
     Both use this. */
  --line-strong:   #DBE3EA;

  /* Dark footer. White text on ink, with the handoff's own muted teal for
     labels — the light-ground --muted fails contrast on ink. */
  --on-ink:        #FFFFFF;
  --on-ink-muted:  #8FB9BD;

  /* The sticky header. The handoff uses 94% on home and Slalom, 88% on
     case pages; 94% is the value its README names, so both use it. */
  --header-bg:     rgba(255, 255, 255, .94);
  --header-blur:   10px;
  /* How I work: illustration roles. The tint is the accent at low strength;
     on-ink-dim is code text on the dark editor. */
  --accent-tint:   rgba(14, 124, 134, .14);
  --on-ink-dim:    rgba(255, 255, 255, .32);

  /* ---- Elevation -------------------------------------------- */
  --shadow-frame:  0 12px 32px -12px rgba(15, 27, 45, .18);  /* case figures */
  --shadow-cover:  0 18px 40px -22px rgba(15, 27, 45, .35);  /* tile covers */
  --shadow-press:  inset 0 0 0 1px rgba(0, 0, 0, .18);        /* the teal button */
  /* The screen viewer. Overlay and blur follow Untitled UI's modal
     (bg-overlay = neutral-950 at 70%, backdrop-blur 6px). */
  --overlay:         rgba(12, 17, 29, .7);
  --overlay-blur:    6px;
  --viewer-btn:      rgba(255, 255, 255, .12);
  --viewer-btn-hover: rgba(255, 255, 255, .24);

  /* ---- Type ------------------------------------------------- */
  /* The handoff set case pages in Inter + Roboto Mono and everything else
     in Instrument Sans + IBM Plex Mono, and asked the builder to pick one.
     Its README calls Instrument Sans + IBM Plex Mono the newer direction,
     and it is what the live site already uses. */
  --sans: 'Instrument Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --fs-11: 11px;  --fs-12: 12px;  --fs-13: 13px;  --fs-14: 14px;
  --fs-15: 15px;  --fs-16: 16px;  --fs-17: 17px;  --fs-18: 18px;
  --fs-19: 19px;  --fs-20: 20px;  --fs-24: 24px;  --fs-30: 30px;

  --fs-home-h1:     clamp(44px, 6.4vw, 88px);
  --fs-home-lead:   clamp(20px, 2.1vw, 26px);
  --fs-about-lead:  clamp(19px, 1.8vw, 22px);
  --fs-contact:     clamp(30px, 4.6vw, 60px);
  --fs-case-h1:     clamp(36px, 6vw, 58px);
  --fs-slalom-h1:   clamp(40px, 5.6vw, 76px);
  --fs-slalom-h2:   clamp(24px, 2.6vw, 32px);
  --fs-slalom-next: clamp(24px, 3vw, 36px);

  --fw-regular: 400;
  --fw-medium:  500;
  --fw-semi:    600;
  --fw-heavy:   680;   /* case headings; needs the variable font axis */
  --fw-bold:    700;

  --lh-tight:  .98;  --lh-1: 1;     --lh-104: 1.04;  --lh-110: 1.1;
  --lh-120: 1.2;     --lh-125: 1.25; --lh-140: 1.4;  --lh-145: 1.45;
  --lh-150: 1.5;     --lh-155: 1.55; --lh-160: 1.6;  --lh-162: 1.62;
  --lh-165: 1.65;

  --tr-display: -.04em;  --tr-contact: -.035em; --tr-case-h1: -.03em;
  --tr-h2:      -.025em; --tr-h3:      -.02em;  --tr-name:    -.01em;
  --tr-caps-sm:  .06em;  --tr-caps-md:  .12em;  --tr-caps:     .14em;

  /* ---- Space ------------------------------------------------ */
  --s-1: 1px;   --s-2: 2px;   --s-3: 3px;   --s-4: 4px;   --s-6: 6px;
  --s-8: 8px;   --s-10: 10px; --s-12: 12px; --s-14: 14px; --s-16: 16px;
  --s-18: 18px; --s-20: 20px; --s-22: 22px; --s-24: 24px; --s-26: 26px;
  --s-28: 28px; --s-32: 32px; --s-40: 40px; --s-48: 48px; --s-52: 52px;
  --s-56: 56px; --s-64: 64px; --s-72: 72px;

  /* Shorter than the handoff's (48–96px top, 28–44px bottom) so the work
     starts on the first screen at 1440x900. */
  --pad-home-hero:    clamp(32px, 4vw, 56px) var(--gutter) clamp(24px, 3vw, 40px);
  --pad-work:         clamp(28px, 4vw, 48px) var(--gutter) clamp(40px, 6vw, 72px);
  --pad-about:        clamp(56px, 8vw, 96px) var(--gutter);
  --pad-contact:      clamp(56px, 8vw, 88px) var(--gutter) var(--s-24);
  --pad-panel:        clamp(16px, 4vw, 48px);
  --pad-panel-device: clamp(24px, 4vw, 48px);
  /* Case screens. A screen is never taller than the window, so it is seen
     whole; two or more in a section sit side by side down to --grid-min. */
  --fit-h:            min(76svh, 760px);
  --grid-min:         280px;
  --opp-min:          240px;   /* blueprint opportunity columns */
  --case-link-w:      520px;
  --bp-art-w:         1000px;  /* the blueprint artboard's own width: never scaled up into legibility */   /* a case page's link to its companion case */
  --viewer-pad:       clamp(12px, 3vw, 32px);
  --pad-slalom-hero:  clamp(48px, 7vw, 96px) var(--gutter) clamp(36px, 5vw, 56px);
  --pad-slalom-group: clamp(44px, 6vw, 72px);
  --pad-slalom-band:  clamp(48px, 7vw, 80px) var(--gutter);
  --pad-slalom-end:   clamp(48px, 6vw, 80px);

  /* ---- Radius ----------------------------------------------- */
  --r-6: 6px;    /* tile covers */
  --r-8: 8px;    /* buttons */
  --r-10: 10px;  /* tiles and figure frames */
  --r-16: 16px;  /* screen panels */
  --r-pill: 999px;
  --r-dot: 50%;

  /* ---- Layout ----------------------------------------------- */
  --page-max:  1400px;
  --case-max:  1120px;
  --gutter:    clamp(20px, 4vw, 48px);
  /* Case side padding. The handoff's enterprise template used a fixed 40px
     and its product template clamp(20px, 5vw, 40px); identical at desktop,
     but the fixed 40px crowds a phone. Both use the clamp. */
  --case-gutter: clamp(20px, 5vw, 40px);
  --label-col:    260px;
  --label-col-home: 240px;
  --label-col-wide: 280px;
  --rail-card:    300px;
  --rail-thumb:   190px;
  --dot:          9px;
  --header-scroll-gap: 56px;
  --pair-gap:     clamp(16px, 3vw, 32px);

  /* Column bases. The layout reflows with flex-wrap rather than media
     queries, so each basis IS a breakpoint: two columns wrap to one when
     the row can no longer hold both bases. */
  --basis-label:      200px;  /* the mono label column */
  --basis-label-wide: 220px;  /* Slalom's "How the work went" label */
  --basis-main:       440px;  /* case text column */
  --basis-cols:       480px;  /* a two-column content area */
  --basis-copy:       380px;  /* About's prose */
  --basis-side:       300px;  /* a side list */
  --basis-wide:       340px;  /* a wider side column */
  --basis-hero:       520px;  /* Slalom's headline */
  --slalom-side-max:  480px;

  --cover-phone-max:  220px;  /* one phone in a tile cover — two per tile now, so each is larger */
  --cover-tablet-max: 360px;  /* one tablet in a tile cover */

  --measure-hero:  40ch;
  --measure-one:   60ch;
  --measure-out:   62ch;
  --measure-body:  64ch;
  /* Contact form: Untitled UI's input spec (8px corners, 1px gray-300 border,
     xs shadow, 4px focus ring) in this site's colors. */
  --field-border:  #D0D5DD;
  --field-area-h:  148px;
  --form-basis:    420px;
  --form-max:      560px;
  --shadow-xs:     0 1px 2px rgba(16, 24, 40, .05);
  --focus-ring:    0 0 0 4px rgba(14, 124, 134, .16);
  --danger:        #B42318;
  /* How I work */
  --node:          40px;   /* the numbered circle on the progress line */
  --rail-w:        2px;
  --ill-max:       420px;  /* the drawing column */
  --text-share:    1.2fr;  /* text against drawing, side by side */
  --ill-share:     1fr;
  --ill-w1:        2px;    /* outline stroke */
  --ill-w2:        4px;    /* drawn line, check, magnifier */
  --ill-rise:      10px;   /* how far a part travels as it appears */
  --ill-scan:      -150px; /* the magnifier's sweep across the checklist */
  --ill-pop-from:  .9;     /* a part's starting scale */
  --measure-h1:    18ch;
  --measure-h1-s:  16ch;

  /* Case pages' base text. The handoff's case pages load Untitled UI's
     stylesheet, whose body sets text-md: 16px on a 24px line. Home and
     Slalom do not load it and keep the browser's normal line height. */
  --base-size: 16px;
  --base-lh:   24px;

  /* ---- Motion ----------------------------------------------- */
  --ease-hover: .15s ease;
  --ease-viewer: .2s ease-out;

  /* How I work: the drawings' motion. Every step plays once on entering view;
     the loops (typing dots, caret, scan, live pulse) run only after that. */
  --stagger:        .14s;   /* between parts of one drawing */
  --dur-pop:        .5s;
  --dur-draw:       1.3s;
  --dur-type:       .45s;
  --dur-loop:       1.2s;
  --dur-scan:       3.6s;
  --dur-fill:       .25s;   /* the progress line catching up with scroll */
  --dur-node:       .3s;
  --ease-pop:       cubic-bezier(.34, 1.4, .64, 1);
  --ease-draw:      cubic-bezier(.65, 0, .35, 1);
  --ease-loop:      ease-in-out;
}

@media (prefers-reduced-motion: reduce) {
  :root { --ease-hover: 0s; --ease-viewer: 0s; }
}

/* ============================================================
   Base
   ============================================================ */
/* The handoff never sets box-sizing, so every element is content-box: a
   container's max-width caps its CONTENT and the padding sits outside it.
   Matching that is what puts the text where the reference puts it (a
   border-box reset moved every container's content in by 20px at 1440).
   The one element the handoff makes border-box says so itself.

   Case pages are the exception: they load Untitled UI's stylesheet, which
   makes everything border-box. So case pages are border-box, which is
   what puts their content 40px inside the header line, as the reference
   does. */
.is-case, .is-case *, .is-case *::before, .is-case *::after { box-sizing: border-box; }
.is-case { font-size: var(--base-size); line-height: var(--base-lh); }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
a { color: var(--ink); text-decoration: none; transition: color var(--ease-hover), border-color var(--ease-hover); }
a:hover { color: var(--accent); }
img { display: block; max-width: 100%; height: auto; }
h1, h2, h3, p, figure { margin: 0; }

.wrap      { max-width: var(--page-max); margin: 0 auto; padding-left: var(--gutter); padding-right: var(--gutter); }
.wrap-case { max-width: var(--case-max); margin: 0 auto; padding-left: var(--case-gutter); padding-right: var(--case-gutter); }

/* The mono label used everywhere: eyebrows, section names, footers. */
.label {
  font-family: var(--mono);
  font-size: var(--fs-12);
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.mono { font-family: var(--mono); }

/* ============================================================
   Header
   ============================================================ */
.site-header {
  position: sticky; top: 0; z-index: 40;
  background: var(--header-bg);
  -webkit-backdrop-filter: blur(var(--header-blur));
  backdrop-filter: blur(var(--header-blur));
  border-bottom: var(--s-1) solid var(--line);
}
.site-header__inner {
  max-width: var(--page-max); margin: 0 auto;
  padding: var(--s-14) var(--gutter);
  display: flex; align-items: center; gap: var(--s-24); flex-wrap: wrap;
}
.site-header__name { font-size: var(--fs-17); font-weight: var(--fw-semi); letter-spacing: var(--tr-name); }
.site-header__nav  { display: flex; gap: var(--s-22); margin-left: auto; font-family: var(--mono); font-size: var(--fs-13); }
.site-header__nav .is-current { color: var(--accent); }
/* The narrowest phones: "TaitzDesign" plus three links needs tighter spacing
   to stay on one line at 320. */
@media (max-width: 360px) { .site-header__nav { gap: var(--s-14); } }

.case-header__inner {
  max-width: var(--case-max); margin: 0 auto;
  padding: var(--s-16) var(--case-gutter);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-16);
}
.case-header__inner--wide { max-width: var(--page-max); padding-left: var(--gutter); padding-right: var(--gutter); }
.case-header__back  { font-family: var(--mono); font-size: var(--fs-13); color: var(--muted); white-space: nowrap; }
.case-header__short { font-family: var(--mono); font-size: var(--fs-13); color: var(--ink); text-align: right; }

/* ============================================================
   Home
   ============================================================ */
.home-hero { max-width: var(--page-max); margin: 0 auto; padding: var(--pad-home-hero); }
.home-hero__h1 {
  font-weight: var(--fw-semi); font-size: var(--fs-home-h1);
  line-height: var(--lh-tight); letter-spacing: var(--tr-display);
}
/* The titles under the name (Kevin, 2026-10-15). Each title stays whole and
   wraps as a unit; the dot between them is drawn, not read aloud. */
.home-hero__titles {
  list-style: none; margin: var(--s-18) 0 0; padding: 0;
  display: flex; flex-wrap: wrap; column-gap: var(--s-14); row-gap: var(--s-4);
  font-size: var(--fs-home-lead); line-height: var(--lh-140); letter-spacing: var(--tr-name); color: var(--body);
}
.home-hero__titles li { white-space: nowrap; }
.home-hero__titles li + li::before { content: "·"; margin-right: var(--s-14); color: var(--accent); }
/* On a phone a wrapped line would start with a dot; stack them instead. Above
   any later rule, but scoped by max-width so it cannot outrank the wide layout. */
@media (max-width: 600px) {
  .home-hero__titles { flex-direction: column; row-gap: var(--s-2); }
  .home-hero__titles li + li::before { content: none; }
}
.home-hero__lead {
  font-size: var(--fs-home-lead); line-height: var(--lh-140); letter-spacing: var(--tr-name);
  margin-top: var(--s-22); max-width: var(--measure-hero); text-wrap: pretty;
}

.work {
  background: var(--surface);
  border-top: var(--s-1) solid var(--line);
  border-bottom: var(--s-1) solid var(--line);
  scroll-margin-top: var(--header-scroll-gap);
}
.work__inner { max-width: var(--page-max); margin: 0 auto; padding: var(--pad-work); }
.work__label { margin-bottom: var(--s-22); }

/* The tile grid: masonry. Every project is a plain tile at its natural height,
   placed in home order into the shortest column (build.mjs), so the first
   tiles fill the top row and the columns end close together. CSS columns flow
   top-to-bottom, so both layouts are rendered and one is shown.
   Desktop (a grid at least 1080 wide, a viewport of 1174): three columns.
   Compact (tablet and phone): two. Only the visible layout's images load. */
.home-grid { display: flex; flex-direction: column; gap: var(--s-20); }
.home-grid--desktop { display: none; }
@media (min-width: 1174px) {
  .home-grid--desktop { display: flex; }
  .home-grid--compact { display: none; }
}
.tiles { display: flex; gap: var(--s-20); align-items: flex-start; }
.tiles__col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: var(--s-20); }


.tile {
  display: block; background: var(--paper);
  border: var(--s-1) solid var(--line-strong); border-radius: var(--r-10);
  overflow: hidden; color: var(--ink);
}
.tile:hover { border-color: var(--ink); color: var(--ink); }
.tile__cover { background: var(--paper); padding: var(--s-14); border-bottom: var(--s-1) solid var(--line); }
.tile__body  { padding: var(--s-12) var(--s-16) var(--s-14); display: flex; flex-direction: column; gap: var(--s-4); }
.tile__top   { display: flex; justify-content: space-between; gap: var(--s-12); align-items: baseline; }
.tile__name  { font-size: var(--fs-16); font-weight: var(--fw-semi); letter-spacing: var(--tr-name); line-height: var(--lh-125); }
.tile__name--project { display: block; }

/* Featured tiles. These must come AFTER .tile: same specificity, so source
   order decides, and above it .tile's display:block silently won — the cover
   never grew and a stretched tile's spare height fell below its caption. */
.tile__year  { font-family: var(--mono); font-size: var(--fs-12); color: var(--muted); white-space: nowrap; }
.tile__line  { font-size: var(--fs-14); line-height: var(--lh-145); color: var(--body); }
.pill {
  align-self: flex-start; margin-top: var(--s-4);
  font-family: var(--mono); font-size: var(--fs-11); color: var(--muted);
  border: var(--s-1) solid var(--line-strong); border-radius: var(--r-pill);
  padding: var(--s-1) var(--s-8);
}

/* A cover is either a redrawn client UI or device-framed app shots. */
.cover--redraw {
  border: var(--s-1) solid var(--line-strong); border-radius: var(--r-6);
  overflow: hidden; box-shadow: var(--shadow-cover);
}
.cover--redraw img { width: 100%; height: auto; }
.cover--shots { display: flex; justify-content: center; gap: var(--s-12); }
.cover--shots.is-tablet { gap: var(--s-14); }
.cover--shots > div { flex: 1 1 0; min-width: 0; max-width: var(--cover-phone-max); }
.cover--shots.is-tablet > div { max-width: var(--cover-tablet-max); }

/* Phones (600 and under): two columns rather than one, so a tile is about
   165px wide at 390. Tighter gaps and padding, smaller tile text, and one
   phone per cover so the UI stays big enough to read. */
@media (max-width: 600px) {
  .home-grid, .tiles, .tiles__col { gap: var(--s-12); }
  .tile__cover { padding: var(--s-8); }
  .tile__body  { padding: var(--s-10) var(--s-10) var(--s-12); }
  /* A long one-word name (LocumTenens.com) leaves no room for the year, so
     the year drops to its own line instead of being clipped. */
  .tile__top   { gap: 0 var(--s-6); flex-wrap: wrap; }
  .tile__name  { min-width: 0; overflow-wrap: anywhere; }
  .tile__name { font-size: var(--fs-15); }
  .tile__line { font-size: var(--fs-13); }
  .tile__year  { font-size: var(--fs-11); }
  .cover--shots.is-phone > div:nth-child(n+2) { display: none; }
}

/* How I work — six steps down a progress line, each with a drawing that plays
   as it scrolls in. Motion lives under html.has-motion, which assets/process.js
   adds only when motion is allowed; without it every drawing is finished. */
.process { border-bottom: var(--s-1) solid var(--line); scroll-margin-top: var(--header-scroll-gap); }
.process__inner {
  max-width: var(--page-max); margin: 0 auto; padding: var(--pad-about);
  display: flex; flex-wrap: wrap; gap: var(--s-40) var(--s-72);
}
.process__label { flex: 1 1 var(--basis-label); max-width: var(--label-col-home); }
.process__main  { flex: 3 1 var(--basis-cols); min-width: 0; container-type: inline-size; }
.process__h2 {
  font-size: var(--fs-slalom-h2); font-weight: var(--fw-heavy); letter-spacing: var(--tr-h2);
  line-height: var(--lh-120); text-wrap: balance;
}
.process__intro { margin-top: var(--s-14); max-width: var(--measure-body); font-size: var(--fs-17); line-height: var(--lh-162); color: var(--body); text-wrap: pretty; }

.process__track { position: relative; margin-top: var(--s-48); }
.process__rail {
  position: absolute; top: 0; bottom: 0; left: calc((var(--node) - var(--rail-w)) / 2);
  width: var(--rail-w); background: var(--line);
}
.process__rail::after {
  content: ""; position: absolute; inset: 0; background: var(--accent);
  transform-origin: top; transform: scaleY(var(--fill, 1)); transition: transform var(--dur-fill) linear;
}
.process__steps { list-style: none; margin: 0; padding: 0; position: relative; }

.step {
  display: grid; grid-template-columns: var(--node) minmax(0, var(--text-share)) minmax(0, var(--ill-share));
  gap: var(--s-20) var(--s-40); align-items: start; padding-bottom: var(--s-56);
}
.step:last-child { padding-bottom: 0; }
.step__node {
  width: var(--node); height: var(--node); border-radius: var(--r-dot);
  display: grid; place-items: center;
  font-family: var(--mono); font-size: var(--fs-12); color: var(--muted);
  background: var(--paper); border: var(--rail-w) solid var(--line-strong);
  transition: background var(--dur-node), border-color var(--dur-node), color var(--dur-node);
}
.step__h3 { font-size: var(--fs-24); font-weight: var(--fw-heavy); letter-spacing: var(--tr-h3); line-height: var(--lh-120); padding-top: var(--s-6); }
.step__claim { margin-top: var(--s-4); font-size: var(--fs-18); line-height: var(--lh-150); color: var(--ink-soft); }
.step__pair { margin-top: var(--s-18); display: grid; gap: var(--s-14); max-width: var(--measure-body); }
.step__tag { font-family: var(--mono); font-size: var(--fs-11); letter-spacing: var(--tr-caps); text-transform: uppercase; color: var(--muted); margin-bottom: var(--s-4); }
.step__tag--ai { color: var(--accent); }
.step__p { font-size: var(--fs-16); line-height: var(--lh-160); color: var(--body); text-wrap: pretty; }
.step__tools { list-style: none; margin: var(--s-16) 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--s-6); }
.tool {
  font-family: var(--mono); font-size: var(--fs-12); color: var(--ink-soft);
  padding: var(--s-4) var(--s-10); border: var(--s-1) solid var(--line-strong); border-radius: var(--r-pill); background: var(--paper);
}
.step__fig { margin: 0; max-width: var(--ill-max); background: var(--surface); border: var(--s-1) solid var(--line); border-radius: var(--r-16); overflow: hidden; }
.step__fig svg { display: block; width: 100%; height: auto; }

/* The drawings' palette, all from tokens. */
.ill-paper  { fill: var(--paper); stroke: var(--line-strong); stroke-width: var(--ill-w1); }
.ill-frame  { stroke: var(--ink); }
.ill-box    { fill: var(--paper); stroke: var(--ink); stroke-width: var(--ill-w1); }
.ill-ink    { fill: var(--ink); }
.ill-accent { fill: var(--accent); }
.ill-tint   { fill: var(--accent-tint); }
.ill-line   { fill: var(--line-strong); }
.ill-onink  { fill: var(--on-ink); }
.ill-onink-dim { fill: var(--on-ink-dim); }
.ill-glass  { fill: var(--accent-tint); stroke: var(--ink); stroke-width: var(--ill-w2); }
.ill-stroke-accent, .ill-stroke-ink, .ill-stroke-onink { fill: none; stroke-width: var(--ill-w2); stroke-linecap: round; stroke-linejoin: round; }
.ill-stroke-accent { stroke: var(--accent); }
.ill-stroke-ink    { stroke: var(--ink); }
.ill-stroke-onink  { stroke: var(--on-ink); }
.ill-text { font-family: var(--mono); font-size: var(--fs-12); fill: var(--ink); text-anchor: middle; }

/* Motion. Parts start hidden only when motion is on, and play when the step is in view. */
.has-motion .step.is-in .step__node { background: var(--accent); border-color: var(--accent); color: var(--on-ink); }
.has-motion .step__fig :is(.pop, .slide, .rise, .type, .draw) { transform-box: fill-box; }
.has-motion .step__fig .pop   { opacity: 0; transform-origin: center; transform: translateY(var(--ill-rise)) scale(var(--ill-pop-from)); }
.has-motion .step__fig .slide { opacity: 0; transform: translateX(calc(var(--ill-rise) * -2)); }
.has-motion .step__fig .rise  { opacity: 0; transform: translateY(calc(var(--ill-rise) * 3)); }
.has-motion .step__fig .type  { transform-origin: left; transform: scaleX(0); }
.has-motion .step__fig .draw  { stroke-dasharray: 1; stroke-dashoffset: 1; }
.has-motion .step.is-in .step__fig :is(.pop, .slide, .rise) {
  animation: ill-in var(--dur-pop) var(--ease-pop) forwards; animation-delay: calc(var(--i, 0) * var(--stagger));
}
.has-motion .step.is-in .step__fig .type {
  animation: ill-type var(--dur-type) var(--ease-draw) forwards; animation-delay: calc(var(--i, 0) * var(--stagger) * 2);
}
.has-motion .step.is-in .step__fig .draw {
  animation: ill-draw var(--dur-draw) var(--ease-draw) forwards; animation-delay: calc(var(--i, 0) * var(--stagger));
}
@keyframes ill-in   { to { opacity: 1; transform: none; } }
@keyframes ill-type { to { transform: none; } }
@keyframes ill-draw { to { stroke-dashoffset: 0; } }

/* Small loops, once the drawing has played. */
.has-motion .step.is-in .dot   { animation: ill-bob var(--dur-loop) var(--ease-loop) infinite; animation-delay: calc(var(--d, 0) * var(--stagger)); }
.has-motion .step.is-in .caret { animation: ill-blink var(--dur-loop) steps(1) infinite; }
.has-motion .step.is-in .scan  { animation: ill-scan var(--dur-scan) var(--ease-loop) infinite alternate; }
.has-motion .step.is-in .pulse { transform-box: fill-box; transform-origin: center; animation: ill-pulse var(--dur-loop) var(--ease-loop) infinite; }
@keyframes ill-bob   { 50% { transform: translateY(calc(var(--ill-rise) * -.6)); } }
@keyframes ill-blink { 50% { opacity: 0; } }
@keyframes ill-scan  { to { transform: translate(var(--ill-scan), calc(var(--ill-scan) * -.1)); } }
@keyframes ill-pulse { 50% { transform: scale(1.6); opacity: .4; } }

/* Narrow: the drawing moves under its text, still beside the line. Keyed to the
   section's own width, not the window's — the label column beside it takes a
   different share at different widths, and a window breakpoint left the text
   0px wide at 901 (2026-10-14). */
@container (max-width: 760px) {
  .step { grid-template-columns: var(--node) minmax(0, 1fr); }
  .step__fig { grid-column: 2; }
}

/* About */
.about { border-bottom: var(--s-1) solid var(--line); }
.about__inner {
  max-width: var(--page-max); margin: 0 auto; padding: var(--pad-about);
  display: flex; flex-wrap: wrap; gap: var(--s-40) var(--s-72);
}
.about__label { flex: 1 1 var(--basis-label); max-width: var(--label-col-home); }
.about__cols  { flex: 3 1 var(--basis-cols); min-width: 0; display: flex; flex-wrap: wrap; gap: var(--s-40) var(--s-56); }
.about__copy  { flex: 1 1 var(--basis-copy); min-width: 0; }
.about__lead  { font-size: var(--fs-about-lead); line-height: var(--lh-150); margin-bottom: var(--s-18); text-wrap: pretty; }
.about__body  { font-size: var(--fs-16); line-height: var(--lh-165); color: var(--body); text-wrap: pretty; }
.about__card {
  margin-top: var(--s-26); display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-16); padding: var(--s-14) var(--s-16);
  border: var(--s-1) solid var(--line-strong); border-radius: var(--r-10);
}
.about__card:hover { border-color: var(--ink); color: var(--ink); }
.about__card-text { display: flex; flex-direction: column; gap: var(--s-2); }
.about__card-eyebrow { font-family: var(--mono); font-size: var(--fs-12); color: var(--muted); }
.about__card-title   { font-size: var(--fs-16); font-weight: var(--fw-semi); }
.about__card-arrow   { font-family: var(--mono); font-size: var(--fs-13); }
.about__skills { flex: 1 1 var(--basis-side); min-width: 0; }
.skill { padding: var(--s-12) 0; border-top: var(--s-1) solid var(--line); }
.skill__h { font-family: var(--mono); font-size: var(--fs-12); letter-spacing: var(--tr-caps-sm); text-transform: uppercase; margin-bottom: var(--s-4); }
.skill__d { font-size: var(--fs-14); line-height: var(--lh-155); color: var(--muted); }

/* Contact */
.contact { max-width: var(--page-max); margin: 0 auto; padding: var(--pad-contact); }
.contact__grid { display: flex; flex-wrap: wrap; gap: var(--s-40) var(--s-72); align-items: flex-start; }
.contact__intro { flex: 1 1 var(--basis-copy); min-width: 0; }
.contact__h2 { margin-top: var(--s-14); font-weight: var(--fw-semi); font-size: var(--fs-contact); letter-spacing: var(--tr-contact); line-height: var(--lh-1); }
/* The address is wider than a 320px phone at this size; it may break after the @. */
.contact__lead { margin-top: var(--s-18); max-width: var(--measure-body); font-size: var(--fs-17); line-height: var(--lh-162); color: var(--body); overflow-wrap: anywhere; }
.contact__form { flex: 1 1 var(--form-basis); max-width: var(--form-max); min-width: 0; display: grid; gap: var(--s-18); }
.field { display: grid; gap: var(--s-6); }
.field label { font-size: var(--fs-14); font-weight: var(--fw-medium); color: var(--ink-soft); }
.field input, .field textarea {
  box-sizing: border-box; width: 100%; font: inherit; font-size: var(--fs-16); line-height: var(--lh-150); color: var(--ink);
  background: var(--paper); border: var(--s-1) solid var(--field-border); border-radius: var(--r-8);
  padding: var(--s-10) var(--s-14); box-shadow: var(--shadow-xs);
  transition: border-color var(--ease-hover), box-shadow var(--ease-hover);
}
.field textarea { min-height: var(--field-area-h); resize: vertical; }
.field input:focus, .field textarea:focus { outline: none; border-color: var(--accent); box-shadow: var(--shadow-xs), var(--focus-ring); }
/* The trap: a field people never see and bots fill in. */
.field--trap { position: absolute; width: var(--s-1); height: var(--s-1); overflow: hidden; clip-path: inset(50%); }
.contact__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-12) var(--s-18); }
.contact__actions .button { border: 0; cursor: pointer; font: inherit; font-size: var(--fs-15); font-weight: var(--fw-semi); }
.contact__actions .button:disabled { opacity: .6; cursor: progress; }
.contact__status { font-size: var(--fs-14); line-height: var(--lh-150); color: var(--muted); }
.contact__status.is-ok { color: var(--accent); }
.contact__status.is-error { color: var(--danger); }
.contact__form.is-sent .field { display: none; }
.contact__links { display: flex; gap: var(--s-24); flex-wrap: wrap; margin-top: var(--s-22); font-family: var(--mono); font-size: var(--fs-14); }
.site-foot {
  margin-top: var(--s-56); padding-top: var(--s-20);
  border-top: var(--s-1) solid var(--line);
  font-family: var(--mono); font-size: var(--fs-12); color: var(--muted);
}

/* ============================================================
   Case studies
   ============================================================ */
.case-hero { border-bottom: var(--s-1) solid var(--ink); }
.case-hero__inner { padding-top: var(--s-72); padding-bottom: var(--s-52); }
.case-hero__eyebrow {
  display: flex; align-items: center; gap: var(--s-10);
  font-family: var(--mono); font-size: var(--fs-12);
  letter-spacing: var(--tr-caps-md); text-transform: uppercase; color: var(--muted);
}
/* The client's color is exhibit content, carried in the data and set per
   page as --client. It never leaks into chrome. */
.case-hero__dot { width: var(--dot); height: var(--dot); border-radius: var(--r-dot); flex: 0 0 auto; background: var(--client); }
.case-hero__h1 {
  font-weight: var(--fw-heavy); font-size: var(--fs-case-h1);
  line-height: var(--lh-104); letter-spacing: var(--tr-case-h1);
  margin: var(--s-18) 0 var(--s-20); max-width: var(--measure-h1); text-wrap: balance;
}
.case-hero--device .case-hero__h1 { margin-bottom: var(--s-14); }
.case-hero__one { font-size: var(--fs-20); line-height: var(--lh-155); color: var(--body); max-width: var(--measure-one); text-wrap: pretty; }
.case-hero__meta {
  margin-top: var(--s-28); display: flex; flex-wrap: wrap; gap: var(--s-8) var(--s-24);
  font-family: var(--mono); font-size: var(--fs-13); color: var(--muted);
}

/* The lead device band on product pages. */
.lead-band { background: var(--surface); border-bottom: var(--s-1) solid var(--line); }
.lead-band__inner { padding-top: var(--s-56); padding-bottom: var(--s-56); display: flex; justify-content: center; gap: var(--s-24) var(--s-64); }
.lead-band__device { flex: 1 1 0; min-width: 0; max-width: var(--lead-w); }

/* A two-column row: label on the left, content on the right. */
.row { display: flex; flex-wrap: wrap; gap: var(--s-24) var(--s-40); padding-top: var(--s-64); padding-bottom: var(--s-64); }
.row--baseline { align-items: baseline; }
.row__label { flex: 1 1 var(--basis-label); max-width: var(--label-col); }
.row__main  { flex: 3 1 var(--basis-main); min-width: 0; }
.band-line  { border-bottom: var(--s-1) solid var(--line); }

.problem__p { font-size: var(--fs-19); line-height: var(--lh-160); color: var(--ink-soft); margin-bottom: var(--s-18); max-width: var(--measure-body); text-wrap: pretty; }
.slash-row {
  display: flex; gap: var(--s-14); padding: var(--s-10) 0;
  border-top: var(--s-1) solid var(--line);
  font-size: var(--fs-16); line-height: var(--lh-150); color: var(--body); max-width: var(--measure-body);
}
.slash { color: var(--accent); font-weight: var(--fw-bold); }

.redraw-note { background: var(--surface); border-bottom: var(--s-1) solid var(--line); }
.redraw-note__inner { padding-top: var(--s-18); padding-bottom: var(--s-18); font-family: var(--mono); font-size: var(--fs-12); line-height: var(--lh-160); color: var(--muted); }

.sections { padding-top: var(--s-16); padding-bottom: var(--s-24); }
.sections--device { padding-bottom: var(--s-40); }
.section { padding: var(--s-56) 0 var(--s-8); border-top: var(--s-1) solid var(--line); }
.section__n { font-family: var(--mono); font-size: var(--fs-12); color: var(--muted); margin-bottom: var(--s-10); }
.section__head { display: flex; flex-wrap: wrap; gap: var(--s-12) var(--s-40); align-items: baseline; }
.section__h3 {
  flex: 1 1 var(--basis-label); max-width: var(--label-col);
  font-weight: var(--fw-heavy); font-size: var(--fs-24); letter-spacing: var(--tr-h3);
  line-height: var(--lh-120); text-wrap: balance;
}
.section__body { flex: 3 1 var(--basis-main); min-width: 0; font-size: var(--fs-17); line-height: var(--lh-162); color: var(--body); max-width: var(--measure-body); text-wrap: pretty; }

/* Product pages stack the number above the heading. */
.section--device .section__head { align-items: flex-start; }
.section__lead { flex: 1 1 var(--basis-label); max-width: var(--label-col); display: flex; flex-direction: column; gap: var(--s-8); }
.section__lead .section__n { margin-bottom: 0; }
.section__lead .section__h3 { flex: none; max-width: none; }

.panel {
  display: flex; flex-direction: column; gap: var(--s-40);
  margin-top: var(--s-32); background: var(--surface);
  border-radius: var(--r-16); padding: var(--pad-panel);
}
.panel--device {
  flex-direction: row; flex-wrap: wrap; justify-content: center; align-items: flex-start;
  gap: var(--s-40) var(--s-32); padding: var(--pad-panel-device);
}
.frame {
  border: var(--s-1) solid var(--line-strong); border-radius: var(--r-10);
  overflow: hidden; box-shadow: var(--shadow-frame); background: var(--paper);
}
.frame img, .shot--bare img { width: 100%; height: auto; }
.pair { display: flex; gap: var(--pair-gap); align-items: flex-start; }
.pair > .frame { flex: var(--grow) 1 0; min-width: 0; }
.figcap { display: flex; gap: var(--s-12); margin-top: var(--s-14); font-size: var(--fs-14); line-height: var(--lh-150); color: var(--muted); }
.figcap__tag { font-family: var(--mono); font-size: var(--fs-12); color: var(--accent); flex: 0 0 auto; padding-top: var(--s-2); }
.shot--device { flex: 0 1 var(--shot-w); min-width: 0; display: flex; flex-direction: column; gap: var(--s-14); }
.shot--device .figcap { margin-top: 0; flex-direction: column; align-items: center; gap: var(--s-4); text-align: center; text-wrap: balance; }
/* A tablet beside the phone that controls it: centered on each other, so the
   taller phone does not leave the tablet hanging at the top of the row. */
.panel--paired { align-items: center; }

/* Case screens: a grid, not a column. Sections with two or three screens put
   them side by side; a single screen is centered and sized to fit the window.
   Every screen opens full size in the viewer, so nothing is lost to the
   smaller size. Cut the Compensation tool page roughly in half (2026-10-09). */
.panel--screens {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--grid-min)), 1fr));
  gap: var(--s-40) var(--s-32); align-items: start;
}
.shot { width: min(100%, calc(var(--fit-h) * var(--ar))); justify-self: center; }
.frame--zoom { display: block; width: 100%; padding: 0; font: inherit; color: inherit; text-align: inherit; cursor: zoom-in; }
button.shot--bare { border: 0; background: none; }
.frame.frame--zoom:hover { border-color: var(--muted); }
.frame--zoom:focus-visible { outline: var(--s-2) solid var(--accent); outline-offset: var(--s-3); }

.viewer {
  width: 100%; height: 100%; max-width: none; max-height: none;
  margin: 0; padding: 0; border: 0; background: none; color: var(--on-ink);
}
.viewer[open] { display: flex; flex-direction: column; animation: viewer-in var(--ease-viewer); }
.viewer::backdrop { background: var(--overlay); backdrop-filter: blur(var(--overlay-blur)); }
.viewer[open]::backdrop { animation: viewer-in var(--ease-viewer); }
@keyframes viewer-in { from { opacity: 0; } }
html:has(.viewer[open]) { overflow: hidden; }
/* Full size means the width it was drawn at (or the window's, if narrower);
   a screen taller than the window scrolls inside the viewer. */
.viewer__stage {
  flex: 1 1 auto; min-height: 0; display: flex; overflow-y: auto; overscroll-behavior: contain;
  padding: var(--viewer-pad) var(--viewer-pad) 0;
}
.viewer__img {
  width: min(var(--w), 100%); height: auto; margin: auto;
  border-radius: var(--r-10); background: var(--paper); box-shadow: var(--shadow-cover);
}
.viewer__bar {
  flex: 0 0 auto; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-8) var(--s-12);
  width: 100%; max-width: var(--page-max); margin: 0 auto;
  padding: var(--s-12) var(--viewer-pad) var(--viewer-pad);
}
.viewer__cap { flex: 1 1 var(--basis-main); min-width: 0; font-size: var(--fs-14); line-height: var(--lh-150); }
.viewer__count { font-family: var(--mono); font-size: var(--fs-12); color: var(--on-ink-muted); }
.viewer__btn {
  display: grid; place-items: center; width: var(--s-40); height: var(--s-40);
  border: 0; border-radius: var(--r-pill); background: var(--viewer-btn); color: var(--on-ink);
  font: inherit; font-size: var(--fs-20); line-height: var(--lh-1); cursor: pointer;
  transition: background var(--ease-hover);
}
.viewer__btn:hover { background: var(--viewer-btn-hover); }
.viewer__btn:focus-visible { outline: var(--s-2) solid var(--on-ink); outline-offset: var(--s-2); }

.craft { border-top: var(--s-1) solid var(--ink); background: var(--surface); }
.craft__row { display: flex; gap: var(--s-14); padding: var(--s-14) 0; border-bottom: var(--s-1) solid var(--line); }
.craft__p { font-size: var(--fs-16); line-height: var(--lh-155); color: var(--ink-soft); }

.outcome { border-top: var(--s-1) solid var(--line); }
.outcome__lead { font-size: var(--fs-18); line-height: var(--lh-155); margin-bottom: var(--s-18); max-width: var(--measure-out); }
.outcome .slash-row { padding: var(--s-12) 0; max-width: var(--measure-out); }

.case-foot { border-top: var(--s-1) solid var(--ink); background: var(--ink); color: var(--on-ink); }
.case-foot__inner {
  padding-top: var(--s-64); padding-bottom: var(--s-64);
  display: flex; flex-wrap: wrap; gap: var(--s-24); align-items: center; justify-content: space-between;
}
.case-foot__next, .case-foot__next:hover { color: var(--on-ink); }
.case-foot__label { font-family: var(--mono); font-size: var(--fs-12); letter-spacing: var(--tr-caps); text-transform: uppercase; color: var(--on-ink-muted); }
.case-foot__name  { font-weight: var(--fw-heavy); font-size: var(--fs-30); letter-spacing: var(--tr-h3); margin-top: var(--s-8); }
.button {
  display: inline-flex; align-items: center;
  padding: var(--s-12) var(--s-22); border-radius: var(--r-8);
  background: var(--accent); color: var(--on-ink);
  font-size: var(--fs-15); font-weight: var(--fw-semi);
  box-shadow: var(--shadow-press);
}
.button:hover { background: var(--accent-hover); color: var(--on-ink); }
.case-foot__copy { padding-bottom: var(--s-40); font-family: var(--mono); font-size: var(--fs-12); color: var(--on-ink-muted); }

/* ============================================================
   Slalom
   ============================================================ */
.slalom-hero {
  max-width: var(--page-max); margin: 0 auto; padding: var(--pad-slalom-hero);
  display: flex; flex-wrap: wrap; gap: var(--s-32) var(--s-72); align-items: flex-end;
}
.slalom-hero__title { flex: 3 1 var(--basis-hero); min-width: 0; }
.slalom-hero__h1 {
  font-weight: var(--fw-semi); font-size: var(--fs-slalom-h1);
  line-height: var(--lh-1); letter-spacing: var(--tr-display);
  margin-top: var(--s-18); max-width: var(--measure-h1-s); text-wrap: balance;
}
.slalom-hero__side { flex: 2 1 var(--basis-wide); min-width: 0; max-width: var(--slalom-side-max); }
.slalom-hero__p { font-size: var(--fs-18); line-height: var(--lh-155); color: var(--body); text-wrap: pretty; }
.slalom-hero__meta { display: flex; flex-wrap: wrap; gap: var(--s-6) var(--s-24); margin-top: var(--s-18); font-family: var(--mono); font-size: var(--fs-13); }

.clients { border-top: var(--s-1) solid var(--line); border-bottom: var(--s-1) solid var(--line); }
.clients__inner { padding-top: var(--s-18); padding-bottom: var(--s-18); display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s-8) var(--s-24); }
.clients__list { display: flex; flex-wrap: wrap; gap: var(--s-4) var(--s-18); font-size: var(--fs-15); }
.clients__list span { white-space: nowrap; }

.groups { padding-bottom: var(--pad-slalom-end); }
.group { padding-top: var(--pad-slalom-group); }
.group__head {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s-6) var(--s-20);
  padding-bottom: var(--s-16); border-bottom: var(--s-1) solid var(--ink);
}
.group__h2   { font-weight: var(--fw-semi); font-size: var(--fs-slalom-h2); letter-spacing: var(--tr-h2); }
.group__desc { font-size: var(--fs-16); color: var(--muted); }
.group__hint { margin-left: auto; font-family: var(--mono); font-size: var(--fs-12); color: var(--muted); }
.rail {
  display: flex; gap: var(--s-20); margin-top: var(--s-20);
  overflow-x: auto; scroll-snap-type: x mandatory;
  padding-bottom: var(--s-14); scrollbar-width: thin;
}
.card { flex: 0 0 var(--rail-card); width: var(--rail-card); scroll-snap-align: start; display: flex; flex-direction: column; gap: var(--s-12); color: var(--ink); }
.card__thumb {
  box-sizing: border-box;
  height: var(--rail-thumb); overflow: hidden; background: var(--surface);
  border: var(--s-1) solid var(--line); border-radius: var(--r-10); padding: var(--s-12);
}
.card:hover .card__thumb { border-color: var(--ink); }
.card:hover { color: var(--ink); }
.card__text { display: flex; flex-direction: column; gap: var(--s-3); }
.card .tile__top { gap: var(--s-10); }

.how { background: var(--surface); border-top: var(--s-1) solid var(--line); }
.how__inner { max-width: var(--page-max); margin: 0 auto; padding: var(--pad-slalom-band); display: flex; flex-wrap: wrap; gap: var(--s-32) var(--s-72); }
.how__label { flex: 1 1 var(--basis-label-wide); max-width: var(--label-col-wide); }
.how__cols  { flex: 3 1 var(--basis-cols); min-width: 0; display: flex; flex-wrap: wrap; gap: var(--s-28) var(--s-56); }
.how__p     { flex: 1 1 var(--basis-wide); font-size: var(--fs-18); line-height: var(--lh-160); text-wrap: pretty; }
.how__list  { flex: 1 1 var(--basis-side); min-width: 0; }
.how__item  { padding: var(--s-12) 0; border-top: var(--s-1) solid var(--line-strong); font-size: var(--fs-15); line-height: var(--lh-150); color: var(--body); }

.slalom-end { max-width: var(--page-max); margin: 0 auto; padding: var(--pad-slalom-band); padding-bottom: var(--s-40); }
.slalom-end__row { display: flex; flex-wrap: wrap; gap: var(--s-24); align-items: flex-end; justify-content: space-between; }
.slalom-end__start { display: flex; flex-direction: column; gap: var(--s-6); }
.slalom-end__name { font-weight: var(--fw-semi); font-size: var(--fs-slalom-next); letter-spacing: var(--tr-h2); line-height: var(--lh-110); }
.slalom-end__email { font-family: var(--mono); font-size: var(--fs-15); color: var(--accent); }

/* ============================================================
   Device frames — exhibit, not chrome.
   A drawn phone and tablet bezel around real app screenshots, ported
   from the handoff's Device component. These grays describe hardware,
   not the site, so they live here and nowhere else.
   ============================================================ */
.device {
  --bezel: linear-gradient(135deg, #43464b 0%, #26282c 20%, #141518 44%, #0c0d0f 56%, #212329 82%, #3a3d42 100%);
  --bezel-tablet: linear-gradient(135deg, #45484d 0%, #2a2c30 22%, #151619 46%, #0d0e10 58%, #232529 82%, #3c3f44 100%);
  --bezel-key: linear-gradient(90deg, #0a0b0d, #3a3d42);
  --bezel-key-r: linear-gradient(270deg, #0a0b0d, #3a3d42);
  --bezel-shadow: inset 0 0 0 1px rgba(255, 255, 255, .07), 0 32px 64px -30px rgba(16, 24, 40, .55), 0 3px 8px rgba(16, 24, 40, .14);
  --bezel-shadow-tablet: inset 0 0 0 1px rgba(255, 255, 255, .07), 0 32px 64px -30px rgba(16, 24, 40, .5), 0 3px 8px rgba(16, 24, 40, .13);
  --glass: #000000;
  --glass-edge: inset 0 0 0 1.5px rgba(0, 0, 0, .85);
  --island: #000000;
  --camera: #0a0a0c;
  --device-caption: #667085;
  --device-caption-size: 12.5px;
  --device-caption-tracking: .01em;
  width: 100%;
  display: flex; flex-direction: column; gap: var(--s-14); align-items: center;
}
.device__phone { position: relative; width: 100%; }
.device__key { position: absolute; width: 1.3%; background: var(--bezel-key); }
.device__key--l { left: -1.1%; border-radius: 2px 0 0 2px; }
.device__key--r { right: -1.1%; border-radius: 0 2px 2px 0; background: var(--bezel-key-r); }
.device__key--1 { top: 20%; height: 5%; box-shadow: -1px 0 1px rgba(0, 0, 0, .3); }
.device__key--2 { top: 28%; height: 9%; }
.device__key--3 { top: 39%; height: 9%; }
.device__key--4 { top: 30%; height: 13%; }
/* Border-box so the bezel sits inside the device's slot. The handoff left this
   content-box on the home page, so every device overflowed its slot by its own
   padding (about 5%) — invisible at small sizes, but at large sizes two
   tablets collided. Case pages were already border-box. */
.device__body {
  box-sizing: border-box;
  width: 100%; border-radius: 15% / 6.9%; padding: 3%;
  background: var(--bezel); box-shadow: var(--bezel-shadow);
}
.device__glass {
  position: relative; width: 100%; aspect-ratio: 1206 / 2622;
  border-radius: 12.5% / 5.8%; overflow: hidden;
  background: var(--glass); box-shadow: var(--glass-edge);
}
.device__glass img { width: 100%; height: 100%; object-fit: cover; object-position: top; }
.device__island {
  position: absolute; top: 2.4%; left: 50%; transform: translateX(-50%);
  width: 30%; height: 3%; min-height: 7px;
  background: var(--island); border-radius: var(--r-pill); z-index: 4;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .04);
}
.device--tablet .device__body { border-radius: 5% / 7.2%; padding: 2.4%; background: var(--bezel-tablet); box-shadow: var(--bezel-shadow-tablet); }
.device--tablet .device__glass { aspect-ratio: 2360 / 1640; border-radius: 3.6% / 5.2%; }
.device__camera {
  position: absolute; top: 1.5%; left: 50%; transform: translateX(-50%);
  width: 1%; aspect-ratio: 1; border-radius: var(--r-dot); background: var(--camera);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .05), inset 0 0 2px rgba(90, 120, 160, .4);
}
.device__caption { font-size: var(--device-caption-size); color: var(--device-caption); letter-spacing: var(--device-caption-tracking); text-align: center; max-width: 92%; }

/* Draft builds only (node build.mjs --draft): a redrawn image not exported yet. */
.draft-gap {
  display: grid; place-items: center; aspect-ratio: 16 / 10;
  background: var(--line); color: var(--muted);
  font-family: var(--mono); font-size: var(--fs-12);
}

/* ---- A live prototype in a case page --------------------------------------
   The phone is the prototype's own page in a frame (proto/, ?embed). The frame
   is the phone's size; the prototype scales itself down when the frame is
   smaller. Sized here, not by the prototype, so the page never jumps. */
.proto {
  --proto-w: 340px;
  display: flex; flex-wrap: wrap; gap: var(--s-32) var(--s-48); align-items: center; justify-content: center;
  margin-top: var(--s-32); background: var(--surface); border-radius: var(--r-16);
  padding: var(--pad-panel-device);
}
.proto__frame { flex: 0 1 var(--proto-w); min-width: 0; }
.proto__frame iframe { display: block; width: 100%; height: 100%; border: 0; background: var(--paper); }
.proto__frame .device__island { pointer-events: none; }
.proto__side { flex: 1 1 var(--basis-label); max-width: var(--label-col-wide); display: flex; flex-direction: column; gap: var(--s-14); }
.proto__lead { font-size: var(--fs-16); line-height: var(--lh-155); color: var(--ink-soft); }
.proto__try { margin: 0; padding-left: var(--s-18); display: flex; flex-direction: column; gap: var(--s-8); font-size: var(--fs-15); line-height: var(--lh-150); color: var(--body); }
.proto__open { font-family: var(--mono); font-size: var(--fs-13); color: var(--accent); text-decoration: none; }
.proto__open:hover { color: var(--accent-hover); text-decoration: underline; }
.case-link { margin-top: var(--s-32); max-width: var(--case-link-w); }
.case-back { padding-bottom: var(--s-56); }

/* ---- Service blueprint: one artboard image, shown at its own size. */
.bp-art { margin: var(--s-32) auto var(--s-8); max-width: var(--bp-art-w); }
.bp-art img { display: block; width: 100%; height: auto; }

/* What the board taught, and what to do about it. */
.learns { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--grid-min)), 1fr)); gap: var(--s-24); margin-top: var(--s-32); }
.learn { border-top: var(--s-2) solid var(--ink); padding-top: var(--s-16); display: flex; flex-direction: column; gap: var(--s-10); }
.learn__n { font-family: var(--mono); font-size: var(--fs-12); color: var(--accent); }
.learn__h { font-weight: var(--fw-semi); font-size: var(--fs-18); line-height: var(--lh-125); letter-spacing: var(--tr-name); color: var(--ink); text-wrap: balance; }
.learn__p { font-size: var(--fs-15); line-height: var(--lh-155); color: var(--body); }
.learn__k { display: block; font-family: var(--mono); font-size: var(--fs-11); letter-spacing: var(--tr-caps-sm); text-transform: uppercase; color: var(--muted); margin-bottom: var(--s-2); }
.opps { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--opp-min)), 1fr)); gap: var(--s-24); margin-top: var(--s-32); }
.opp { background: var(--surface); border-radius: var(--r-10); padding: var(--s-20) var(--s-24) var(--s-24); }
.opp__h { font-weight: var(--fw-semi); font-size: var(--fs-17); color: var(--ink); margin-bottom: var(--s-12); }
.opp__list { margin: 0; padding-left: var(--s-18); display: flex; flex-direction: column; gap: var(--s-10); font-size: var(--fs-15); line-height: var(--lh-150); color: var(--body); }

/* ---- Chef Vola's: phone call to table -------------------------------------
   EXHIBIT BLOCK. The restaurant's own colors (oxblood dark, gold, cream),
   scoped to .vflow. One 12s loop; every panel shares the clock and starts at
   its --i quarter. Reduced motion: everything rests in its finished state. */
.vflow {
  --vf-bg: #19130D; --vf-panel: #241B13; --vf-line: #3A2E22;
  --vf-gold: #C9A05E; --vf-cream: #F2EBDD; --vf-muted: #A39276;
  --vf-green: #8CCB72; --vf-blue: #6E9BD6;
  --vf-loop: 12s; --vf-q: 3s;
  /* the small loops inside each panel */
  --vf-glow: 12px; --vf-ring: 1.6s; --vf-ring-gap: .8s; --vf-wave: 1.1s; --vf-wave-step: 90ms;
  --vf-key-step: 260ms; --vf-slot-step: 120ms; --vf-sms-gap: 1.4s; --vf-cc-gap: .7s; --vf-cc-angle: 135deg;
  position: relative; margin-top: var(--s-32);
  background: var(--vf-bg); border-radius: var(--r-16); padding: var(--s-40) var(--s-32) var(--s-32);
  color: var(--vf-cream); overflow: hidden;
}
.vflow__steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-24); position: relative; z-index: 1; }
.vflow__step { display: flex; flex-direction: column; gap: var(--s-8); animation: vf-focus var(--vf-loop) infinite; animation-delay: calc(var(--i) * var(--vf-q)); animation-fill-mode: backwards; opacity: .55; }
.vflow__art {
  position: relative; height: var(--vf-art-h); overflow: hidden; border-radius: var(--r-10); background: var(--vf-panel);
  border: var(--s-1) solid var(--vf-line); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-12);
  padding: var(--s-16); margin-bottom: var(--s-8);
}
.vflow { --vf-art-h: 290px; }
.vflow__n { font-family: var(--mono); font-size: var(--fs-12); color: var(--vf-gold); }
.vflow__h { font-weight: var(--fw-semi); font-size: var(--fs-17); color: var(--vf-cream); }
.vflow__p { font-size: var(--fs-14); line-height: var(--lh-150); color: var(--vf-muted); }
.vflow__track { position: absolute; left: var(--s-32); right: var(--s-32); top: calc(var(--s-40) + var(--vf-art-h) + var(--s-4)); height: var(--s-2); background: var(--vf-line); z-index: 0; }
.vflow__track span { position: absolute; top: calc(var(--s-4) * -1); width: var(--s-10); height: var(--s-10); border-radius: var(--r-dot); background: var(--vf-gold); box-shadow: 0 0 var(--vf-glow) var(--vf-gold); animation: vf-travel var(--vf-loop) infinite linear; }
@keyframes vf-focus { 0% { opacity: .55; } 4%, 25% { opacity: 1; } 31%, 100% { opacity: .55; } }
@keyframes vf-travel { 0% { left: 0; } 100% { left: 100%; } }

/* 01 the call */
.vf-phone { position: relative; width: var(--s-56); height: var(--s-56); border-radius: var(--r-dot); background: var(--vf-gold); display: grid; place-items: center; }
.vf-phone svg { width: var(--s-28); height: var(--s-28); position: relative; z-index: 1; }
.vf-stroke { fill: none; stroke: var(--vf-bg); stroke-width: 3.4; stroke-linejoin: round; }
.vf-ring { position: absolute; inset: 0; border-radius: var(--r-dot); border: var(--s-2) solid var(--vf-gold); animation: vf-ring var(--vf-ring) infinite ease-out; }
.vf-ring--2 { animation-delay: var(--vf-ring-gap); }
@keyframes vf-ring { from { transform: scale(1); opacity: .8; } to { transform: scale(1.9); opacity: 0; } }
.vf-wave { display: flex; gap: var(--s-4); align-items: center; height: var(--s-28); }
.vf-wave span { width: var(--s-4); border-radius: var(--s-2); background: var(--vf-cream); height: var(--s-6); animation: vf-wave var(--vf-wave) infinite ease-in-out; animation-delay: calc(var(--k) * var(--vf-wave-step)); }
@keyframes vf-wave { 0%, 100% { height: var(--s-6); } 50% { height: var(--s-26); } }
.vf-keys { display: flex; gap: var(--s-6); }
.vf-keys span { width: var(--s-28); height: var(--s-28); border-radius: var(--r-6); border: var(--s-1) solid var(--vf-line); display: grid; place-items: center; font-family: var(--mono); font-size: var(--fs-13); color: var(--vf-cream); animation: vf-key var(--vf-loop) infinite; animation-delay: calc(var(--k) * var(--vf-key-step)); }
@keyframes vf-key { 0%, 2% { background: transparent; } 4% { background: var(--vf-gold); color: var(--vf-bg); } 8%, 100% { background: transparent; } }

/* 02 checked live */
.vf-slots { width: 100%; display: flex; flex-direction: column; gap: var(--s-8); }
.vf-slot { display: grid; grid-template-columns: var(--s-40) 1fr; align-items: center; gap: var(--s-8); font-family: var(--mono); font-size: var(--fs-12); color: var(--vf-muted); }
.vf-slot b { height: var(--s-8); border-radius: var(--r-pill); background: var(--vf-line); position: relative; overflow: hidden; }
.vf-slot b::after { content: ""; position: absolute; inset: 0 auto 0 0; width: var(--w); background: var(--vf-muted); border-radius: inherit; animation: vf-fill var(--vf-loop) infinite; animation-delay: calc(var(--vf-q) + var(--k) * var(--vf-slot-step)); transform-origin: left; }
.vf-slot.is-pick { color: var(--vf-cream); }
.vf-slot.is-pick b::after { background: var(--vf-green); }
@keyframes vf-fill { 0% { transform: scaleX(0); } 6%, 100% { transform: scaleX(1); } }
.vf-chip { display: inline-flex; align-items: center; gap: var(--s-6); padding: var(--s-4) var(--s-10); border-radius: var(--r-pill); border: var(--s-1) solid var(--vf-green); color: var(--vf-green); font-size: var(--fs-12); font-weight: var(--fw-semi); }
.vf-chip i { width: var(--s-6); height: var(--s-6); border-radius: var(--r-dot); background: var(--vf-green); }

/* 03 on Lou's phone */
.vf-push { width: 100%; display: flex; gap: var(--s-10); align-items: center; padding: var(--s-8) var(--s-10); border-radius: var(--r-10); background: var(--vf-cream); color: var(--vf-bg); font-size: var(--fs-12); line-height: var(--lh-140); animation: vf-drop var(--vf-loop) infinite; animation-delay: calc(var(--vf-q) * 2); }
.vf-dot { flex: none; width: var(--s-24); height: var(--s-24); border-radius: var(--r-6); background: var(--vf-bg); box-shadow: inset 0 0 0 var(--s-6) var(--vf-gold); }
@keyframes vf-drop { 0% { transform: translateY(-140%); opacity: 0; } 4%, 100% { transform: none; opacity: 1; } }
.vf-card { width: 100%; display: flex; flex-direction: column; gap: var(--s-4); padding: var(--s-10) var(--s-12); border-radius: var(--r-10); border: var(--s-1) solid var(--vf-line); background: var(--vf-bg); }
.vf-badge { align-self: flex-start; font-size: var(--fs-11); font-weight: var(--fw-semi); color: var(--vf-gold); border: var(--s-1) solid var(--vf-gold); border-radius: var(--r-6); padding: 0 var(--s-6); letter-spacing: var(--tr-caps-sm); text-transform: uppercase; }
.vf-name { font-family: Georgia, 'Times New Roman', serif; font-size: var(--fs-17); color: var(--vf-cream); }
.vf-meta { font-size: var(--fs-12); color: var(--vf-muted); }
.vf-btn { margin-top: var(--s-4); text-align: center; font-size: var(--fs-12); font-weight: var(--fw-semi); color: var(--vf-bg); background: var(--vf-gold); border-radius: var(--r-8); padding: var(--s-6); }

/* 04 held and booked */
.vf-sms { align-self: flex-start; max-width: 92%; font-size: var(--fs-11); line-height: var(--lh-140); background: var(--vf-line); color: var(--vf-cream); padding: var(--s-6) var(--s-10); border-radius: var(--r-10) var(--r-10) var(--r-10) var(--s-2); animation: vf-pop var(--vf-loop) infinite; animation-delay: calc(var(--vf-q) * 3); }
.vf-sms--2 { background: var(--vf-blue); color: var(--vf-bg); animation-delay: calc(var(--vf-q) * 3 + var(--vf-sms-gap)); }
.vf-cc { position: relative; width: 70%; aspect-ratio: 1.6; border-radius: var(--r-8); background: linear-gradient(var(--vf-cc-angle), var(--vf-gold), var(--vf-panel)); padding: var(--s-10); display: flex; flex-direction: column; justify-content: space-between; animation: vf-pop var(--vf-loop) infinite; animation-delay: calc(var(--vf-q) * 3 + var(--vf-cc-gap)); }
.vf-cc-chip { width: var(--s-24); height: var(--s-18); border-radius: var(--s-3); background: var(--vf-cream); opacity: .7; }
.vf-cc-num { font-family: var(--mono); font-size: var(--fs-12); color: var(--vf-cream); }
.vf-ok { position: absolute; right: calc(var(--s-8) * -1); top: calc(var(--s-8) * -1); width: var(--s-24); height: var(--s-24); border-radius: var(--r-dot); background: var(--vf-green); color: var(--vf-bg); display: grid; place-items: center; font-size: var(--fs-13); font-weight: var(--fw-bold); }
@keyframes vf-pop { 0% { transform: scale(.85); opacity: 0; } 4%, 100% { transform: none; opacity: 1; } }

@media (max-width: 860px) {
  .vflow__steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .vflow__track { display: none; }
}
@media (max-width: 480px) {
  .vflow { padding: var(--s-24) var(--s-16); }
  .vflow__steps { grid-template-columns: minmax(0, 1fr); }
}
@media (prefers-reduced-motion: reduce) {
  .vflow *, .vflow__step { animation: none !important; }
  .vflow__step { opacity: 1; }
}
.vf-push, .vf-sms, .vf-cc, .vf-slot b::after { animation-fill-mode: backwards; }
