/* Self-hosted variable fonts (OFL 1.1): Archivo for display, Geist for text, Geist Mono for labels. */

@font-face {
  font-family: "Geist";
  src: url("../fonts/geist-latin-var.woff2?v=9d846db8") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Geist Mono";
  src: url("../fonts/geist-mono-latin-var.woff2?v=0e04bb6e") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Archivo";
  src: url("../fonts/archivo-latin-var.woff2?v=510b8100") format("woff2");
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
}


/* Design tokens: the single source for colour, type, space, grid and motion.
   Rule of the house: no gradients anywhere. Panton ring colours are for graphics only, never text or controls. */

:root {
  /* Colour: UI */
  --surface: #F4F3F0;          /* near-white, pulled toward the Vitra silver */
  --surface-silver: #E4E2DF;   /* secondary panels */
  --ink: #141414;              /* 16.6:1 on surface */
  --ink-muted: #5C5A57;        /* 6.2:1 on surface; captions, meta */
  --rule: #D6D3CE;             /* hairlines */
  --accent: #4E338F;           /* Panton violet, the only UI accent; 8.6:1 on surface */
  --accent-tint: #E6E0F2;      /* flat highlighter behind ink text (15:1) */
  --violet: #4E338F;           /* brand violet for graphics (markers, band dots, the hero poster), in both themes */
  --on-accent: #FFFFFF;

  /* Colour: the Panton rings: concentric bands on violet, in our own palette (graphics only,
     never text or controls). */
  --ring-1: #F6E3B4;   /* cream */
  --ring-2: #F2735A;   /* coral */
  --ring-3: #B8A6F2;   /* lilac */
  --ring-4: #2B1A55;   /* plum */

  /* Type families: Archivo expanded for display (chosen in lab/type), Geist for text */
  --font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --font-text: "Geist", "Helvetica Neue", Arial, sans-serif;
  --display-stretch: 118%;
  --font-mono: "Geist Mono", ui-monospace, Menlo, Consolas, monospace;

  /* Type scale: fluid between 375px and 1440px viewports */
  --step-display: clamp(2.5rem, 1.2rem + 5.6vw, 6.25rem);
  --step-hero: clamp(2.25rem, 1.4rem + 3.6vw, 5rem);   /* the hero sentence: 7 of 12 columns, beside the illustration */
  --step-h1: clamp(2.5rem, 1.46rem + 4.4vw, 5.5rem);
  --step-h2: clamp(1.75rem, 1.3rem + 1.9vw, 3rem);
  --step-h3: clamp(1.25rem, 1.1rem + 0.6vw, 1.625rem);
  --step-lead: clamp(1.125rem, 1.05rem + 0.35vw, 1.375rem);
  --step-body: 1.0625rem;      /* 17px */
  --step-small: 0.875rem;
  --step-label: 0.8125rem;   /* 13px */
  --step-note: 0.9375rem;    /* 15px: sentence-length notes, never uppercase */

  --leading-tight: 0.95;
  --leading-snug: 1.15;
  --leading-body: 1.6;
  --tracking-display: -0.05em;
  --tracking-tight: -0.02em;
  --tracking-label: 0.08em;

  /* Space: 4/8 based */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px; --s-5: 24px; --s-6: 32px;
  --s-7: 48px; --s-8: 64px; --s-9: 96px; --s-10: 128px; --s-11: 192px;
  --section-gap: clamp(96px, 60px + 9vw, 192px);

  /* Grid */
  --columns: 12;
  --gutter: clamp(16px, 2vw, 32px);
  --margin: clamp(20px, 5vw, 80px);
  --max-width: 1440px;

  /* Shape */
  --radius-s: 6px;
  --radius-m: 12px;
  --radius-l: 20px;

  /* Motion */
  --dur-fast: 200ms;
  --dur-base: 400ms;
  --dur-slow: 700ms;
  --ease-out: cubic-bezier(.2, .7, .2, 1);
  --band-duration: 60s;        /* one full loop of the AI pipeline band */
}

/* Light is the default for everyone; dark only when picked in the header (data-theme on <html>).
   The choice is saved and restored before first paint by the inline script in <head>. */
:root { color-scheme: light; }
:root[data-theme="dark"] {
  color-scheme: dark;
  --surface: #141312;
  --surface-silver: #22201E;
  --ink: #F1EFEA;              /* 16:1 on surface */
  --ink-muted: #A7A29B;        /* 7.2:1 on surface, 6.3:1 on silver */
  --rule: #3A3733;
  --accent: #B8A6F2;           /* the violet, lifted for dark: 8.5:1 on surface */
  --on-accent: #141312;
  --accent-tint: #2D2442;      /* highlighter: ink on it is 13:1 */
}

@media (max-width: 767px) {
  :root { --columns: 4; }
}

/* Very narrow screens (and 400% zoom): long Portuguese words must fit without hyphenation. */
@media (max-width: 360px) {
  :root {
    --step-display: 2.2rem;
    --step-hero: 2.2rem;
    --step-h1: 2rem;
    --step-h2: 1.6rem;
  }
}

/* Base: reset, type defaults, links, focus, motion preferences. */

*, *::before, *::after { box-sizing: border-box; }

/* A flat highlighter for the one sentence a section must not lose. */
.highlight {
  padding: 0.04em 0.3em;
  border-radius: 4px;
  background: var(--accent-tint);
  color: var(--ink);
  font-weight: 600;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* Text hierarchy inside running copy, strongest first:
   strong 700        opens a step or a decision (a lead-in);
   .highlight 600    the one sentence a section must not lose, on the tint;
   .term 600 violet  a name from the product's world: a product, a company, a role, a screen, a
                     document, an assistant, a UI label (scripts/terms.mjs marks them from
                     src/data/terms.json). The site's one accent (8.6:1 light, 8.5:1 dark) and no
                     underline, so it never reads as a link (links are ink and underlined);
   .foreign          an English word in the Portuguese copy (lang="en"): the same violet 600, in
                     italic, the Portuguese convention for a foreign word, so it is told apart from a name;
   body 400; .note and .label stay quiet. */
strong { font-weight: 700; }
.term, .foreign { font-weight: 600; color: var(--accent); }
.foreign { font-style: italic; }

/* `hidden` must win over any component `display` (the motion toggles are hidden until JS shows them). */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--surface);
  color: var(--ink);
  font-family: var(--font-text);
  font-size: var(--step-body);
  line-height: var(--leading-body);
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, p, ul, ol, figure, blockquote, dl, dd { margin: 0; }
ul[role="list"], ol[role="list"] { list-style: none; padding: 0; }

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: var(--display-stretch);
  line-height: var(--leading-snug);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
  overflow-wrap: break-word;   /* safety net only; display type is never auto-hyphenated */
  hyphens: manual;
}

p { text-wrap: pretty; max-width: 62ch; }

img, svg, video { display: block; max-width: 100%; height: auto; }

a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:hover { color: var(--accent); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: 6px;
}
/* Keyboard focus eases in instead of snapping on; a click only dims the link for a moment. */
@media (prefers-reduced-motion: no-preference) {
  :focus-visible { animation: focus-in 180ms var(--ease-out, ease-out); }
  a, button { transition: opacity 150ms ease-out; }
}
@keyframes focus-in { from { outline-color: transparent; outline-offset: 8px; } }
a:active, button:active { opacity: 0.6; }

::selection { background: var(--accent); color: var(--on-accent); }

.label {
  font-family: var(--font-mono);
  font-size: var(--step-label);
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  line-height: 1.3;
}

.muted { color: var(--ink-muted); }

/* Sentence-length notes (footnotes, NDA note, captions): readable text, never mono caps. */
.note {
  font-family: var(--font-text);
  font-size: var(--step-note);
  line-height: 1.5;
  color: var(--ink-muted);
  text-transform: none;
  letter-spacing: 0;
}

/* Anchored sections land with breathing room below the sticky header (--header-h, set by main.js;
   the fallback is the full-height header on desktop). */
html { scroll-padding-top: calc(var(--header-h, 72px) + var(--s-5)); }   /* anchors and keyboard focus alike (WCAG 2.4.11) */

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: var(--margin);
  top: -100px;
  z-index: 100;
  padding: var(--s-3) var(--s-4);
  background: var(--ink);
  color: var(--surface);
  text-decoration: none;
}
.skip-link:focus { top: var(--s-4); }

/* Cross-document page transitions (progressive: ignored where unsupported). */
@view-transition { navigation: auto; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  @view-transition { navigation: none; }
}

/* <picture> wraps content images (AVIF with a JPEG fallback, scripts/build.mjs); it takes no box, so
   every image keeps the layout it had as a direct child. */
picture { display: contents; }

/* Layout: page frame with named lines, and the 12/8/4 column grid inside it. */

:root { --content-max: 82rem; }

.frame {
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--margin), 1fr)
    [content-start] min(100% - 2 * var(--margin), var(--content-max)) [content-end]
    minmax(var(--margin), 1fr) [full-end];
}
.frame > * { grid-column: content; }
.frame > .bleed { grid-column: full; }

.grid {
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  column-gap: var(--gutter);
}

.section { padding-block: var(--section-gap) 0; }
.section:last-of-type { padding-block-end: var(--section-gap); }

@media (min-width: 768px) and (max-width: 1023px) {
  :root { --columns: 8; }
}

/* Components. Rule of the house: no gradients; Panton ring colours only in graphics (markers, covers, the hero illustration). */

/* Site header: stays on top while scrolling, slimmer once the page has moved (main.js) ---- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  padding-block: var(--s-5);
  background: var(--surface);
  transition: padding-block var(--dur-base) var(--ease-out), margin-block-end var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
/* Slimmer once stuck, and the lost height comes back as margin in step with the padding, so the
   header's place in the page never changes: nothing below it jumps while the visitor scrolls. */
.site-header.is-stuck { padding-block: var(--s-3); margin-block-end: calc(2 * (var(--s-5) - var(--s-3))); box-shadow: 0 1px 0 var(--rule); }
.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--s-5);
}
.site-header__name { display: inline-block; padding-block: 4px; margin-inline-end: auto; text-decoration: none; }   /* a 24 px target */
.site-header__nav { display: flex; flex-wrap: wrap; justify-content: flex-end; column-gap: var(--s-5); }
.site-header__nav a { display: inline-block; padding-block: 6px; text-decoration: none; }
/* Hover and the current item look the same: violet with a violet underline. Current = the page (Work, Process), the
   section of a case (Work), or on the home the section in view (main.js initNavSpy). The case bar matches. */
.site-header__nav a:hover, .site-header__nav a[aria-current] { color: var(--accent); text-decoration: underline; text-decoration-color: var(--accent); }
.site-header__tools { display: flex; align-items: center; gap: var(--s-2); }
.theme-toggle, .site-header__menu {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  margin-block: -4px;
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: 50%;
  background: none;
  color: var(--ink);
  cursor: pointer;
}
.theme-toggle:hover, .site-header__menu:hover { border-color: var(--accent); color: var(--accent); }
.theme-toggle svg, .site-header__menu svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.theme-toggle[aria-pressed="true"] .theme-toggle__moon,
.theme-toggle[aria-pressed="false"] .theme-toggle__sun { display: none; }
.site-header__menu { display: none; }
.site-header__menu[aria-expanded="true"] .site-header__menu-open,
.site-header__menu[aria-expanded="false"] .site-header__menu-close { display: none; }

/* Below 800px the links no longer fit one line beside the name (PT wraps from 768px). With JS they
   fold behind a menu button; the theme toggle stays outside, next to it. A disclosure, not a dialog:
   the panel drops below the header, Esc or a tap outside closes it (main.js initMenu). Without JS
   the links simply wrap under the name. The header keeps one height here: no slimming on scroll. */
@media (max-width: 799px) {
  .site-header, .site-header.is-stuck { padding-block: var(--s-3); margin-block-end: 0; }
  html:not(.js) .site-header__inner { flex-wrap: wrap; row-gap: var(--s-1); }
  html:not(.js) .site-header__nav { justify-content: flex-start; column-gap: var(--s-3); }
  .js .site-header__menu:not([hidden]) { display: inline-grid; order: 3; }   /* after the toggle on screen; before the links in the DOM, so they follow it */
  .site-header__tools { order: 2; }
  .js .theme-toggle, .js .site-header__menu { width: 44px; height: 44px; margin-block: 0; }   /* touch targets */
  .js .theme-toggle svg, .js .site-header__menu svg { width: 20px; height: 20px; }
  .js .site-header__nav {
    display: none;
    position: absolute;
    inset-inline: 0;
    top: 100%;
    flex-direction: column;
    padding: var(--s-2) var(--margin) var(--s-5);
    background: var(--surface);
    border-block-end: 1px solid var(--rule);
    box-shadow: 0 12px 24px -16px rgb(0 0 0 / 0.25);
  }
  .js .site-header[data-menu-open] .site-header__nav { display: flex; }
  .js .site-header__nav a { display: block; padding-block: 14px; border-block-start: 1px solid var(--rule); font-size: 0.9375rem; }
  .js .site-header__nav a:first-child { border-block-start: 0; }
  .js .site-header__nav .site-header__lang { margin-block-start: var(--s-3); border-block-start-color: var(--ink); }
}

/* Cases bar (case pages, layout.mjs caseBar): a strip inside the sticky header, under its row, with every
   case in the home's order, the open one marked like the menu's current item, and round arrows (the theme toggle's shape) to the
   case before and after. The header keeps its slimming: only its top padding changes, so the margin
   that holds its place makes up for that alone. Below 900px the four no longer fit one line: only the
   open case shows, as "03 of 04 · name"; on phones "03 · name", on two lines only when it can't fit one. */
