/* ------------------------------------------------------------------
   Base
------------------------------------------------------------------- */

/* Albert Sans — self-hosted variable font (100–900) */
@font-face {
  font-family: "Albert Sans";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/fonts/albert-sans-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Albert Sans";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/fonts/albert-sans-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ------------------------------------------------------------------
   Design tokens — the single source of truth for type, colour,
   spacing and shape. Components below consume only these.
------------------------------------------------------------------- */
:root {
  /* type — Albert Sans scale from the Figma text styles:
     H1 56/60·-4%  H2 40/44·-4%  H3 34/38·-3%  H4 28/34·-3%  H5 20/28·-2%
     Text XL 18/28·-1%  L 16/24·-1%  M 14/20·0  S 12/16·0  Button 16/24·500 */
  --font-sans: "Albert Sans", -apple-system, "Segoe UI", "PingFang SC",
    "Hiragino Sans GB", sans-serif;
  --fs-h1: 56px; --lh-h1: 60px; --ls-h1: -0.04em;
  --fs-h2: 40px; --lh-h2: 44px; --ls-h2: -0.04em;
  --fs-h3: 34px; --lh-h3: 38px; --ls-h3: -0.03em;
  --fs-h4: 28px; --lh-h4: 34px; --ls-h4: -0.03em;
  --fs-h5: 20px; --lh-h5: 28px; --ls-h5: -0.02em;
  --fs-xl: 18px; --lh-xl: 28px; --ls-xl: -0.01em;
  --fs-l: 16px;  --lh-l: 24px;  --ls-l: -0.01em;
  --fs-m: 14px;  --lh-m: 20px;  --ls-m: 0;
  --fs-s: 12px;  --lh-s: 16px;  --ls-s: 0;

  /* colour — neutrals (Black / Text from the Figma palette) */
  --ink: #09090b;        /* primary text ("Black")            */
  --body-c: #6d7888;     /* secondary text ("Text")           */
  --muted: #a3a49b;      /* labels, deemphasised text         */
  --ink-warm: #3c3d36;   /* warm near-black: icons, strokes   */
  --slate: #6d7888;      /* data/table text ("Text")          */
  --slate-200: #d5d6de;  /* neutral pill fill                 */
  /* keyboard focus ring, site-wide */
  --focus-ring: var(--body-c);  /* colour                                  */
  --focus-ring-width: 2px;      /* line thickness                          */
  --focus-ring-offset: 2px;     /* gap between the element and the ring    */
  --focus-ring-radius: 4px;     /* corners, for links without their own    */
  --surface: #f4f2ec;    /* warm image placeholder            */
  --line: #eceae2;       /* hairline rules                    */
  --border: rgba(0, 0, 0, 0.15);      /* card outlines        */
  --border-soft: rgba(0, 0, 0, 0.12); /* softer card outlines */

  /* colour — CJ lime accent family */
  --accent-100: #f0fbd5; /* highlight card fill               */
  --accent-300: #c7ef4e; /* annotation lime                   */
  --accent-600: #8cb52f; /* headline metrics                  */
  --accent-700: #6e9024; /* accent text on accent-100         */

  /* colour — PLUS blue accent family */
  --accent-blue-100: #f1faff; /* highlight card fill          */
  --accent-blue-200: #e4f5ff; /* active step / panel fill     */
  --accent-blue-600: #3da4e1; /* accent text on blue-100      */
  --accent-blue-700: #3e84ad; /* quote text on blue fill      */

  /* layout */
  --pad: 8%;             /* horizontal rhythm inside panels   */

  /* corner radii — Apple-style scale: big surfaces get the large
     radius, media nested inside a padded surface steps down one
     (concentric corners), icon buttons and pills at the ends */
  --radius-xl: 28px;    /* top-level cards, modal panel            */
  --radius-lg: 18px;    /* media/tiles nested inside padded panels */
  --radius-md: 14px;    /* component cards (quote, stat, compare)  */
  --radius-sm: 10px;    /* icon buttons                            */
  --radius-pill: 980px; /* badges & pills (Apple's pill value)     */
}
*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

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

body {
  font-family: var(--font-sans);
  background: #ffffff;
  color: var(--ink);
  overflow-x: hidden;
}

/* wide-tracked labels: letter-spacing also trails the last letter,
   which leaves a gap after it (and nudges centred text left) — the
   last letter goes in .track-end to drop that trailing space */
.track-end {
  letter-spacing: 0;
}

/* one keyboard focus ring everywhere: dark grey, never the browser blue.
   The ring follows the element's own corner radius; links that have
   none (text links) take --focus-ring-radius — :where() keeps this at
   zero specificity so it never overrides a component's own radius
   (e.g. the 13px case cards). */
:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}

:where(a:focus-visible) {
  border-radius: var(--focus-ring-radius);
}

/* ------------------------------------------------------------------
   Type scale — reusable text components matching the Figma styles.
   Apply the class, or read the --fs/--lh/--ls tokens directly.
------------------------------------------------------------------- */
.ui-h1 { font-size: var(--fs-h1); line-height: var(--lh-h1); letter-spacing: var(--ls-h1); font-weight: 400; }
.ui-h2 { font-size: var(--fs-h2); line-height: var(--lh-h2); letter-spacing: var(--ls-h2); font-weight: 400; }
.ui-h3 { font-size: var(--fs-h3); line-height: var(--lh-h3); letter-spacing: var(--ls-h3); font-weight: 400; }
.ui-h4 { font-size: var(--fs-h4); line-height: var(--lh-h4); letter-spacing: var(--ls-h4); font-weight: 400; }
.ui-h5 { font-size: var(--fs-h5); line-height: var(--lh-h5); letter-spacing: var(--ls-h5); font-weight: 400; }
.ui-text-xl { font-size: var(--fs-xl); line-height: var(--lh-xl); letter-spacing: var(--ls-xl); font-weight: 400; }
.ui-text-l  { font-size: var(--fs-l);  line-height: var(--lh-l);  letter-spacing: var(--ls-l);  font-weight: 400; }
.ui-text-m  { font-size: var(--fs-m);  line-height: var(--lh-m);  letter-spacing: var(--ls-m);  font-weight: 400; }
.ui-text-s  { font-size: var(--fs-s);  line-height: var(--lh-s);  letter-spacing: var(--ls-s);  font-weight: 400; }
.ui-text-xl--medium, .ui-text-l--medium,
.ui-text-m--medium,  .ui-text-s--medium { font-weight: 500; }
.ui-text-button { font-size: var(--fs-l); line-height: var(--lh-l); letter-spacing: var(--ls-l); font-weight: 500; }

img {
  display: block;
  max-width: none;
  user-select: none;
  -webkit-user-drag: none;
}

/* ------------------------------------------------------------------
   Intro stage
   Design space is the Figma "Animation" frame: 1440 x 808.
   .intro__fit scales that space to cover the real viewport;
   .intro__camera receives the scroll-driven zoom;
   each .intro__layer receives its own parallax translate3d.
------------------------------------------------------------------- */
.intro {
  position: relative;
  background: #ffffff;
}

.intro__viewport {
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  background: #ffffff;
}

.intro__fit {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 1440px;
  height: 808px;
  /* scale is set from JS: translate(-50%,-50%) scale(fit) */
  transform: translate(-50%, -50%);
  will-change: transform;
  /* hidden until every intro asset has decoded (preload gate);
     intro.js fades it in */
  opacity: 0;
}

.intro__camera {
  position: absolute;
  inset: 0;
  transform-origin: 719.5px 403.5px; /* window centre in design space (overridable via config) */
  will-change: transform;
  /* white backdrop inside the camera group so the multiply layers
     always resolve against paper white (Figma "White Background") */
  background: #ffffff;
}

.intro__layer {
  position: absolute;
  will-change: transform, opacity;
}

.intro__layer img {
  width: 100%;
  height: 100%;
}

/* Geometry straight from the Figma layers (Animation-frame coordinates) */
.intro__layer--background {
  left: 208px;
  top: 116px;
  width: 1023.1px;
  height: 575.8px;
  opacity: 0;
}

.intro__layer--background img {
  /* the source fill is 2880x2048; cover-crop it to the layer box
     exactly like Figma's "fill" image mode */
  object-fit: cover;
  /* bleed sized against the worst case: drift = strength(40) x
     landscapeBoost(1.8) / camera scale at the moment the wall turns
     transparent (~1.33) ≈ 54px, vs vertical bleed 576 x 0.10 = 58px */
  transform: scale(1.2);
}

/* The artwork uses the original transparent-alpha paintings from the
   Figma fills, composited with normal blending — colours stay as vivid
   as the design. (No mix-blend-mode: multiply used to mute them.) */
