/* ==========================================================================
   Case study — shared UI language for every project page in /work.
   Event Platform (event-platform.html) is the reference layout: centred or
   left section heads with pill eyebrows, alternating white / surface
   sections, ring + soft-shadow cards, tilted sticker icons, persona cards
   with an illustrated avatar, and results as cards. Every case study links
   this file first, then its own small stylesheet for page-only rules (the
   hero glow image, and anything used by one page only).
   Tokens are copied 1:1 from the homepage (assets/styles.css): change them
   there first, then here.
   ========================================================================== */

:root {
  --color-primary: #1A73E8;
  --color-primary-hover: #1557B0;
  --color-white: #FFFFFF;
  --color-surface: #F8F9FA;
  --color-text: #5F6368;
  --color-heading: #202124;
  --color-hairline: rgb(32 33 36 / 0.08);
  --color-hairline-strong: rgb(32 33 36 / 0.16);
  --color-primary-tint: rgb(26 115 232 / 0.12);
  --color-secondary: #F40F48;
  --color-secondary-tint: rgb(244 15 72 / 0.12);

  --font-sans: "Google Sans Flex", "Google Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --text-h1: 2.25rem;
  --text-h2: 2rem;
  --text-h3: 1.5rem;
  --text-body: 1.125rem;
  --text-small: 1rem;
  --text-xs: 0.875rem;
  --text-eyebrow: 0.8125rem;
  --weight-medium: 500;
  --weight-heading: 560;

  --space-0-5: 0.25rem;
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2rem;
  --space-5: 2.5rem;
  --space-6: 3rem;
  --space-8: 4rem;
  --space-10: 5rem;
  --space-12: 6rem;
  --space-16: 8rem;

  --container: 75rem;
  --gutter: var(--space-3);
  --section-y: var(--space-8);
  --grid-gap: var(--space-3);
  /* Column system, copied from the homepage's tokens: 4 columns below 48em, 8 from
     48em, 12 from 64em; gutter = --grid-gap. See assets/styles.css. */
  --cols: 4;
  --grid-12: repeat(12, minmax(0, 1fr));
  /* Components are sized by the columns (see assets/styles.css): a component that cannot use
     grid-column sets --n, the number of columns it spans, and takes its width from --span
     (n columns plus the n-1 gutters between them, against a box one container wide). */
  --nav-offset: var(--space-1);
  --nav-height: 3.5rem;

  --bezel: var(--space-1);
  --radius-inner: 1rem;
  --radius-outer: 1.5rem;
  --radius-pill: 999px;

  --ring: 0 0 0 1px var(--color-hairline);
  --shadow-1: 0 1px 2px rgb(32 33 36 / 0.04), 0 8px 24px -12px rgb(32 33 36 / 0.12);
  --shadow-2: 0 2px 4px rgb(32 33 36 / 0.04), 0 24px 48px -20px rgb(32 33 36 / 0.22);
  --shadow-primary: 0 1px 2px rgb(26 115 232 / 0.24), 0 8px 24px -8px rgb(26 115 232 / 0.5);

  --ease-out: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-soft: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-fast: 200ms;
  --dur-base: 400ms;
  --dur-slow: 600ms;
  --dur-reveal: 800ms;
}
@media (min-width: 48em) {
  :root { --cols: 8; --gutter: var(--space-4); --section-y: var(--space-12); --text-h1: 3rem; --text-h2: 2.5rem; --text-h3: 1.75rem; }
}
@media (min-width: 64em) {
  :root { --cols: 12; --gutter: var(--space-5); --section-y: var(--space-16); --grid-gap: var(--space-4); --nav-offset: var(--space-2); --text-h1: 3.5rem; }
}
@media (min-width: 106em) {
  :root { --container: 90rem; --gutter: var(--space-6); }
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
/* ▸ Baseline grid (7 Oct 2026). Every element's line-height is its ratio times its OWN
   font size, rounded to the nearest 4px, so every line of text sits on the 4px baseline
   (an 18px paragraph at 1.5 is 28px, not 27; a 40px heading at 1.15 is 48px, not 46).
   Components set the ratio with --lh (it inherits exactly like a unitless line-height
   used to); this one rule turns it into px. A browser without CSS round() keeps the
   plain ratio from the first declaration. */
*, *::before, *::after {
  line-height: var(--lh, 1.5);
  line-height: round(nearest, calc(var(--lh, 1.5) * 1em), 4px);
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: calc(var(--nav-offset) + var(--nav-height) + var(--space-3));
}
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }

body {
  margin: 0;
  background: var(--color-white);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  --lh: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

/* Same fixed 4-column hairline grid as the homepage. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  max-width: var(--container);
  margin-inline: auto;
  pointer-events: none;
  background-image: repeating-linear-gradient(to right, var(--color-hairline) 0, var(--color-hairline) 1px, transparent 1px, transparent 25%);
}
/* Opt-out for a page whose text the four hairlines would run through. */
body.no-grid-lines::before { display: none; }

h1, h2, h3, p, dl, dd, ol, ul, figure { margin: 0; }
ul[role="list"], ol[role="list"] { list-style: none; padding: 0; }
img, svg { display: block; max-width: 100%; }
button { font: inherit; color: inherit; }
a { color: var(--color-primary); }
strong { color: var(--color-heading); font-weight: 600; }

:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 3px; }
main:focus { outline: none; }

.skip-link {
  position: fixed; top: var(--space-1); left: var(--space-1); z-index: 40;
  display: inline-flex; align-items: center; min-height: 44px;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--color-heading); color: var(--color-white);
  font-weight: var(--weight-medium); text-decoration: none;
  transform: translateY(-200%);
  transition: transform var(--dur-base) var(--ease-out);
}
.skip-link:focus { transform: none; }

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */
.section { position: relative; }
.section-alt { background: var(--color-surface); }
.frame {
  max-width: calc(var(--container) + var(--gutter) * 2);
  margin-inline: auto;
  padding: var(--section-y) var(--gutter);
}

/* --------------------------------------------------------------------------
   Type
   -------------------------------------------------------------------------- */
.eyebrow {
  display: inline-flex; align-items: center;
  min-height: 28px;
  margin-bottom: var(--space-3);
  padding: var(--space-0-5) var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--color-white);
  box-shadow: var(--ring);
  color: var(--color-text);
  font-size: var(--text-eyebrow);
  font-weight: var(--weight-medium);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.h1, .h2, .h3 { color: var(--color-heading); font-weight: var(--weight-heading); text-wrap: balance; }