.site-header:has(.case-bar) { padding-block-end: var(--s-2); }
/* On arrival the bar slides down from under the header row, quickly; nothing moves with reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  .case-bar { animation: case-bar-in 280ms var(--ease-out) both; }
}
@keyframes case-bar-in { from { opacity: 0; transform: translateY(-14px); clip-path: inset(14px 0 0 0); } to { opacity: 1; transform: none; clip-path: inset(0); } }
.site-header.is-stuck:has(.case-bar) { padding-block-end: var(--s-2); margin-block-end: calc(var(--s-5) - var(--s-3)); }
.case-bar { display: flex; align-items: center; gap: var(--s-4); margin-block-start: var(--s-3); padding-block-start: var(--s-2); border-block-start: 1px solid var(--rule); }
.case-bar__list { display: flex; flex: 1; min-width: 0; column-gap: var(--s-6); margin: 0; padding: 0; list-style: none; }
.case-bar__list a { display: inline-block; padding-block: 6px; color: var(--ink-muted); text-decoration: none; white-space: nowrap; }
.case-bar__list a:hover, .case-bar__list a[aria-current] { color: var(--accent); text-decoration: underline; text-decoration-color: var(--accent); }   /* the menu's hover and current style */
.case-bar__of { display: none; }
.case-bar__step { display: inline-grid; flex: none; place-items: center; width: 28px; height: 28px; border: 1px solid var(--rule); border-radius: 50%; color: var(--ink); }
a.case-bar__step:hover { border-color: var(--accent); color: var(--accent); }
.case-bar__step--off { opacity: 0.35; }
.case-bar__step svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
@media (max-width: 899px) {
  .case-bar:has([aria-current]) .case-bar__list { justify-content: center; }
  .case-bar:has([aria-current]) .case-bar__list li:not(:has([aria-current])) { display: none; }
  .case-bar:has([aria-current]) .case-bar__list li { min-width: 0; }
  .case-bar:has([aria-current]) .case-bar__list a { white-space: normal; text-align: center; }   /* wraps rather than clips (WCAG 1.4.12) */
  .case-bar__of { display: inline; }
  .case-bar:not(:has([aria-current])) .case-bar__list { overflow-x: auto; }
}
@media (max-width: 799px) {
  .site-header:has(.case-bar), .site-header.is-stuck:has(.case-bar) { padding-block-end: var(--s-1); margin-block-end: 0; }
  .case-bar { gap: var(--s-2); margin-block-start: var(--s-2); padding-block-start: var(--s-1); }
  .case-bar__step { width: 44px; height: 44px; }
  .case-bar__step svg { width: 18px; height: 18px; }
}
@media (max-width: 479px) { .case-bar__of { display: none; } .case-bar__num::after { content: " ·"; content: " ·" / ""; } }   /* phones: the name before the count */

/* Ring marker (cases, posters): five concentric circles in an inline SVG, outermost first; each band
   is 8% of the diameter. SVG, not inset shadows: the shadows let the violet fray the outer edge.
   Plum never touches the violet: it would vanish. Each variant reorders the bands. */
.marker {
  --m: var(--marker-size, 56px);
  --r1: var(--ring-1); --r2: var(--ring-2); --r3: var(--ring-4); --r4: var(--ring-3);
  display: inline-block;
  width: var(--m);
  height: var(--m);
  max-width: none;
  flex: none;
}
.marker circle:nth-child(1) { fill: var(--r1); }
.marker circle:nth-child(2) { fill: var(--r2); }
.marker circle:nth-child(3) { fill: var(--r3); }
.marker circle:nth-child(4) { fill: var(--r4); }
.marker circle:nth-child(5) { fill: var(--violet); }
.marker--2 { --r1: var(--ring-2); --r2: var(--ring-1); --r3: var(--ring-4); --r4: var(--ring-3); }
.marker--3 { --r1: var(--ring-3); --r2: var(--ring-4); --r3: var(--ring-1); --r4: var(--ring-2); }
.marker--4 { --r1: var(--ring-1); --r2: var(--ring-4); --r3: var(--ring-2); --r4: var(--ring-3); }

/* Hero: the sentence on the left, the illustration on the right (stacked below 1024px) */
.hero { padding-block: clamp(48px, 4vw + 32px, 128px) 0; }
.hero__grid {
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  column-gap: var(--gutter);
  row-gap: var(--s-8);
  align-items: center;
}
.hero__text { grid-column: 1 / -1; }
.hero-art { grid-column: 1 / -1; width: 100%; max-width: 34rem; }
/* On a phone the poster leads, so the animation plays where it is seen (it also waits until half
   of it is on screen, main.js). The DOM keeps the sentence first for screen readers. */
@media (max-width: 767px) { .hero-art { order: -1; } }
@media (min-width: 1024px) {
  .hero__text { grid-column: 1 / span 7; }
  .hero-art { grid-column: 8 / -1; max-width: none; }
}

.hero__title {
  font-size: var(--step-hero);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-display);
  font-weight: 800;
}
.hero__title .accent { color: var(--accent); }