.intro__layer--draft {
  left: 483px;
  top: 156px;
  width: 473px;
  height: 496px;
}

/* identical box to the draft layer — the colour pass must sit
   exactly on top of the line art at all times (no ghosting) */
.intro__layer--colored {
  left: 483px;
  top: 156px;
  width: 473px;
  height: 496px;
}

/* the ink mask starts fully closed, so the layer itself stays opaque */
.intro__ink {
  display: block;
  width: 100%;
  height: 100%;
}

/* hover ink: colour dropped by the cursor on the first frame */
.intro__ink-hover {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* opaque white wall around the window opening (Figma boolean Subtract) */
.intro__layer--window {
  left: 0;
  top: 0;
  width: 1440px;
  height: 808px;
}

/* The SVG carries a 50px bleed on every side (viewBox -50 -50 1540 908):
   the outer wall rect is extended while the quatrefoil hole keeps its
   exact Figma coordinates — so mouse drift never reveals the stage edge
   and the opening never misaligns with the ring.
   NOTE: the selector must out-rank ".intro__layer img" (which sets
   100%/100%) or the bleed box collapses and the hole drifts off. */
.intro__layer--window img.intro__surround {
  position: absolute;
  left: -50px;
  top: -50px;
  width: 1540px;
  height: 908.03px;
}

/* the sketched window ring artwork (true-alpha composite of the
   node's two image fills) */
.intro__layer--ring {
  left: 315.98px;
  top: 0;
  width: 808.03px;
  height: 808.03px;
}

.intro__ring {
  width: 100%;
  height: 100%;
}

/* ------------------------------------------------------------------
   Exit overlay — fades the finished animation to white while the
   page content scrolls up over it
------------------------------------------------------------------- */
.intro__exit-overlay {
  position: absolute;
  inset: 0;
  background: #ffffff;
  opacity: 0;
  pointer-events: none;
}

/* ------------------------------------------------------------------
   Cursor follower — a small quatrefoil, kin to the window, that
   whispers "scroll" while hovering the opening
------------------------------------------------------------------- */
.intro__cursor {
  position: fixed;
  top: 0;
  left: 0;
  /* above everything, including the case-study modal (z 100) —
     the label ring must never be occluded by content */
  z-index: 200;
  width: 96px;
  height: 96px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-warm);
  font-size: 9.5px;
  letter-spacing: 0.3em;
  text-indent: 0.3em; /* optically recentre the letterspaced word */
  text-transform: uppercase;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  will-change: transform;
}

.intro__cursor-shape {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  fill: rgba(255, 255, 255, 0.72);
  stroke: rgba(60, 61, 54, 0.45);
  stroke-width: 1.2;
  animation: cursor-breath 4.2s ease-in-out infinite;
}

/* the ring keeps the native cursor's 1.2px line at every size, so
   the handoff and the grow never change its weight */
.intro__cursor-shape circle {
  vector-effect: non-scaling-stroke;
}

/* × shown while hovering outside a previewed image (click closes) */
.intro__cursor-icon {
  position: absolute;
  width: 20px;
  height: 20px;
  fill: none;
  stroke: var(--ink-warm);
  stroke-width: 1.3;
  stroke-linecap: round;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.intro__cursor-icon path {
  vector-effect: non-scaling-stroke;
}

.intro__cursor.has-icon .intro__cursor-icon {
  opacity: 1;
}

@keyframes cursor-breath {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.045); }
}

.intro__cursor span {
  position: relative;
  opacity: 0;
  visibility: hidden;
  will-change: transform, opacity;
}

/* Custom cursor the michelle-liu way: a CSS cursor image, rendered
   by the OS itself — zero latency, custom face (the same soft circle
   as before). The DOM follower only appears when it has a word to
   say. */
html.has-cursor,
html.has-cursor * {
  cursor: url(assets/img/cursor-default.svg) 18 18,
          url(assets/img/cursor-small.svg) 14 14,
          auto !important;
}

/* label-state handoff: while the label ring speaks, the native
   circle steps aside — one cursor on screen at all times */
html.has-cursor.label-active,
html.has-cursor.label-active * {
  cursor: none !important;
}

/* ------------------------------------------------------------------
   Identity — same voice as the closing header: small-caps name,
   large serif line. Portrait: centred above the window.
   Landscape: left of the window, balanced by the hint on the right.
------------------------------------------------------------------- */
.intro__identity {
  position: absolute;
  /* breathe below the screen edge; still clears the window top */
  top: clamp(48px, 9vh, 120px);
  left: 0;
  right: 0;
  text-align: center;
  padding: 0 34px;
  pointer-events: none;
}

.intro__identity-name {
  letter-spacing: 0.42em;
  text-transform: uppercase;
  font-size: 13px;
  color: #5d5e55;
}

.intro__identity-role {
  margin: 16px auto 0;
  max-width: 560px;
  font-size: clamp(20px, 5vw, var(--fs-h4));
  line-height: 1.35;
  letter-spacing: var(--ls-h4);
  color: var(--ink-warm);
}

@media (orientation: landscape) {
  .intro__identity {
    top: 50%;
    left: 4vw;
    right: auto;
    transform: translateY(-50%);
    text-align: left;
    padding: 0;
    max-width: min(22vw, 420px);
  }

  .intro__identity-role {
    margin: 18px 0 0;
    max-width: none;
    font-size: clamp(20px, 2.1vw, 34px);
  }
}

/* ------------------------------------------------------------------
   Scroll hint
------------------------------------------------------------------- */
.intro__hint {
  position: absolute;
  bottom: 34px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  font-size: 11px;
  color: #8a8a86;
  pointer-events: none;
}

.intro__hint span {
  transition: color 0.6s ease, opacity 0.4s ease;
}