.h1 { font-size: var(--text-h1); --lh: 1.1; letter-spacing: -0.025em; }
.h2 { font-size: var(--text-h2); --lh: 1.15; letter-spacing: -0.02em; margin-bottom: var(--space-2); }
.h3 { font-size: var(--text-h3); --lh: 1.25; letter-spacing: -0.01em; margin-bottom: var(--space-1); }
.lede { font-size: var(--text-body); color: var(--color-text); }
.muted-note { font-size: var(--text-xs); color: var(--color-text); --lh: 1.55; }

.center { text-align: center; }
.center .h2, .center .lede { margin-inline: auto; }
.measure { max-width: 40rem; }
.measure-wide { max-width: 44rem; }

/* Card title: one size for every card grid on every page. */
.persona-card .h3, .principle-title, .method .h3, .result .h3 {
  font-size: 1.25rem; --lh: 1.3; letter-spacing: -0.01em;
}

/* --------------------------------------------------------------------------
   Header — floating island, same as the homepage navbar
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky; top: 0; z-index: 30;
  padding: var(--nav-offset) var(--gutter) 0;
  pointer-events: none;
}
/* ▸ Full-width atmospheric band behind the header, same technique as the
   homepage navbar: softens and fades whatever scrolls past on either side
   of the pill so the blur reads as one smooth surface, not a blurred
   island sitting in an otherwise untouched strip. */
.site-header::before {
  content: "";
  position: absolute;
  z-index: 0;
  inset: 0 0 auto 0;
  height: calc(var(--nav-offset) + var(--nav-height) + var(--space-10));
  background: linear-gradient(to bottom,
    rgb(255 255 255 / 0.55) 0%,
    rgb(237 242 253 / 0.4) 45%,
    rgb(26 115 232 / 0.1) 70%,
    transparent 100%);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 55%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 55%, transparent 100%);
  pointer-events: none;
}
.site-header_row {
  position: relative; z-index: 2;
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-1);
  max-width: var(--container);
  height: var(--nav-height);
  margin-inline: auto;
  padding: 0 var(--space-1) 0 var(--space-3);
  border-radius: var(--radius-pill);
  /* Diagonal transparency gradient (near-opaque by the logo, easing to a
     pale blue tint by the CTA) instead of a flat tint, same glass recipe
     as the homepage pill. */
  background: linear-gradient(135deg, rgb(255 255 255 / 0.88) 0%, rgb(237 242 253 / 0.62) 55%, rgb(26 115 232 / 0.16) 100%);
  box-shadow: var(--ring), var(--shadow-1), inset 0 1px 0 rgb(255 255 255 / 0.6);
  pointer-events: auto;
  transition: box-shadow var(--dur-slow) var(--ease-soft);
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .site-header_row {
    -webkit-backdrop-filter: blur(16px) saturate(1.8);
    backdrop-filter: blur(16px) saturate(1.8);
  }
}
.site-header_back {
  display: inline-flex; align-items: center; gap: var(--space-1);
  min-height: 44px;
  color: var(--color-heading);
  font-size: 1.25rem; font-weight: 600; letter-spacing: -0.02em;
  text-decoration: none;
}
.site-header_logo { width: 40px; height: 40px; flex: none; }
.site-header_arrow { font-size: 1rem; transition: transform var(--dur-base) var(--ease-out); }
.site-header_back:hover .site-header_arrow { transform: translateX(-3px); }

.site-footer { box-shadow: inset 0 1px 0 var(--color-hairline); }
.site-footer_row {
  max-width: calc(var(--container) + var(--gutter) * 2);
  margin-inline: auto;
  padding: var(--space-4) var(--gutter);
  display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3);
  align-items: center; justify-content: space-between;
  font-size: var(--text-xs);
}
.site-footer_row a {
  display: inline-flex; align-items: center; min-height: 44px;
  color: var(--color-heading); font-weight: var(--weight-medium);
  text-decoration: underline; text-decoration-color: var(--color-hairline-strong);
  text-underline-offset: 4px;
  transition: text-decoration-color var(--dur-fast) var(--ease-soft);
}
.site-footer_row a:hover { text-decoration-color: currentColor; }

/* --------------------------------------------------------------------------
   Buttons & tags — homepage .button / .tag
   -------------------------------------------------------------------------- */
.button {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: 48px; padding: 0 var(--space-3);
  border: 0; border-radius: var(--radius-pill);
  font-size: var(--text-small); font-weight: var(--weight-medium); --lh: 1.2;
  text-decoration: none; white-space: nowrap; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--dur-fast) var(--ease-soft), box-shadow var(--dur-base) var(--ease-soft), transform var(--dur-fast) var(--ease-out);
}
.button:active { transform: scale(0.98); }
.button.is-primary { padding-right: var(--space-1); background: var(--color-primary); color: var(--color-white); box-shadow: var(--shadow-primary); }
.button.is-primary:hover { background: var(--color-primary-hover); }
.button.is-secondary { background: var(--color-white); color: var(--color-heading); box-shadow: inset 0 0 0 1px var(--color-hairline-strong); }
.button.is-secondary:hover { background: var(--color-surface); box-shadow: inset 0 0 0 1px var(--color-hairline-strong), var(--shadow-1); }
.button.is-small { min-height: 44px; padding: 0 var(--space-3); font-size: var(--text-xs); }
.button.is-small.is-primary { box-shadow: none; }

.button_icon {
  display: grid; place-items: center;
  width: 32px; height: 32px; flex: none;
  border-radius: 50%;
  background: rgb(255 255 255 / 0.18);
  transition: transform var(--dur-base) var(--ease-out), background-color var(--dur-fast) var(--ease-soft);
}
.button_icon svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.button.is-primary:hover .button_icon { transform: translateX(2px) scale(1.06); background: rgb(255 255 255 / 0.24); }

.tag-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.tag {
  display: inline-flex; align-items: center;
  min-height: 28px; padding: 0 12px;
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  color: var(--color-heading);
  font-size: var(--text-eyebrow); font-weight: var(--weight-medium); letter-spacing: 0.02em;
}
/* ▸ Status tag (e.g. "Exploring, not built") and placeholder tag (a figure
   that isn't measured yet). The placeholder tag is dashed so it never reads
   as a real result. */
.tag.is-status { background: var(--color-primary-tint); color: var(--color-primary); }
.tag.is-placeholder { background: transparent; color: var(--color-text); border: 1px dashed var(--color-hairline-strong); }
.tag-row.is-start { justify-content: flex-start; }

/* Media well: homepage double-bezel (white shell, 8px, inner radius 16). */
.media, .company-media {
  padding: var(--bezel);
  border-radius: var(--radius-outer);
  background: var(--color-white);
  box-shadow: var(--ring), var(--shadow-1);
}
.media img, .company-media img { width: 100%; height: auto; border-radius: var(--radius-inner); }