.hero__lead {
  margin-block-start: var(--s-6);
  font-size: var(--step-lead);
  max-width: 46ch;
}
.hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-5);
  margin-block-start: var(--s-6);
  color: var(--ink-muted);
}
.hero__cta { display: flex; flex-wrap: wrap; column-gap: var(--s-6); row-gap: var(--s-2); margin-block-start: var(--s-5); }
.hero__cta a {
  display: inline-block;
  padding-block: 6px;
  font-family: var(--font-mono);
  font-size: var(--step-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.35em;
}
.hero__cta a:hover { color: var(--accent); }

/* Hero illustration: a design canvas that ends as a poster (markup in src/partials/hero-art.html,
   story in main.js). The styles below are the finished poster; main.js drives everything before it. */
/* A light artboard in either theme, like a screenshot of a design tool: it re-declares the light palette. */
.hero-art {
  position: relative;
  --art-tool-x: 0px; --art-prompt: 0;
  --ink: #141414; --ink-muted: #5C5A57; --rule: #D6D3CE; --surface-silver: #E4E2DF;
  --accent: #4E338F; --on-accent: #FFFFFF;
}
.hero-art__svg { display: block; width: 100%; height: auto; }
/* The finished card leans a little towards the mouse (main.js sets --tilt-*; 0 without it). */
@media (prefers-reduced-motion: no-preference) {
  .hero-art[data-motion="on"] { transform: perspective(1200px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)); transition: transform var(--dur-slow) var(--ease-out); }
}
.art-canvas, .art-wipe { fill: var(--accent); }
.art-ring { transform-box: fill-box; transform-origin: center; }
.art-ring--1 { fill: var(--ring-1); }
.art-ring--2 { fill: var(--ring-2); }
.art-ring--3 { fill: var(--ring-4); }
.art-ring--4 { fill: var(--ring-3); }
.art-name text {
  font-family: var(--font-display);
  font-stretch: var(--display-stretch);
  font-weight: 800;
  font-size: 54px;
  letter-spacing: -0.02em;
  fill: #FFFFFF;
}
.art-crops { fill: none; stroke: #FFFFFF; stroke-width: 1; stroke-opacity: 0.8; }
.hero-art pattern circle { fill: #CAC6C0; }

/* Editing shows the path, its points and the dragged point's handles. */
.art-outline { fill: none; stroke: var(--accent); stroke-width: 1.5; stroke-linejoin: round; }
.art-anchors rect { fill: #FFFFFF; stroke: var(--accent); stroke-width: 1.5; }
.art-anchors rect.is-active { fill: var(--accent); }
.art-handles { opacity: 0; }
.art-handles path { fill: none; stroke: var(--accent); stroke-width: 1; }
.art-handles circle { fill: #FFFFFF; stroke: var(--accent); stroke-width: 1.5; }

/* One pin per stakeholder: a coloured dot while its point is out of place, a check once it is home. */
.art-pin rect { fill: #FFFFFF; stroke: var(--rule); }
.art-pin text { font-family: var(--font-text); font-size: 12px; font-weight: 600; fill: var(--ink); }
.art-pin__dot { fill: var(--pin, var(--accent)); }
.art-pin__check { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; opacity: 0; }
.art-pin.is-aligned .art-pin__dot { opacity: 0; }
.art-pin.is-aligned .art-pin__check { opacity: 1; }
.art-pin--2 { --pin: var(--ring-2); }
.art-pin--3 { --pin: var(--ring-3); }
.art-pin--4 { --pin: var(--ring-4); }
.art-pin--5 { --pin: var(--ring-2); }
.art-pin--6 { --pin: var(--ink); }
.art-pin--7 { --pin: var(--ring-3); }
.art-pin--8 { --pin: var(--ring-4); }

/* Toolbar, and the prompt it turns into. */
.art-toolbar { opacity: calc(1 - var(--art-prompt)); }
.art-toolbar__bg { fill: #FFFFFF; stroke: var(--rule); }
.art-toolbar__active { fill: var(--accent); transform: translateX(var(--art-tool-x)); }
.art-tool { color: var(--ink); fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.hero-art[data-tool="select"] .art-tool--select,
.hero-art[data-tool="direct"] .art-tool--direct,
.hero-art[data-tool="ai"] .art-tool--ai { color: var(--on-accent); }
/* Illustrator's pair: Selection is the solid arrow, Direct Selection the hollow one. */
.art-tool--select path { fill: currentColor; }
.art-tool--direct path { fill: #FFFFFF; }
.hero-art[data-tool="direct"] .art-tool--direct path { fill: var(--accent); }
.art-prompt { opacity: var(--art-prompt); }
.art-prompt__bg { fill: #FFFFFF; stroke: var(--accent); stroke-width: 1.5; }
.art-prompt__spark, .art-prompt__send, .art-prompt__caret { fill: var(--accent); }
.art-prompt__text { font-family: var(--font-text); font-size: 13px; font-weight: 500; fill: var(--ink); }
.art-prompt__arrow { fill: none; stroke: var(--on-accent); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

.art-cursor { stroke: #FFFFFF; stroke-width: 1.5; stroke-linejoin: round; }
.art-me .art-cursor, .art-me__tag { fill: var(--accent); }
.art-tag { font-family: var(--font-text); font-size: 12px; font-weight: 600; fill: var(--on-accent); }
.art-me__press { transform-box: fill-box; transform-origin: 0 0; }
.art-me.is-pressed .art-me__press { transform: scale(.84); }

.hero-art__replay {
  position: absolute;
  right: 7.4%;
  bottom: 4.7%;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: 50%;
  background: #FFFFFF;
  color: var(--ink);
  cursor: pointer;
}
.hero-art__replay:hover { border-color: var(--accent); color: var(--accent); }
.hero-art__icon { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.hero-art__icon--skip path:first-child { fill: currentColor; }
.hero-art__replay[data-mode="skip"] .hero-art__icon--replay,
.hero-art__replay[data-mode="replay"] .hero-art__icon--skip { display: none; }

/* Small transitions for the states main.js switches; the loop itself is scripted (initHeroArt). */
@media (prefers-reduced-motion: no-preference) {
  .hero-art[data-motion="on"] :is(.art-pin, .art-pin__dot, .art-pin__check) { transition: opacity var(--dur-fast) linear; }
  .hero-art[data-motion="on"] .art-toolbar__active { transition: transform var(--dur-fast) var(--ease-out); }
  .hero-art[data-motion="on"] .art-tool { transition: color var(--dur-fast) linear; }
  .hero-art[data-motion="on"] .art-me__press { transition: transform 90ms ease-out; }
  .hero-art[data-motion="on"] .art-prompt__caret { animation: art-caret 1s steps(1) infinite; }
  /* Until main.js has drawn the first frame, show nothing rather than a flash of the poster;
     if the script never arrives, the poster appears anyway. */
  .js .hero-art:not([data-ready]) { opacity: 0; animation: art-failsafe 0s linear 2.5s forwards; }
}
@keyframes art-failsafe { to { opacity: 1; } }
@keyframes art-caret { 50% { opacity: 0; } }

/* Section head: index · title · intro on one 12-column row ------------- */
.section-head {
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  column-gap: var(--gutter);
  row-gap: var(--s-4);
  align-items: baseline;
  padding-block-start: var(--s-5);
  border-block-start: 1px solid var(--ink);
  margin-block-end: var(--s-8);
}
.section-head__index { grid-column: 1 / span 1; color: var(--ink-muted); }
.section-head__title {
  grid-column: 2 / span 6;
  font-size: var(--step-h1);
  font-weight: 800;
  line-height: var(--leading-tight);
  letter-spacing: -0.04em;
}
.section-head__intro { grid-column: 8 / -1; align-self: start; color: var(--ink-muted); }
/* A date line under the title (Recent work): the intro keeps its place beside both. */
.section-head__updated { grid-column: 2 / span 6; color: var(--ink-muted); }
@media (min-width: 1024px) {
  .section-head__updated { grid-row: 2; }
  .section-head:has(.section-head__updated) .section-head__intro { grid-row: 1 / span 2; }
}
@media (max-width: 1023px) { .section-head__updated { grid-column: 2 / -1; } }
@media (max-width: 767px) { .section-head__updated { grid-column: 1 / -1; } }
/* Beside the title, the intro's first line starts at the title's lowercase height (measured: 16px
   at 1440, scaling with the title). Stacked below it, no offset. */
@media (min-width: 1024px) { .section-head__intro { padding-block-start: calc(var(--step-h1) * 0.273 - 7.7px); } }
.section-head:not(:has(.section-head__intro)) .section-head__title { grid-column: 2 / -1; }
@media (max-width: 1023px) {
  .section-head__title { grid-column: 2 / -1; }
  .section-head__intro { grid-column: 2 / -1; }
}
@media (max-width: 767px) {
  .section-head__index, .section-head__title, .section-head__intro { grid-column: 1 / -1; }
}

/* Case cards: the story in the section title's columns, a poster of the work in the intro's
   (stacked below 1024px). Meta on the poster's top line, "Read the case" on its bottom line. */
.cases { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s-9); }

.case-card {
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  column-gap: var(--gutter);
  row-gap: var(--s-5);
  align-items: start;
}
.case-card__text { grid-column: 2 / -1; display: grid; row-gap: var(--s-3); align-content: start; }
.case-card__media { grid-column: 2 / -1; display: block; text-decoration: none; }
@media (min-width: 1024px) {
  .case-card__text { grid-column: 2 / span 6; grid-row: 1; align-self: stretch; grid-template-rows: auto auto auto 1fr; }
  .case-card__media { grid-column: 8 / -1; grid-row: 1; }
  .case-card__more { align-self: end; }
}
@media (max-width: 767px) { .case-card__text, .case-card__media { grid-column: 1 / -1; } }
/* Work page: the ring marker stands in the head's index column (the home has "01" there). */
.section-head__index .marker { --marker-size: 28px; display: block; }
/* Work page: the link to the case that isn't on the home sits in the cards' text column. */
.work-more { max-width: none; display: grid; grid-template-columns: repeat(var(--columns), minmax(0, 1fr)); column-gap: var(--gutter); }
.work-more > a { grid-column: 2 / -1; justify-self: start; }
@media (max-width: 767px) { .work-more > a { grid-column: 1 / -1; } }

.plate {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-l);
  background: var(--surface-silver);
}
.plate > img, .plate > picture > img { width: 100%; height: 100%; object-fit: cover; }
.plate .marker { position: absolute; top: var(--s-5); right: var(--s-5); }
.plate__placeholder {
  position: absolute;
  left: var(--s-6);
  bottom: calc(var(--s-6) * -0.6);
  font-family: var(--font-display);
  font-stretch: var(--display-stretch);
  font-weight: 800;
  font-size: clamp(8rem, 4rem + 18vw, 22rem);
  line-height: 1;
  letter-spacing: -0.06em;
  color: var(--surface);
}

.case-card__meta { color: var(--ink-muted); }
.case-card__title {
  font-size: var(--step-h2);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: var(--leading-snug);
}
.case-card__title a { text-decoration: none; }
.case-card__more a { display: inline-block; padding-block: 4px; color: var(--accent); text-decoration: none; }
.case-card__more a:hover { text-decoration: underline; text-decoration-color: var(--accent); }
.case-card__outcome { color: var(--ink-muted); max-width: 46ch; }

/* The poster: a flat violet plate, the case's Panton ring window (its marker, in the case's own
   ring order) and a detail of the real screen at a readable scale, coming out of the window and
   running off the plate. Sizes in cqw, so the whole poster scales as one piece. */
.poster {
  position: relative;
  overflow: hidden;
  container-type: inline-size;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-l);
  background: var(--violet);
}
@media (min-width: 1024px) { .poster { aspect-ratio: 4 / 5; } }   /* tall enough for the longest card text next to it */
@media (min-width: 1280px) { .poster { aspect-ratio: 1; } }
.poster__rings { position: absolute; --marker-size: 78cqw; }
.poster__ui {
  position: absolute;
  max-width: none;
  border-radius: 1.6cqw;
  box-shadow: 2.4cqw 2.4cqw 0 rgb(20 20 20 / 0.32);   /* flat offset shadow, no blur */
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
.case-card:has(a:hover) .poster__ui { transform: translate(-0.8cqw, -0.8cqw); box-shadow: 3.2cqw 3.2cqw 0 rgb(20 20 20 / 0.32); }
/* Three links open the case: the poster (mouse only; the title is the link for keyboards and screen readers),
   the title and "Read the case". The empty space between them opens nothing. Pointing at any of the three
   lights the card as one: a pill on the poster ("Read the case →", from data-more; decorative, the link
   already says it), the title in violet and the arrow nudging forward. Keyboard focus shows the same. */
.case-card__media::after {
  content: attr(data-more); content: attr(data-more) / "";
  position: absolute; left: 4cqw; bottom: 4cqw; z-index: 1;
  padding: 0.7em 1.1em; border-radius: 999px;
  background: var(--surface); color: var(--ink);
  font-family: var(--font-mono); font-size: var(--step-label); letter-spacing: var(--tracking-label); text-transform: uppercase; line-height: 1;
  box-shadow: 0.6cqw 0.6cqw 0 rgb(20 20 20 / 0.32);
  opacity: 0; transform: translateY(6px); pointer-events: none;
}
.case-card:has(a:hover, a:focus-visible) .case-card__media::after { opacity: 1; transform: none; }
.case-card:has(a:hover) .case-card__title a { color: var(--accent); }
.case-card__more { justify-self: start; transition: transform var(--dur-base) var(--ease-out); }
.case-card:has(a:hover) .case-card__more { transform: translateX(4px); }
@media (prefers-reduced-motion: no-preference) { .case-card__media::after { transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out); } }
@media (prefers-reduced-motion: reduce) { .case-card:has(a:hover) .case-card__more { transform: none; } }
/* Region Admin: the window top left; the question card and the Edit roles button it is pinned to. */
.poster--da .poster__rings { left: -9cqw; top: -3cqw; }
.poster--da .poster__ui { left: 20cqw; top: 16cqw; width: 76cqw; }
/* Ready for Audit: the window low on the left; the table runs off the right edge, as it does on screen. */
.poster--ctb .poster__rings { left: -12cqw; top: auto; bottom: -14cqw; }
.poster--ctb .poster__ui { left: 12cqw; top: 12cqw; width: 92cqw; }
/* From my project to the whole team: the window low on the right; the walkthrough and the prototype it opens. */
.poster--tt .poster__rings { right: -12cqw; top: auto; bottom: -14cqw; }
.poster--tt .poster__ui { left: 9cqw; top: 12cqw; width: 84cqw; }
/* UI Inspector: the window top right; the panel on the left. */
.poster--le .poster__rings { right: -9cqw; top: -3cqw; }
.poster--le .poster__ui { left: 8cqw; top: 10cqw; width: 62cqw; }
@media (max-width: 767px) {
  .poster--da .poster__ui { left: 12cqw; width: 84cqw; }
  .poster--le .poster__ui { width: 70cqw; }
}

/* Cases still being written: a compact list, clearly not links, on the cards' columns. */
.wip {
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  column-gap: var(--gutter);
  margin-block-start: var(--s-9);
}
.wip__title { grid-column: 2 / -1; color: var(--ink-muted); margin-block-end: var(--s-4); }
.wip ul { grid-column: 1 / -1; list-style: none; margin: 0; padding: 0; }
.wip li {
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  column-gap: var(--gutter);
  row-gap: var(--s-2);
  align-items: start;
  padding-block: var(--s-4);
  border-block-start: 1px solid var(--rule);
}
.wip li > * { grid-column: 2 / -1; }
.wip li h4 { font-family: var(--font-display); font-stretch: var(--display-stretch); font-weight: 800; font-size: var(--step-h3); letter-spacing: -0.02em; }
.wip li .label { color: var(--ink-muted); }
.wip li p:not(.label) { color: var(--ink-muted); font-size: var(--step-small); }
@media (min-width: 1024px) {
  .wip li .label, .wip li h4 { grid-column: 2 / span 6; }
  .wip li p:not(.label) { grid-column: 8 / -1; grid-row: 1 / span 2; }
}
@media (max-width: 767px) { .wip__title, .wip li > * { grid-column: 1 / -1; } }

/* AI pipeline band: the site's single continuous motion ---------------- */
.band-wrap { margin-block: var(--s-7) var(--s-8); }
.band-toggle {
  justify-self: end;
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 44px;
  padding: var(--s-2) var(--s-4);
  margin-block-end: var(--s-4);
  border: 1px solid var(--ink-muted);
  border-radius: 999px;
  background: none;
  color: var(--ink);
  cursor: pointer;
}
.band-toggle:hover { border-color: var(--accent); color: var(--accent); }
.band {
  overflow: hidden;
  border-block: 1px solid var(--rule);
  padding-block: var(--s-5);
}
.band__track { display: flex; width: max-content; }
.band__group {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}
.band__group li {
  display: flex;
  align-items: center;
  font-family: var(--font-display);
  font-stretch: var(--display-stretch);
  font-weight: 800;
  font-size: clamp(3rem, 1.6rem + 6vw, 7.5rem);
  line-height: 1;
  letter-spacing: -0.045em;
  white-space: nowrap;
}
.band__group li::after {
  content: "";
  display: inline-block;
  width: 0.5em;
  aspect-ratio: 1;
  margin-inline: 0.5em;
  /* the ring marker as an image (colours fixed here: keep in sync with --ring-* and --violet) */
  background: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20100%20100%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22%23F6E3B4%22%2F%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2242%22%20fill%3D%22%23F2735A%22%2F%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2234%22%20fill%3D%22%232B1A55%22%2F%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2226%22%20fill%3D%22%23B8A6F2%22%2F%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2218%22%20fill%3D%22%234E338F%22%2F%3E%3C%2Fsvg%3E") center / contain no-repeat;
}
@media (prefers-reduced-motion: no-preference) {
  .band[data-motion="on"] .band__track { animation: band var(--band-duration) linear infinite; }
  .band:hover .band__track,
  .band[data-paused] .band__track,
  .band[data-offscreen] .band__track { animation-play-state: paused; }
}
@keyframes band { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .band__track { width: auto; }
  .band__group { flex-wrap: wrap; row-gap: var(--s-4); }
  .band__group + .band__group { display: none; }
}

.pipeline { list-style: none; margin: 0; padding: 0; }
.pipeline li {
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  column-gap: var(--gutter);
  align-items: baseline;
  padding-block: var(--s-5);
  border-block-start: 1px solid var(--rule);
}
/* Step numbers are round badges, so they never read as the section numbers (01, 02…) beside them. */
.pipeline .label {
  grid-column: 1 / span 1;
  align-self: start;
  margin-block-start: calc((var(--step-h3) * var(--leading-snug, 1.15) - 2rem) / 2);
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--accent-tint);
  color: var(--accent);
  font-weight: 600;
  letter-spacing: 0;
}
.pipeline h3 { grid-column: 2 / span 3; font-size: var(--step-h3); font-weight: 800; }
.pipeline p { grid-column: 5 / span 7; color: var(--ink-muted); }
/* Three pillars under the steps: what holds the process together. */
.pillars {
  list-style: none;
  margin: var(--s-8) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: var(--gutter);
}
.pillars li { padding-block-start: var(--s-4); border-block-start: 2px solid var(--accent); }
.pillars h3 { font-size: var(--step-h3); font-weight: 800; }
.pillars p { margin-block-start: var(--s-2); color: var(--ink-muted); }
.pillars .label a { display: inline-block; padding-block: 4px; }
/* Feature icons: line icons on a 24 grid from the page’s sprite (src/partials/*-icons.html),
   in the accent colour, one radius for every box in the set. */
.icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.pillars__icon { display: block; width: 28px; height: 28px; margin-block-end: var(--s-3); color: var(--accent); fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.section-more { margin-block-start: var(--s-7); }
.section-more a { display: inline-block; padding-block: 6px; color: var(--accent); }
@media (max-width: 767px) {
  .pipeline h3 { grid-column: 2 / -1; }
  .pipeline p { grid-column: 2 / -1; margin-block-start: var(--s-2); }
}

/* Numbers -------------------------------------------------------------- */
.numbers {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s-7) var(--gutter);
}
.numbers li { display: grid; gap: var(--s-3); align-content: start; }
.numbers__value {
  font-family: var(--font-display);
  font-stretch: var(--display-stretch);
  font-weight: 800;
  font-size: clamp(3.5rem, 2rem + 5vw, 7rem);
  line-height: 0.9;
  letter-spacing: -0.01em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.numbers li > span { color: var(--ink-muted); max-width: 24ch; }
/* Archivo has no arrow glyph: draw it in Geist so it sits on the numerals' midline. */
.numbers__arrow, .case-results .arrow {
  font-family: var(--font-text);
  font-weight: 500;
  font-stretch: normal;
  font-size: 0.7em;
  vertical-align: 0.12em;
  margin-inline: 0.12em;
}
.numbers__source { margin-block-start: var(--s-7); max-width: 60ch; }
@media (max-width: 1023px) { .numbers { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Visual: an editorial grid of image-only pieces ----------------------- */
.visual {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  gap: var(--gutter);
}
.visual__item { grid-column: span 4; }
.visual__item--wide { grid-column: 1 / span 8; grid-row: span 2; }
.visual__item:not(.visual__item--wide) { grid-column: 9 / -1; }
.visual__item { display: grid; gap: var(--s-3); align-content: start; }
/* Zoomable screenshots on the case pages: a bare button around the image. */
.visual__zoom { display: block; padding: 0; border: 0; background: none; cursor: zoom-in; border-radius: var(--radius-m); }
.visual__zoom:focus-visible { outline-offset: 4px; }
/* The whole card opens the Behance project: the "View on Behance" link stretches over it. */
.visual__item { position: relative; }
.visual__frame { display: block; overflow: hidden; border-radius: var(--radius-m); }
.visual__frame img { transition: transform var(--dur-slow) var(--ease-out); }
.visual__item:has(.visual__meta a:hover) .visual__frame img { transform: scale(1.02); }
.visual__meta a::after { content: ""; position: absolute; inset: 0; border-radius: var(--radius-m); }
.visual__meta { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--s-2) var(--s-4); }
.visual__meta a { display: inline-block; padding-block: 6px; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.25em; }
.visual__item img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-m);
  background: var(--surface-silver);
}
.visual__item--wide { grid-template-rows: 1fr auto; }
.visual__item--wide .visual__frame, .visual__item--wide img { height: 100%; }
.visual__item--wide img { aspect-ratio: auto; }
.visual__caption { color: var(--ink-muted); padding-block: 6px; }
.visual__more { margin-block-start: var(--s-6); }

/* Websites: freelance design and code, 2000–2019. A plain browser frame around each home page. */
.web { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(var(--columns), minmax(0, 1fr)); column-gap: var(--gutter); row-gap: var(--s-7); }
.web__item { grid-column: span 6; display: grid; gap: var(--s-4); align-content: start; }
@media (max-width: 767px) { .web__item { grid-column: 1 / -1; } }
.web__shot { display: block; overflow: hidden; border-radius: var(--radius-m); border: 1px solid var(--rule); background: var(--surface-silver); text-decoration: none; color: var(--ink-muted); }
.web__shot img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; object-position: top; transform-origin: top center; transition: transform var(--dur-slow) var(--ease-out); }
.web__shot:hover img { transform: scale(1.02); }
.web__bar { display: flex; align-items: center; gap: 6px; padding: 10px 14px; border-block-end: 1px solid var(--rule); background: var(--surface); font-family: var(--font-mono); font-size: var(--step-label); }
.web__bar i { width: 8px; height: 8px; border-radius: 50%; background: var(--rule); }
.web__bar span { margin-inline-start: var(--s-3); }
.web__placeholder { display: grid; place-items: center; aspect-ratio: 16 / 10; font-family: var(--font-display); font-stretch: var(--display-stretch); font-weight: 800; font-size: var(--step-h3); color: var(--ink-muted); }
.web__meta { display: grid; gap: var(--s-1); }
.web__name { font-size: var(--step-h3); font-weight: 800; }
.web__what { color: var(--ink-muted); }
.web__role { color: var(--ink-muted); }
.web__meta a { display: inline-block; padding-block: 6px; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.25em; }
.visual__more a { display: inline-block; padding-block: 6px; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.25em; }
@media (max-width: 1023px) {
  .visual__item--wide, .visual__item:not(.visual__item--wide) { grid-column: 1 / -1; grid-row: auto; }
  .visual__item--wide img { aspect-ratio: 4 / 3; height: auto; }
}

/* Lightbox (native dialog) */
.lightbox { max-width: min(92vw, 1600px); max-height: 92vh; padding: 0; border: 0; border-radius: var(--radius-m); background: var(--surface); }
.lightbox::backdrop { background: rgb(20 20 20 / 0.82); }
.lightbox img { display: block; max-width: 100%; max-height: 86vh; width: auto; height: auto; margin: 0 auto; }
.lightbox__bar { display: flex; justify-content: space-between; align-items: center; gap: var(--s-4); padding: var(--s-2) var(--s-4); }
.lightbox__close { min-height: 44px; padding: var(--s-2) var(--s-4); border: 1px solid var(--ink-muted); border-radius: 999px; background: none; color: var(--ink); cursor: pointer; }

/* About ------------------------------------------------------------- */
.about__body { display: grid; gap: var(--s-5); max-width: 62ch; margin-inline-start: calc((100% - 11 * var(--gutter)) / 12 + var(--gutter)); }
.about__lead {
  font-family: var(--font-display);
  font-stretch: var(--display-stretch);
  font-weight: 700;
  font-size: var(--step-h3);
  line-height: 1.3;
  letter-spacing: -0.02em;
}
.about__subhead { margin-block: var(--s-9) var(--s-4); color: var(--ink-muted); font-family: var(--font-mono); font-stretch: normal; font-weight: 500; }
.timeline, .certs { list-style: none; margin: 0; padding: 0; }
.about__cv { margin-block-start: var(--s-5); }
.about__cv a { display: inline-block; padding-block: 6px; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.25em; }
.timeline li {
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  column-gap: var(--gutter);
  padding-block: var(--s-4);
  border-block-start: 1px solid var(--rule);
}
.timeline__years { grid-column: 1 / span 2; color: var(--ink-muted); padding-block-start: 0.2em; }
.timeline__role { grid-column: 3 / span 5; font-weight: 500; }
.timeline__org { grid-column: 8 / -1; }
/* 8 columns leave the organisation a single column: put it under the role instead. */
@media (min-width: 768px) and (max-width: 1023px) {
  .timeline__role, .timeline__org { grid-column: 3 / -1; }
}
/* Newest first, read down each column (not across), so the order is plain chronology. */
.certs { columns: 2; column-gap: var(--gutter); }
.certs li { break-inside: avoid; }
.certs li { display: grid; padding-block: var(--s-3); border-block-start: 1px solid var(--rule); }
.certs li span:first-child { font-weight: 500; }
@media (max-width: 767px) {
  .about__body { margin-inline-start: 0; }
  .timeline__years, .timeline__role, .timeline__org { grid-column: 1 / -1; }
  .certs { columns: 1; }
}

/* Contact ------------------------------------------------------------ */
/* An address stays on one line: the paragraph is a size container and the link's type shrinks to fit
   it (the address is 14.45em wide, so 6.8cqi fits). Only wider user text spacing makes it break. */
.contact__email {
  font-family: var(--font-display);
  font-stretch: var(--display-stretch);
  font-weight: 800;
  font-size: clamp(1.75rem, 0.8rem + 4.4vw, 5rem);
  line-height: 1;
  letter-spacing: -0.04em;
  max-width: none;
  container-type: inline-size;
}
.contact__email a { font-size: min(1em, 6.8cqi); overflow-wrap: anywhere; }   /* sized to fit one line; breaks only under user text spacing (WCAG 1.4.12) */
.contact__email a { text-decoration-thickness: 0.06em; text-underline-offset: 0.12em; text-decoration-color: var(--accent); }
.contact__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3) var(--s-6); margin-block-start: var(--s-7); }   /* room for the Copied tooltip under the address */
.contact__actions a { display: inline-block; padding-block: 6px; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.25em; }
.contact__actions a:hover { color: var(--accent); }
.contact__copy {
  min-height: 40px;
  padding: var(--s-2) var(--s-4);
  border: 1px solid var(--ink);
  border-radius: 999px;
  background: var(--ink);
  color: var(--surface);
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}
.contact__copy:hover { background: var(--accent); border-color: var(--accent); }
.contact__copy-wrap { position: relative; display: inline-block; }
/* "Copied": a small tooltip above the button that comes and goes by itself (main.js initCopy). Out of the
   flow, so the links beside the button never move. Same pill as the button, with a caret toward it. */
.contact__status {
  position: absolute; bottom: calc(100% + 8px); left: 0;
  width: max-content; max-width: min(22rem, calc(100vw - 2 * var(--margin)));
  padding: 3px 9px; border-radius: 999px; font-size: 0.75rem;
  background: var(--ink); color: var(--surface);
  opacity: 0; transform: translateY(4px); pointer-events: none;
  transition: opacity 160ms var(--ease-out), transform 160ms var(--ease-out);
}
.contact__status::after { content: ""; position: absolute; top: 100%; left: 20px; border: 4px solid transparent; border-top-color: var(--ink); }
.contact__status.is-on { opacity: 1; transform: none; }
.contact__status:empty { padding: 0; }
@media (prefers-reduced-motion: reduce) { .contact__status { transition: none; transform: none; } }

/* Footer --------------------------------------------------------------- */
.site-footer { padding-block: var(--s-8) var(--s-7); margin-block-start: var(--section-gap); }
/* One line, three zones: name, sections, contact. They wrap as the width runs out, and stack on phones. */
.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3) var(--s-7);
  padding-block-start: var(--s-5);
  border-block-start: 1px solid var(--ink);
}
.site-footer__inner > :first-child { padding-block: 6px; }
.site-footer__links { display: flex; flex-wrap: wrap; column-gap: var(--s-5); }
.site-footer__contact { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--s-3); }
.site-footer__links a, .site-footer__contact a:not(.site-footer__icon) { display: inline-block; padding-block: 6px; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.25em; }
.site-footer__links a:hover, .site-footer__contact a:hover { color: var(--accent); }
/* Brand marks: a 20px glyph in a 32px target. */
.site-footer__icon { display: inline-grid; place-items: center; width: 32px; height: 32px; margin-inline: -6px; border-radius: 6px; color: var(--ink); }
.site-footer__icon svg { width: 20px; height: 20px; fill: currentColor; }
@media (max-width: 599px) {
  .site-footer__inner { flex-direction: column; align-items: flex-start; }
}

/* Reveal on scroll (only where JS runs and motion is welcome) ---------- */
@media (prefers-reduced-motion: no-preference) {
  /* Hiding is instant (never seen: it happens below the fold); only the way in is animated. */
  .js [data-reveal] { opacity: 0; transform: translateY(16px); }
  .js [data-reveal].is-in { opacity: 1; transform: none; transition: opacity var(--dur-slow) var(--ease-out) var(--reveal-delay, 0ms), transform var(--dur-slow) var(--ease-out) var(--reveal-delay, 0ms); }
  /* Swimlane bars draw in from the left instead of rising. */
  .js [data-reveal="draw"] { transform: none; clip-path: inset(0 100% 0 0); }
  .js [data-reveal="draw"].is-in { clip-path: inset(0 0 0 0); transition: clip-path 600ms var(--ease-out) var(--reveal-delay, 0ms), opacity 250ms linear var(--reveal-delay, 0ms); }
}
@media print { [data-reveal] { opacity: 1 !important; transform: none !important; } }

/* Page start: the hero settles in, quickly and once. Its blocks fade up 8px, 50ms apart, all done
   in about 0.7s, so the page feels like it is starting rather than snapping on. CSS only, so it runs
   before any script; off under reduced motion. Blocks keep their place in the layout (nothing
   shifts), and the fill is backwards only, so the poster's tilt and the sticker's angle stay theirs. */
@keyframes hero-enter { from { opacity: 0; transform: translateY(8px); } }
@media (prefers-reduced-motion: no-preference) {
  :is(.hero__text, .case-hero > div) > *, .hero-art {
    animation: hero-enter 420ms var(--ease-out) backwards;
    animation-delay: calc(40ms + var(--enter, 0) * 50ms);
  }
  :is(.hero__text, .case-hero > div) > :nth-child(2) { --enter: 1; }
  :is(.hero__text, .case-hero > div) > :nth-child(3) { --enter: 2; }
  :is(.hero__text, .case-hero > div) > :nth-child(4) { --enter: 3; }
  :is(.hero__text, .case-hero > div) > :nth-child(5) { --enter: 4; }
  :is(.hero__text, .case-hero > div) > :nth-child(n+6) { --enter: 5; }
  .hero-art { --enter: 2; }
}

/* Case study template. Same grid, same rules: labels in mono, titles in Archivo expanded,
   one accent, Panton colour only inside markers. */

.case-hero { padding-block: clamp(48px, 4vw + 32px, 112px) var(--s-8); }
.case-hero__eyebrow { color: var(--ink-muted); margin-block-end: var(--s-5); display: flex; align-items: center; gap: var(--s-3); }
.case-hero__eyebrow .marker { --marker-size: 28px; }
.case-hero__title {
  font-size: var(--step-h1);
  font-weight: 800;
  line-height: var(--leading-tight);
  letter-spacing: -0.045em;
  max-width: 16ch;
}
.case-hero__outcome {
  margin-block-start: var(--s-5);
  font-size: var(--step-lead);
  max-width: 44ch;
}

.meta-row {
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  column-gap: var(--gutter);
  row-gap: var(--s-5);
  margin: var(--s-8) 0 0;
  padding-block-start: var(--s-4);
  border-block-start: 1px solid var(--ink);
}
.meta-row > div { grid-column: span 2; display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-1); align-content: start; }
.meta-row > div:last-child { grid-column: span 4; }
.meta-row dt { color: var(--ink-muted); }
.meta-row dd { margin: 0; }
.case-hero__nda { margin-block-start: var(--s-5); color: var(--ink-muted); }
/* Cases with product screens: the NDA notice, highlighted, before anything else on the page. */
.case-nda {
  display: grid;
  gap: var(--s-2);
  max-width: 72ch;
  margin-block-start: var(--s-6);
  padding: var(--s-4) var(--s-5);
  border-inline-start: 4px solid var(--accent);
  border-radius: var(--radius-m);
  background: var(--accent-tint);
  color: var(--ink);
}
.case-nda__label { color: var(--accent); }

/* A small case says so, with a wink (Ready for Audit): a "B-side" sticker under the outcome line.
   Flat offset shadow and a slight tilt, no gradient; the record (the site's ring language) peeks over
   the corner, so the text keeps the full width on a phone. It
   straightens on hover and the record turns, only when motion is welcome. */
.case-sticker {
  position: relative;
  display: grid;
  max-width: 62ch;
  margin-block-start: var(--s-6);
  padding: var(--s-4) var(--s-5);
  border: 1.5px solid var(--ink);
  border-radius: 18px;
  background: var(--surface);
  box-shadow: 4px 4px 0 var(--ink);
  transform: rotate(-1.2deg);
  transform-origin: 20% 50%;
}
.case-sticker__disc { position: absolute; top: -22px; right: 20px; width: 56px; height: 56px; transform: rotate(-14deg); }   /* peeks over the top-right corner */
.case-sticker__vinyl { fill: #141414; stroke: var(--ink); stroke-width: 2; }
.case-sticker__groove { fill: none; stroke: rgb(255 255 255 / 0.18); stroke-width: 1.2; }
.case-sticker__center { fill: var(--violet); }
.case-sticker__hole { fill: var(--surface); }
.case-sticker__text { display: grid; gap: var(--s-2); }
.case-sticker__tag { justify-self: start; padding: 2px 10px; border-radius: 999px; background: var(--accent); color: var(--on-accent); }
@media (prefers-reduced-motion: no-preference) {
  .case-sticker { transition: transform var(--dur-base) var(--ease-out); }
  .case-sticker__disc { transition: transform 1.2s var(--ease-out); }
  .case-sticker:hover { transform: rotate(0deg); }
  .case-sticker:hover .case-sticker__disc { transform: rotate(186deg); }
}
/* A four-item row leaves two of the twelve columns free: Role and Team take them, so their text
   (mono caps) has room to keep its last two words together. */
@media (min-width: 1024px) { .meta-row > div:first-child:nth-last-child(4), .meta-row > div:first-child:nth-last-child(4) + div { grid-column: span 3; } }
@media (max-width: 1023px) { .meta-row > div, .meta-row > div:last-child { grid-column: span 4; } }
@media (max-width: 767px) { .meta-row > div, .meta-row > div:last-child { grid-column: 1 / -1; } }

.case-figure { margin: 0; }
.case-figure .plate { aspect-ratio: auto; }
.case-figure .plate img { display: block; width: 100%; height: auto; }
.case-figure figcaption { margin-block-start: var(--s-3); color: var(--ink-muted); font-size: var(--step-small); max-width: 62ch; }

/* Sections: sticky rail label on the left, reading column on the right. */
.case-block { padding-block-start: var(--section-gap); }
.case-section {
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  column-gap: var(--gutter);
}
.case-section > h2 {
  grid-column: 1 / span 3;
  align-self: start;
  position: sticky;
  top: calc(var(--header-h, 72px) + var(--s-5));
  font-family: var(--font-mono);
  font-stretch: normal;
  font-size: var(--step-label);
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ink-muted);
  padding-block-start: 0.4em;
}
/* Default for anything else placed straight in a section (a list, a figure): the reading column
   onwards, never a single stray column. Zero specificity, so every named rule below still wins. */
:where(.case-section > :not(h2)) { grid-column: 4 / -1; }
.case-section > .case-prose { grid-column: 4 / span 6; display: grid; gap: var(--s-5); }
.case-section > .case-wide { grid-column: 1 / -1; margin-block-start: var(--s-7); }
.case-block > .case-wide { margin-block-start: var(--s-7); }
.case-prose p { max-width: 64ch; }
.case-prose ul { margin: 0; padding-inline-start: 1.1em; display: grid; gap: var(--s-2); }
.case-prose .lead { font-size: var(--step-lead); }
@media (max-height: 560px) { .case-section > h2 { position: static; } }
/* The rail title only sticks when nothing in its section runs under it (numbered lists, the AI
   layer panel and wide figures reach into the rail's columns). */
.case-section:has(> .decisions, > .ai-layer, > .case-wide) > h2 { position: static; }
@media (max-width: 1023px) {
  .case-section > h2 { grid-column: 1 / -1; position: static; margin-block-end: var(--s-4); }
  :where(.case-section > :not(h2)) { grid-column: 1 / -1; }
  .case-section > .case-prose { grid-column: 1 / -1; }
}

/* Decisions: numbered, each with its image. */
.decisions { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-10); grid-column: 1 / -1; }
.decision {
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  column-gap: var(--gutter);
  row-gap: var(--s-4);
}
.decision__num { grid-column: 1 / span 3; color: var(--accent); font-family: var(--font-mono); font-size: var(--step-label); letter-spacing: var(--tracking-label); padding-block-start: 0.8em; }
.decision h3 {
  grid-column: 4 / span 7;
  font-size: var(--step-h2);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: var(--leading-snug);
}
.decision > p { grid-column: 4 / span 6; }
.decision > .case-figure { grid-column: 1 / -1; margin-block-start: var(--s-5); }
/* Close-ups (a picker, a document, a popover) stay on the reading column, never above their real size. */
.case-figure--detail { max-width: 600px; }
.case-figure--detail .plate--shot img { max-width: var(--shot-w, 100%); margin-inline: auto; }   /* a close-up narrower than the column sits centred, at its real size */
@media (min-width: 1024px) { .decision > .case-figure--detail { grid-column: 4 / span 6; } }
@media (max-width: 1023px) {
  .decision__num, .decision h3, .decision > p { grid-column: 1 / -1; }
}