.intro__hint i {
  display: block;
  width: 1px;
  height: 44px;
  background: linear-gradient(to bottom, #b9b9b4, transparent);
  animation: hint-drop 2.4s ease-in-out infinite;
  transform-origin: top center;
  transition: height 0.6s ease, opacity 0.4s ease;
}

/* while the cursor follower is active, the bottom hint steps aside
   (child opacity, so it never fights the timeline's autoAlpha) */
.intro__hint.is-retreated span,
.intro__hint.is-retreated i {
  opacity: 0;
}

/* idle nudge: after a few still seconds the hint leans in a little */
.intro__hint.is-eager span {
  color: #63635e;
}

.intro__hint.is-eager i {
  height: 62px;
  animation-duration: 1.5s;
}

/* landscape: the hint balances the identity block on the right side.
   Same anchor as the identity (top 50%, -50%) plus a small optical
   lift so the hanging line doesn't drag its centre below the text. */
@media (orientation: landscape) {
  .intro__hint {
    left: auto;
    right: 4vw;
    bottom: auto;
    top: 50%;
    transform: translateY(-50%);
  }
}

@keyframes hint-drop {
  0%   { transform: scaleY(0); }
  45%  { transform: scaleY(1); }
  100% { transform: scaleY(1); opacity: 0; }
}

/* ------------------------------------------------------------------
   Page — rises over the pinned intro during the exit tail
   (negative top margin is set from JS), then flows normally.
------------------------------------------------------------------- */
.intro {
  z-index: 1;
}

.page {
  position: relative;
  z-index: 2;
  /* transparent while overlapping the fading artwork;
     the body's white shows behind afterwards */
}

/* --- site nav ---------------------------------------------------------
   One centred line across the top, always there: CYNTHIA LU | WORK
   ABOUT, over a white fade. The views use the footer's link
   system (small tracked capitals, an underline for the current one /
   on hover). On Work it never shows over the opening film: it
   arrives once the film's backdrop has gone fully white (html.nav-on,
   set by js/intro.js). --nav-h is the band it covers; pinned scenes keep
   clear of it. */
:root {
  --nav-h: 76px;
}

.site-nav {
  position: fixed;
  z-index: 40;
  top: 0;
  left: 0;
  right: 0;
  padding: 30px 24px 44px;
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: 28px;
  background: linear-gradient(#fff 50%, rgba(255, 255, 255, 0));
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.6s ease, visibility 0s linear 0.6s;
}

html.nav-on .site-nav,
html.no-intro .site-nav {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.6s ease;
}

.site-nav a {
  pointer-events: auto;
  text-decoration: none;
}

.site-nav__name {
  font-size: 12px;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: #3c3d36;
  white-space: nowrap;
}

/* a short upright rule, like the divider in the case-card pills */
.site-nav__dash {
  align-self: center;
  width: 1px;
  height: 12px;
  margin: 0 2px;
  background: var(--line);
}

/* same as .footer__links a */
.site-nav__item {
  font-size: 12px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #77786f;
  padding-bottom: 3px;
  border-bottom: 1px solid transparent;
  transition: color 0.3s ease, border-color 0.3s ease;
}

.site-nav__item:hover,
.site-nav__item:focus-visible,
.site-nav__item.is-current {
  color: var(--ink-warm);
  border-color: var(--ink-warm);
}

@media (max-width: 600px) {
  :root {
    --nav-h: 64px;
  }

  .site-nav {
    padding: 22px 16px 36px;
    gap: 16px;
    background: linear-gradient(#fff 64%, rgba(255, 255, 255, 0));
  }

  .site-nav__name {
    letter-spacing: 0.28em;
  }


  .site-nav__item {
    letter-spacing: 0.16em;
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-nav {
    transition: none;
  }
}

/* --- about view ------------------------------------------------------
   Two modes, same markup:
     .about             plain column (small screens, reduced motion)
     .about.is-cinema   wide screens: the stage pins and js/about.js
                        places the frame, captions and copy each frame
--------------------------------------------------------------------- */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.about[hidden] {
  display: none;
}

/* About has no opening film (also set before first paint
   by the inline script in <head>, so a deep link never flashes it) */
html.no-intro .intro,
html.no-intro .page__work {
  display: none;
}

html.is-about .about[hidden] {
  display: block;
}

.about {
  --kw-line: #364a02;
  padding-bottom: 64px;
}

/* Figma (About, 897:4318): the heading sits 117 (header) + 64 + 64
   from the top of the page, and the keyword grid 64 + 40 below it */
.about__hero {
  max-width: 800px;
  margin: 0 auto;
  padding: 245px 32px 64px;
  text-align: center;
}

/* type: the case-study system — the heading on the H2 tokens, and
   .ui-label / .ui-title (Body 1) / .ui-prose (Body 2) in the markup */
.about__heading {
  font-weight: 400;
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--ls-h2);
  color: var(--ink);
}

.about-copy .ui-label + p {
  margin-top: 16px;
}

.about strong {
  font-weight: 700;
}

/* --- stage: keyword grid → photograph → full shot --- */
.about-stage__inner {
  max-width: 800px;
  margin: 0 auto;
  padding: 0 32px;
}

.about-frame {
  position: relative;
  width: 100%;
  max-width: 580px;
  aspect-ratio: 580 / 558;
  margin: 40px auto 0;
  overflow: hidden;
  /* the same corner as every photograph on the page, from the first
     frame of the keyword grid to the full shot */
  border-radius: 13px;
  /* keeps the rounded clip on the GPU while the frame morphs */
  isolation: isolate;
}

/* width-fit, vertically centred: the close shot is exactly the middle
   band of the long shot, so a taller/narrower frame shows more of it */
.about-frame__photo {
  position: absolute;
  left: 0;
  top: 50%;
  width: 100%;
  height: auto;
  transform: translateY(-50%);
  display: none;
}

.kw {
  position: absolute;
  inset: 0;
  --kw-s: 1;
}

.kw__canvas,
.kw__fallback {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.kw__fallback {
  display: none;
  background: #fff url("assets/img/about/halftone-bw.webp") center / 100% 100% no-repeat;
}

.kw.is-fallback .kw__fallback {
  display: block;
}

.kw.is-fallback .kw__canvas {
  display: none;
}

.kw__fallback span {
  position: absolute;
  background-image: url("assets/img/about/halftone-orange.webp");
  background-repeat: no-repeat;
  background-size: 389.9% 391.9%;
}

/* the 4×4 lattice: three inner lines each way (the outer ones sit just
   outside the frame, as in the design). The shader draws it crisply on
   whole pixels; these are for the image fallback. */
.kw__grid {
  display: none;
}

.kw.is-fallback .kw__grid {
  display: block;
}

.kw__grid i,
.kw__grid b {
  position: absolute;
  background: var(--kw-line);
}

.kw__grid i {
  top: 0;
  bottom: 0;
  width: 1px;
  left: calc((148.75 * var(--n) - 7.5) / 580 * 100%);
}

.kw__grid b {
  left: 0;
  right: 0;
  height: 1px;
  top: calc((142.4 * var(--n) - 6) / 558 * 100%);
}

.kw__grid :nth-child(3n + 1) { --n: 1; }
.kw__grid :nth-child(3n + 2) { --n: 2; }
.kw__grid :nth-child(3n)     { --n: 3; }

.kw__label {
  position: absolute;
  left: calc((148.75 * (var(--c) + 0.5) - 7.5) / 580 * 100%);
  top: calc((142.4 * (var(--r) + 0.5) - 6) / 558 * 100%);
  transform: translate(-50%, -50%);
  padding: 0.375em 0.625em;
  background: rgba(255, 255, 255, 0.6);
  font-size: max(12px, calc(16px * var(--kw-s)));
  line-height: 1.48;
  letter-spacing: -0.01em;
  color: #000;
  white-space: nowrap;
}

.about-caption {
  padding: 40px 0 0;
}

/* on a short screen the caption steps down from Body 1 to Body 2 so
   the full-size grid still fits above it (js/about.js) */
.about-caption.is-compact .about-caption__text {
  font-size: var(--fs-l);
  line-height: 1.7;
  letter-spacing: var(--ls-l);
}

.about-caption__text--why {
  margin-top: 128px;
  text-align: center;
}

.about-flow-close {
  position: relative;
  width: 100%;
  max-width: 580px;
  aspect-ratio: 580 / 558;
  margin: 104px auto 0;
  border-radius: 13px;
  overflow: hidden;
}

.about-flow-close img {
  position: absolute;
  left: 0;
  top: 50%;
  width: 100%;
  transform: translateY(-50%);
}

.about-pair {
  display: grid;
  grid-template-columns: 360px minmax(0, 1fr);
  gap: 80px;
  align-items: start;
  padding: 128px 0 64px;
}

.about-flow-long {
  width: 100%;
  aspect-ratio: 2 / 3;
  border-radius: 13px;
}

/* cinema: the stage is one pinned screen; js/about.js sets the frame
   rect, the caption/copy positions and every opacity */
.about.is-cinema .about-stage {
  height: 100vh;
  height: 100svh;
}

.about.is-cinema .about-stage__inner {
  position: relative;
  height: 100%;
}

.about.is-cinema .about-frame {
  position: absolute;
  max-width: none;
  aspect-ratio: auto;
  margin: 0;
  will-change: left, top, width, height;
}

.about.is-cinema .about-frame__photo {
  display: block;
}

.about.is-cinema .about-caption {
  position: absolute;
  left: 32px;
  right: 32px;
  padding: 0;
  display: grid;
}

.about.is-cinema .about-caption__text {
  grid-area: 1 / 1;
  margin: 0;
  align-self: start;
}

.about.is-cinema .about-flow-close,
.about.is-cinema .about-flow-long {
  display: none;
}

.about.is-cinema .about-pair {
  display: contents;
}

.about.is-cinema .about-stage__copy {
  position: absolute;
  left: 472px;
  width: 296px;
}

/* --- knowing what to frame --- */
.about-frame-copy {
  max-width: 800px;
  margin: 0 auto;
  padding: 64px 32px;
  display: grid;
  grid-template-columns: 360px minmax(0, 1fr);
  gap: 80px;
}

/* --- the lattice window ---
   An 800×800 stage (the Figma frame). At rest it shows the final
   frame — the window with the ink painting; in cinema mode the
   section pins for a screen and js/about.js plays photo → window →
   ink. The ring overhangs the stage on the way, so nothing clips. */
.about-window {
  padding: 40px 32px;
  display: flex;
  justify-content: center;
}

.about-window__stage {
  position: relative;
  width: min(800px, 100%);
  aspect-ratio: 1;
}

.about-window__view {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.about.is-cinema .about-window {
  height: 100vh;
  height: 100svh;
  padding: 0;
  align-items: center;
}

/* centred on the whole screen, with room above it for the nav */
.about.is-cinema .about-window__stage {
  width: min(800px, calc(100% - 64px), calc(100svh - 2 * var(--nav-h) - 32px));
}

/* --- in my spare time --- */
.about-me {
  max-width: 800px;
  margin: 0 auto;
  padding: 64px 32px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 80px;
  align-items: start;
}

.about-me__photo {
  width: 100%;
  aspect-ratio: 267 / 400;
  object-fit: cover;
  border-radius: 13px;
  background: var(--surface);
}

.about-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 28px;
  margin-top: 28px;
}

.about-btn {
  --sage: #dfe5cd;      /* the site's selection colour */
  --sage-line: #364a02; /* the keyword lattice line    */
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: 15px;
  letter-spacing: -0.01em;
  color: var(--ink-warm);
  text-decoration: none;
}

.about-btn__window {
  position: relative;
  flex: none;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
}

.about-btn__shape {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  transition: transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}

.about-btn__shape path {
  fill: transparent;
  stroke: currentColor;
  stroke-width: 9;
  transition: fill 0.4s ease, stroke 0.4s ease;
}

.about-btn__icon {
  position: relative;
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.about-btn:hover .about-btn__shape,
.about-btn:focus-visible .about-btn__shape {
  transform: rotate(45deg) scale(1.06);
}

.about-btn:hover .about-btn__shape path,
.about-btn:focus-visible .about-btn__shape path {
  fill: var(--sage);
  stroke: var(--sage-line);
}

@media (max-width: 767px) {
  .about__hero {
    padding: 96px 24px 32px;
  }

  .about__heading {
    font-size: 30px;
    line-height: 36px;
  }

  .about-stage__inner,
  .about-frame-copy,
  .about-me {
    padding-left: 24px;
    padding-right: 24px;
  }

  .about-caption {
    padding-top: 40px;
  }

  .about-caption__text--why {
    margin-top: 72px;
  }

  .about-flow-close {
    margin-top: 56px;
  }

  .about-pair,
  .about-frame-copy,
  .about-me {
    grid-template-columns: 1fr;
    gap: 24px;
  }

  .about-pair {
    padding: 72px 0 32px;
  }

  .about-flow-long {
    max-width: 360px;
  }

  .about-frame-copy {
    padding-top: 48px;
    padding-bottom: 48px;
    gap: 16px;
  }

  .about-me {
    gap: 32px;
  }

  .about-me__photo {
    max-width: 360px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .about-btn__shape,
  .about-btn__shape path {
    transition: none;
  }
}

/* --- case studies (layout mirrors the reference grid) --- */
/* the top padding leaves room for the nav line above the first row */
.page__work {
  max-width: 1440px;
  margin: 0 auto;
  padding: 104px 64px 32px;
}

.case-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}

.case {
  display: flex;
  flex-direction: column;
  gap: 12px;
  cursor: pointer;
}

.case__media {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 13px;
  overflow: hidden;
  background: #ece9e2;
  transition: transform 0.3s ease;
}

.case:hover .case__media {
  transform: scale(0.99);
}

/* shared artwork tints (grid cards + modal reuse) */
.case__media--sage,  .art--sage  { background: linear-gradient(135deg, #eef0e2 0%, #d9e0c6 55%, #c6d2b4 100%); }
.case__media--blush, .art--blush { background: linear-gradient(135deg, #f9eeea 0%, #f3dcd6 55%, #e9c8c4 100%); }
.case__media--sky,   .art--sky   { background: linear-gradient(135deg, #e9f0f2 0%, #d3e2e8 55%, #bfd3dd 100%); }
.case__media--sand,  .art--sand  { background: linear-gradient(135deg, #f7f1e4 0%, #eee2c9 55%, #e2d2b2 100%); }
.case__media--mist,  .art--mist  { background: linear-gradient(135deg, #edeff1 0%, #dbdfe3 55%, #c7cdd4 100%); }
.case__media--plum,  .art--plum  { background: linear-gradient(135deg, #f2ecf0 0%, #e4d7e0 55%, #d3bfcd 100%); }

/* hairline frame over the artwork */
.case__frame {
  position: absolute;
  inset: 0;
  border: 1px solid rgba(60, 61, 54, 0.08);
  border-radius: 13px;
  pointer-events: none;
}

/* cover slideshow (COFE+): slides cross-fade in turn while the card
   is hovered; each slide keeps its own grey/colour pair, so the one
   left showing turns grey again on leave (js/work.js) */
.case__slides {
  position: absolute;
  inset: 0;
  z-index: 0;   /* own stacking context: stays under badge + awards */
  overflow: hidden;
}

.case__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
}

.case__slide.is-out {
  z-index: 1;
  opacity: 1;
}

.case__slide.is-on {
  z-index: 2;
  opacity: 1;
  transition: opacity 0.8s ease;
}

/* award marks, top-right on the artwork (same in grey and colour).
   They scale with the card (container units against the 644px
   design width, --w = design width in px) so they stay in the margin
   beside the device instead of covering it on narrow cards. */
.case__awards {
  position: absolute;
  top: clamp(8px, 1.86cqw, 12px);
  right: clamp(8px, 1.86cqw, 12px);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(5px, 1.24cqw, 8px);
  pointer-events: none;
}

.case__awards img {
  display: block;
  width: clamp(calc(var(--w) * 0.66px), calc(var(--w) / 644 * 100cqw), calc(var(--w) * 1px));
  height: auto;
}

/* pill badge, bottom-left on the artwork */
.case__badge {
  position: absolute;
  left: 12px;
  bottom: 12px;
  background: #ffffff;
  border: 1px solid #f1efe9;
  border-radius: var(--radius-pill);
  padding: 5px 12px;
  font-size: 15px;
  line-height: 18px;
  letter-spacing: 0.005em;
  color: var(--ink);
}

/* tags folded inside the badge; they unfold to the right on hover */
.case__tags {
  display: inline-grid;
  grid-template-columns: 0fr;
  vertical-align: top;
  transition: grid-template-columns 0.55s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.case__tags > span {
  overflow: hidden;
  white-space: nowrap;
  color: var(--body-c);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.case__tags > span::before {
  content: '';
  display: inline-block;
  width: 1px;
  height: 12px;
  margin: 0 10px 0 12px;
  vertical-align: -1px;
  background: var(--line);
}

.case.is-hot .case__tags {
  grid-template-columns: 1fr;
}

.case.is-hot .case__tags > span {
  opacity: 1;
  transition-delay: 0.12s;
}

/* a card too narrow for one long pill: the tags unfold downward as a
   second line inside the badge instead */
.case__media {
  container-type: inline-size;
}

@container (max-width: 439px) {
  .case__badge {
    border-radius: 15px;
  }

  .case__tags {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-columns 0.5s cubic-bezier(0.2, 0.8, 0.2, 1),
      grid-template-rows 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);
  }

  .case.is-hot .case__tags {
    grid-template-rows: 1fr;
  }

  .case__tags > span {
    padding-top: 2px;
    font-size: 13px;
    line-height: 17px;
  }

  .case__tags > span::before {
    display: none;
  }
}

/* touch: no hover, so the tags are always shown */
@media (hover: none) {
  .case__tags {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr;
  }

  .case__tags > span {
    opacity: 1;
  }
}

.case__badge i,
.case__titlerow i {
  font-style: normal;
  color: var(--muted);
}

/* description under the card — always shown */
.case__caption {
  padding: 0 13px;
  margin-top: -2px;
  font-size: 15px;
  line-height: 18px;
  letter-spacing: 0.005em;
  color: var(--muted);
}

/* playground cards: title row under the artwork, link on hover */
.case__titlerow {
  padding: 0 13px;
  margin-top: -4px;
  font-size: 15px;
  letter-spacing: 0.005em;
}

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

.case__hoverbits {
  opacity: 0;
  transition: opacity 0.3s ease-out;
}

.case:hover .case__hoverbits {
  opacity: 1;
}

.case__try {
  color: #5e7360;
}

.case:hover .case__try {
  text-decoration: underline;
  text-underline-offset: 3px;
}

@media (max-width: 760px) {
  .page__work {
    padding: 88px 24px 32px;
  }

  .case-grid {
    grid-template-columns: 1fr;
    gap: 40px;
  }
}

/* touch devices: no hover — the hover-only bits stay visible */
@media (hover: none) {
  .case__hoverbits {
    opacity: 1;
  }
}

/* ------------------------------------------------------------------
   Debug readout (enabled with ?debug in the URL)
------------------------------------------------------------------- */
.intro-debug {
  position: fixed;
  top: 12px;
  right: 12px;
  z-index: 999;
  background: rgba(20, 20, 20, 0.82);
  color: #eee;
  font: 11px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace;
  padding: 10px 14px;
  border-radius: 6px;
  pointer-events: none;
  white-space: pre;
}

@media (prefers-reduced-motion: reduce) {
  .intro__hint i { animation: none; }
}

/* ------------------------------------------------------------------
   Floating case-study detail
------------------------------------------------------------------- */
html.has-modal,
html.has-modal body {
  overflow: hidden;
}

.work-modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
}

.work-modal[hidden] {
  display: none;
}

.work-modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(42, 43, 38, 0.42);
  opacity: 0;
  transition: opacity 0.4s ease-out;
}

.work-modal__panel {
  --pad: 32px;
  position: relative;
  display: flex;
  flex-direction: column;
  width: 83.333%;
  max-width: 1240px;
  height: 90vh;
  background: #ffffff;
  border-radius: var(--radius-xl);
  overflow: hidden;
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 0.4s ease-out, transform 0.4s ease-out,
              width 0.45s ease, height 0.45s ease,
              max-width 0.45s ease, border-radius 0.45s ease;
}

.work-modal.is-open .work-modal__backdrop { opacity: 1; }
.work-modal.is-open .work-modal__panel { opacity: 1; transform: none; }

/* soft white fade under the top edge, like the reference */
.work-modal__fade {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 128px;
  z-index: 20;
  pointer-events: none;
  background: linear-gradient(
    rgba(255, 255, 255, 0.5) 0%,
    rgba(255, 255, 255, 0.27) 34%,
    rgba(255, 255, 255, 0.1) 65%,
    rgba(255, 255, 255, 0.02) 86%,
    transparent 100%
  );
}

/* top-right: expand/collapse, then close */
.work-modal__actions {
  position: absolute;
  top: 22px;
  right: 22px;
  z-index: 30;
  display: flex;
  gap: 12px;
  /* own compositing layer, so repainting the hover fill never
     re-rasters it together with the scrolling, video-filled panel
     underneath (Safari flickers the buttons otherwise) */
  transform: translateZ(0);
}

.work-modal__btn {
  position: relative;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  border-radius: 999px;
  color: var(--muted);
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease;
}

.work-modal__btn:hover {
  background: var(--line);
  color: var(--ink-warm);
}

.work-modal__btn svg {
  width: 20px;
  height: 20px;
  fill: currentColor;
}

/* expand and collapse icons share one slot: going fullscreen spins
   the outward arrows away as the inward ones spin in, timed with the
   panel's own resize */
.work-modal__btn--expand svg {
  position: absolute;
  top: 4px;
  left: 4px;
  transition: opacity 0.3s ease, transform 0.45s cubic-bezier(0.3, 0.7, 0.2, 1);
}

.work-modal__icon-in {
  opacity: 0;
  transform: rotate(-90deg) scale(0.6);
}

.work-modal.is-full .work-modal__icon-out {
  opacity: 0;
  transform: rotate(90deg) scale(0.6);
}

.work-modal.is-full .work-modal__icon-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .work-modal__btn--expand svg {
    transition: opacity 0.2s ease;
  }
}

.work-modal__scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
}

/* the design's content column: every block caps at 800px, centred */
.work-modal__scroll > *,
.work-modal__sections > section {
  width: 100%;
  max-width: 800px;
  margin-left: auto;
  margin-right: auto;
}

/* --- hero --- */
.work-modal__hero {
  display: flex;
  flex-direction: column;
  gap: 32px;
  padding: 128px var(--pad) 64px;
}

.work-modal__logo {
  width: 80px;
  height: 80px;
  border-radius: var(--radius-lg);
}

/* logos are parked for now — delete this rule to bring them back */
.work-modal__logo {
  display: none;
}

.work-modal__title {
  font-weight: 400;
  font-size: var(--fs-h2);
  line-height: 1.1;
  letter-spacing: var(--ls-h2);
  color: var(--ink);
}

.work-modal__meta {
  display: flex;
  gap: 20px;
  width: 100%;
}

.work-modal__meta > div {
  flex: 1;
  font-size: 15.5px;
  line-height: 1.6;
  color: #4b4c43;
}

.work-modal__meta-label {
  color: var(--muted);
  margin-bottom: 10px;
}

.work-modal__rule {
  border: 0;
  height: 1px;
  width: 100%;
  margin: 0;
  background: var(--line);
}

.work-modal__cover {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;   /* same artwork as the homepage card */
  border-radius: 13px;
  overflow: hidden;
}

/* 64px from the facts to the cover: the hero's 32px gap + 32px */
.work-modal__hero .work-modal__cover {
  margin-top: 32px;
}

.work-modal__cover video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* --- mission --- */
.work-modal__mission {
  display: flex;
  flex-wrap: wrap;
  gap: 32px 80px; /* Figma: 80px columns; 32px before a wrapped quote */
  padding: 64px var(--pad);
}

.work-modal__mission-left {
  width: 360px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* shared type components — .ui-* are the canonical names; the
   .work-modal__* forms are kept as aliases for existing markup */
.ui-label,
.work-modal__label {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: var(--fs-l);
  color: var(--muted);
}

.ui-title,
.work-modal__headline {
  font-size: var(--fs-h5);
  line-height: 1.45;
  letter-spacing: var(--ls-h5);
  color: var(--ink);
}

.ui-prose,
.work-modal__prose {
  flex: 1 1 0;
  min-width: 200px;
  font-size: var(--fs-l);
  line-height: 1.7;
  letter-spacing: var(--ls-l);
  color: var(--body-c);
}

.ui-prose p + p,
.work-modal__prose p + p {
  margin-top: 22px;
}

.work-modal__hr-wrap {
  padding: 0 var(--pad);
}

/* --- confidential card --- */
.work-modal__conf-wrap {
  padding: 40px var(--pad);
}

.work-modal__confidential {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 26px;
  background: var(--surface);
  border-radius: var(--radius-lg);
  padding: 64px;
}

.work-modal__lock {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 6px 18px rgba(60, 61, 54, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
}

.work-modal__lock svg {
  width: 24px;
  height: 24px;
  stroke: var(--ink-warm);
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.work-modal__conf-title {
  font-size: 24px;
  color: var(--ink);
}

.work-modal__conf-sub {
  margin-top: -16px;
  font-size: 17px;
  color: var(--muted);
}

.work-modal__conf-sub a {
  color: #5e7360;
  text-decoration: none;
}

.work-modal__conf-sub a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* --- also check out --- */
.work-modal__also {
  display: flex;
  flex-direction: column;
  gap: 36px;
  padding: 56px var(--pad) 80px;
}

.work-modal__also-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}

@media (max-width: 760px) {
  .work-modal__panel {
    width: 100%;
    height: 84vh;
    align-self: flex-end;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  }

  .work-modal__hero {
    padding: 96px 28px 48px;
  }

  .work-modal__meta {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 18px;
  }

  .work-modal__mission {
    display: flex;
    flex-direction: column;
    gap: 32px;
    padding: 48px 28px;
  }

  .work-modal__mission-left {
    width: auto;
  }

  .work-modal__mission .ui-quote {
    margin-top: 0;
  }

  .work-modal__hr-wrap,
  .work-modal__conf-wrap {
    padding-left: 28px;
    padding-right: 28px;
  }

  .work-modal__confidential {
    padding: 48px 28px;
  }

  .work-modal__also {
    padding: 48px 28px 64px;
  }

  .work-modal__also-grid {
    grid-template-columns: 1fr;
  }
}

/* ------------------------------------------------------------------
   Footer — the window, once more
------------------------------------------------------------------- */
.footer--c {
  max-width: 1440px;
  margin: 0 auto;
  padding: 32px 64px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 22px;
}

/* quatrefoil button with a thin up arrow inside — same thin-stroke
   language as the cursor follower and the window itself */
.footer__window {
  position: relative;
  width: 96px;
  height: 96px;
  background: none;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* the actual first-screen window artwork, in miniature */
.footer__window-art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1),
              opacity 0.4s ease;
}

.footer__window-arrow {
  position: relative;
  width: 20px;
  height: 20px;
  fill: none;
  stroke: #77786f;
  stroke-width: 1.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: opacity 0.35s ease, transform 0.45s cubic-bezier(0.22, 1, 0.36, 1),
              stroke 0.4s ease;
}

.footer__window:hover .footer__window-art {
  transform: scale(1.12);
}

/* with the custom cursor active, the arrow steps aside on hover and
   the cursor speaks ("Return"); without it (touch, reduced motion)
   the arrow stays as the only affordance */
html.has-cursor .footer__window:hover .footer__window-arrow {
  opacity: 0;
}

html:not(.has-cursor) .footer__window:hover .footer__window-arrow {
  transform: translateY(-3px);
  stroke: var(--ink-warm);
}

.footer__eyebrow {
  margin-top: 14px;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  font-size: var(--fs-s);
  color: var(--muted);
}

.footer__links {
  display: flex;
  gap: 28px;
}

.footer__links a {
  font-size: 12px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #77786f;
  text-decoration: none;
  padding-bottom: 3px;
  border-bottom: 1px solid transparent;
  transition: color 0.3s ease, border-color 0.3s ease;
}

.footer__links a:hover {
  color: var(--ink-warm);
  border-color: var(--ink-warm);
}

.footer__copy {
  margin-top: 14px;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}

@media (max-width: 700px) {
  .footer--c {
    padding-left: 34px;
    padding-right: 34px;
  }
}


/* ------------------------------------------------------------------
   Modal: quiet scrollbar + fullscreen toggle
------------------------------------------------------------------- */
/* scrollbar: translucent, and inset from the rounded corners so the
   thumb never gets clipped at the extremes */
/* Standard scrollbar props only where ::-webkit-scrollbar is NOT
   supported (Firefox). In Chrome/Safari, setting scrollbar-width
   would DISABLE the ::-webkit-scrollbar styling below - including
   the track margin that keeps the thumb clear of the corners. */
@supports not selector(::-webkit-scrollbar) {
  .work-modal__scroll {
    scrollbar-width: thin;
    scrollbar-color: rgba(60, 61, 54, 0.18) transparent;
  }
}

.work-modal__scroll::-webkit-scrollbar {
  width: 10px;
}

.work-modal__scroll::-webkit-scrollbar-track {
  background: transparent;
  margin: 36px 0;   /* keep the travel clear of the corner radius */
}

.work-modal__scroll::-webkit-scrollbar-thumb {
  background: rgba(60, 61, 54, 0.18);
  border-radius: 999px;
  border: 3px solid transparent;
  background-clip: padding-box;
}

.work-modal__scroll::-webkit-scrollbar-thumb:hover {
  background: rgba(60, 61, 54, 0.32);
  border: 3px solid transparent;
  background-clip: padding-box;
}

/* fullscreen: the panel grows to fill the viewport */
.work-modal.is-full .work-modal__panel {
  width: 100vw;
  max-width: none;
  height: 100vh;
  height: 100svh;
  border-radius: 0;
}

/* ------------------------------------------------------------------
   Case media with a real image
------------------------------------------------------------------- */
.case__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* the coloured cover sits over the grey one and fades in on hover
   (.is-hot is set by js/work.js, which also plays a video cover) */
.case__img--hot {
  opacity: 0;
  transition: opacity 0.4s ease;
}

.case.is-hot .case__img--hot {
  opacity: 1;
}

/* modal cover / logo can carry a real image via background */
.work-modal__cover.has-img,
.work-modal__logo.has-img {
  background-size: cover;
  background-color: var(--surface);
}

.work-modal__cover.has-img {
  background-position: center 30%;
}

/* a logo is composed square — centre it rather than biasing up the
   way a wide cover photo wants */
.work-modal__logo.has-img {
  background-position: center;
}

/* wordmark logos: keep the natural aspect at a fixed height instead
   of cover-cropping into the square tile */
.work-modal__logo--wordmark {
  /* a block div ignores aspect-ratio once width resolves to auto-fill,
     so compute the width from the wordmark's natural ratio */
  width: calc(56px * 943 / 188);
  max-width: 100%;
  height: 56px;
  border-radius: 0;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: left center;
  background-color: transparent;
}

/* meta values may carry line breaks (award lists etc.) */
.work-modal__meta div p {
  white-space: pre-line;
}

/* ------------------------------------------------------------------
   Modal gallery — data-driven rows of images
------------------------------------------------------------------- */
.work-modal__gallery {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 0 var(--pad) 40px;
}

.work-modal__gallery-row {
  display: grid;
  gap: 20px;
}

.work-modal__gallery img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-lg);
  background: var(--surface);
}

@media (max-width: 700px) {
  .work-modal__gallery-row {
    grid-template-columns: 1fr !important;
  }
}

/* ------------------------------------------------------------------
   Component library (ui-*) — reusable, token-driven building blocks
   for case-study pages. Layout wrappers end in -grid / -block; each
   component only consumes design tokens, so it works anywhere.
------------------------------------------------------------------- */
/* the display rules above would otherwise defeat the hidden attr */
.work-modal__mission[hidden],
.work-modal__gallery[hidden],
.work-modal__sections[hidden] {
  display: none;
}

/* full-width intro: label + large statement (+ optional .ui-quote) */
.ui-intro {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 64px var(--pad);
}

.ui-intro .ui-title {
  max-width: 46em;
}

.ui-intro .ui-title + .ui-title {
  margin-top: -4px;
}

/* full-width media block for images and looping demo videos */
.ui-media {
  padding: 40px var(--pad);
}

.ui-media img,
.ui-media video {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-lg);
  background: var(--surface);
}

/* collages carry their own whitespace + shadows — no frame */
.ui-media--plain img {
  border-radius: 0;
  background: none;
}

/* pills — accent (on lime) and neutral (on gray) */
.ui-pill {
  display: inline-block;
  padding: 4px 12px;
  border-radius: var(--radius-pill);
  font-size: var(--fs-l);
}

.ui-pill--accent {
  background: #ffffff;
  color: var(--accent-700);
}

.ui-pill--neutral {
  background: var(--slate-200);
  color: var(--slate);
}

/* icon cards: 2-up grid of icon + title + caption */
.ui-card-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  padding: 40px var(--pad);
}

.ui-icon-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 16px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
}

.ui-icon-card img {
  width: 64px;
  height: 64px;
  object-fit: cover;
  flex-shrink: 0;
}

.ui-card-title {
  font-size: var(--fs-l);
  color: var(--ink);
}

.ui-card-sub {
  margin-top: 3px;
  font-size: var(--fs-m);
  line-height: var(--lh-m);
  color: var(--body-c);
}

/* feature columns: 3-up image + title + caption */
.ui-feature-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 36px;
  padding: 40px var(--pad);
}

.ui-feature img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: contain;
  margin-bottom: 16px;
}

/* highlighted question card — lime accent pull-quote */
.ui-quote {
  width: 100%;
  padding: 32px 16px;
  background: var(--accent-100);
  border-radius: var(--radius-md);
  text-align: center;
  font-size: var(--fs-h5);
  line-height: 1.45;
  color: var(--accent-700);
}

.ui-intro .ui-quote {
  margin-top: 16px;
}

.work-modal__mission .ui-quote {
  width: 100%;
}

/* comparison table: label column + n option columns, one of which
   may be highlighted (.is-hl on its cells, -top/-bot on the ends) */
.ui-compare-block {
  padding: 40px var(--pad);
  overflow-x: auto;
}

.ui-compare {
  display: grid;
  grid-template-columns: max-content repeat(3, 1fr);
  min-width: 560px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.ui-cmp-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 14px 10px;
  font-size: var(--fs-m);
  color: var(--slate);
  text-align: center;
}

.ui-cmp-cell img {
  width: 24px;
  height: 24px;
}

.ui-cmp-name {
  font-size: var(--fs-l);
  opacity: 0.7;
}

.ui-cmp-cell.is-hl { background: var(--accent-100); }
.ui-cmp-cell.is-hl-top { border-radius: var(--radius-md) var(--radius-md) 0 0; }
.ui-cmp-cell.is-hl-bot { border-radius: 0 0 var(--radius-md) var(--radius-md); }

/* blue variant of the highlight quote card (PLUS accent) */
.ui-quote--blue {
  background: color-mix(in srgb, var(--accent-blue-200) 70%, transparent);
  color: var(--accent-blue-700);
}

.ui-pill--blue {
  background: #ffffff;
  color: var(--accent-blue-600);
}

/* media extras: relative frame carrying corner badge, overlay pill,
   link hotspots; caption line below */
.ui-media-frame {
  position: relative;
}

.ui-media .ui-media-badge {
  position: absolute;
  right: 10px;
  bottom: 10px;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: none;
}

.ui-pill--overlay {
  position: absolute;
  top: 24px;
  right: 24px;
  background: #ffffff;
  color: var(--accent-blue-600);
}

.ui-media-caption {
  margin-top: 24px;
  font-size: var(--fs-m);
  line-height: var(--lh-m);
  color: var(--body-c);
  text-align: center;
}

.ui-media-hotspot {
  position: absolute;
  border-radius: 4px;
}

.ui-media-hotspot:focus-visible {
  outline-offset: 0;   /* hotspots sit on the image edge-to-edge */
}

/* diagrams displayed below full column width, centred */
.ui-media--narrow img {
  max-width: 68%;
  margin: 0 auto;
}

/* exported full sections: padding + whitespace baked into the image */
.ui-media.ui-media--bare {
  padding: 0;
}

.ui-media--bare img {
  border-radius: 0;
  background: none;
}

/* chapter divider: number + title over a hairline */
.ui-chapter {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 64px var(--pad);
}

.ui-chapter-row {
  display: flex;
  gap: 24px;
}

.ui-chapter-num,
.ui-chapter-title {
  font-size: var(--fs-h5);
  line-height: 1.45;
  letter-spacing: var(--ls-h5);
  color: var(--ink);
}

.ui-chapter-rule {
  width: 100%;
  height: 1px;
  margin: 0;
  border: none;
  background: var(--border);
}

/* table-of-contents cards: thumbnail + chapter number, title, tag */
.ui-toc {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  padding: 40px var(--pad);
}

.ui-toc-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.ui-toc-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
}

.ui-toc-top img {
  width: 72px;
  height: 72px;
  object-fit: cover;
  border-radius: 8px;
}

.ui-toc-num {
  font-size: var(--fs-h5);
  color: var(--muted);
  opacity: 0.6;
}

/* before/after panels: tinted card, pill, media flush to the base */
.ui-panels {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  padding: 40px var(--pad);
}

.ui-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 24px 16px 0;
  border-radius: var(--radius-md);
  overflow: hidden;
}

.ui-panel--gray { background: rgba(226, 227, 231, 0.5); }
.ui-panel--blue { background: var(--accent-blue-100); }

.ui-panel-media {
  width: 100%;
}

.ui-panel-media img,
.ui-panel-media video {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  background: var(--surface);
}

/* outcome list: numbered heading + body pairs in the prose column */
.ui-list {
  flex: 1 1 0;
  min-width: 200px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.ui-list-title {
  font-size: var(--fs-l);
  color: var(--ink);
  margin-bottom: 6px;
}

.ui-list-body {
  font-size: var(--fs-l);
  line-height: 1.6;
  color: var(--body-c);
}

/* feature-grid variants: 2-up layout, centred natural-ratio images */
.ui-feature-grid--two {
  grid-template-columns: repeat(2, 1fr);
}

.ui-feature-grid--center .ui-feature {
  text-align: center;
}

.ui-feature-grid--center .ui-feature img {
  aspect-ratio: auto;
  border-radius: var(--radius-lg);
}

@media (max-width: 760px) {
  .ui-chapter {
    padding: 48px 28px;
  }

  .ui-toc,
  .ui-panels {
    grid-template-columns: 1fr;
    padding-left: 28px;
    padding-right: 28px;
  }

  .ui-feature-grid--two {
    grid-template-columns: 1fr;
  }
}


/* before/after cards with a draggable reveal line (JS sets --ba) */
.ui-ba-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  padding: 40px var(--pad);
}

.ui-ba-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 24px 16px;
  border-radius: var(--radius-md);
}

.ui-ba-card--gray { background: rgba(226, 227, 231, 0.5); }
.ui-ba-card--green { background: var(--accent-100); }

.ui-ba {
  position: relative;
  width: 100%;
  aspect-ratio: 229.5 / 306;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: #e1e3e4;
  cursor: ew-resize;
  touch-action: none;
  user-select: none;
}

.ui-ba img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

.ui-ba-before {
  clip-path: inset(0 calc(100% - var(--ba, 50%)) 0 0);
}

.ui-ba-line {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--ba, 50%);
  width: 2px;
  margin-left: -1px;
  background: #ffffff;
}

.ui-ba-line::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 30px;
  height: 30px;
  background: #ffffff;
  border: 1px solid #cfc4c5;
  border-radius: 50%;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
}

/* headline metric cards */
.ui-stat-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  padding: 40px var(--pad);
}

.ui-stat {
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.ui-stat-value {
  font-size: var(--fs-h2);
  line-height: 1.1;
  letter-spacing: var(--ls-h2);
  color: var(--accent-600);
  white-space: nowrap;
}

.ui-stat-value small {
  font-size: var(--fs-h5);
}

.ui-stat-label {
  margin-top: 6px;
  font-size: var(--fs-m);
  color: var(--body-c);
  opacity: 0.8;
}

/* testimonial: quote + byline + avatar (--rev flips the sides) */
.ui-testimonial {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 64px;
  padding: 80px 64px;
}

.ui-testimonial--rev {
  flex-direction: row-reverse;
}

.ui-tst-content {
  position: relative;
  max-width: 445px;
}

.ui-tst-quote {
  position: absolute;
  top: -44px;
  left: -52px;
  width: 96px;
  opacity: 0.5;
  pointer-events: none;
}

.ui-tst-text {
  position: relative;
  font-size: var(--fs-h5);
  line-height: 1.4;
  letter-spacing: var(--ls-h5);
  color: var(--ink);
}

.ui-tst-byline {
  margin-top: 28px;
  font-size: var(--fs-l);
}

.ui-tst-byline p:first-child {
  color: var(--ink);
}

.ui-tst-byline p + p {
  margin-top: 3px;
  color: var(--body-c);
  opacity: 0.75;
}

.ui-tst-avatar {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}

@media (max-width: 760px) {
  .ui-intro {
    padding: 48px 28px;
  }

  .ui-media,
  .ui-card-grid,
  .ui-feature-grid,
  .ui-compare-block,
  .ui-ba-grid,
  .ui-stat-grid {
    padding-left: 28px;
    padding-right: 28px;
  }

  .ui-card-grid,
  .ui-feature-grid,
  .ui-ba-grid,
  .ui-stat-grid {
    grid-template-columns: 1fr;
  }

  .ui-testimonial,
  .ui-testimonial--rev {
    flex-direction: column;
    gap: 28px;
    padding: 48px 36px;
  }

  .ui-tst-quote {
    left: -16px;
  }
}

/* ------------------------------------------------------------------
   PLUS UNO components — showcase panel, sticky stepper, before/after
   flows, sticky horizontal flow strip
------------------------------------------------------------------- */
.ui-toc--two {
  grid-template-columns: repeat(2, 1fr);
}

/* videos given a fixed ratio fill it (poster + clip crop alike) */
.ui-media video {
  object-fit: cover;
}

.ui-pill--strong {
  font-weight: 500;
}

/* showcase: tinted panel, pill heading, rows of media */
.ui-showcase-block {
  padding: 40px var(--pad);
}

.ui-showcase {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 24px 16px;
  border-radius: var(--radius-md);
  overflow: hidden;
}

.ui-showcase--gray { background: rgba(226, 227, 231, 0.5); }
.ui-showcase--blue { background: var(--accent-blue-200); }

/* a flush (cropped) screenshot runs into the panel's bottom edge */
.ui-showcase:has(.is-flush) {
  padding-bottom: 0;
}

.ui-showcase-row {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 12px;
  width: 100%;
}

.ui-showcase-row video,
.ui-showcase-crop {
  display: block;
  width: 100%;
  border-radius: var(--radius-sm);
  background: var(--surface);
}

.ui-showcase-row video {
  object-fit: cover;
}

.ui-showcase-crop {
  overflow: hidden;
  background: #ffffff;
}

.ui-showcase-crop.is-flush {
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}

.ui-showcase-crop img {
  display: block;
  width: 100%;
  height: auto;
}

/* auto-playing showcase: slides stack and cross-fade; each slide's
   tag slides in from the panel's right edge (classes set by JS) */
.ui-showcase {
  position: relative;
}

.ui-cycle {
  position: relative;
}

.ui-cycle .ui-cycle-slide {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
  transition: opacity 0.45s ease;
}

.ui-cycle .ui-cycle-slide.is-on {
  opacity: 1;
}

.ui-cycle-tag {
  position: absolute;
  top: 90px;
  right: 1px;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 32px;
  padding: 4px 8px 4px 4px;
  background: #ffffff;
  border: 1px solid rgba(96, 108, 124, 0.4);
  border-right: 0;
  border-radius: var(--radius-pill) 0 0 var(--radius-pill);
  filter: drop-shadow(4px 4px 4px rgba(0, 0, 0, 0.08));
  font-size: var(--fs-m);
  line-height: 1.4;
  color: var(--slate);
  white-space: nowrap;
  opacity: 0;
  transform: translateX(calc(100% + 8px));
  transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.3s ease;
}

.ui-cycle-tag.is-on {
  opacity: 1;
  transform: none;
}

.ui-cycle-tag img {
  display: block;
  width: 24px;
  height: 24px;
}

@media (prefers-reduced-motion: reduce) {
  .ui-cycle .ui-cycle-slide,
  .ui-cycle-tag {
    transition: none;
  }
}

/* scrollytelling: the section is a tall track (height set by JS), the
   stage pins for exactly one scroller viewport (--scroll-h) */
.work-modal__sections > section.ui-scrolly {
  max-width: none;
  position: relative;
}

/* the horizontal strip bleeds past the 800px column to the panel's
   edges (--scroll-w is the scroller's width, set by JS) */
.work-modal__sections > section.ui-scrolly--h {
  width: var(--scroll-w, 100%);
  margin-left: calc((100% - var(--scroll-w, 100%)) / 2);
}

.ui-scrolly-stage {
  position: sticky;
  top: 0;
  height: var(--scroll-h, 80vh);
  display: flex;
  flex-direction: column;
  justify-content: safe center;
  overflow: hidden;
  pointer-events: none;
}

.ui-scrolly-stage > * {
  pointer-events: auto;
}

/* stepper: the step list pins on the left while the step cards
   scroll past on the right (--steps-top is set by JS so the list sits
   level with a card centred in the viewport) */
.ui-steps {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 40px var(--pad);
}

.ui-steps-nav {
  position: sticky;
  top: var(--steps-top, 120px);
  z-index: 1;
  width: 110px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.ui-step {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  width: 100%;
  padding: 16px;
  border: 0;
  border-radius: var(--radius-md);
  background: #ffffff;
  opacity: 0.5;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color 0.35s ease, opacity 0.35s ease;
}

.ui-step:hover {
  opacity: 0.75;
}

.ui-step.is-active {
  background: var(--accent-blue-200);
  opacity: 1;
}

.ui-step-num {
  font-size: var(--fs-h5);
  line-height: 1.45;
  color: var(--muted);
  opacity: 0.6;
  transition: color 0.35s ease;
}

.ui-step.is-active .ui-step-num {
  color: var(--body-c);
}

.ui-step-name {
  font-size: var(--fs-m);
  line-height: 1.4;
  color: var(--ink);
}

.ui-steps-list {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.ui-steps-pane {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: #ffffff;
  opacity: 0.45;
  transition: opacity 0.4s ease;
}

.ui-steps-pane.is-active {
  opacity: 1;
}

.ui-steps-text {
  font-size: var(--fs-m);
  line-height: 1.4;
  color: var(--body-c);
}

.ui-steps-media {
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.ui-steps-media img,
.ui-steps-media video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ui-steps-pane.is-contain .ui-steps-media {
  border-radius: 0;
}

.ui-steps-pane.is-contain .ui-steps-media img,
.ui-steps-pane.is-contain .ui-steps-media video {
  object-fit: contain;
}

/* before/after flows: steps joined by down arrows */
.ui-flows {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  padding: 40px var(--pad);
}

.ui-flow-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 24px 16px;
  border-radius: var(--radius-md);
}

.ui-flow-panel--gray { background: rgba(226, 227, 231, 0.5); }
.ui-flow-panel--blue { background: var(--accent-blue-200); }

.ui-flow-steps {
  flex: 1;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 24px;
}

.ui-flow-step {
  position: relative;
  font-size: var(--fs-l);
  line-height: 1.48;
  letter-spacing: var(--ls-l);
  font-weight: 500;
  color: var(--body-c);
  text-align: center;
}

/* the step that changed: a white chip, 3px clear of its arrows */
.ui-flow-step.is-key {
  margin: 3px 0;
  padding: 8px 16px;
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.8);
  color: var(--ink);
}

/* every gap is 24px + the chip's 3px margin; centre the arrow in it */
.ui-flow-step + .ui-flow-step::before {
  content: "";
  position: absolute;
  left: 50%;
  top: -22.5px;
  width: 10px;
  height: 18px;
  transform: translateX(-50%);
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='18' viewBox='0 0 10 18' fill='none' stroke='%23b4b4bb' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 1v16M1.5 13.5 5 17l3.5-3.5'/%3E%3C/svg%3E") center / contain no-repeat;
}

.ui-flow-head {
  display: flex;
  align-items: center;
  gap: 16px;
}

.ui-flow-num {
  flex-shrink: 0;
  font-size: var(--fs-h5);
  line-height: 1.45;
  color: var(--muted);
  opacity: 0.6;
}

.ui-flow-title {
  font-size: var(--fs-l);
  line-height: 1.48;
  letter-spacing: var(--ls-l);
  font-weight: 500;
  color: var(--ink);
}

/* sub-questions sit under the title, past the step number */
.ui-flow-sub {
  padding-left: 41px;
}

.ui-flow-q {
  font-size: var(--fs-l);
  line-height: 1.48;
  letter-spacing: var(--ls-l);
  color: var(--body-c);
}

.ui-flow-a {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  font-size: var(--fs-m);
  line-height: 1.4;
  color: var(--body-c);
}

.ui-flow-sub-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

/* horizontal flow strip: starts on the column's left edge, slides
   (transform set by JS) until the last card meets its right edge */
.ui-hflow {
  display: flex;
  align-items: stretch;
  align-self: flex-start;
  flex-shrink: 0;
  width: max-content;
  padding: 40px max(var(--pad), calc((100% - 800px) / 2 + var(--pad)));
  will-change: transform;
}

.ui-hflow-card {
  width: 363px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: #ffffff;
}

.ui-hflow-card--wide {
  width: 781px;
}

.ui-hflow .ui-flow-head {
  gap: 8px;
}

.ui-hflow-card--wide > .ui-flow-head {
  justify-content: center;
}

.ui-hflow .ui-flow-sub {
  padding-left: 33px;
}

.ui-hflow-media {
  flex: 1;
  display: flex;
  align-items: center;
}

.ui-hflow-media video {
  display: block;
  width: 100%;
  aspect-ratio: 298 / 203;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background: var(--surface);
}

.ui-hflow-cols {
  display: flex;
  gap: 12px;
}

.ui-hflow-col {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.ui-hflow-media--wide {
  flex: none;
  padding-left: 33px;
}

.ui-hflow-media--wide video {
  aspect-ratio: 405 / 228;
}

.ui-hflow-arrow {
  width: 32px;
  flex-shrink: 0;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='10' viewBox='0 0 18 10' fill='none' stroke='%23b4b4bb' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 5h16M13.5 1.5 17 5l-3.5 3.5'/%3E%3C/svg%3E") center / 18px 10px no-repeat;
}

@media (max-width: 760px) {
  .ui-showcase-block,
  .ui-flows,
  .ui-steps {
    padding-left: 28px;
    padding-right: 28px;
  }

  .ui-flows {
    grid-template-columns: 1fr;
  }

  /* steps become a row of chips pinned above the cards, clear of
     the panel's expand button */
  .ui-steps {
    flex-direction: column;
    align-items: stretch;
  }

  .ui-steps-nav {
    top: 56px;
    width: auto;
    padding: 8px 0;
    background: #ffffff;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 6px;
  }

  .ui-step {
    gap: 2px;
    padding: 10px;
  }

  .ui-step-num {
    font-size: var(--fs-l);
  }

  .ui-step-name {
    font-size: var(--fs-s);
  }

  .ui-hflow {
    --pad: 28px;
  }

  .ui-hflow-card {
    width: 290px;
  }

  .ui-hflow-card--wide {
    width: 600px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ui-step,
  .ui-step-num,
  .ui-steps-pane {
    transition: none;
  }
}

/* ------------------------------------------------------------------
   Media preview (lightbox) — click an image or video in a case study:
   it rises to the centre over a warm dim, and sinks away on close
------------------------------------------------------------------- */
[data-zoomable] {
  cursor: zoom-in;
}

.lightbox {
  position: fixed;
  inset: 0;
  /* above the case-study modal (100), below the cursor ring (200) */
  z-index: 150;
  display: flex;
  align-items: center;
  justify-content: center;
}

.lightbox[hidden] {
  display: none;
}

.lightbox__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(42, 43, 38, 0.62);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity 0.38s ease;
}

.lightbox.is-open .lightbox__backdrop {
  opacity: 1;
}

.lightbox__stage {
  position: relative;
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  opacity: 0;
  transform: translateY(40px) scale(0.97);
  transition: transform 0.55s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.35s ease;
}

.lightbox.is-open .lightbox__stage {
  opacity: 1;
  transform: none;
}

.lightbox.is-closing .lightbox__stage {
  opacity: 0;
  transform: translateY(28px) scale(0.985);
  transition: transform 0.3s cubic-bezier(0.4, 0, 1, 1), opacity 0.26s ease;
}

.lightbox.is-closing .lightbox__backdrop {
  opacity: 0;
  transition-duration: 0.3s;
}

.lightbox__media {
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.28);
}

.lightbox__media img,
.lightbox__media video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.lightbox__caption {
  max-width: 60ch;
  font-size: var(--fs-m);
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.82);
  text-align: center;
}

.lightbox__caption:empty {
  display: none;
}

.lightbox__close {
  position: absolute;
  top: 24px;
  right: 24px;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(60, 61, 54, 0.18);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  color: var(--ink-warm);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.3s ease, background-color 0.2s ease, transform 0.2s ease;
}

.lightbox.is-open .lightbox__close {
  opacity: 1;
}

.lightbox__close:hover {
  background: #ffffff;
  transform: scale(1.06);
}

.lightbox__close:focus:not(:focus-visible) {
  outline: none;
}

.lightbox__close svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}

@media (max-width: 760px) {
  .lightbox__close {
    top: 16px;
    right: 16px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .lightbox__stage,
  .lightbox.is-closing .lightbox__stage {
    transform: none;
  }
}

/* ------------------------------------------------------------------
   Selection colour — sage, from the garden
------------------------------------------------------------------- */
::selection {
  background: #dfe5cd;
  color: var(--ink);
}