/* Card: homepage focus/stack card. */
.persona-card, .principle-card, .result {
  border-radius: var(--radius-outer);
  background: var(--color-white);
  box-shadow: var(--ring), var(--shadow-1);
  transition: transform var(--dur-slow) var(--ease-out), box-shadow var(--dur-slow) var(--ease-soft);
}
.persona-card:hover, .result:hover { box-shadow: var(--ring), var(--shadow-2); }

/* Sticker icon: homepage .focus_icon */
.sticker {
  display: grid; place-items: center;
  width: 48px; height: 48px; flex: none;
  padding: 12px;
  border-radius: 14px;
  background: var(--color-white);
  box-shadow: var(--ring), 0 10px 20px -8px rgb(26 115 232 / 0.35), var(--shadow-1);
  transform: rotate(var(--rotate, -6deg));
  transition: transform var(--dur-slow) var(--ease-out);
}
.sticker svg { width: 100%; height: 100%; fill: none; stroke: var(--color-heading); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.sticker img { width: 100%; height: 100%; object-fit: contain; }
.principle-card:hover .sticker { transform: rotate(0deg) translateY(-3px); }

/* ▸ Sticker row: two tool badges side by side, for cards that name a pair
   of tools rather than one. Smaller than a lone .sticker so the pair reads
   as one unit, not two full-size badges competing for attention. */
.sticker-row { display: flex; gap: 8px; }
.sticker-row .sticker { width: 36px; height: 36px; padding: 8px; border-radius: 12px; }

/* --------------------------------------------------------------------------
   Hero — the glow image and its sampling positions are set per page.
   -------------------------------------------------------------------------- */
.hero { overflow-x: clip; }
.hero .frame { position: relative; z-index: 1; text-align: center; padding-block: var(--space-10) var(--section-y); }
@media (min-width: 64em) { .hero .frame { padding-block: var(--space-16) var(--space-12); } }
.hero .h1 { max-width: 16ch; margin: 0 auto var(--space-3); }
.hero .lede { max-width: 38rem; margin: 0 auto var(--space-4); font-size: 1.25rem; }
/* Longer project titles / ledes get a wider measure. */
.hero .h1.is-wide { max-width: 20ch; }
.hero .lede.is-wide { max-width: 42rem; }
/* One factual outcome line under the description: a label, then the result. */
.hero_outcome { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center; gap: var(--space-1) var(--space-2); max-width: 38rem; margin: 0 auto var(--space-4); color: var(--color-heading); font-size: var(--text-body); --lh: 1.5; }
.hero_outcome-label { flex: none; color: var(--color-primary); font-size: var(--text-small); font-weight: var(--weight-medium); }

/* Two soft glows sampled from each project's own artwork, the homepage
   hero's atmosphere technique. */
.hero_atmosphere {
  position: absolute; inset: 0; z-index: 0; overflow: clip; pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, #000 55%, transparent);
  mask-image: linear-gradient(to bottom, #000 55%, transparent);
}
.hero_blob {
  position: absolute; border-radius: 50%;
  background-size: 300% auto;
  filter: blur(64px) saturate(1.3);
}
.hero_blob-a { top: -6rem; left: -6rem; width: 18rem; height: 18rem; background-position: 5% 10%; opacity: 0.3; }
.hero_blob-b { bottom: -8rem; right: -6rem; width: 20rem; height: 20rem; background-position: 95% 80%; opacity: 0.28; }
@media (min-width: 48em) {
  .hero_blob-a { top: -10rem; left: -4rem; width: 28rem; height: 28rem; }
  .hero_blob-b { bottom: -12rem; right: -4rem; width: 30rem; height: 30rem; }
}
@media (prefers-reduced-motion: no-preference) {
  .hero_blob-a { animation: hero-drift-a 26s var(--ease-soft) infinite; }
  .hero_blob-b { animation: hero-drift-b 32s var(--ease-soft) infinite; }
}
@keyframes hero-drift-a { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(2.5rem, 1.5rem); } }
@keyframes hero-drift-b { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(-2rem, -2.5rem); } }

/* --------------------------------------------------------------------------
   The company / overview
   -------------------------------------------------------------------------- */
.company-grid { display: grid; gap: var(--space-5); }
@media (min-width: 64em) {
  /* Text on columns 1–7, details on 8–12. */
  .company-grid { grid-template-columns: var(--grid-12); column-gap: var(--grid-gap); align-items: end; }
  .company-grid > :nth-child(1) { grid-column: 1 / span 7; }
  .company-grid > :nth-child(2) { grid-column: 8 / span 5; }
}
.meta-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-outer);
  background: var(--color-white);
  box-shadow: var(--ring);
}
.meta-grid dt { margin-bottom: 4px; color: var(--color-text); font-size: var(--text-eyebrow); font-weight: var(--weight-medium); letter-spacing: 0.12em; text-transform: uppercase; }
.meta-grid dd { color: var(--color-heading); font-weight: var(--weight-medium); }
.meta-grid dd a { text-underline-offset: 3px; }
.company-media { margin-top: var(--space-8); }

/* ▸ Company showcase: two real product screens floating on a full-bleed
   abstract photo (Unsplash, free licence), built with real markup instead
   of one flattened composite JPG. */
.company-showcase {
  position: relative;
  margin-top: var(--space-8);
  padding: var(--space-3);
  border-radius: var(--radius-outer);
  overflow: hidden;
  isolation: isolate;
}
.company-showcase_bg {
  position: absolute; inset: 0; z-index: -1;
  width: 100%; height: 100%;
  object-fit: cover;
}
.company-showcase_stage {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
}
.company-showcase_screen {
  position: absolute;
  width: 68%;
  height: auto;
  border-radius: calc(var(--radius-inner) * 0.85);
  box-shadow: 0 32px 56px -20px rgb(0 0 0 / 0.45), 0 4px 14px rgb(0 0 0 / 0.2);
}
.company-showcase_screen.is-back { top: 4%; left: 2%; width: 56%; transform: rotate(-5deg); z-index: 1; }
.company-showcase_screen.is-front { bottom: 4%; right: 2%; width: 60%; transform: rotate(3deg); z-index: 2; }

/* --------------------------------------------------------------------------
   Section heads + card grids
   -------------------------------------------------------------------------- */
.principles-head { max-width: 40rem; margin-bottom: var(--space-6); }
.principles-head.measure-wide { max-width: 44rem; }
/* A left-aligned head already carries the gap; the grid below doesn't add
   a second one. */