/* AI layer: a quiet silver panel with two columns. */
.ai-layer {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(var(--columns), minmax(0, 1fr));
  column-gap: var(--gutter);
  row-gap: var(--s-6);
  padding: clamp(24px, 4vw, 64px);
  border-radius: var(--radius-l);
  background: var(--surface-silver);
}
.ai-layer > div { grid-column: span 4; display: grid; gap: var(--s-3); align-content: start; }
.ai-layer h3 { font-size: var(--step-h3); font-weight: 800; }
.ai-layer ul { margin: 0; padding-inline-start: 1.1em; display: grid; gap: var(--s-3); }
@media (max-width: 1023px) { .ai-layer > div { grid-column: 1 / -1; } }

/* Next case. */
.next-case { padding-block: var(--section-gap) 0; }
.next-case a {
  display: grid;
  gap: var(--s-3);
  padding-block-start: var(--s-5);
  border-block-start: 1px solid var(--ink);
  text-decoration: none;
}
.next-case__title {
  font-family: var(--font-display);
  font-stretch: var(--display-stretch);
  font-weight: 800;
  font-size: var(--step-h1);
  line-height: var(--leading-tight);
  letter-spacing: -0.045em;
}
.next-case a:hover .next-case__title { color: var(--accent); }

/* Evidence list inside a case: value and meaning side by side. */
.numbers--case { grid-template-columns: 1fr; gap: var(--s-5); }
.numbers--case li { grid-template-columns: minmax(9rem, auto) 1fr; align-items: start; column-gap: var(--s-5); padding-block-start: var(--s-4); border-block-start: 1px solid var(--rule); }
.numbers--case .numbers__value { font-size: clamp(2.5rem, 1.8rem + 2.4vw, 4rem); }
.numbers--case li > span { max-width: 40ch; }
@media (max-width: 767px) { .numbers--case li { grid-template-columns: 1fr; } }