.principles-head + :is(.card-grid, .method-grid, .persona-grid, .process-grid, .kpi-grid, .result-grid, .flow-steps, .img-grid-2, .img-grid-3, .shot-grid) { margin-top: 0; }

.principle-grid { display: grid; gap: var(--grid-gap); }
@media (min-width: 48em) {
  .principle-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .principle-card.is-wide { grid-column: span 2; background: var(--color-surface); }
}
.principle-card { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-1); padding: var(--space-3); }
@media (min-width: 64em) { .principle-card { padding: var(--space-4); } }
.principle-title { margin-top: var(--space-2); color: var(--color-heading); font-weight: var(--weight-heading); }
.principle-card p { max-width: 62ch; }

/* ▸ Card grid: card sets that aren't the 2-up principle grid. 3 across on
   desktop, 4 across with .is-quad. */
.card-grid { display: grid; gap: var(--grid-gap); margin-top: var(--space-6); }
@media (min-width: 48em) { .card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 64em) {
  .card-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .card-grid.is-quad { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.card-grid .principle-card { padding: var(--space-3); }
.card-grid .principle-card p { font-size: var(--text-small); }

/* ▸ AI-process glow — Apple Intelligence–style animated gradient aura behind
   each card, scoped to #ai-process only (not every .principle-card) since
   it's a visual cue tied to that section's subject. Only the blurred aura is
   new; the card keeps its white surface and light-grey hairline.
   The card is always its own stacking context (isolation), because .reveal
   makes it one while it fades in (opacity < 1 + transform) and a card that
   flips between "stacking context" and "not" flips the glow with it: inside
   a stacking context a z-index:-1 pseudo paints ON TOP of the card's own
   background, so the card showed rainbow-tinted for the whole fade and then
   snapped to white when the fade ended. With the context fixed, the white
   surface is a second pseudo painted after the glow, so the order is the
   same at every moment: glow, then white, then content. */
@property --ai-glow-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}
@supports (background: conic-gradient(from 0deg, red, blue)) {
  #ai-process .principle-card { position: relative; isolation: isolate; background: transparent; }
  #ai-process .principle-card::before {
    content: "";
    position: absolute;
    z-index: -2;
    inset: -6px;
    border-radius: inherit;
    background: conic-gradient(from var(--ai-glow-angle),
      #22D3EE, #3B82F6, #8B5CF6, #D946EF, #F472B6, #FB923C, #FDE68A, #22D3EE);
    filter: blur(18px);
    opacity: 0.22;
    animation: ai-glow-spin 8s linear infinite;
    pointer-events: none;
  }
  #ai-process .principle-card::after {
    content: "";
    position: absolute;
    z-index: -1;
    inset: 0;
    border-radius: inherit;
    background: var(--color-white);
    box-shadow: var(--ring);
    pointer-events: none;
  }
  /* No point repainting the gradient while the card is still hidden. */
  .js #ai-process .principle-card.reveal:not(.is-in)::before { animation-play-state: paused; }
}
@keyframes ai-glow-spin { to { --ai-glow-angle: 360deg; } }

/* --------------------------------------------------------------------------
   Personas
   -------------------------------------------------------------------------- */
.persona-grid { display: grid; grid-template-columns: 1fr; gap: var(--grid-gap); margin-top: var(--space-6); }
@media (min-width: 40em) { .persona-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 64em) {
  .persona-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .persona-grid.is-quad { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
/* Two cards: stacked on a phone, side by side from 40em (2 × span 2 of 4, 2 × span 4 of 8,
   2 × span 6 of 12). Explicit columns instead of auto-fit, which left an empty track. */
.persona-grid.is-pair { grid-template-columns: 1fr; }
@media (min-width: 40em) { .persona-grid.is-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.persona-grid.is-single { grid-template-columns: 1fr; margin-top: 0; }
.persona-card { display: flex; flex-direction: column; align-items: flex-start; padding: var(--space-3); }
.persona-avatar { width: 64px; height: 64px; margin-bottom: var(--space-3); border-radius: 18px; object-fit: cover; box-shadow: var(--ring); }
.persona-card p { font-size: var(--text-small); }
.persona-card .tag { margin-top: var(--space-2); }
.persona-card_head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); margin-bottom: var(--space-1); }
.persona-card_head .h3 { margin-bottom: 0; }
.persona-card_head .tag { margin-top: 0; }

/* --------------------------------------------------------------------------
   Process — open steps, homepage contact-step numerals
   -------------------------------------------------------------------------- */
.process-grid { display: grid; gap: var(--space-5); margin-top: var(--space-6); counter-reset: step; }
@media (min-width: 64em) { .process-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--grid-gap); } } /* 3 × span 4 */
.process-step { padding-top: var(--space-3); box-shadow: inset 0 1px 0 var(--color-hairline-strong); }
.process-num {
  display: grid; place-items: center;
  width: 44px; height: 44px; margin-bottom: var(--space-3);
  border-radius: 50%;
  background: var(--color-secondary-tint);
  color: var(--color-secondary);
  font-size: var(--text-small); font-weight: 600; font-variant-numeric: tabular-nums;
}
.process-step p { max-width: 36ch; }
.principle-card .process-num { margin-bottom: var(--space-1); }

/* --------------------------------------------------------------------------
   Split (text | media)
   -------------------------------------------------------------------------- */
.split { display: grid; gap: var(--space-5); align-items: center; }
@media (min-width: 64em) {
  /* Text on columns 1–5, media on 6–12. */
  .split { grid-template-columns: var(--grid-12); column-gap: var(--grid-gap); }
  .split > :nth-child(1) { grid-column: 1 / span 5; }
  .split > :nth-child(2) { grid-column: 6 / span 7; }
}
.split p:not(.eyebrow) { max-width: 38rem; }
.media-wide { margin-top: var(--space-6); }

.check-list { display: grid; gap: var(--space-2); margin-top: var(--space-3); max-width: 38rem; }
.check-list li { display: flex; align-items: flex-start; gap: var(--space-2); color: var(--color-text); font-size: var(--text-body); }
.check-list li::before { content: "–"; flex: none; color: var(--color-primary); font-weight: 600; }

/* --------------------------------------------------------------------------
   Challenges & constraints — horizontal accordion (vertical on mobile).
   Homepage FAQ states: collapsed = surface, expanded = white.
   -------------------------------------------------------------------------- */
.accordion {
  display: flex; flex-direction: column;
  margin-top: var(--space-6);
  border-radius: var(--radius-outer);
  background: var(--color-white);
  box-shadow: var(--ring), var(--shadow-1);
  overflow: hidden;
}
.acc-item { background: var(--color-surface); box-shadow: inset 0 1px 0 var(--color-hairline); transition: background-color var(--dur-base) var(--ease-soft); }
.acc-item:first-child { box-shadow: none; }
.acc-item.is-open { background: var(--color-white); }
.acc-tab {
  all: unset; box-sizing: border-box; cursor: pointer;
  display: flex; align-items: center; gap: var(--space-2);
  width: 100%; min-height: var(--space-8);
  padding: var(--space-2) var(--space-3);
  font-family: var(--font-sans);
}
.acc-tab:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -4px; border-radius: var(--radius-outer); }
.acc-num {
  display: grid; place-items: center;
  width: 32px; height: 32px; flex: none;
  border-radius: 50%;
  background: var(--color-white);
  box-shadow: var(--ring);
  color: var(--color-secondary);
  font-size: var(--text-xs); font-weight: 600; font-variant-numeric: tabular-nums;
  transition: background-color var(--dur-base) var(--ease-soft), color var(--dur-base) var(--ease-soft);
}
.acc-item.is-open .acc-num { background: var(--color-secondary); color: var(--color-white); box-shadow: none; }
.acc-label { color: var(--color-heading); font-size: var(--text-body); font-weight: var(--weight-medium); }
.acc-panel { display: none; padding: 0 var(--space-3) var(--space-4); }
.acc-item.is-open .acc-panel { display: block; }
.acc-panel p { max-width: 62ch; }
.acc-panel .muted-note { margin-top: var(--space-2); }
.acc-media { margin-top: var(--space-3); overflow: hidden; border-radius: var(--radius-inner); box-shadow: var(--ring); }
.acc-media img { width: 100%; height: auto; }
@media (max-width: 55.99em) {
  .acc-dup { display: none; }
  .acc-media { max-height: 360px; }
  .acc-media img { object-fit: cover; object-position: top left; }
}

@media (min-width: 56em) {
  .accordion { flex-direction: row; height: 620px; }
  .acc-item { box-shadow: inset 1px 0 0 var(--color-hairline); flex: 0 0 80px; min-width: 0; overflow: hidden; display: flex; transition: flex-grow 700ms var(--ease-out), background-color var(--dur-base) var(--ease-soft); }
  .acc-item.is-open { flex-grow: 1; }
  .acc-tab { width: 80px; flex: 0 0 80px; height: 100%; flex-direction: column; align-items: center; justify-content: space-between; padding: var(--space-3) 0; }
  .acc-tab:focus-visible { border-radius: var(--radius-inner); }
  .acc-label { writing-mode: vertical-rl; transform: rotate(180deg); white-space: nowrap; font-size: 1.25rem; }
  .acc-panel { display: block; flex: 1 1 auto; min-width: 0; overflow: hidden; padding: var(--space-4) var(--space-5) 0 var(--space-1); opacity: 0; transition: opacity var(--dur-base) var(--ease-soft); }
  .acc-item.is-open .acc-panel { opacity: 1; transition-delay: 200ms; }
  .acc-item:not(.is-open) .acc-panel { visibility: hidden; }
  .acc-panel_inner { width: min(680px, 62vw); }
  .acc-panel .h3 { margin-top: var(--space-4); }
  .acc-media { max-height: 300px; }
  .acc-media img { object-fit: cover; object-position: top left; }
}

/* --------------------------------------------------------------------------
   Open rows — homepage scope-list rhythm (methods, feature lists, principles)
   -------------------------------------------------------------------------- */
.method-grid { display: grid; gap: var(--space-5); margin-top: var(--space-6); }
@media (min-width: 64em) { .method-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--grid-gap); } } /* 3 × span 4 */
@media (min-width: 40em) { .method-grid.is-quad { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--grid-gap); } }
.method { padding-top: var(--space-3); box-shadow: inset 0 1px 0 var(--color-hairline-strong); }
.method .h3 { color: var(--color-heading); }
.method p { max-width: 38ch; font-size: var(--text-small); }
.method-note { margin: var(--space-6) auto 0; max-width: 44rem; text-align: center; }

/* --------------------------------------------------------------------------
   Image grids, screenshot frames and image placeholders
   -------------------------------------------------------------------------- */
.shot-grid, .img-grid-2, .img-grid-3 { display: grid; grid-template-columns: 1fr; gap: var(--grid-gap); margin-top: var(--space-6); }
@media (min-width: 40em) { .shot-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 48em) { .img-grid-2, .img-grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 64em) { .shot-grid, .img-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* An image slot still waiting for a real screenshot. */
.img-placeholder {
  display: flex; align-items: center; justify-content: center;
  width: 100%; min-height: 200px;
  border-radius: var(--radius-inner);
  background: #E1E1E1;
  color: #595959;
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  text-align: center;
  padding: var(--space-3);
}

/* Browser-window frame for full-page screenshots (lightbox.js adds an
   "Enlarge" button to every .os-window image). */
.os-window {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-outer);
  background: var(--color-white);
  box-shadow: var(--ring), var(--shadow-1);
}
.os-window_bar { display: flex; align-items: center; gap: 8px; padding: 12px 16px; box-shadow: inset 0 -1px 0 var(--color-hairline); }
.os-window_bar span { width: 9px; height: 9px; border-radius: 50%; background: var(--color-hairline-strong); }
.os-window_body { position: relative; background: var(--color-surface); }
.os-window_body img { display: block; width: 100%; height: auto; }

/* --------------------------------------------------------------------------
   Screens carousel — the site's global carousel component (assets/carousel.js,
   started from case-study.js in its centred mode): a full-bleed scroller whose
   slide in focus always rests at the centre of the screen, with the others
   beside it at lower opacity. One arrow click = one slide, one dot per slide,
   and the first and last slides can be centred too. Slides are whole columns:
   3 of 4 on a phone, 6 of 8 on a tablet, 8 of 12 on desktop, so the neighbours
   show on both sides.
   -------------------------------------------------------------------------- */