/* Until a capture lands, an empty plate keeps a 16:9 footprint. */
.case-figure .plate:not(:has(img)) { aspect-ratio: 16 / 9; }
.case-figure .plate:not(:has(img)) .plate__placeholder { font-size: clamp(4rem, 2rem + 8vw, 10rem); bottom: var(--s-5); }

/* Native diagrams (HTML/CSS, no images). Monochrome + accent; states differ by stroke, not colour. */
.diagram {
  position: relative;
  border-radius: var(--radius-l);
  background: var(--surface-silver);
  padding: clamp(20px, 4vw, 56px);
  display: grid;
  gap: var(--s-5);
}
.diagram__caption { color: var(--ink-muted); }

/* CSD columns as states */
.csd { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gutter); align-items: start; }
.csd__col { display: grid; gap: var(--s-3); }
.csd__col > p.label { color: var(--ink-muted); }
.csd__col > h4 { font-family: var(--font-display); font-stretch: var(--display-stretch); font-weight: 800; font-size: var(--step-h3); letter-spacing: -0.02em; }
.csd__col > .csd__def { font-size: var(--step-small); color: var(--ink-muted); min-height: 3.2em; }
.csd__card {
  padding: var(--s-3) var(--s-4);
  border-radius: var(--radius-s);
  font-size: var(--step-small);
  line-height: 1.4;
  background: var(--surface);
  border: 1.5px solid var(--ink);
}
.csd__card--certain { background: var(--ink); color: var(--surface); }
.csd__card--doubt { border-style: dashed; background: transparent; }
.csd__card--moving { outline: 2px solid var(--accent); outline-offset: 3px; }
.csd__move { display: flex; align-items: center; gap: var(--s-2); color: var(--accent); font-family: var(--font-mono); font-size: var(--step-label); letter-spacing: var(--tracking-label); text-transform: uppercase; }
@media (max-width: 767px) { .csd { grid-template-columns: 1fr; } .csd__col > .csd__def { min-height: 0; } }

/* Access matrix, as a What's New shows it: one row per capability, one column per role. */
.access { position: relative; min-width: 0; max-width: 100%; overflow-x: auto; border-radius: var(--radius-s); }   /* relative: the screen-reader Yes/No spans scroll with the table */
.case-figure.diagram:has(> .access) { min-width: 0; }   /* the table scrolls inside, the page never does */
.access:focus-visible { outline-offset: 4px; }
.access__table { width: 100%; min-width: 600px; border-collapse: collapse; font-size: var(--step-small); line-height: 1.4; background: var(--surface); }
.access__table th, .access__table td { padding: var(--s-3) var(--s-4); text-align: left; vertical-align: top; border-block-end: 1px solid var(--rule); }
.access__table tbody tr:last-child > * { border-block-end: 0; }
.access__table thead th { font-family: var(--font-mono); font-size: var(--step-label); font-weight: 500; letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink-muted); border-block-end: 1.5px solid var(--ink); }
.access__table tbody th { font-weight: 600; width: 34%; }
.access__yes { color: var(--accent); font-weight: 700; }
.access__no { color: var(--ink-muted); }
.access__only { display: block; margin-block-start: 2px; color: var(--ink-muted); font-size: var(--step-label); }
.access__yes + .visually-hidden + .access__only { margin-block-start: 2px; }
/* Contrast table: a swatch of each candidate colour (graphics, fixed hex on purpose). */
.contrast__swatch { display: inline-block; width: 0.9em; height: 0.9em; margin-inline-end: var(--s-2); border-radius: 3px; vertical-align: -0.1em; box-shadow: inset 0 0 0 1px rgb(20 20 20 / 0.15); }
/* Illustrative tones with the same relative luminance as the measured ones, so the ratios hold. */
.contrast__swatch--app { background: #F7B442; }
.contrast__swatch--orange { background: #E07406; }
.contrast__swatch--ds { background: #BA7C00; }
/* A dated timeline: the dates number the steps, so the counter goes. */
.loop--dated li::before { content: none; }
.loop--dated li .label { color: var(--accent); }

/* A documented flow: numbered steps on a line, each chip opening the prototype in that state. */
.flowdoc { display: grid; gap: var(--s-4); }
.flowdoc__doc { color: var(--ink-muted); }
.flowdoc__steps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-4); }
.flowdoc__step { position: relative; display: grid; grid-template-columns: 2rem minmax(0, 3fr) minmax(0, 2fr); column-gap: var(--s-4); align-items: start; }
.flowdoc__step:not(:last-child)::before { content: ""; position: absolute; left: calc(1rem - 1px); top: 2rem; bottom: calc(var(--s-4) * -1); border-inline-start: 2px solid var(--accent); }
.flowdoc__num { display: grid; place-items: center; width: 2rem; height: 2rem; border-radius: 50%; background: var(--accent); color: var(--on-accent); font-family: var(--font-mono); font-size: var(--step-label); font-weight: 600; }
.flowdoc__card { max-width: none; padding: var(--s-3) var(--s-4); border: 1.5px solid var(--ink); border-radius: var(--radius-s); background: var(--surface); font-size: var(--step-small); line-height: 1.5; }
.flowdoc__chip { display: inline-block; margin-inline-end: var(--s-2); padding: 1px 10px; border-radius: 999px; background: var(--accent-tint); color: var(--accent); font-family: var(--font-mono); font-size: 12px; text-decoration: underline; text-underline-offset: 2px; }
.flowdoc__state { max-width: none; padding-block-start: var(--s-3); color: var(--accent); font-size: var(--step-small); line-height: 1.45; }
@media (max-width: 767px) {
  .flowdoc__step { grid-template-columns: 2rem minmax(0, 1fr); row-gap: var(--s-2); }
  .flowdoc__state { grid-column: 2; padding-block-start: 0; }
}

/* A doubt in a long document does not raise itself */
.longdoc { display: grid; grid-template-columns: 5fr 7fr; gap: var(--gutter); align-items: stretch; }
.longdoc__doc { background: var(--surface); border-radius: var(--radius-m); padding: var(--s-5); display: grid; gap: 10px; align-content: start; }
.longdoc__line { height: 8px; border-radius: 4px; background: var(--rule); }
.longdoc__line--flag { background: var(--surface-silver); box-shadow: inset 3px 0 0 var(--accent); height: 22px; border-radius: 3px; }
.longdoc__screen { border-radius: var(--radius-m); border: 1.5px solid var(--ink); display: grid; place-items: center; padding: var(--s-6); text-align: center; }
.longdoc__screen p { font-family: var(--font-display); font-stretch: var(--display-stretch); font-weight: 800; font-size: var(--step-h3); letter-spacing: -0.02em; max-width: 18ch; }
@media (max-width: 767px) { .longdoc { grid-template-columns: 1fr; } }

/* The meeting loop */
.loop { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--s-3); }
/* Each card is a size container, so its title scales to the card: 11.5cqi fits the longest unbreakable
   chunk in any title (≈8.4em, "the developers") at 97% of the card; the track never grows past the card. */
.loop li { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-2); padding: var(--s-4); border-radius: var(--radius-m); background: var(--surface); border: 1.5px solid var(--ink); container-type: inline-size; }
/* Step numbers by position, not a CSS counter: each card is a size container, and containment
   scopes counters to the card (every step would read 01). */
.loop li::before { content: "01"; font-family: var(--font-mono); font-size: var(--step-label); letter-spacing: var(--tracking-label); color: var(--accent); }
.loop li:nth-child(2)::before { content: "02"; } .loop li:nth-child(3)::before { content: "03"; } .loop li:nth-child(4)::before { content: "04"; }
.loop li:nth-child(5)::before { content: "05"; } .loop li:nth-child(6)::before { content: "06"; } .loop li:nth-child(7)::before { content: "07"; }
.loop li strong { font-family: var(--font-display); font-stretch: var(--display-stretch); font-weight: 800; font-size: var(--step-h3); font-size: min(var(--step-h3), 11.5cqi); letter-spacing: -0.02em; line-height: 1.1; text-wrap: balance; overflow-wrap: break-word; }
.loop li span { font-size: var(--step-small); color: var(--ink-muted); max-width: 62ch; }
.loop li:not(:last-child)::after { content: "→"; position: absolute; right: -0.75em; top: 50%; transform: translateY(-50%); color: var(--accent); font-weight: 700; z-index: 1; background: var(--surface-silver); padding-inline: 2px; }
.loop li.loop__manual { border-style: dashed; }
.loop__back { display: flex; align-items: center; gap: var(--s-2); color: var(--accent); font-family: var(--font-mono); font-size: var(--step-label); letter-spacing: var(--tracking-label); text-transform: uppercase; }
/* Five cards in a row need 1280px; below that they stack (a three-step loop keeps its row from 1024px, case-extra.css). */
@media (max-width: 1279px) { .loop { grid-template-columns: 1fr; } .loop li:not(:last-child)::after { content: "↓"; right: auto; left: var(--s-4); top: auto; bottom: -1.1em; transform: none; } }

/* The whole flow: steps across, lanes down; each bar spans the steps it runs through. From 1280px
   it's a chart; below, the lanes stack and every bar shows a seven-dot timeline and its step names. */
.flow__grid { position: relative; display: grid; --flow-lane: 9rem; --flow-gap: var(--s-5); }
.flow__row { display: grid; gap: var(--s-3); padding-block: var(--s-4); border-block-start: 1px solid var(--rule); }
.flow__guides, .flow__row--head { display: none; }
.flow__row--head + .flow__row { border-block-start: 0; padding-block-start: 0; }
.flow__lane { color: var(--ink); }
.flow__bars { margin: 0; padding: 0; display: grid; gap: var(--s-2); }
.flow__bar {
  max-width: none;
  padding: var(--s-2) var(--s-3);
  border-radius: var(--radius-s);
  border: 1.5px solid var(--ink);
  background: var(--surface-silver);
  font-size: var(--step-small);
  line-height: 1.35;
}
.flow__bar strong { font-weight: 600; }
.flow__bar--docs, .flow__bar--lofi, .flow__bar--pin, .flow__bar--check, .flow__bar--docs-in { background: var(--surface); }
.flow__bar--pin, .flow__bar--check, .flow__bar--docs-in { border-color: var(--accent); }
.flow__bar--proto:not(.flow__bar--lofi, .flow__bar--pin, .flow__bar--check, .flow__bar--docs-in) { background: var(--ink); color: var(--surface); }
.flow__bar--ai { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.flow__bar--eng { border-style: dashed; }
.flow__pin {
  display: inline-grid; place-items: center;
  width: 1.35em; height: 1.35em; margin-inline-end: 0.35em;
  border-radius: 50%;
  background: var(--accent); color: var(--on-accent);
  font-size: 0.8em; font-weight: 700; line-height: 1;
  vertical-align: 0.1em;
}
/* Letter badges (scripts/build.mjs flowLinks): an assistant and what it produces share a letter. */
.flow__keys { display: inline-flex; gap: 2px; margin-inline-start: 0.4em; vertical-align: 0.06em; }
.flow__keys--lead { margin-inline: 0 0.4em; }
.flow__keys--group { margin-inline-start: 0.15em; }   /* after a real space: the group may wrap as a whole */
.flow__key {
  display: inline-grid; place-items: center;
  width: 1.5em; height: 1.5em;
  border-radius: 50%;
  background: var(--accent); color: var(--on-accent);
  font-family: var(--font-mono); font-size: 0.78em; font-weight: 600; line-height: 1; letter-spacing: 0; text-transform: none;
}
.flow__bar--ai .flow__key { background: var(--on-accent); color: var(--accent); }
.flow__end { white-space: nowrap; }
.flow__range {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-1) var(--s-2);
  margin-block-end: var(--s-1);
  font-family: var(--font-mono); font-size: var(--step-label); letter-spacing: var(--tracking-label); text-transform: uppercase;
  color: var(--ink-muted);
}
.flow__bar--proto:not(.flow__bar--lofi, .flow__bar--pin, .flow__bar--check, .flow__bar--docs-in) .flow__range, .flow__bar--ai .flow__range { color: inherit; }
.flow__dots { display: inline-flex; gap: 2px; }
.flow__dots i { width: 8px; height: 4px; border-radius: 2px; background: currentColor; opacity: 0.25; }
.flow__dots i.is-on { opacity: 1; }