.carousel { position: relative; margin-top: var(--space-6); }
.carousel_viewport {
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; scrollbar-width: none;
  /* Room for the slides' shadow; the sides are set by carousel.js. */
  padding-block: var(--space-2) var(--space-5); margin-block: calc(var(--space-2) * -1) calc(var(--space-5) * -1);
}
.carousel_viewport::-webkit-scrollbar { display: none; }
.carousel_viewport:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -2px; }
.carousel_track { display: flex; gap: var(--grid-gap); width: 100%; } /* 100% = one container: the viewport is padded to it */
.carousel_slide {
  --n: 3;
  --span: calc(var(--n) * (100% - (var(--cols) - 1) * var(--grid-gap)) / var(--cols) + (var(--n) - 1) * var(--grid-gap));
  flex: 0 0 var(--span);
  scroll-snap-align: start;
  aspect-ratio: 1850 / 1044;
  overflow: hidden;
  border-radius: var(--radius-inner);
  background: var(--color-white);
  box-shadow: var(--ring), var(--shadow-2);
}
.carousel_slide img { width: 100%; height: 100%; object-fit: cover; object-position: top center; }
/* Centred mode (carousel.js adds .is-centered, so none of this applies without the script). */
.carousel_viewport.is-centered .carousel_slide {
  scroll-snap-align: center; scroll-snap-stop: always; /* one swipe, one slide */
  opacity: 0.4; cursor: pointer;
  transition: opacity var(--dur-base) var(--ease-soft);
}
.carousel_viewport.is-centered .carousel_slide.is-current { opacity: 1; cursor: default; }

/* Arrows + dots: same as the related-projects carousel below. */
.carousel_arrow {
  position: absolute; top: 50%; translate: 0 -50%; z-index: 2;
  display: grid; place-items: center;
  width: 48px; height: 48px; padding: 0; /* the UA gives <button> 6px of side padding */
  border: 0; border-radius: 50%; cursor: pointer;
  background: var(--color-white); color: var(--color-heading);
  box-shadow: var(--ring), var(--shadow-1);
  transition: background-color var(--dur-fast) var(--ease-soft), opacity var(--dur-fast) var(--ease-soft), transform var(--dur-fast) var(--ease-out);
}
.carousel_arrow svg { width: 18px; height: 18px; }
.carousel_arrow:hover { background: var(--color-surface); }
.carousel_arrow:active { transform: scale(0.96); }
.carousel_arrow:disabled { opacity: 0.35; cursor: default; }
.carousel_arrow-prev { left: 2%; }
.carousel_arrow-next { right: 2%; }
.carousel_dots { display: flex; justify-content: center; flex-wrap: wrap; gap: 12px; margin-top: var(--space-4); }
.carousel_dot {
  width: 8px; height: 8px; padding: 0; border: 0; border-radius: var(--radius-pill); cursor: pointer;
  background: rgb(32 33 36 / 0.18);
  transition: background-color var(--dur-fast) var(--ease-soft), transform var(--dur-fast) var(--ease-out);
}
.carousel_dot:hover { transform: scale(1.3); }
.carousel_dot.is-active { background: var(--color-primary); transform: scale(1.3); }
@media (min-width: 48em) { .carousel_slide { --n: 6; } }
@media (min-width: 64em) { .carousel_slide { --n: 8; } }
@media (max-width: 40em) {
  .carousel_arrow { width: 44px; height: 44px; }
}

/* --------------------------------------------------------------------------
   Results
   -------------------------------------------------------------------------- */
.result-grid { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--grid-gap); margin-top: var(--space-6); }
.result { --n: 4; --span: calc(var(--n) * (100% - (var(--cols) - 1) * var(--grid-gap)) / var(--cols) + (var(--n) - 1) * var(--grid-gap)); flex: 0 0 var(--span); display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-1); padding: var(--space-3); }
.result.is-wide { --n: 4; }
@media (min-width: 48em) { .result.is-wide { --n: 8; } } /* centred on columns 3–10 */
.result-icon { width: 44px; height: 44px; margin-bottom: var(--space-2); }
svg.result-icon { fill: none; stroke: var(--color-heading); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.result p { font-size: var(--text-small); }
.result p strong { color: var(--color-primary); }
.result-note { margin: var(--space-6) auto 0; max-width: 48rem; text-align: center; }
.result > .tag { margin-bottom: var(--space-1); }
/* A result that isn't measured yet: dashed, flat, no blue emphasis, so it
   can't be mistaken for a real outcome. */
.result.is-placeholder { background: transparent; box-shadow: none; border: 1px dashed var(--color-hairline-strong); }
.result.is-placeholder:hover { transform: none; box-shadow: none; }
.result.is-placeholder p strong { color: var(--color-heading); }

/* --------------------------------------------------------------------------
   Decision / option spec cards
   -------------------------------------------------------------------------- */
.spec-card {
  margin-top: var(--space-4);
  padding: var(--space-3);
  border-radius: var(--radius-outer);
  background: var(--color-white);
  box-shadow: var(--ring), var(--shadow-1);
}
@media (min-width: 64em) { .spec-card { padding: var(--space-4); } }
.spec-card:first-of-type { margin-top: var(--space-6); }
.spec-head { display: flex; align-items: baseline; gap: var(--space-2); margin-bottom: var(--space-3); }
.spec-num { color: var(--color-text); font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.04em; font-variant-numeric: tabular-nums; }
.spec-fields { display: grid; gap: var(--space-3); }
@media (min-width: 48em) { .spec-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.spec-fields dt {
  margin-bottom: 4px; color: var(--color-text);
  font-size: var(--text-eyebrow); font-weight: var(--weight-medium);
  letter-spacing: 0.08em; text-transform: uppercase;
}
.spec-fields dd { margin: 0; color: var(--color-text); font-size: var(--text-small); }
@media (min-width: 48em) { .spec-fields .is-wide { grid-column: 1 / -1; } }

/* --------------------------------------------------------------------------
   Pricing cards — swipeable carousel on mobile, 3 × span 4 grid from 64em
   -------------------------------------------------------------------------- */
.pricing-grid {
  display: flex;
  gap: var(--grid-gap);
  margin-top: var(--space-6);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.pricing-grid::-webkit-scrollbar { display: none; }
@media (min-width: 64em) {
  .pricing-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--grid-gap); overflow-x: visible; scroll-snap-type: none; align-items: start; }
}
.pricing-card {
  --n: 3;
  --span: calc(var(--n) * (100% - (var(--cols) - 1) * var(--grid-gap)) / var(--cols) + (var(--n) - 1) * var(--grid-gap));
  position: relative;
  flex: 0 0 var(--span);
  scroll-snap-align: start;
  padding: var(--space-4);
  border-radius: var(--radius-outer);
  background: var(--color-white);
  box-shadow: var(--ring), var(--shadow-1);
}
@media (min-width: 48em) { .pricing-card { --n: 4; } }
.pricing-card.is-popular { box-shadow: 0 0 0 2px var(--color-primary), var(--shadow-2); }
.pricing-badge {
  position: absolute; top: var(--space-3); right: var(--space-3);
  display: inline-flex; align-items: center;
  min-height: 24px; padding: 0 var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--color-primary-tint);
  color: var(--color-primary);
  font-size: var(--text-eyebrow); font-weight: var(--weight-medium);
  letter-spacing: 0.04em; text-transform: uppercase;
}
.pricing-desc { margin-top: var(--space-1); min-height: 2.6em; color: var(--color-text); font-size: var(--text-small); }
.pricing-price { margin-top: var(--space-3); display: flex; align-items: baseline; gap: 4px; }
.pricing-amount { font-size: 2.25rem; font-weight: var(--weight-heading); color: var(--color-heading); letter-spacing: -0.02em; }
.pricing-period { color: var(--color-text); font-size: var(--text-small); }
.pricing-rate { margin-top: 4px; color: var(--color-text); font-size: var(--text-xs); }
.pricing-features { margin-top: var(--space-3); padding-top: var(--space-3); border-top: 1px solid var(--color-hairline); display: grid; gap: var(--space-1); }
.pricing-features li { position: relative; padding-left: var(--space-3); color: var(--color-text); font-size: var(--text-small); }
.pricing-features li::before { content: "✓"; position: absolute; left: 0; color: var(--color-primary); font-weight: 600; }