/* The sync strip sits on the line between Documents and Prototype. */
.flow__row--sync { position: relative; border: 0; padding-block: 0; }
.flow__row--sync::before { content: ""; position: absolute; inset-inline: 0; top: 50%; border-block-start: 1px solid var(--rule); }
.flow__row--sync + .flow__row { border-block-start: 0; }
.flow__row--sync .flow__lane { display: none; }
/* The one idea the diagram is about, so it is the loudest strip in it. */
.flow__bar--sync {
  position: relative;
  padding: var(--s-2) var(--s-4);
  border: 2px solid var(--accent);
  border-radius: var(--radius-s);   /* same corners as every bar in the flow */
  background: var(--accent-tint);
  color: var(--ink);
  font-family: var(--font-display); font-stretch: var(--display-stretch); font-weight: 700;
  font-size: var(--step-body); line-height: 1.25;
  text-align: center;
}
.flow__bar--sync::before, .flow__bar--sync::after {
  content: "↕"; content: "↕" / "";
  display: inline-grid; place-items: center; vertical-align: 0.05em;
  width: 1.5em; height: 1.5em; margin-inline: 0.6em;
  border-radius: 50%;
  background: var(--accent); color: var(--on-accent);
  font-family: var(--font-text); font-size: 0.8em; font-weight: 700; line-height: 1;
}
.flow__bar--sync .flow__range { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* The loop back: the Help pages updated after the build feed the next feature's knowledge base. */
.flow__row--loop { padding-block-end: 0; }
.flow__row--loop .flow__lane { display: none; }
.flow__bar--loop {
  padding-block: var(--s-1);
  border: 1.5px dashed var(--accent);
  border-radius: var(--radius-s);   /* same corners as every bar in the flow */
  color: var(--accent);
  font-family: var(--font-mono); font-size: var(--step-label); letter-spacing: var(--tracking-label); text-transform: uppercase;
}
.flow__bar--loop::before { content: "←"; content: "←" / ""; margin-inline-end: 0.6em; }

@media (min-width: 768px) and (max-width: 1279px) {
  .flow__bars { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .flow__bar--sync, .flow__bar--loop { grid-column: 1 / -1; }
}
@media (min-width: 1280px) {
  .flow__grid { --flow-lane: 7.5rem; }   /* "AI assistants" on one line in the lane's mono caps */
  .diagram.flow { padding: clamp(24px, 2.8vw, 40px); gap: var(--s-4); }
  .flow__row { position: relative; grid-template-columns: var(--flow-lane) minmax(0, 1fr); column-gap: var(--flow-gap); align-items: start; padding-block: var(--s-3); }
  .flow__bar { font-size: var(--step-label); }
  .flow__bar:not(.flow__bar--sync, .flow__bar--loop) { padding: 6px 10px; }
  .flow__bar--sync { font-size: var(--step-body); }
  .flow__row--sync { padding-block: var(--s-2); }
  .flow__row--head { display: grid; border: 0; padding-block: 0 var(--s-3); }
  .flow__row--head + .flow__row { padding-block-start: var(--s-3); }
  .flow__row--sync .flow__lane, .flow__row--loop .flow__lane { display: block; }
  .flow__steps { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--s-2); }
  .flow__steps span { padding-block-end: var(--s-2); border-block-end: 1.5px solid var(--ink); }
  .flow__steps b { font-weight: 500; color: var(--accent); }
  .flow__lane { padding-block-start: var(--s-2); }
  .flow__bars { grid-template-columns: repeat(7, minmax(0, 1fr)); grid-auto-flow: row dense; }
  .flow__bar[data-from="1"] { grid-column-start: 1; } .flow__bar[data-from="2"] { grid-column-start: 2; }
  .flow__bar[data-from="3"] { grid-column-start: 3; } .flow__bar[data-from="4"] { grid-column-start: 4; }
  .flow__bar[data-from="5"] { grid-column-start: 5; } .flow__bar[data-from="6"] { grid-column-start: 6; }
  .flow__bar[data-from="7"] { grid-column-start: 7; }
  .flow__bar[data-to="1"] { grid-column-end: 2; } .flow__bar[data-to="2"] { grid-column-end: 3; }
  .flow__bar[data-to="3"] { grid-column-end: 4; } .flow__bar[data-to="4"] { grid-column-end: 5; }
  .flow__bar[data-to="5"] { grid-column-end: 6; } .flow__bar[data-to="6"] { grid-column-end: 7; }
  .flow__bar[data-to="7"] { grid-column-end: 8; }
  .flow__bar[data-row="1"] { grid-row-start: 1; } .flow__bar[data-row="2"] { grid-row-start: 2; } .flow__bar[data-row="3"] { grid-row-start: 3; }
  /* The columns carry the steps here; screen readers still get them from each bar. */
  .flow__range { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .flow__guides {
    display: grid; position: absolute; inset-block: 0; inset-inline: calc(var(--flow-lane) + var(--flow-gap)) 0;
    grid-template-columns: repeat(7, minmax(0, 1fr)); column-gap: var(--s-2);
    pointer-events: none;
  }
  .flow__guides span + span { margin-inline-start: calc(var(--s-2) / -2); border-inline-start: 1px dashed var(--ink-muted); opacity: 0.4; }
  .flow__guides span:last-child { border-inline-start: 1.5px solid var(--ink); opacity: 0.55; }
  .flow__bar[data-row="4"] { grid-row-start: 4; } .flow__bar[data-row="5"] { grid-row-start: 5; } .flow__bar[data-row="6"] { grid-row-start: 6; }
  /* Each bar keeps its own height: a one-step bar that wraps to five lines must not stretch the
     long bar beside it into an empty block. */
  .flow__bars { align-items: start; }
  /* The steps stay in view while the flow scrolls: stuck under the site header (--header-h comes
     from main.js initHeader) and let go where the flow ends, since the sticky box is the grid. */
  .flow__row--head { position: sticky; top: var(--header-h, 72px); z-index: 2; background: var(--surface-silver); padding-block-start: var(--s-3); margin-block-start: calc(var(--s-3) * -1); }
}
/* Pointing at an assistant lights up what it produces, and pointing at a result lights up its
   assistants; everything else steps back. Only with a mouse, where the chart has its columns. */
@media (hover: hover) and (min-width: 1280px) {
  .flow__bar { outline: 2px solid transparent; outline-offset: 2px; transition: opacity 160ms ease-out, outline-color 160ms ease-out; }
  .flow__grid:has([data-ai]:hover, [data-by]:hover) .flow__bar { opacity: 0.3; }
  .flow__grid:has([data-ai]:hover, [data-by]:hover) .flow__bar:hover { opacity: 1; outline-color: var(--accent); }
  .flow__grid:has([data-ai="tracking"]:hover) :is([data-ai="tracking"], [data-by~="tracking"]), .flow__grid:has([data-by~="tracking"]:hover) [data-ai="tracking"],
  .flow__grid:has([data-ai="reader"]:hover) :is([data-ai="reader"], [data-by~="reader"]), .flow__grid:has([data-by~="reader"]:hover) [data-ai="reader"],
  .flow__grid:has([data-ai="tracer"]:hover) :is([data-ai="tracer"], [data-by~="tracer"]), .flow__grid:has([data-by~="tracer"]:hover) [data-ai="tracer"],
  .flow__grid:has([data-ai="handoff"]:hover) :is([data-ai="handoff"], [data-by~="handoff"]), .flow__grid:has([data-by~="handoff"]:hover) [data-ai="handoff"],
  .flow__grid:has([data-ai="inspector"]:hover) :is([data-ai="inspector"], [data-by~="inspector"]), .flow__grid:has([data-by~="inspector"]:hover) [data-ai="inspector"],
  .flow__grid:has([data-ai="sync"]:hover) :is([data-ai="sync"], [data-by~="sync"]), .flow__grid:has([data-by~="sync"]:hover) [data-ai="sync"],
  .flow__grid:has([data-ai="parity"]:hover) :is([data-ai="parity"], [data-by~="parity"]), .flow__grid:has([data-by~="parity"]:hover) [data-ai="parity"],
  .flow__grid:has([data-ai="writing"]:hover) :is([data-ai="writing"], [data-by~="writing"]), .flow__grid:has([data-by~="writing"]:hover) [data-ai="writing"] { opacity: 1; outline-color: var(--accent); }
}
/* A click or tap pins an item (main.js initFlowPanel), at any width: the hover's dimming, held, and a panel
   fixed at the bottom of the screen listing what the item links to. A transparent button covers each bar,
   so the whole bar is the target and the ring goes around it. */
.flow__bar:has(> .flow__hit) { position: relative; cursor: pointer; }
.flow__hit { position: absolute; inset: 0; margin: 0; padding: 0; border: 0; border-radius: inherit; background: none; cursor: pointer; }
.flow__hit:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.flow__grid.is-pinned .flow__bar { opacity: 0.3; }
.flow__grid.is-pinned .flow__bar.is-lit { opacity: 1; outline: 2px solid var(--accent); outline-offset: 2px; }
.flow__bar.is-flash { animation: flow-flash 1.4s var(--ease-out); }
@keyframes flow-flash { 0%, 35% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 35%, transparent); } 100% { box-shadow: 0 0 0 0 transparent; } }
.flow-panel {
  position: fixed; z-index: 15; left: 50%; bottom: var(--s-4); transform: translateX(-50%);
  width: min(56rem, calc(100vw - 2 * var(--margin)));
  max-height: 40vh; overflow: auto;
  padding: var(--s-3) var(--s-4) var(--s-4);
  border: 1.5px solid var(--ink); border-radius: var(--radius-s);   /* the flow's corners */
  background: var(--surface); color: var(--ink);
  box-shadow: 0 16px 40px -16px rgb(0 0 0 / 0.4);
  font-size: var(--step-small); line-height: 1.35;
}
.flow-panel[hidden] { display: none; }
/* One line on top: the item, what the list is, and ×. Then the linked items as chips that wrap. */
.flow-panel__head { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--s-3); row-gap: 2px; padding-inline-end: 36px; position: relative; }
.flow-panel__title { margin: 0; font-weight: 600; }
.flow-panel__label { margin: var(--s-2) 0 0; color: var(--ink-muted); }   /* a breath between the item and what the list is */
.flow-panel__title .flow__key, .flow-panel__list .flow__key { margin-inline-end: 0.35em; vertical-align: 0.06em; }
.flow-panel__close { position: absolute; top: -2px; right: -6px; display: inline-grid; place-items: center; width: 28px; height: 28px; padding: 0; border: 1px solid var(--rule); border-radius: 50%; background: none; color: var(--ink); cursor: pointer; }
.flow-panel__close:hover { border-color: var(--accent); color: var(--accent); }
.flow-panel__close svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; }
.flow-panel__list { display: flex; flex-wrap: wrap; gap: 6px; margin: var(--s-3) 0 0; padding: 0; list-style: none; }
.flow-panel__list button { all: unset; box-sizing: border-box; display: inline-flex; align-items: baseline; padding: 4px 10px; border: 1px solid var(--rule); border-radius: var(--radius-s); background: var(--surface); cursor: pointer; }
.flow-panel__list button:hover { border-color: var(--accent); color: var(--accent); }
.flow-panel__list button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.flow-panel__dir { flex: none; color: var(--accent); font-family: var(--font-mono); }
.flow-panel__dir[data-dir="up"] > [aria-hidden]::before { content: "↑"; margin-inline-end: 0.45em; }
.flow-panel__dir[data-dir="down"] > [aria-hidden]::before { content: "↓"; margin-inline-end: 0.45em; }
@media (max-width: 799px) { .flow-panel { bottom: var(--s-2); max-height: 45vh; } .flow-panel__list button { padding-block: 8px; } }
@media (prefers-reduced-motion: reduce) { .flow__bar { transition: none; } .flow__bar.is-flash { animation: none; } }
/* The narrowest seven-column widths: an even 6px inset, so the longest PT pairs ("o desenvolvimento",
   "quando necessário") still fit a one-step bar together. */
@media (min-width: 1280px) and (max-width: 1365px) {
  .flow__bar:not(.flow__bar--sync, .flow__bar--loop) { padding-inline: 6px; }
}

/* A pull quote that only appears at the end of the episode that earns it. */
.case-quote {
  grid-column: 4 / -1;
  margin: var(--s-7) 0 0;
  padding-inline-start: var(--s-5);
  border-inline-start: 3px solid var(--accent);
}
.case-quote p {
  font-family: var(--font-display);
  font-stretch: var(--display-stretch);
  font-weight: 800;
  font-size: var(--step-h2);
  line-height: var(--leading-snug);
  letter-spacing: -0.03em;
  max-width: 24ch;
}
@media (max-width: 1023px) { .case-quote { grid-column: 1 / -1; } }


/* Top of a case: back link, results strip, on-this-page row. */
.case-back { margin-block-end: var(--s-6); }
.case-back a, .case-toc a { display: inline-block; padding-block: 6px; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.25em; }
.case-results { list-style: none; margin: var(--s-6) 0 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gutter); }
.case-results li { display: grid; gap: var(--s-1); align-content: start; padding-block-start: var(--s-3); border-block-start: 2px solid var(--accent); }
.case-results strong { font-family: var(--font-display); font-stretch: var(--display-stretch); font-weight: 800; font-size: clamp(1.75rem, 1.3rem + 1.6vw, 2.75rem); line-height: 1; letter-spacing: -0.02em; color: var(--accent); font-variant-numeric: tabular-nums; }
.case-results span { color: var(--ink-muted); font-size: var(--step-small); }
.case-toc { display: flex; flex-wrap: wrap; column-gap: var(--s-5); margin-block-start: var(--s-6); }
.case-toc > span { padding-block: 6px; color: var(--ink-muted); }
@media (max-width: 767px) { .case-results { grid-template-columns: 1fr; } }