/* --------------------------------------------------------------------------
   Infographics — plain HTML + CSS, no chart library. Every value is real
   text; bars are aria-hidden decoration whose width comes from an inline
   custom property (--v, or --a/--b for a range). Each value and bar carries
   data-src, tying it to an entry in the case-study source manifest.
   -------------------------------------------------------------------------- */

/* ▸ Before / after (or option vs option) bars, inside a result card.
   One grid for the whole comparison (label | track | value); every row and
   its <dd> join it through subgrid, so all bars in a comparison share the
   same track length and their percentages stay on one common scale, however
   long any single value label is. */
.metric-compare {
  display: grid;
  grid-template-columns: 4.25rem minmax(3rem, 1fr) max-content;
  gap: 12px var(--space-2);
  width: 100%;
  margin: var(--space-1) 0 var(--space-2);
}
.metric-compare > div { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; align-items: center; row-gap: 8px; }
.metric-compare dt { color: var(--color-text); font-size: var(--text-xs); --lh: 1.3; }
.metric-compare dd { grid-column: 2 / -1; display: grid; grid-template-columns: subgrid; align-items: center; min-width: 0; }
/* Named options (e.g. providers): label column sized to the labels on wide
   screens; on narrow ones each label sits above its own bar instead. */
.metric-compare.is-labelled { grid-template-columns: minmax(3rem, 1fr) max-content; }
.metric-compare.is-labelled dt, .metric-compare.is-labelled dd { grid-column: 1 / -1; }
@media (min-width: 40em) {
  .metric-compare.is-labelled { grid-template-columns: minmax(0, max-content) minmax(3rem, 1fr) max-content; }
  .metric-compare.is-labelled dt { grid-column: 1; }
  .metric-compare.is-labelled dd { grid-column: 2 / -1; }
}
.metric-bar {
  position: relative; min-width: 0;
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  box-shadow: inset 0 0 0 1px var(--color-hairline);
  overflow: hidden;
}
.metric-bar::before {
  content: "";
  position: absolute; top: 0; bottom: 0; left: 0;
  width: var(--v, 0%);
  border-radius: inherit;
  background: var(--color-hairline-strong);
  transform-origin: left center;
  transition: transform 900ms var(--ease-out);
}
.metric-bar.is-after::before { background: var(--color-primary); }
/* Range ("$9–16"): a segment from --a to --b. */
.metric-bar.is-range::before { left: var(--a, 0%); width: calc(var(--b, 0%) - var(--a, 0%)); }
/* Upper bound ("under 15 min"): no end cap and the last 40% fades out, so
   the bar reads as "at most", not as an exact reading. */
.metric-bar.is-upper-bound::before {
  border-radius: var(--radius-pill) 0 0 var(--radius-pill);
  -webkit-mask-image: linear-gradient(to right, #000 60%, transparent);
  mask-image: linear-gradient(to right, #000 60%, transparent);
}
.metric-value {
  color: var(--color-heading);
  font-size: var(--text-xs); font-weight: 600; font-variant-numeric: tabular-nums;
  text-align: right; white-space: nowrap;
}

/* ▸ Big-number tiles. .kpi_value also works on its own inside a .result. */
.kpi-grid { display: grid; gap: var(--grid-gap); grid-template-columns: 1fr; margin-top: var(--space-6); }
/* ▸ Columns, not auto-fit (7 Oct 2026): auto-fit made 3 or 4 columns by width alone,
   which landed off the column lines. 1 column on a phone, 2 from 40em (span 2 of 4),
   and from 64em 12 columns with the tiles spanning 4 (three across, the default),
   6 (exactly two) or 3 (exactly four). */
@media (min-width: 40em) { .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 64em) {
  .kpi-grid { grid-template-columns: var(--grid-12); }
  .kpi-grid > * { grid-column: span 4; }
  .kpi-grid > :first-child:nth-last-child(2), .kpi-grid > :first-child:nth-last-child(2) ~ * { grid-column: span 6; }
  .kpi-grid > :first-child:nth-last-child(4), .kpi-grid > :first-child:nth-last-child(4) ~ * { grid-column: span 3; }
}
.kpi {
  display: flex; flex-direction: column; gap: var(--space-1);
  padding: var(--space-3);
  border-radius: var(--radius-outer);
  background: var(--color-white);
  box-shadow: var(--ring), var(--shadow-1);
}
.kpi_value {
  color: var(--color-heading);
  font-size: clamp(2rem, 1.6rem + 1.6vw, 2.75rem); font-weight: var(--weight-heading);
  --lh: 1; letter-spacing: -0.03em; font-variant-numeric: tabular-nums;
}
.kpi_label { color: var(--color-text); font-size: var(--text-small); --lh: 1.45; }
/* .result p sets body-small text, so the figure restates its own size. */
.result .kpi_value { margin: var(--space-1) 0; font-size: clamp(2rem, 1.6rem + 1.6vw, 2.75rem); }

/* ▸ Stacked share-of-total bar with a legend carrying the real numbers.
   Any part of 100% the source doesn't name stays as empty track. */
.split-bar { display: grid; gap: var(--space-2); }
.split-bar_track {
  display: flex; height: 12px; overflow: hidden;
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  box-shadow: inset 0 0 0 1px var(--color-hairline);
}
.split-bar_seg { flex: none; width: var(--v, 0%); background: var(--color-primary); }
.split-bar_seg.is-secondary { background: var(--color-secondary); }
.split-bar_legend { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3); font-size: var(--text-small); }
.split-bar_legend li { display: inline-flex; align-items: center; gap: var(--space-1); }
.split-bar_key { width: 10px; height: 10px; border-radius: 3px; background: var(--color-primary); }
.split-bar_key.is-secondary { background: var(--color-secondary); }
.split-bar_value { color: var(--color-heading); font-weight: 600; font-variant-numeric: tabular-nums; }

/* ▸ Single share meter. */
.meter { display: grid; gap: var(--space-1); }
.meter_head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); font-size: var(--text-small); }
.meter_value { color: var(--color-heading); font-weight: 600; font-variant-numeric: tabular-nums; }
.meter_track { position: relative; height: 8px; overflow: hidden; border-radius: var(--radius-pill); background: var(--color-surface); box-shadow: inset 0 0 0 1px var(--color-hairline); }
.meter_fill { position: absolute; inset: 0 auto 0 0; width: var(--v, 0%); border-radius: inherit; background: var(--color-primary); }

/* ▸ A panel holding a split bar / meters under a card set. */
.data-panel {
  display: grid; gap: var(--space-4);
  margin-top: var(--grid-gap);
  padding: var(--space-3);
  border-radius: var(--radius-outer);
  background: var(--color-white);
  box-shadow: var(--ring), var(--shadow-1);
}
@media (min-width: 56em) { .data-panel { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: end; gap: var(--space-6); } }
@media (min-width: 64em) { .data-panel { padding: var(--space-4); } }
/* Figures directly above a card set read as one block. */
.kpi-grid + .card-grid { margin-top: var(--grid-gap); }
.data-panel_title { margin-bottom: var(--space-2); color: var(--color-heading); font-size: var(--text-small); font-weight: var(--weight-medium); }

/* ▸ Flow steps: numbered nodes joined by a hairline. Vertical below 64em, one row on
   the 12 columns from 64em (7 Oct 2026): steps span 3 (four steps, the default), 4
   (three steps), or 2 (five steps, centred on columns 2–11; the compact three-step
   flow centres on columns 4–9). Numbers use the numbered-badge colour. */
.flow-steps { --node: 44px; display: grid; gap: var(--space-2); margin-top: var(--space-6); }
.flow-steps.is-compact { max-width: 44rem; margin-inline: auto; }
.flow-step { position: relative; display: flex; align-items: center; gap: var(--space-2); }
.flow-step_num {
  position: relative; z-index: 1;
  display: grid; place-items: center;
  width: var(--node); height: var(--node); flex: none;
  border-radius: 50%;
  background: var(--color-white);
  box-shadow: inset 0 0 0 1px var(--color-secondary-tint), 0 0 0 6px var(--color-secondary-tint);
  color: var(--color-secondary);
  font-size: var(--text-small); font-weight: 600; font-variant-numeric: tabular-nums;
}
.flow-step_label {
  flex: 1 1 auto;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-inner);
  background: var(--color-white);
  box-shadow: var(--ring), var(--shadow-1);
  color: var(--color-heading);
  font-size: var(--text-small); font-weight: var(--weight-medium); --lh: 1.35;
}
.flow-step:not(:last-child)::after {
  content: "";
  position: absolute;
  left: calc(var(--node) / 2); top: calc(50% + var(--node) / 2);
  height: calc(100% - var(--node) + var(--space-2));
  width: 1px;
  background: var(--color-hairline-strong);
}
@media (min-width: 64em) {
  .flow-steps { grid-template-columns: var(--grid-12); column-gap: var(--grid-gap); }
  .flow-steps.is-compact { max-width: none; margin-inline: 0; }
  .flow-step { grid-column: span 3; flex-direction: column; align-items: center; text-align: center; gap: var(--space-3); }
  .flow-step:first-child:nth-last-child(3), .flow-step:first-child:nth-last-child(3) ~ .flow-step { grid-column: span 4; }
  .flow-step:first-child:nth-last-child(5), .flow-step:first-child:nth-last-child(5) ~ .flow-step { grid-column: span 2; }
  .flow-step:first-child:nth-last-child(5) { grid-column: 2 / span 2; }
  .flow-steps.is-compact > .flow-step:first-child:nth-last-child(3), .flow-steps.is-compact > .flow-step:first-child:nth-last-child(3) ~ .flow-step { grid-column: span 2; }
  .flow-steps.is-compact > .flow-step:first-child:nth-last-child(3) { grid-column: 4 / span 2; }
  .flow-step_label { width: 100%; }
  .flow-step:not(:last-child)::after {
    left: calc(50% + var(--node) / 2 + 8px); right: calc(-50% + var(--node) / 2 + 8px - var(--grid-gap));
    top: calc(var(--node) / 2); width: auto; height: 1px;
  }
}

/* --------------------------------------------------------------------------
   Related projects + closing
   -------------------------------------------------------------------------- */
#more-projects .rp-carousel { margin-top: var(--space-5); }
.closing_actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-2); margin-top: var(--space-4); }

/* --------------------------------------------------------------------------
   Motion — homepage reveal (24px, 800ms, 80ms stagger)
   -------------------------------------------------------------------------- */
:is(.process-grid, .method-grid, .principle-grid, .persona-grid, .card-grid, .result-grid, .kpi-grid, .shot-grid, .img-grid-2, .img-grid-3, .pricing-grid) > :nth-child(2) { --i: 1; }
:is(.process-grid, .method-grid, .principle-grid, .persona-grid, .card-grid, .result-grid, .kpi-grid, .shot-grid, .img-grid-3, .pricing-grid) > :nth-child(3) { --i: 2; }
:is(.principle-grid, .persona-grid, .card-grid, .method-grid, .kpi-grid) > :nth-child(4) { --i: 3; }

@media (prefers-reduced-motion: no-preference) {
  .js .reveal {
    opacity: 0;
    transform: translateY(var(--space-3));
    transition: opacity var(--dur-reveal) var(--ease-out), transform var(--dur-reveal) var(--ease-out);
    transition-delay: calc(var(--i, 0) * 80ms);
  }
  .js .reveal.is-in { opacity: 1; transform: none; }
  .js .persona-card.reveal.is-in, .js .result.reveal.is-in {
    transition: opacity var(--dur-reveal) var(--ease-out), transform var(--dur-slow) var(--ease-out), box-shadow var(--dur-slow) var(--ease-soft);
    transition-delay: 0ms;
  }
  /* Bars grow in once their card is revealed. */
  .js .reveal:not(.is-in) .metric-bar::before { transform: scaleX(0); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; transition-delay: 0ms !important; }
  html { scroll-behavior: auto; }
}

/* A swipe list (the pricing cards) shows its dots only while it scrolls, i.e. below 64em. */
@media (min-width: 64em) { .pricing-grid + .carousel_dots { display: none; } }