/* End of a case: contact, back to work, what's next. */
.case-close { padding-block: var(--section-gap) 0; }
.case-close__inner { display: grid; gap: var(--s-5); padding-block-start: var(--s-5); border-block-start: 1px solid var(--ink); }
.case-close h2 { font-size: var(--step-h1); font-weight: 800; line-height: var(--leading-tight); letter-spacing: -0.045em; }
/* Same as the home page address: one line at any width (14.69em wide, so 6.7cqi fits). */
.case-close__email { font-family: var(--font-display); font-stretch: var(--display-stretch); font-weight: 800; font-size: clamp(1.5rem, 0.9rem + 2.6vw, 3rem); letter-spacing: -0.03em; container-type: inline-size; }
.case-close__email a { font-size: min(1em, 6.7cqi); overflow-wrap: anywhere; text-decoration-color: var(--accent); text-decoration-thickness: 0.06em; text-underline-offset: 0.12em; }
.case-close__links { display: flex; flex-wrap: wrap; column-gap: var(--s-5); }
.case-close__links a { display: inline-block; padding-block: 6px; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.25em; }

/* Results strip: numbers inside <strong> keep their size and colour. */
.case-results strong span { font-size: inherit; color: inherit; }
/* Outcome rows share one number column so the descriptions line up. */
.numbers--case { grid-template-columns: max-content 1fr; column-gap: var(--s-5); }
.numbers--case li { grid-column: 1 / -1; grid-template-columns: subgrid; }
.case-close__next { font-size: var(--step-lead); }
.case-close__next a { text-decoration-color: var(--accent); text-decoration-thickness: 2px; text-underline-offset: 0.25em; }
@media (max-width: 767px) { .numbers--case { grid-template-columns: 1fr; } }

/* Real (sanitized) product screens: framed on silver, zoomable. */
.case-figure .plate--shot { padding: clamp(12px, 2.4vw, 40px); background: var(--surface-silver); border-radius: var(--radius-l); }
.case-figure .plate--shot img { border-radius: var(--radius-m); box-shadow: 0 1px 2px rgb(20 20 20 / 0.08), 0 8px 24px rgb(20 20 20 / 0.06); }
.case-figure .plate--shot .visual__zoom { display: block; width: 100%; }
/* Every screen says it is an adaptation, even when seen on its own: a tag above the capture,
   never over it. */
.case-figure .plate--shot::before {
  content: "Illustrative adaptation · NDA";
  content: "Illustrative adaptation · NDA" / "";
  display: block;
  width: fit-content;
  margin-block-end: var(--s-3);
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--ink);
  color: var(--surface);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  pointer-events: none;
}
:lang(pt) .case-figure .plate--shot::before { content: "Adaptação ilustrativa · NDA"; content: "Adaptação ilustrativa · NDA" / ""; }

/* Animated figures (main.js initFlowshot): layered 2x captures, a CSS hand cursor and click ripples.
   The finished state is the picture itself, so without JS or with reduced motion nothing is lost.
   Layer positions are percentages of the captured stage. */
.flowshot { position: relative; display: block; }
.flowshot > img, .flowshot > picture > img { display: block; width: 100%; height: auto; }
.flowshot__play, .flowshot__cursor, .flowshot__ripple { display: none; }
/* Animation control (main.js initFlowshot), on the tag's line: the plate becomes a wrapping row so the
   tag and the button sit side by side and the screenshot takes the full width below. Same pill as the
   tag, outlined instead of filled; the ring fills over the animation's length and freezes with it. */
.case-figure .plate--shot:has(> .flowshot__ctrl) { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--s-2); row-gap: var(--s-3); }
.case-figure .plate--shot:has(> .flowshot__ctrl)::before { margin-block-end: 0; }
.case-figure .plate--shot:has(> .flowshot__ctrl) > .visual__zoom { flex: 1 0 100%; }
.flowshot__ctrl { display: inline-flex; align-items: center; gap: 6px; min-height: 24px; padding: 2px 11px 2px 3px; border: 1px solid var(--ink); border-radius: 999px;
  background: transparent; color: var(--ink); font-family: var(--font-mono); font-size: 11px; letter-spacing: var(--tracking-label); text-transform: uppercase; line-height: 1; cursor: pointer;
  transition: background-color 150ms ease-out; }
.flowshot__ctrl:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); }
.flowshot__ctrl-mark { display: grid; place-items: center; width: 18px; height: 18px; }
.flowshot__ctrl-mark > svg { grid-area: 1 / 1; }
.flowshot__ring { width: 18px; height: 18px; transform: rotate(-90deg); fill: none; stroke-width: 2; }
.flowshot__ring circle:first-child { stroke: color-mix(in srgb, var(--ink) 20%, transparent); }
.flowshot__ring circle:last-child { stroke: currentColor; stroke-linecap: round; stroke-dasharray: 100; stroke-dashoffset: 100; }
.flowshot__ctrl.is-running .flowshot__ring circle:last-child { animation: flowshot-ring var(--flow-t) linear forwards; }
.flowshot__ctrl[data-state="paused"] .flowshot__ring circle:last-child { animation-play-state: paused; }
.flowshot__ctrl:is([data-state="idle"], [data-state="done"]) .flowshot__ring { display: none; }
@keyframes flowshot-ring { to { stroke-dashoffset: 0; } }
.flowshot__ctrl-icon { width: 8px; height: 8px; fill: currentColor; }
.flowshot__ctrl-icon--play { transform: translateX(0.5px); }
.flowshot__ctrl-icon--replay { width: 12px; height: 12px; }
.flowshot__ctrl:not([data-state="playing"]) .flowshot__ctrl-icon--pause,
.flowshot__ctrl:not([data-state="paused"], [data-state="idle"]) .flowshot__ctrl-icon--play,
.flowshot__ctrl:not([data-state="done"]) .flowshot__ctrl-icon--replay { display: none; }
.flowshot.is-paused, .flowshot.is-paused * { animation-play-state: paused !important; }
@media (prefers-reduced-motion: no-preference) {
  .js .flowshot.is-ready:not(.is-done) .flowshot__play { display: block; position: absolute; inset: 0; overflow: hidden; border-radius: var(--radius-m); }
  .case-figure .plate--shot .flowshot__play img { position: absolute; display: block; max-width: none; border-radius: 0; box-shadow: none; }
  .case-figure .plate--shot .flowshot__play img.flowshot__start { inset: 0; width: 100%; height: 100%; }
  .flowshot__cursor { display: block; position: absolute; opacity: 0; transform: translate(-41%, -6%); filter: drop-shadow(0 1px 2px rgb(0 0 0 / 0.35)); }
  .flowshot__cursor svg { display: block; width: 100%; height: auto; }
  .flowshot__ripple { display: block; position: absolute; aspect-ratio: 1; border-radius: 50%; background: rgb(91 63 184 / 0.28); opacity: 0; transform: translate(-50%, -50%) scale(0.2); }
  .flowshot.is-playing .flowshot__play { animation: flowshot-timer var(--flow-t) linear forwards; }

  /* Regions (1440 × 900): hover a row, click it, the drawer slides in, click Edit. */
  .flowshot--regions { --flow-t: 5.4s; }
  .flowshot--regions .flowshot__cursor { left: 78%; top: 84%; width: 1.9%; }
  .flowshot--regions .flowshot__ripple { width: 3%; }
  .case-figure .plate--shot .flowshot--regions img.flowshot__row { left: 2.222%; top: 44.889%; width: 95.556%; height: 5.333%; opacity: 0; }
  .case-figure .plate--shot .flowshot--regions img.flowshot__drawer { left: 58.333%; top: 0; width: 41.667%; height: 100%; transform: translateX(110%); box-shadow: 0 2px 6px rgb(22 24 29 / 0.06), 0 16px 40px rgb(22 24 29 / 0.1), -2px 0 12px rgb(22 24 29 / 0.06); }
  .case-figure .plate--shot .flowshot--regions img.flowshot__edit { left: 58.333%; top: 0; width: 41.667%; height: 100%; opacity: 0; }
  .flowshot--regions .flowshot__ripple--row { left: 23.056%; top: 47.556%; }
  .flowshot--regions .flowshot__ripple--edit { left: 96.493%; top: 2.444%; }
  .flowshot--regions.is-playing .flowshot__cursor { animation: flowshot-regions-cursor var(--flow-t) forwards; }
  .flowshot--regions.is-playing .flowshot__row { animation: flowshot-regions-row var(--flow-t) forwards; }
  .flowshot--regions.is-playing .flowshot__ripple--row { animation: flowshot-regions-ripple-row var(--flow-t) forwards; }
  .flowshot--regions.is-playing .flowshot__ripple--edit { animation: flowshot-regions-ripple-edit var(--flow-t) forwards; }
  .flowshot--regions.is-playing .flowshot__drawer { animation: flowshot-regions-drawer var(--flow-t) forwards; }
  .flowshot--regions.is-playing .flowshot__edit { animation: flowshot-regions-edit var(--flow-t) forwards; }

  /* The walkthrough (case "From my project to the whole design team"): the doc on step 1, a click on step 2's
     chip, the prototype changes to that step, the Save button lights up and its Click here marker pops in. */
  .flowshot--walk { --flow-t: 5.4s; }
  .flowshot--walk .flowshot__cursor { left: 88%; top: 86%; width: 3.4%; }
  .flowshot--walk .flowshot__ripple { width: 6%; left: 60.594%; top: 53.72%; }
  .case-figure .plate--shot .flowshot--walk img.flowshot__layer { left: 0; top: 0; width: 100%; height: 100%; opacity: 0; }
  .case-figure .plate--shot .flowshot--walk img.flowshot__layer--spot { left: 22.292%; top: 55%; width: 15.819%; height: auto; transform-origin: 72% 92%; }
  .flowshot--walk.is-playing .flowshot__cursor { animation: flowshot-walk-cursor var(--flow-t) forwards; }
  .flowshot--walk.is-playing .flowshot__ripple { animation: flowshot-walk-ripple var(--flow-t) forwards; }
  .flowshot--walk.is-playing .flowshot__layer--s2 { animation: flowshot-walk-s2 var(--flow-t) forwards; }
  .flowshot--walk.is-playing .flowshot__layer--s3 { animation: flowshot-walk-s3 var(--flow-t) forwards; }
  .flowshot--walk.is-playing .flowshot__layer--spot { animation: flowshot-walk-spot var(--flow-t) forwards; }
  /* Region picker (the 600 × 900 drawer): click Region, type "st", point at a region out of reach. */
  .flowshot--picker { --flow-t: 5.6s; }
  .flowshot--picker .flowshot__cursor { left: 70%; top: 32.889%; width: 4.4%; }
  .flowshot--picker .flowshot__ripple { width: 7%; left: 25.333%; top: 53.556%; }
  .case-figure .plate--shot .flowshot--picker img.flowshot__layer { left: 0; top: 47.778%; width: 100%; height: 43.222%; opacity: 0; }
  .flowshot--picker.is-playing .flowshot__cursor { animation: flowshot-picker-cursor var(--flow-t) forwards; }
  .flowshot--picker.is-playing .flowshot__ripple { animation: flowshot-picker-ripple var(--flow-t) forwards; }
  .flowshot--picker.is-playing .flowshot__layer--focus { animation: flowshot-picker-focus var(--flow-t) forwards; }
  .flowshot--picker.is-playing .flowshot__layer--s { animation: flowshot-picker-s var(--flow-t) forwards; }
  .flowshot--picker.is-playing .flowshot__layer--st { animation: flowshot-picker-st var(--flow-t) forwards; }

  /* Write Prompt (case UI Inspector, the 800 × 640 crop): click Weight, type 600 (the counter on Write Prompt goes
     from 3 to 4), Enter, click Write Prompt, the prompt opens, click Copy (Copied! for 1.2 s, as in the tool). */
  .flowshot--prompt { --flow-t: 8s; }
  .flowshot--prompt .flowshot__cursor { left: 74%; top: 66%; width: 3.2%; }
  .flowshot--prompt .flowshot__ripple { width: 6%; }
  .flowshot--prompt .flowshot__ripple--weight { left: 65.313%; top: 76.563%; }
  .flowshot--prompt .flowshot__ripple--write { left: 86.063%; top: 96.25%; }
  .flowshot--prompt .flowshot__ripple--copy { left: 38.813%; top: 95%; }
  .case-figure .plate--shot .flowshot--prompt img.flowshot__layer { opacity: 0; }
  .case-figure .plate--shot .flowshot--prompt img.flowshot__layer--b1, .case-figure .plate--shot .flowshot--prompt img.flowshot__layer--d2 { left: 62.25%; top: 74.063%; width: 11.5%; height: 5.625%; }
  .case-figure .plate--shot .flowshot--prompt img.flowshot__layer--c1 { left: 63.25%; top: 74.063%; width: 5.5%; height: 5.625%; }
  .case-figure .plate--shot .flowshot--prompt img.flowshot__layer--c2 { left: 92.25%; top: 94.063%; width: 3.5%; height: 4.375%; }
  .case-figure .plate--shot .flowshot--prompt img.flowshot__layer--d1 { left: 51.25%; top: 74.063%; width: 7.5%; height: 4.375%; }
  .case-figure .plate--shot .flowshot--prompt img.flowshot__layer--e1 { left: 2.25%; top: 5.313%; width: 51.5%; height: 94.688%; transform-origin: 100% 100%; }
  .case-figure .plate--shot .flowshot--prompt img.flowshot__layer--f1 { left: 23.25%; top: 91.563%; width: 19.5%; height: 6.875%; }
  .flowshot--prompt.is-playing .flowshot__cursor { animation: flowshot-prompt-cursor var(--flow-t) forwards; }
  .flowshot--prompt.is-playing .flowshot__ripple--weight { animation: flowshot-prompt-ripple-weight var(--flow-t) forwards; }
  .flowshot--prompt.is-playing .flowshot__ripple--write { animation: flowshot-prompt-ripple-write var(--flow-t) forwards; }
  .flowshot--prompt.is-playing .flowshot__ripple--copy { animation: flowshot-prompt-ripple-copy var(--flow-t) forwards; }
  .flowshot--prompt.is-playing .flowshot__layer--b1 { animation: flowshot-prompt-b var(--flow-t) forwards; }
  .flowshot--prompt.is-playing .flowshot__layer--c1 { animation: flowshot-prompt-c var(--flow-t) forwards; }
  .flowshot--prompt.is-playing .flowshot__layer--c2 { animation: flowshot-prompt-count var(--flow-t) forwards; }
  .flowshot--prompt.is-playing :is(.flowshot__layer--d1, .flowshot__layer--d2) { animation: flowshot-prompt-d var(--flow-t) forwards; }
  .flowshot--prompt.is-playing .flowshot__layer--e1 { animation: flowshot-prompt-e var(--flow-t) forwards; }
  .flowshot--prompt.is-playing .flowshot__layer--f1 { animation: flowshot-prompt-f var(--flow-t) forwards; }
}
@keyframes flowshot-timer { from, to { opacity: 1; } }
@keyframes flowshot-regions-cursor {
  0% { left: 78%; top: 84%; opacity: 0; transform: translate(-41%, -6%) scale(1); animation-timing-function: ease-out; }
  5.6% { opacity: 1; animation-timing-function: cubic-bezier(.45, 0, .25, 1); }
  22.2% { left: 23.056%; top: 47.556%; transform: translate(-41%, -6%) scale(1); }
  25% { transform: translate(-41%, -6%) scale(0.84); }
  27.8% { left: 23.056%; top: 47.556%; transform: translate(-41%, -6%) scale(1); }
  40.7% { left: 23.056%; top: 47.556%; animation-timing-function: cubic-bezier(.45, 0, .25, 1); }
  55.6% { left: 96.493%; top: 2.444%; transform: translate(-41%, -6%) scale(1); }
  58.3% { transform: translate(-41%, -6%) scale(0.84); }
  61.1% { left: 96.493%; top: 2.444%; transform: translate(-41%, -6%) scale(1); opacity: 1; }
  81.5% { left: 96.493%; top: 2.444%; opacity: 1; }
  88.9%, 100% { left: 96.493%; top: 2.444%; opacity: 0; transform: translate(-41%, -6%) scale(1); }
}
@keyframes flowshot-regions-row { 0%, 20.4% { opacity: 0; } 24%, 100% { opacity: 1; } }
@keyframes flowshot-regions-ripple-row { 0%, 25% { opacity: 0; transform: translate(-50%, -50%) scale(0.2); } 27% { opacity: 1; } 33.3%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.4); } }
@keyframes flowshot-regions-ripple-edit { 0%, 58.3% { opacity: 0; transform: translate(-50%, -50%) scale(0.2); } 60.2% { opacity: 1; } 66.7%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.4); } }
@keyframes flowshot-regions-drawer { 0%, 28.7% { transform: translateX(110%); animation-timing-function: cubic-bezier(.16, .84, .3, 1); } 35.2%, 100% { transform: translateX(0); } }
@keyframes flowshot-regions-edit { 0%, 62% { opacity: 0; } 66.7%, 100% { opacity: 1; } }
@keyframes flowshot-walk-cursor {
  0% { left: 88%; top: 86%; opacity: 0; transform: translate(-41%, -6%) scale(1); animation-timing-function: ease-out; }
  6% { opacity: 1; animation-timing-function: cubic-bezier(.45, 0, .25, 1); }
  28% { left: 60.594%; top: 53.72%; transform: translate(-41%, -6%) scale(1); }
  31% { transform: translate(-41%, -6%) scale(0.84); }
  34% { left: 60.594%; top: 53.72%; transform: translate(-41%, -6%) scale(1); }
  64% { left: 60.594%; top: 53.72%; opacity: 1; animation-timing-function: ease-in; }
  74%, 100% { left: 66%; top: 64%; opacity: 0; transform: translate(-41%, -6%) scale(1); }
}
@keyframes flowshot-walk-ripple { 0%, 30% { opacity: 0; transform: translate(-50%, -50%) scale(0.2); } 32% { opacity: 1; } 40%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.4); } }
@keyframes flowshot-walk-s2 { 0%, 34% { opacity: 0; } 40%, 100% { opacity: 1; } }
@keyframes flowshot-walk-s3 { 0%, 52% { opacity: 0; } 56%, 100% { opacity: 1; } }
@keyframes flowshot-walk-spot { 0%, 54% { opacity: 0; transform: scale(0.6); } 60% { opacity: 1; transform: scale(1.08); } 64%, 100% { opacity: 1; transform: scale(1); } }
@keyframes flowshot-picker-cursor {
  0% { left: 70%; top: 32.889%; opacity: 0; transform: translate(-41%, -6%) scale(1); animation-timing-function: ease-out; }
  5% { opacity: 1; animation-timing-function: cubic-bezier(.45, 0, .25, 1); }
  19.6% { left: 25.333%; top: 53.556%; transform: translate(-41%, -6%) scale(1); }
  22% { transform: translate(-41%, -6%) scale(0.84); }
  24.5% { left: 25.333%; top: 53.556%; transform: translate(-41%, -6%) scale(1); }
  35.7% { left: 25.333%; top: 53.556%; animation-timing-function: cubic-bezier(.45, 0, .25, 1); }
  50% { left: 50%; top: 85.889%; transform: translate(-41%, -6%) scale(1); opacity: 1; }
  78.6% { left: 50%; top: 85.889%; opacity: 1; }
  87.5%, 100% { left: 50%; top: 85.889%; opacity: 0; transform: translate(-41%, -6%) scale(1); }
}
@keyframes flowshot-picker-ripple { 0%, 22% { opacity: 0; transform: translate(-50%, -50%) scale(0.2); } 24% { opacity: 1; } 31%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.4); } }
@keyframes flowshot-picker-focus { 0%, 22.5% { opacity: 0; } 24.5%, 100% { opacity: 1; } }
@keyframes flowshot-picker-s { 0%, 28.5% { opacity: 0; } 28.6%, 100% { opacity: 1; } }
@keyframes flowshot-picker-st { 0%, 32.9% { opacity: 0; } 33%, 100% { opacity: 1; } }
@keyframes flowshot-prompt-cursor {
  0% { left: 74%; top: 66%; opacity: 0; transform: translate(-41%, -6%) scale(1); animation-timing-function: ease-out; }
  5% { opacity: 1; animation-timing-function: cubic-bezier(.45, 0, .25, 1); }
  14% { left: 65.313%; top: 76.563%; transform: translate(-41%, -6%) scale(1); }
  16% { transform: translate(-41%, -6%) scale(0.84); }
  18% { left: 65.313%; top: 76.563%; transform: translate(-41%, -6%) scale(1); animation-timing-function: ease-out; }
  22% { left: 68.5%; top: 80.5%; }
  35% { left: 68.5%; top: 80.5%; animation-timing-function: cubic-bezier(.45, 0, .25, 1); }
  50% { left: 86.063%; top: 96.25%; transform: translate(-41%, -6%) scale(1); }
  52% { transform: translate(-41%, -6%) scale(0.84); }
  54% { left: 86.063%; top: 96.25%; transform: translate(-41%, -6%) scale(1); }
  60% { left: 86.063%; top: 96.25%; animation-timing-function: cubic-bezier(.45, 0, .25, 1); }
  72% { left: 38.813%; top: 95%; transform: translate(-41%, -6%) scale(1); }
  74% { transform: translate(-41%, -6%) scale(0.84); }
  76% { left: 38.813%; top: 95%; transform: translate(-41%, -6%) scale(1); animation-timing-function: ease-out; }
  80% { left: 42.5%; top: 94%; }
  84% { left: 42.5%; top: 94%; opacity: 1; animation-timing-function: ease-in; }
  92%, 100% { left: 46%; top: 86%; opacity: 0; transform: translate(-41%, -6%) scale(1); }
}
@keyframes flowshot-prompt-ripple-weight { 0%, 16% { opacity: 0; transform: translate(-50%, -50%) scale(0.2); } 17.5% { opacity: 1; } 23%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.4); } }
@keyframes flowshot-prompt-ripple-write { 0%, 52% { opacity: 0; transform: translate(-50%, -50%) scale(0.2); } 53.5% { opacity: 1; } 59%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.4); } }
@keyframes flowshot-prompt-ripple-copy { 0%, 74% { opacity: 0; transform: translate(-50%, -50%) scale(0.2); } 75.5% { opacity: 1; } 81%, 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.4); } }
@keyframes flowshot-prompt-b { 0%, 16.9% { opacity: 0; } 17%, 100% { opacity: 1; } }
@keyframes flowshot-prompt-c { 0%, 26.9% { opacity: 0; } 27%, 100% { opacity: 1; } }
@keyframes flowshot-prompt-count { 0%, 26.9% { opacity: 0; transform: scale(1); } 27% { opacity: 1; transform: scale(1.35); } 31%, 100% { opacity: 1; transform: scale(1); } }
@keyframes flowshot-prompt-d { 0%, 32.9% { opacity: 0; } 33%, 100% { opacity: 1; } }
@keyframes flowshot-prompt-e { 0%, 54% { opacity: 0; transform: scale(0.96); animation-timing-function: cubic-bezier(.16, .84, .3, 1); } 59%, 100% { opacity: 1; transform: scale(1); } }
@keyframes flowshot-prompt-f { 0%, 75.9% { opacity: 0; } 76%, 90.9% { opacity: 1; } 91%, 100% { opacity: 0; } }

/* Case extras: small variants the shared case template does not have yet.
   Same rules as case.css: monochrome + accent, states differ by stroke, no gradients. */

/* A shorter loop: three steps in one row. */
@media (min-width: 1024px) {
  .loop--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .loop--3 li:not(:last-child)::after { content: "→"; right: -0.75em; left: auto; top: 50%; bottom: auto; transform: translateY(-50%); }
}

/* A four-step loop: one row from 1280px, like the five-step one, with no empty fifth column. */
@media (min-width: 1280px) { .loop--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.loop-title { margin-block-end: var(--s-3); color: var(--accent); }
.loop-title + .loop { margin-block-end: var(--s-6); }

/* A close-up placed right after the prose, outside a numbered decision: the same breathing room
   a figure gets inside one. */
.case-section > .case-prose + .case-figure--detail { margin-block-start: var(--s-6); }

/* A long feature list split into groups, each with its own label (the hand-off assistant's features). */
.case-section > .case-group { margin-block-start: var(--s-8); color: var(--accent); }
.case-group + .pillars { margin-block-start: var(--s-4); }
.case-group + .case-prose { margin-block-start: var(--s-3); }
.case-group + .case-prose + .pillars { margin-block-start: var(--s-5); }
.pillars + .case-figure--detail, .case-figure--detail + .case-figure--detail { margin-block-start: var(--s-6); }

/* A link that closes a section of a case ("the documents at work, in another case →"), like the
   home's section links: accent, a comfortable target, after whatever the section shows. */
.case-more { margin-block-start: var(--s-6); }
.case-more a { display: inline-block; padding-block: 6px; color: var(--accent); }

/* The CSD columns as a two-state comparison. */
@media (min-width: 768px) {
  .csd--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* AI layer with four columns: a 2 × 2 grid. */
@media (min-width: 1024px) {
  .ai-layer--2x2 > div { grid-column: span 6; }
}

/* Icon ink: generic glyph outlines inside the app's ink box. Schematic, not the product's icons.
   Dashed = the app's ink box. Solid = the prototype's glyph. */
.ink { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gutter); }
.ink__panel { display: grid; gap: var(--s-5); align-content: start; padding: var(--s-5); border-radius: var(--radius-m); background: var(--surface); }
.ink__panel > .label { color: var(--ink-muted); }
.ink__row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-6); min-height: 104px; padding-inline: var(--s-2); }
.ink__slot { position: relative; flex: none; width: var(--w); height: var(--h); border: 1.5px dashed var(--accent); border-radius: 2px; }
.ink__slot--1 { --w: 66px; --h: 66px; }
.ink__slot--2 { --w: 78px; --h: 78px; }
.ink__slot--3 { --w: 81px; --h: 81px; }
.ink__slot--4 { --w: 54px; --h: 66px; }
.ink__mark {
  position: absolute;
  left: 50%;
  top: 50%;
  box-sizing: border-box;
  width: var(--mw);
  height: var(--mh);
  border: 2px solid var(--ink);
  transform: translate(-50%, -50%);
}
.ink__row--box .ink__mark { --mw: 60px; --mh: 60px; }
.ink__row--box .ink__slot--4 .ink__mark { --mw: 44px; }   /* same box height; a narrow glyph inside it */
.ink__row--ink .ink__mark { --mw: calc(var(--w) - 3px); --mh: calc(var(--h) - 3px); }
.ink__mark--circle { border-radius: 50%; }
.ink__mark--square { border-radius: 22%; }
.ink__mark--capsule { border-radius: 999px; }
.ink__mark--diamond { width: calc(var(--mw) * 0.7); height: calc(var(--mh) * 0.7); border-radius: 3px; transform: translate(-50%, -50%) rotate(45deg); }
.ink__gap { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: var(--s-3); max-width: none; }
.ink__gap strong {
  font-family: var(--font-display);
  font-stretch: var(--display-stretch);
  font-weight: 800;
  font-size: var(--step-h2);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.ink__gap span { font-size: var(--step-small); color: var(--ink-muted); }
@media (max-width: 767px) { .ink { grid-template-columns: 1fr; } }

/* A few rows of a failure → rule table. The rule column carries the accent, like a flag. */
.rules {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  border-radius: var(--radius-m);
  overflow: hidden;
  background: var(--surface);
  font-size: var(--step-small);
  line-height: 1.45;
}
.rules th {
  padding: var(--s-4) var(--s-5);
  text-align: start;
  vertical-align: bottom;
  font-family: var(--font-mono);
  font-size: var(--step-label);
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ink-muted);
  border-block-end: 1.5px solid var(--ink);
}
.rules td { padding: var(--s-4) var(--s-5); vertical-align: top; border-block-start: 1px solid var(--rule); }
.rules tbody tr:first-child td { border-block-start: 0; }
.rules th:nth-child(1), .rules td:nth-child(1) { width: 32%; }
.rules th:nth-child(2), .rules td:nth-child(2) { width: 32%; color: var(--ink-muted); }
.rules td:last-child { box-shadow: inset 3px 0 0 var(--accent); font-weight: 600; }
@media (max-width: 767px) {
  .rules thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .rules tr, .rules td { display: block; width: auto; }
  .rules th:nth-child(n), .rules td:nth-child(n) { width: auto; }
  .rules tbody tr + tr { border-block-start: 1.5px solid var(--ink); }
  .rules td { border-block-start: 0; padding-block: var(--s-2); }
  .rules td::before {
    content: attr(data-label);
    display: block;
    margin-block-end: var(--s-1);
    font-family: var(--font-mono);
    font-size: var(--step-label);
    font-weight: 500;
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--ink-muted);
  }
}
