/*
 * AEON Point Design System Tokens
 *
 * Approach: Fluid typography + fluid spacing via clamp().
 * All sizes scale smoothly between breakpoints (375 / 768 / 1440 / 1920).
 * Paper designs are pixel-accurate at 1440; smaller/larger screens interpolate.
 *
 * Reference: FinSweet (https://finsweet.com)
 */

/* Self-hosted Roboto Flex (variable, latin) — served from /fonts so it loads instantly with no
   Google round-trip, killing the nav-link FOUT (the condensed wdth-50 display font was the most
   visible swap). Geist + Geist Mono still come from Google (body, normal width — negligible flash). */
@font-face {
  font-family: "Roboto Flex";
  font-style: normal;
  font-weight: 100 1000;
  font-stretch: 25% 151%;
  font-display: swap;
  src: url("/fonts/roboto-flex.woff2") format("woff2"); /* ?v bump busts cache when the font file changes (it's a static public path, not fingerprinted) */
}

/* ─────────────────────────────────────────────────────────────────────────
   AEON Point — Public site design tokens
   Extracted from Paper "Design System" (artboards 01–07).
   Cinema-grade dark, monochrome anchor. Admin theme lives separately in
   admin_theme.css and is NOT affected by these tokens.

   These are plain :root CSS variables for use in inline styles and component
   CSS. The matching Tailwind v4 utility tokens live in the @theme block in
   app/assets/tailwind/application.css.
   ───────────────────────────────────────────────────────────────────────── */

:root {
  /* ── Colors · Surfaces (01 Colors) ──────────────────────────────────── */
  --bg: #0B0B0B;               /* SURFACE / BASE — page background */
  --surface-raised: #000000;   /* SURFACE / RAISED — dense inner panels */
  --surface-card: #181818;     /* SURFACE / CARD — content cards */
  --surface-inverted: #FFFFFF; /* SURFACE / INVERTED — spotlight moments */

  /* ── Colors · Text on dark ──────────────────────────────────────────── */
  --text-primary: #FFFFFF;                  /* 100% — display, headings, labels */
  --text-muted: rgba(255, 255, 255, 0.80);  /* 80%  — body, descriptions, stats */
  --text-subtle: rgba(255, 255, 255, 0.50); /* 50%  — meta, copyright, dividers */
  --text-on-light: #000000;                 /* on inverted surfaces + primary btn */

  /* ── Colors · Glass (pair with backdrop-blur) ───────────────────────── */
  --glass-header: rgba(0, 0, 0, 0.10);     /* header overlay, blur 12 */
  --glass-chip: rgba(243, 243, 243, 0.10); /* tag / chip on photo, blur 16 */
  --glass-play: rgba(0, 0, 0, 0.60);       /* play CTA over hero video, blur 12 */

  /* ── Colors · Accent (the only chroma — status dot) ─────────────────── */
  --accent: #2DD480; /* status / "LIVE" dot. Brand accent otherwise TBD. */

  --divider: rgba(255, 255, 255, 0.20); /* 1px hairline between sections */

  /* ── Colors · Semantic ──────────────────────────────────────────────── */
  /* From Paper Section · Form-level error (2FI7-0). One red for all error states. */
  --danger: #FF6B6B;        /* error message text + required asterisk */
  --danger-border: #FF6B6B; /* invalid input border (1px) — same hex */
  /* No error-specific background — invalid fields keep the default field bg (#FFFFFF · 7%). */
  /* Semantic colors success/warning/info: TBD — add when needed */

  /* ── Type families ──────────────────────────────────────────────────── */
  --font-display: "Roboto Flex", system-ui, sans-serif; /* display + UI, uppercase */
  --font-body: "Geist", ui-sans-serif, system-ui, sans-serif; /* body, sentence case */
  --font-mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace; /* contact-cta hover pill label */

  /* ── Fluid type scale (max = Paper 1440px value; mins are fluid floors) ─ */
  --size-display: clamp(56px, 11cqw, 160px); /* DISPLAY / H1 — hero only */
  --size-h2: clamp(40px, 6.1cqw, 88px);      /* DISPLAY / H2 — section titles */
  --size-h3: clamp(32px, 4.2cqw, 60px);      /* DISPLAY / H3 — about / big stats */
  --size-h4: clamp(26px, 3cqw, 44px);        /* DISPLAY / H4 — featured card title */
  --size-h5: clamp(20px, 1.8cqw, 24px);      /* DISPLAY / H5 — blog card title */
  --size-h6: 18px;                          /* DISPLAY / H6 — subhead */
  --size-kicker: clamp(16px, 1.6cqw, 24px);  /* UI / KICKER XL */

  /* ── Layout (see ai_docs/04_ux/02_layout_strategy.md) ───────────────── */
  --side-padding: clamp(16px, 1.6667cqw, 24px); /* UNUSED — real page gutters are per-band literals per section; desktop side gutter is now 24 (was 48) */
  --section-py: clamp(80px, 8.3cqw, 120px);   /* SPACE/10 — standard section padding */
  --section-py-sm: clamp(56px, 5.5cqw, 80px); /* SPACE/9  — small section padding */
}

/* ── Variable-font helpers (Roboto Flex axes — Tailwind can't express these) ──
   Roboto Flex is condensed for display (wdth 50) and UI labels (wdth 55),
   always uppercase per the type spec. */
.ds-display {
  font-family: var(--font-display);
  /* Full Roboto Flex display axes (matches Paper hero 50J4 + .about-display). GRAD -200 lightens the
     strokes — without it (and with the old wdth 50) the headings rendered too heavy vs Paper. */
  font-variation-settings: "wght" 700, "wdth" 55, "GRAD" -200, "XOPQ" 95,
    "XTRA" 470, "YOPQ" 80, "YTDE" -200, "YTFI" 740, "YTLC" 510, "YTUC" 710;
  text-transform: uppercase;
  line-height: 0.85;
  letter-spacing: 0.02em;
}

/* Hero H1 display size — SINGLE SOURCE for every hero headline. Per band, identical to the page-title H1 scale
   (.contact__title / .page-hero__title / .projects-index__title / .thanks__title): 44 @375 / 88 @768 / 130 @1440.
   Put this class on every hero <h1> so all H1 scale the same across breakpoints (no per-hero continuous values). */
.hero-title { font-size: 11.7333cqw; }
@media (min-width: 640px)  { .hero-title { font-size: 11.4583cqw; } } /* 88 @768 */
@media (min-width: 1024px) { .hero-title { font-size: 9.0278cqw; } }  /* 130 @1440 */

/* Home Hero heading — two stacked layers (real + aria-hidden decorative copy) for the doubled "overlay" blend.
   The grid stack overlaps them in one cell on every breakpoint; on desktop the scroll controller takes both out
   of flow (position:absolute) and the grid collapses. The stack is intentionally NOT a stacking context (no
   z-index/transform/opacity) so each layer still blends with the page backdrop, not with the stack. */
.hero-text-stack { display: grid; place-items: center; }
.hero-text-layer { grid-area: 1 / 1; }

/* Hero top-darkening mask geometry (top + height) — top-anchored (height shrinks from the BOTTOM, top edge stays
   put). Mobile: height squashed 50% (72vh vs 144vh) and raised ~30px so it darkens less of the area behind the
   heading (the darkening weakened the overlay blend there). Tablet/desktop unchanged. Width/transform/background
   stay inline (transform is JS-driven by the scroll). */
.hero-mask { top: -34.6667cqw; height: 72vh; } /* mobile: -130px@375 (was -100, raised 30 = 8cqw) / 72vh (was 144) */
@media (min-width: 640px)  { .hero-mask { top: -26.0417cqw; height: 144vh; } } /* tablet: -200px@768 (was -100, raised 100) */
@media (min-width: 1024px) { .hero-mask { top: -13.8889cqw; } }                /* desktop: -200px@1440 (was -100, raised 100); height 144vh inherited */

.ds-kicker {
  font-family: var(--font-display);
  font-variation-settings: "wght" 500, "wdth" 55;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  line-height: 1.4;
}

/* Hero descriptive subtitle — SINGLE SOURCE for the subtitle under a hero H1 (About, For-Agencies, Services,
   Blog, Capabilities, FAQ, Contact, Thank You). Geist body, 14 / 14 / 18 per band, line-height 160% — identical
   to the service About statement (.svc-intro__sub). Per-hero classes own only their max-width / colour / align. */
.hero-sub { font-family: var(--font-body); font-size: 3.7333cqw; line-height: 160%; text-transform: none; letter-spacing: normal; text-wrap: pretty; max-width: 100%; } /* 14 @375. pretty = natural paragraph wrap (NOT balance — balance is for short headings and shortens interior lines). Width unified across every hero subtitle. */
@media (min-width: 640px)  { .hero-sub { font-size: 1.8229cqw; max-width: 55.7292cqw; } } /* 14; w428 @768 */
@media (min-width: 1024px) { .hero-sub { font-size: 1.1111cqw; max-width: 42.5cqw; } }   /* 16; w612 @1440 */

/* ── Descriptive-text wrapping — ONE rule, site-wide ───────────────────────────────────────────────────────
   Every body / subtitle / description paragraph uses text-wrap: pretty so the browser avoids orphan words
   (a lone word stranded on the last line) for ANY copy — not just lucky wording. Compound words
   (award-winning, high-impact) are kept whole by non_breaking_hyphens (cms_text + render_markdown). Headings
   deliberately use text-wrap: balance on their own classes, NOT pretty — DO NOT add headings to this list.
   New descriptive class? Add it here. (.hero-sub already sets pretty; .contact__sub / .thanks__sub /
   .page-hero__sub inherit font+wrap from .hero-sub.) */
.proj-body, .proj-card__desc, .proj-detail__summary,
.featured-sub, .featured-card__desc,
.awards-sub, .awards-quote__text,
.services-card__desc, .service-card__desc, .services-v2__desc,
.blog-card__dek, .blog-featured__dek,
.team-head__sub, .team-card__bio-text,
.svc-intro__sub, .svc-faq__a-text, .work-showcase__sub,
.fa-why__sub, .fa-why__card-desc,
.contact-cta__sub, .contact-thanks__sub, .notfound__sub,
.article-content p,
.cap-desc, .wwm-desc, .legal__intro, .legal__copy {
  text-wrap: pretty;
}

/* Hero vertical rhythm — applied as margins (so the two gaps can differ, which a single flex gap can't).
   Kicker→title: 16 desktop / 12 tablet / 12 mobile. Title→subtitle: 16 on every band. Put .hero-gap-kicker on
   the eyebrow kicker and .hero-gap-sub on the descriptive subtitle; the H1 carries no vertical margin. */
.hero-gap-kicker { margin-bottom: 3.2cqw; } /* 12 @375 */
.hero-gap-sub    { margin-top: 4.2667cqw; } /* 16 @375 */
@media (min-width: 640px)  { .hero-gap-kicker { margin-bottom: 1.5625cqw; } .hero-gap-sub { margin-top: 2.0833cqw; } } /* 12 / 16 @768 */
@media (min-width: 1024px) { .hero-gap-kicker { margin-bottom: 1.1111cqw; } .hero-gap-sub { margin-top: 1.1111cqw; } } /* 16 / 16 @1440 */

.ds-action {
  font-family: var(--font-display);
  font-variation-settings: "wght" 500, "wdth" 50;
  text-transform: uppercase;
  letter-spacing: 0;
  line-height: 1;
}

/* ── DS button (Paper 04 Buttons) — the ONE button component. Every section reuses
   components/_button (which applies .ds-btn), never re-authors a button. Fluid per artboard
   (375/768/1440), bands 640/1024: 32h / px16 / radius4 / 12 label, constant across artboards but
   still scaled. Colour variants live in components/_button. Base = mobile. */
.ds-btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 2.1333cqw; height: 8.5333cqw; padding-inline: 4.2667cqw; border-radius: 1.0667cqw;
  font-size: 3.2cqw; white-space: nowrap; text-decoration: none; cursor: pointer;
}
.ds-btn--block { width: 100%; }                 /* full-width (e.g. mobile) */
.ds-btn--ghost { padding-inline: 0; background: none; } /* text-link variant */
@media (min-width: 640px) {
  .ds-btn { gap: 1.0417cqw; height: 4.1667cqw; padding-inline: 2.0833cqw; border-radius: 0.5208cqw; font-size: 1.5625cqw; }
}
@media (min-width: 1024px) {
  .ds-btn { gap: 0.5556cqw; height: 2.2222cqw; padding-inline: 1.1111cqw; border-radius: 0.2778cqw; font-size: 0.8333cqw; }
}

/* ── DS nav link (header nav + footer columns) — Roboto Flex wght500 wdth50 uppercase 12, colour
   inherits (theme-aware), fluid per-band. */
.ds-nav-link { color: inherit; text-decoration: none; line-height: 93.7%; font-size: 3.2cqw; transition: opacity 0.2s ease; white-space: nowrap; cursor: pointer; } /* opacity only (hover fade); theme colour switches instantly */
.ds-nav-link:hover { opacity: 0.6; }
@media (min-width: 640px)  { .ds-nav-link { font-size: 1.5625cqw; } }
@media (min-width: 1024px) { .ds-nav-link { font-size: 0.8333cqw; } }

/* ── DS icon (components/_icon) — inline SVG primitive, currentColor, sized by the consumer. */
.ds-icon { display: block; flex-shrink: 0; }
.ds-icon--demo { height: 14px; width: auto; } /* styleguide swatch sizing */

.ds-body {
  font-family: var(--font-body);
  line-height: 1.6;
}

/* ── Section-About — fluid by Paper artboard (375 / 768 / 1440) ───────────────
   Three bands, one per Paper artboard, with two switch points (640 / 1024). Each
   band is its artboard scaled uniformly by the viewport (pure vw) — so every
   value scales by the SAME factor, line breaks stay frozen within the band, and
   we hit the artboard exactly at its native width. value_vw = artboard_px /
   artboard_width × 100. The ≥1024 band keeps growing past 1440 (no cap).

     • < 640    → Mobile 375  (denser: bigger text relative to width)
     • 640–1023 → Tablet 768
     • ≥ 1024   → Desktop 1440 (and up)

   Switch points (640 / 1024) match the stats layout flip in the partial
   (Tailwind sm: = 640 → stacked becomes a 3-col row). Expect a size step at each
   switch — that is the layout snapping to the next artboard, by design.

   The Roboto Flex display axes (wdth 55 + extended, captured from 50TW-0/50TZ-0)
   are a distinct on-brand treatment, wider/lighter than .ds-display (wdth 50). */
.about-display {
  font-family: var(--font-display);
  font-weight: 700;
  font-variation-settings: "wght" 700, "wdth" 55, "GRAD" -200, "XOPQ" 95,
    "XTRA" 470, "YOPQ" 80, "YTDE" -200, "YTFI" 740, "YTLC" 510, "YTUC" 710;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
/* Service hero title stays on ONE line on desktop (e.g. "Broadcast + Media", which otherwise wraps), and the
   title's container is widened so the longer one-line titles fit fully inside it — no overflow for the page's
   overflow-x:clip to cut on the right. There's ample room before the section edges. Below 1024: unchanged.
   Scoped to the service hero only (extra_class on hero_media_v2). Same display font everywhere — no size change. */
@media (min-width: 1024px) {
  .hero-media-v2--service h1 { white-space: nowrap; }
  .hero-media-v2--service [data-hero-media-v2-target="text"] { width: 88cqw; }
}
.about-stat-label {
  font-family: var(--font-display);
  font-weight: 500;
  font-variation-settings: "wght" 500, "wdth" 55;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  line-height: 140%;
  color: rgba(255, 255, 255, 0.70); /* Paper #FFFFFFB3 — between --text-muted and --text-subtle */
}

/* Image trail (desktop hover effect, image-trail Stimulus controller). The layer sits
   behind the text (z-0); the JS appends <img.about-trail__img> at the cursor and
   animates them out. pointer-events:none so it never blocks the CTA / text selection. */
.about-trail {
  position: absolute;
  inset: 0;
  z-index: 1; /* above the section background, BEHIND the z-10 text/stats/CTA */
  overflow: visible; /* trail images may spill onto the neighbouring sections (the section is relative, so it
                        paints above its static neighbours); horizontal spill is clipped by html{overflow-x:clip} */
  pointer-events: none;
}
.about-trail__img {
  position: absolute;
  top: 0;
  left: 0;
  width: 11.4583cqw; /* 165 @1440 (220 −25%) — desktop-only effect (gated ≥1024 + fine pointer), scales uncapped */
  height: auto;
  border-radius: 0.2778cqw; /* 4 @1440 */
  opacity: 0; /* hidden until GSAP animates it in (positioned via GSAP x/y from top-left) */
  will-change: transform, opacity, filter;
}

/* ── Section-FeaturedCase (Home) — fluid per Paper artboard (375/768/1440), bands 640/1024.
   Desktop (≥1024): sticky left panel + scrolling right photos; the active card's body is
   cloned into the panel (featured_case_controller). <1024: a plain card stack (photo +
   body). Reuses .about-display (display axes) and .about-stat-label (label axes/colour);
   the .featured-* classes carry sizes/layout. Each band = its artboard scaled by viewport. */

/* MOBILE band (< 640) — 375 artboard × viewport */
.featured-case      { gap: 12.8cqw; padding-block: 16cqw; padding-inline: 4.2667cqw; }
.featured-heading   { width: 91.4667cqw; gap: 4.2667cqw; }
.featured-title     { font-size: 11.7333cqw; line-height: 80%; width: 72.8cqw; opacity: 0.9; text-align: center; }
.featured-sub       { font-size: 3.7333cqw; line-height: 160%; width: 78.4cqw; opacity: 0.8; text-align: center; font-family: var(--font-body); } /* 14 */
.featured-stack     { gap: 0; }
.featured-scroll    { width: 100%; gap: 16cqw; align-items: stretch; }
.featured-sticky    { display: none; }

/* Per-field "roll" transition for the sticky panel (featured_case_controller): each rollable
   field is a clip box (grid + overflow:hidden) holding stacked .featured-roll__item lines;
   the current line slides up & out while the next slides in from below. */
.featured-roll        { display: grid; overflow: hidden; align-items: start; }
.featured-roll__item  {
  grid-area: 1 / 1;
  transform: translateY(0);
  opacity: 1;
  transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.45s ease;
  will-change: transform, opacity;
}
.featured-card__cats.featured-roll .featured-roll__item { display: flex; flex-wrap: nowrap; align-items: center; gap: inherit; } /* sticky panel (desktop) — keep meta on one line */

.featured-card           { gap: 6.4cqw; align-items: stretch; text-decoration: none; color: inherit; }
.featured-card__media    { position: relative; width: 100%; } /* wraps the photo + service tags so they reveal as one block (tags don't move vs the photo → blur intact); the absolute services position against this */
.featured-card__photo    { width: 100%; aspect-ratio: 343 / 192; object-fit: cover; border-radius: 2.1333cqw; display: block; }
.featured-card__services { position: absolute; top: 3.2cqw; left: 3.2cqw; z-index: 2; display: flex; align-items: center; gap: 2.1333cqw; } /* service pills overlaid on the photo top-left; 12 inset, 8 gap @375 */
.featured-card__body     { gap: 6.4cqw; align-items: flex-start; text-align: left; }
.featured-card__content  { gap: 4.2667cqw; } /* 16 — meta row ↔ title */
.featured-card__cats     { gap: 3.2cqw; } /* 12 — service pills + tag labels */
.featured-card__cats .featured-card__cat { font-size: 2.6667cqw; line-height: 140%; white-space: nowrap; } /* 10 — specificity beats .about-stat-label (also on the span) */
.featured-card__titleblock { gap: 3.2cqw; }
.featured-card__title    { font-size: 6.4cqw; line-height: 90%; }
.featured-card__desc     { font-size: 3.7333cqw; line-height: 160%; opacity: 0.8; font-family: var(--font-body); }
.featured-card__stat     { display: flex; flex-direction: row; align-items: flex-start; gap: 3.2cqw; }
.featured-card__stat-num { font-size: 9.6cqw; line-height: 90%; opacity: 0.9; }
.featured-card__stat-label { font-size: 3.2cqw; line-height: 140%; width: 56cqw; } /* 12; w210 @375 */
.featured-cta            { align-self: flex-start; width: auto; }

/* ── DS glass button (Paper 5ZU7-1: Play Video + View Project) ────────────────
   Shared by the View Project / View Service / View Article pills (and the hero Play).
   Everything scales per-band vw (mobile/375, tablet/768, desktop/1440): gap 8, radius 6,
   padding 8/12, icon pad-left 8, label 10 — all constant across artboards but still scaled.
   Base = mobile. Black 60% + blur 12, Geist label uppercase, line-height 130%. */
.glass-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 2.1333cqw;
  border-radius: 1.6cqw;
  padding: 2.1333cqw 3.2cqw; /* View Project: symmetric (no icon) */
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.glass-pill--icon { padding-left: 2.1333cqw; } /* Play Video: smaller left padding balances the icon */
.glass-pill__label {
  font-family: var(--font-body); /* Geist */
  font-size: 2.6667cqw; /* 10 @375 */
  line-height: 130%;
  text-transform: uppercase;
  color: #FFFFFF;
  white-space: nowrap;
}
@media (min-width: 640px) {
  .glass-pill { gap: 1.0417cqw; border-radius: 0.78125cqw; padding: 1.0417cqw 1.5625cqw; }
  .glass-pill--icon { padding-left: 1.0417cqw; }
  .glass-pill__label { font-size: 1.3021cqw; }
}
@media (min-width: 1024px) {
  .glass-pill { gap: 0.5556cqw; border-radius: 0.4167cqw; padding: 0.5556cqw 0.8333cqw; }
  .glass-pill--icon { padding-left: 0.5556cqw; }
  .glass-pill__label { font-size: 0.6944cqw; } /* 10 @1440 */
}

/* ── Section-Services (shared) — fluid per artboard (375/768/1440), bands 640/1024.
   Hover/tap a row → services_picker swaps the right card image + reveals the description
   and marks the row .is-active (active row stays lit, every other row dims to .5; .glass-pill fades in).
   Default = image only (description hidden while empty). Reuses .about-display (titles),
   .about-stat-label (numbers), .glass-pill (View Service). */

/* MOBILE (< 640) — 375 artboard × viewport */
.services-section { position: relative; overflow: clip; padding-block: 16cqw; padding-inline: 4.2667cqw; }
/* Ambient colour glow anchored to the bottom-right CORNER (image pushed slightly past the
   corner + blur → light emanates from the edge inward; section overflow:clip hides the
   off-corner part). Shown on all breakpoints. */
/* Exported Paper glow frame (5ZU9-1) anchored to the bottom-right corner; its black bg
   blends into the section, leaving the corner glow. width scales per band. */
.services-ambient {
  display: block; position: absolute; right: 0; bottom: 0;
  width: 100%; height: auto;
  pointer-events: none;
  z-index: 0;
}
.services-inner   { display: flex; flex-direction: column; gap: 12.8cqw; position: relative; z-index: 1; }
.services-sidebar { display: flex; flex-direction: column; align-items: flex-start; gap: 6.4cqw; width: 100%; }
.services-label   { font-family: var(--font-display); font-weight: 500; font-variation-settings: "wght" 500, "wdth" 50; text-transform: uppercase; line-height: 140%; color: rgba(255, 255, 255, 0.7); font-size: 3.2cqw; }
.services-list    { display: flex; flex-direction: column; align-items: flex-start; gap: 3.2cqw; list-style: none; margin: 0; padding: 0; }
.services-row     { display: flex; align-items: flex-start; gap: 3.2cqw; appearance: none; background: none; border: 0; margin: 0; padding: 0; cursor: pointer; text-align: left; color: inherit; text-decoration: none; position: relative; }
.services-row__num   { font-size: 3.2cqw; line-height: 140%; flex-shrink: 0; }
.services-row__title { font-size: 9.6cqw; line-height: 80%; opacity: 0.9; white-space: nowrap; transition: opacity 0.5s ease-out; }
/* Hover logic: the hovered/active row stays lit; every OTHER row dims to 0.5. (is-active is toggled by
   services_picker, desktop only — so on adaptive nothing dims.) */
.services-list:has(.is-active) .services-row:not(.is-active) .services-row__title { opacity: 0.3; }
.services-card       { display: flex; flex-direction: column; align-items: flex-start; gap: 8.5333cqw; width: 100%; }
.services-card__img  { width: 100%; aspect-ratio: 343 / 192; object-fit: cover; border-radius: 2.1333cqw; display: block; }
.services-card__desc { font-family: var(--font-body); font-size: 3.7333cqw; line-height: 160%; opacity: 0.8; color: #fff; } /* 14 */
.services-card__desc:empty { display: none; }

/* TABLET (≥ 640) — 768 artboard × viewport */
@media (min-width: 640px) {
  .services-section { padding-block: 10.4167cqw; padding-inline: 4.1667cqw; }
  .services-ambient { width: 75%; }
  .services-inner   { flex-direction: row; align-items: flex-start; gap: 3.125cqw; }
  .services-sidebar { width: 44.27cqw; min-height: 61.6cqw; justify-content: space-between; gap: 0; }
  .services-label   { font-size: 1.5625cqw; }
  .services-list    { gap: 1.5625cqw; }
  .services-row     { gap: 1.5625cqw; }
  .services-row__num   { font-size: 1.5625cqw; }
  .services-row__title { font-size: 5.7292cqw; }
  .services-card       { width: 44.27cqw; align-self: flex-start; gap: 3.125cqw; }
  .services-card__img  { aspect-ratio: 340 / 221; border-radius: 1.0417cqw; }
  .services-card__desc { font-size: 1.8229cqw; } /* 14 */
}

/* DESKTOP (≥ 1024) — 1440 artboard × viewport, uncapped above 1440 */
@media (min-width: 1024px) {
  .services-section { padding-block: 8.3333cqw; padding-inline: 1.6667cqw; }
  .services-ambient { width: 59%; }
  /* content height (≈560 @1440, not the full 800 section) so names align with the description;
     capped to the viewport so the image + left text fit one screen on wide displays */
  .services-inner   { flex-direction: row; justify-content: space-between; align-items: stretch; gap: 0; min-height: min(38.89cqw, 70vh); position: relative; }
  .services-sidebar { width: 45.833cqw; min-height: 0; justify-content: space-between; gap: 0; }
  .services-label   { font-size: 0.8333cqw; }
  .services-list    { gap: 0.8333cqw; }
  .services-row     { gap: 0.8333cqw; }
  .services-row__num   { font-size: 0.8333cqw; }
  .services-row__title { font-size: 4.1667cqw; }
  .services-card       { width: 30.833cqw; align-self: flex-start; gap: 2.2222cqw; }
  .services-card__img  { aspect-ratio: 444 / 289; border-radius: 0.5556cqw; }
  .services-card__desc { font-size: 0.9722cqw; } /* 14 */
}

/* ── Section-Services v2 (Home) — centred column, NO image (alternate of the .services-* block above).
   Default: kicker + 4 stacked titles. Desktop hover (≥1024, services_v2 controller): the active title
   stays lit, every OTHER dims to 0.3, the active row reveals its description below + the "View Service"
   cursor pill. Per Paper 64RL/64QM (desktop 1440). Adaptive (mobile/tablet) layout is a PLACEHOLDER
   (centred titles, no reveal) — proper adaptives pending. */
.services-v2 { position: relative; overflow: clip; background: var(--color-base); padding-block: 16cqw; padding-inline: 4.2667cqw; display: flex; flex-direction: column; align-items: flex-start; } /* mobile 60 block / 16 inline */
/* Ambient glow — the services default photo, blurred (the Paper frame 64W1 backdrop). MOBILE/TABLET (base):
   anchored to the section bottom and pushed DOWN by 50% of its own height (translateY 50%), so the section's
   bottom edge bisects the image — top half glows up into the section, bottom half is clipped. Grows with the
   open accordion (bottom stays glued). DESKTOP (@1024): overridden — pushed fully below the bottom. */
/* ADAPTIVE (mobile + tablet) glow: taller (reaches up to ~Show Production) and ZOOMED into the central
   blue stage so the warm/muddy crowd + arena edges are cropped out — only blue + grey-white remain. The
   desktop band below overrides size/mask back to its own (shorter, cover) framing. */
.services-v2__glow { position: absolute; left: 50%; bottom: 0; width: 160%; height: 142cqw; transform: translateX(-50%) translateY(43cqw);
  opacity: 0.8; filter: blur(80px) saturate(1.5); pointer-events: none; z-index: 0;
  /* Framed UP (32%) + extra zoom (215%) so the warm/muddy crowd (lower third of the photo) is cropped out
     entirely — only the blue dome + white stage are in view. Taller (128cqw) so the glow reaches up to
     ~Show Production on mobile. */
  background: url("/media/images/services/default.webp") center 32% / 215% auto no-repeat;
  -webkit-mask-image: radial-gradient(90% 80% at 50% 100%, #000 24%, transparent 88%);
  mask-image: radial-gradient(90% 80% at 50% 100%, #000 24%, transparent 88%); }
.services-v2__inner { display: flex; flex-direction: column; align-items: flex-start; gap: 6.4cqw; position: relative; z-index: 1; width: 100%; } /* mobile: left-aligned, label↔list 24 */
.services-v2__label { font-family: var(--font-display); font-weight: 500; font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; color: rgba(255,255,255,0.7); font-size: 3.7333cqw; } /* 14; Roboto Flex wdth55 tracked, white 0.7 (#FFFFFFB3) — matches the For Agencies eyebrow, white variant */
.services-v2__list  { display: flex; flex-direction: column; align-items: stretch; gap: 5.3333cqw; list-style: none; margin: 0; padding: 0; width: 100%; } /* mobile: rows 20 apart */
.services-v2__row   { position: relative; text-align: left; } /* ADAPTIVE accordion item (column: head + panel) */
.services-v2__row.is-open { padding-bottom: 4.2667cqw; } /* 16 below the open panel (Paper 65BC) */
/* Head = title (left) + +/- icon (right). The whole head is the service link / accordion toggle. */
.services-v2__head  { display: flex; align-items: flex-start; justify-content: space-between; gap: 4.2667cqw; width: 100%; text-decoration: none; color: inherit; cursor: pointer; }
.services-v2__title { font-size: 8.5333cqw; line-height: 80%; letter-spacing: 0.02em; text-transform: uppercase; opacity: 0.9; transition: opacity 0.4s cubic-bezier(0.22, 1, 0.36, 1);
  text-box-trim: trim-both; text-box-edge: cap alphabetic; }
/* +/- icon (adaptive only) — reuses the FAQ toggle technique: two bars, the vertical one collapses when open. */
.services-v2__icon  { position: relative; width: 4.8cqw; height: 4.8cqw; flex-shrink: 0; } /* matches .svc-faq__icon (18px @375) */
.services-v2__icon::before, .services-v2__icon::after { content: ""; position: absolute; top: 50%; left: 50%; background: #fff; transform: translate(-50%, -50%); }
.services-v2__icon::before { width: 100%; height: 1.5px; }
.services-v2__icon::after  { width: 1.5px; height: 100%; transition: transform 0.25s ease; }
.services-v2__row.is-open .services-v2__icon::after { transform: translate(-50%, -50%) scaleY(0); } /* + → - */
/* Reveal panel (adaptive: accordion grid reveal; desktop overrides to a fixed-height hover reveal). */
.services-v2__panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.3s ease; }
.services-v2__row.is-open .services-v2__panel { grid-template-rows: 1fr; }
.services-v2__panel-clip { overflow: hidden; min-height: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 5.3333cqw; } /* desc↔button 20. NO padding here — it's on .desc, so a CLOSED panel truly collapses to 0 (padding on the clipped box leaks height between closed rows). */
.services-v2__desc  { font-family: var(--font-body); font-weight: 400; line-height: 160%; opacity: 0.8; color: #fff; font-size: 3.7333cqw; align-self: stretch; padding-top: 3.2cqw; } /* 14; padding-top = title↔desc gap (lives on the inner so it collapses when closed) */
/* Solid light "view service" button (Paper 65BH/65DW): #E9E8E7, dark uppercase label, radius 4. */
.services-v2__btn   { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; gap: 2.1333cqw; border-radius: 1.0667cqw; padding: 2.6667cqw 4.2667cqw; background: #E9E8E7; text-decoration: none; }
.services-v2__btn-label { font-family: var(--font-display); font-weight: 500; font-variation-settings: "wght" 500, "wdth" 50; text-transform: uppercase; line-height: 94%; font-size: 3.2cqw; color: rgba(0,0,0,0.9); white-space: nowrap; }

@media (min-width: 640px) { /* TABLET (768) */
  .services-v2 { padding-block: 10.4167cqw; padding-inline: 4.1667cqw; }
  /* Tablet glow: shorter than mobile, same crowd-cropped framing; pushed strongly DOWN so the white-stage
     spot's centre sits on the section's bottom edge (lower half clips off). */
  .services-v2__glow { height: 100cqw; background-position: center 35%; background-size: 215% auto; transform: translateX(-50%) translateY(38cqw); }
  .services-v2__inner { gap: 4.1667cqw; }            /* 32 */
  .services-v2__label { font-size: 1.8229cqw; } /* 14 (was 12) */
  .services-v2__list  { gap: 4.1667cqw; }            /* 32 */
  .services-v2__head  { gap: 2.0833cqw; }            /* 16 */
  .services-v2__title { font-size: 7.8125cqw; }      /* 60 */
  .services-v2__icon  { width: 2.3438cqw; height: 2.3438cqw; } /* matches .svc-faq__icon tablet (18px @768) */
  .services-v2__row.is-open { padding-bottom: 2.0833cqw; } /* 16 @768 */
  .services-v2__panel-clip { gap: 2.6042cqw; } /* desc↔button 20 */
  .services-v2__desc  { font-size: 1.8229cqw; max-width: 52.0833cqw; padding-top: 1.5625cqw; } /* 14 (was 12); title↔desc gap 12 */
  .services-v2__btn   { gap: 1.0417cqw; border-radius: 0.5208cqw; padding: 1.3021cqw 2.0833cqw; }
  .services-v2__btn-label { font-size: 1.5625cqw; }
}

@media (min-width: 1024px) { /* DESKTOP (1440) — centred, hover reveal, cursor pill; accordion bits hidden */
  .services-v2 { padding-block: 8.3333cqw; padding-inline: 1.6667cqw; }
  /* Desktop glow: shorter, bottom-anchored; own cover framing + own (lower) mask — independent of the taller
     zoomed adaptive base above. Mask radius 51% sits the glow ~20% lower than the 64% it was. */
  .services-v2__glow { bottom: 0; width: 132.5cqw; /* 1908 */ height: 67.6cqw; /* 52 +30% */ transform: translateX(-50%) translateY(8.3333cqw); /* down 120 */ filter: blur(11.111cqw) saturate(1.5); /* 160 */ background-position: center top; background-size: cover;
    -webkit-mask-image: radial-gradient(78% 51% at 50% 100%, #000 28%, transparent 84%);
    mask-image: radial-gradient(78% 51% at 50% 100%, #000 28%, transparent 84%); }
  .services-v2__inner { align-items: center; gap: 2.2222cqw; } /* centred; label↔list 32 */
  .services-v2__label { font-size: 0.9722cqw; }      /* 14 (was 12) */
  .services-v2__list  { align-items: center; gap: 0; width: fit-content; } /* fit-content → list is as wide as the WIDEST row */
  .services-v2__row   { display: flex; flex-direction: column; align-items: center; text-align: center; transition: padding 0.4s cubic-bezier(0.22, 1, 0.36, 1); padding-block: 0.4167cqw; } /* centred column (title + desc centred under it); 6 top/bottom; grows on hover */
  .services-v2__row.is-open { padding-bottom: 0.4167cqw; } /* desktop ignores is-open (reveal is hover/is-active driven) — reset the adaptive default-open padding back to 6 */
  .services-v2__row.is-active { padding-top: 0.9722cqw; padding-bottom: 1.1111cqw; } /* open: 14 top (6+8 air) / 16 bottom (Paper 64QR) */
  .services-v2__head  { justify-content: center; padding-inline: 3.3333cqw; cursor: none; } /* 48 each side → equal-width, edge-to-edge hover hit area */
  .services-v2__icon  { display: none; }            /* no +/- on desktop */
  .services-v2__title { font-size: 6.1111cqw; white-space: nowrap; } /* 88 */
  /* No-jank reveal: description has a FIXED open height, so every row opens to the SAME height. activate()
     swaps .is-active in ONE tick → collapse + expand are the same delta at the same time → total list height
     never changes. Smooth ease-out, 0.4s. ⚠ This height is tied to the desc font-size (.services-v2__desc): if
     that changes, recompute = gap 12 + (max lines × font × 1.6). At 14px the descs are 2 lines. */
  .services-v2__panel { display: block; grid-template-rows: none; width: 28.0556cqw; height: 0; overflow: hidden; opacity: 0; transition: height 0.4s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.4s cubic-bezier(0.22, 1, 0.36, 1); }
  .services-v2__row.is-active .services-v2__panel { height: 3.9444cqw; opacity: 1; } /* 56.8 = 12 gap + 2×22.4 lines (14px desc, lh 160%) */
  .services-v2__panel-clip { align-items: center; gap: 0; } /* centred desc under the title; button hidden so desc only */
  .services-v2__desc  { font-size: 0.9722cqw; text-align: center; max-width: none; padding-top: 0.8333cqw; } /* 14 (was 12); title↔desc gap 12 */
  .services-v2__btn   { display: none; }            /* desktop uses the cursor View Service pill, not a button */
  /* Active title stays lit; every other row dims to 0.3. */
  .services-v2__list:has(.is-active) .services-v2__row:not(.is-active) .services-v2__title { opacity: 0.3; }
}

/* ── Section-Awards (shared) — fluid per artboard (375/768/1440), bands 640/1024.
   Two-column header (intro + 3 stat rows with dividers) on desktop; stacked <1024.
   Full-bleed marquee of award logos reuses .logos-marquee. Reuses .about-display
   (title + stat numbers) and .about-stat-label (stat labels). */

/* MOBILE (< 640) */
.awards-section { position: relative; padding-block: 16cqw; gap: 16cqw; } /* gap 60 @375 (header↔marquee); no clip: lets the 100vw marquee spill past the 1920 cap to the screen edges; header stays capped */
.awards-header  { display: flex; flex-direction: column; align-items: flex-start; gap: 12.8cqw; padding-inline: 4.2667cqw; width: 100%; }
.awards-heading { display: flex; flex-direction: column; align-items: flex-start; gap: 4.2667cqw; }
.awards-title   { font-size: 11.7333cqw; line-height: 80%; opacity: 0.9; max-width: 91.47cqw; }
.awards-sub     { font-size: 3.7333cqw; line-height: 160%; opacity: 0.8; font-family: var(--font-body); max-width: 91.47cqw; } /* 14 */
/* Stats header (alt variant: heading | 3 award numbers — shared/_awards_stats). Restored alongside the
   testimonial + no-quote variants so all three stay available in the styleguide. */
.awards-stats   { display: flex; flex-direction: column; align-items: flex-start; gap: 6.4cqw; align-self: stretch; }
.awards-stat    { display: flex; align-items: center; gap: 2.667cqw; }
.awards-stat__num   { font-size: 11.7333cqw; line-height: 90%; opacity: 0.9; min-width: 26.6667cqw; } /* 44 / 100 @375 */
.awards-stat__label { font-size: 3.2cqw; line-height: 140%; }
.awards-divider { align-self: stretch; height: 1px; background: var(--divider); }
/* Testimonial card (Paper 60M1 / 60L4 / 67SE). Mobile: single column — logo, quote (mark + text), name/role
   (the left .__col is display:contents so its logo + name/role flow as direct items, ordered around the quote).
   Desktop/tablet: two columns (logo top + name/role bottom on the left; quote on the right) split by a 1px
   divider. Quote is Geist body / sentence case (NOT the uppercase display). 1:1 per Paper. */
.awards-quote   { display: flex; flex-direction: column; align-items: flex-start; align-self: stretch; gap: 10.6667cqw; background: #181818; border-radius: 4.2667cqw; padding: 6.4cqw 4.2667cqw; } /* gap40 r16; py24 px16 @375 */
.awards-quote__col { display: contents; } /* mobile: logo + name/role become direct flex items of the card */
.awards-quote__logo { order: 1; width: 33.0667cqw; height: 9.6cqw; object-fit: contain; object-position: left; } /* 124×36 @375; no opacity — the PNG already carries its muted tone */
.awards-quote__divider { display: none; } /* mobile: no divider */
.awards-quote__body { order: 2; display: flex; flex-direction: column; align-items: flex-start; align-self: stretch; } /* mark above text */
.awards-quote__mark { font-size: 11.7333cqw; line-height: 90%; color: #fff; } /* " 44 @375 (.about-display) */
.awards-quote__text { font-family: var(--font-body); font-size: 4.2667cqw; line-height: 160%; opacity: 0.8; color: #fff; align-self: stretch; margin-top: -2.1333cqw; } /* 16 @375 Geist sentence-case; -8 pulls text up under the mark */
.awards-quote__by { order: 3; display: flex; flex-direction: column; align-items: flex-start; } /* name/role flush, no gap */
.awards-quote__name { font-family: var(--font-body); font-size: 3.7333cqw; line-height: 160%; text-transform: uppercase; color: #fff; } /* 14 Geist, uppercase */
.awards-quote__role { font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; font-size: 3.7333cqw; line-height: 140%; opacity: 0.8; color: #fff; } /* 14 */
/* compound selector (.marquee.awards-marquee) so 100vw beats the later `.marquee { width: 100% }` rule.
   100vw + the section's align-items:center → spans the full viewport (full-bleed); ≤1920 = viewport = no-op */
.marquee.awards-marquee { width: 100vw; overflow: clip; opacity: 0.7; }
/* award logos are sized exactly like the client LogosStrip (uniform height h-12/14/16) — see partial */

/* TABLET (≥ 640) */
@media (min-width: 640px) {
  .awards-section { padding-block: 10.4167cqw; gap: 10.4167cqw; } /* gap 80 @768 (was 120) */
  .awards-header  { gap: 7.8125cqw; padding-inline: 4.1667cqw; }
  .awards-heading { gap: 2.0833cqw; }
  .awards-title   { font-size: 7.8125cqw; max-width: 61.07cqw; }
  .awards-sub     { font-size: 1.8229cqw; max-width: 48.96cqw; } /* 14 (was 12) */
  .awards-stats   { gap: 3.125cqw; }
  .awards-stat    { gap: 1.302cqw; }
  .awards-stat__num   { font-size: 5.7292cqw; min-width: 13.0208cqw; }
  .awards-stat__label { font-size: 1.5625cqw; }
  .awards-quote   { flex-direction: row; align-items: flex-start; gap: 3.125cqw; min-height: 43.4896cqw; padding: 3.125cqw; border-radius: 2.0833cqw; } /* row; gap24 r16 p24; min-h334; full width @768 */
  .awards-quote__col { display: flex; flex-direction: column; justify-content: space-between; align-self: stretch; gap: 3.125cqw; width: 25.3906cqw; flex-shrink: 0; } /* logo top, name bottom; w195 */
  .awards-quote__logo { width: 16.1458cqw; height: 4.6875cqw; } /* 124×36 @768 */
  .awards-quote__divider { display: block; width: 1px; align-self: stretch; flex-shrink: 0; background: rgba(255,255,255,0.1); } /* vertical hairline */
  .awards-quote__body { flex-direction: row; align-items: flex-start; gap: 1.5625cqw; flex: 1; } /* mark left of text; gap12 */
  .awards-quote__mark { font-size: 5.7292cqw; } /* 44 */
  .awards-quote__text { font-size: 2.3438cqw; margin-top: 0; flex: 1; } /* 18; reset mobile -mt; fills the column */
  .awards-quote__name { font-size: 1.8229cqw; } /* 14 */
  .awards-quote__role { font-size: 1.8229cqw; } /* 14 */
}

/* DESKTOP (≥ 1024) — heading | stats side by side */
@media (min-width: 1024px) {
  .awards-section { padding-block: 8.3333cqw; gap: 8.3333cqw; }
  .awards-header  { flex-direction: row; align-items: flex-start; justify-content: space-between; gap: 1.6667cqw; padding-inline: 3.3333cqw; } /* side padding 48 @1440 */
  .awards-heading { gap: 1.1111cqw; justify-content: center; flex: 1; max-width: 45.833cqw; }
  /* No-quote variant: heading + sub centred on desktop only (block centred via the header, text centred
     within). Tablet/mobile keep the shared left-aligned layout. */
  .awards--centered .awards-header  { justify-content: center; }
  .awards--centered .awards-heading { align-items: center; text-align: center; }
  .awards-title   { font-size: 6.1111cqw; max-width: 37.917cqw; }
  .awards-sub     { font-size: 1.1111cqw; max-width: 26.111cqw; } /* 16 */
  .awards-stats   { gap: 1.6667cqw; flex: 1; }
  .awards-stat    { gap: 0.6944cqw; }
  .awards-stat__num   { font-size: 3.0556cqw; min-width: 6.9444cqw; }
  .awards-stat__label { font-size: 0.8333cqw; }
  .awards-quote   { flex: 1; gap: 1.6667cqw; min-height: 23.1944cqw; padding: 1.6667cqw; border-radius: 1.1111cqw; } /* row; gap24 r16 p24; min-h334; fills the right portion */
  .awards-quote__col { width: 14.0972cqw; gap: 1.6667cqw; } /* w203; logo↔name 24 */
  .awards-quote__logo { width: 8.6111cqw; height: 2.5cqw; } /* 124×36 @1440 */
  .awards-quote__body { gap: 0.8333cqw; } /* mark↔text 12 */
  .awards-quote__mark { font-size: 3.0556cqw; } /* 44 */
  .awards-quote__text { font-size: 1.25cqw; } /* 18 */
  .awards-quote__name { font-size: 0.9722cqw; } /* 14 */
  .awards-quote__role { font-size: 0.9722cqw; } /* 14 */
}
/* ── Section-BlogPreview (shared) — fluid per artboard (375/768/1440), bands 640/1024.
   "Insights" heading + 3 article cards (3-col desktop, stacked <1024) + See-all CTA.
   Everything scales per-band vw (mobile/375, tablet/768, desktop/1440); reuses .about-display. */
.blog-preview        { gap: 12.8cqw; padding-block: 16cqw; padding-inline: 4.2667cqw; }
.blog-preview__title { font-size: 11.7333cqw; line-height: 80%; opacity: 0.9; }
.blog-preview__cards { display: flex; flex-direction: column; align-items: stretch; gap: 16cqw; align-self: stretch; }

/* Card internals: EVERYTHING scales per-band vw (mobile/375, tablet/768, desktop/1440), even
   values that are identical across all three artboards (title 24, dek 12, chip 32/16/12, radii 8/4,
   widths 272/324, gaps 24/12). Same px on every artboard does NOT mean fixed — each band still
   anchors that px at its control width and scales it with the viewport. Base = mobile (/375). */
.blog-card        { gap: 6.4cqw; text-decoration: none; color: inherit; position: relative; }
.blog-card__cover { position: relative; aspect-ratio: 16 / 9; border-radius: 2.1333cqw; overflow: clip; align-self: stretch; }
.blog-card__cover img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; transform: scale(1.02); } /* scale 1.02 (parent clips) kills any sub-pixel edge strip — same recipe as .gallery-media */
.blog-card__tags { position: absolute; top: 3.2cqw; left: 3.2cqw; z-index: 2; display: flex; align-items: center; gap: 2.1333cqw; } /* category glass tag on the cover top-left; 12 inset @375 */
.blog-chip {
  position: absolute; left: 3.2cqw; top: 3.2cqw;
  display: inline-flex; align-items: center;
  height: 8.5333cqw; padding: 0 4.2667cqw; border-radius: 1.0667cqw;
  background: rgba(0, 0, 0, 0.07);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  font-family: var(--font-display); font-weight: 500; font-variation-settings: "wght" 500, "wdth" 50;
  text-transform: uppercase; font-size: 3.2cqw; line-height: 93.7%; color: #fff; white-space: nowrap;
}
.blog-card__text  { gap: 3.2cqw; }
.blog-card__cats  { display: flex; align-items: flex-start; flex-wrap: wrap; gap: 3.2cqw; } /* 12 — category tags (out of the photo) */
.blog-card__cat   { font-family: var(--font-display); font-weight: 500; font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; color: rgba(255,255,255,0.7); font-size: 3.2cqw; white-space: nowrap; } /* 12 */
.blog-card__title { font-size: 6.4cqw; line-height: 90%; opacity: 0.9; max-width: 72.5333cqw; color: #fff; }
.blog-card__dek   { font-size: 3.7333cqw; line-height: 160%; opacity: 0.7; font-family: var(--font-body); font-weight: 500; max-width: 86.4cqw; color: #fff; } /* 14 */
.blog-card__foot  { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; align-self: stretch; } /* pins the meta to the card bottom */
.blog-card__meta  { display: flex; align-items: center; justify-content: flex-start; flex-wrap: wrap; gap: 2.4cqw; opacity: 0.6; } /* author · date · read-time, all left, dot-separated; 9 */
.blog-card__meta span { font-family: var(--font-display); font-weight: 500; font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; font-size: 3.2cqw; line-height: 140%; color: #fff; white-space: nowrap; }
.blog-card__dot   { width: 1.0667cqw; height: 1.0667cqw; border-radius: 50%; background: #fff; flex-shrink: 0; }

/* Tablet band (640–1023) → /768. */
@media (min-width: 640px) {
  .blog-preview        { gap: 7.8125cqw; padding-block: 10.4167cqw; padding-inline: 4.1667cqw; }
  .blog-preview__title { font-size: 7.8125cqw; }
  .blog-preview__cards { gap: 7.8125cqw; }
  .blog-card        { gap: 3.125cqw; }
  .blog-card__cover { border-radius: 1.0417cqw; }
  .blog-card__tags { top: 1.5625cqw; left: 1.5625cqw; gap: 1.0417cqw; } /* 12 inset @768 */
  .blog-chip        { left: 1.5625cqw; top: 1.5625cqw; height: 4.1667cqw; padding: 0 2.0833cqw; border-radius: 0.5208cqw; font-size: 1.5625cqw; }
  .blog-card__text  { gap: 1.5625cqw; }
  .blog-card__cats  { gap: 1.5625cqw; } /* 12 */
  .blog-card__cat   { font-size: 1.5625cqw; } /* 12 */
  .blog-card__title { font-size: 3.125cqw; max-width: 35.4167cqw; }
  .blog-card__dek   { font-size: 1.8229cqw; max-width: 42.1875cqw; } /* 14 (was 12) */
  .blog-card__meta  { gap: 1.1719cqw; }
  .blog-card__meta span { font-size: 1.8229cqw; } /* 14 (was 12) — author · date · read-time */
  .blog-card__dot   { width: 0.5208cqw; height: 0.5208cqw; }
}
/* Desktop band (≥1024) → /1440. */
@media (min-width: 1024px) {
  .blog-preview        { gap: 5.5556cqw; padding-block: 8.3333cqw; padding-inline: 1.6667cqw; }
  .blog-preview__title { font-size: 6.1111cqw; }
  .blog-preview__cards { flex-direction: row; align-items: stretch; gap: 1.6667cqw; } /* equal-height cards → meta aligns at bottom */
  .blog-card           { flex: 1; min-width: 0; gap: 1.6667cqw; }
  .blog-card__cover { border-radius: 0.5556cqw; }
  .blog-card__tags { top: 0.8333cqw; left: 0.8333cqw; gap: 0.5556cqw; } /* 12 inset @1440 */
  .blog-chip        { left: 0.8333cqw; top: 0.8333cqw; height: 2.2222cqw; padding: 0 1.1111cqw; border-radius: 0.2778cqw; font-size: 0.8333cqw; }
  .blog-card__text  { gap: 0.8333cqw; }
  .blog-card__cats  { gap: 0.8333cqw; } /* 12 */
  .blog-card__cat   { font-size: 0.8333cqw; } /* 12 */
  .blog-card__title { font-size: 1.6667cqw; max-width: 18.8889cqw; }
  .blog-card__dek   { font-size: 0.9722cqw; max-width: 22.5cqw; } /* 14 (was 12) */
  .blog-card__meta  { gap: 0.625cqw; }
  .blog-card__meta span { font-size: 0.9722cqw; } /* 14 (was 12) — author · date · read-time */
  .blog-card__dot   { width: 0.2778cqw; height: 0.2778cqw; }
}

/* Cursor-following pill positioning (card_hover_controller moves it to the cursor; the glass
   styling comes from .glass-pill on the same element). Shared by the project-card "View
   Project", Services "View Service" and blog-card "View Article" pills — one DS hover pattern.
   HOVER-ONLY: a hover affordance must never appear on adaptive/touch (tablet + mobile). Gate by
   WIDTH (≥1024 = desktop), NOT by hover/pointer media queries (Arc desktop misreports them). */
.cursor-pill {
  display: none; /* hidden on tablet/mobile (<1024); the tap interaction still swaps content */
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, -50%);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s ease;
  z-index: 5;
}
@media (min-width: 1024px) { .cursor-pill { display: inline-flex; } } /* desktop only */

/* TABLET band (≥ 640) — 768 artboard × viewport */
@media (min-width: 640px) {
  .featured-case      { gap: 7.8125cqw; padding-block: 10.4167cqw; padding-inline: 4.1667cqw; }
  .featured-heading   { width: 70.7031cqw; gap: 2.0833cqw; }
  .featured-title     { font-size: 7.8125cqw; width: 47.3958cqw; }
  .featured-sub       { font-size: 1.8229cqw; width: 38.2813cqw; } /* 14 (was 12) */
  .featured-scroll    { gap: 7.8125cqw; }

  .featured-card           { gap: 4.1667cqw; }
  .featured-card__photo    { aspect-ratio: 704 / 391; border-radius: 1.0417cqw; }
  .featured-card__services { top: 1.5625cqw; left: 1.5625cqw; gap: 1.0417cqw; } /* 12 inset, 8 gap @768 */
  .featured-card__body     { gap: 4.1667cqw; }
  .featured-card__content  { gap: 2.0833cqw; } /* 16 */
  .featured-card__cats     { gap: 1.5625cqw; } /* 12 */
  .featured-card__cats .featured-card__cat { font-size: 1.3021cqw; } /* 10 */
  .featured-card__titleblock { gap: 1.5625cqw; }
  .featured-card__title    { font-size: 5.7292cqw; }
  .featured-card__desc     { font-size: 1.8229cqw; max-width: 60.8073cqw; } /* 14; width capped to match .proj-card__desc (Projects page cards) on tablet */
  .featured-card__stat     { gap: 2.0833cqw; }
  .featured-card__stat-num { font-size: 5.7292cqw; }
  .featured-card__stat-label.about-stat-label { font-size: 1.8229cqw; width: 33.8542cqw; } /* 14 (was 12); compound beats .about-stat-label. w260 @768 */
}

/* DESKTOP band (≥ 1024) — 1440 artboard × viewport, uncapped above 1440 */
@media (min-width: 1024px) {
  .featured-case      { gap: 5.5556cqw; padding-block: 8.3333cqw; padding-inline: 1.6667cqw; }
  .featured-heading   { width: 37.7083cqw; gap: 1.1111cqw; }
  .featured-title     { font-size: 6.1111cqw; width: 25.2778cqw; }
  .featured-sub       { font-size: 1.1111cqw; width: 20.4167cqw; } /* 16 */
  .featured-stack     { gap: 1.6667cqw; }
  .featured-scroll    { width: 53.75cqw; flex-shrink: 0; gap: 1.6667cqw; }

  /* sticky left panel shows; the scroll cards drop their body (cloned into the panel) */
  /* ~160px above the text block, KPI stat pinned 48px from the bottom (space-between fills the gap) */
  .featured-sticky    { display: flex; position: sticky; top: 8.3333cqw; align-self: flex-start; flex: 1; height: calc(100vh - 11.6667cqw); } /* 120 top / 168 (120+48) @1440 */
  .featured-panel     { height: 100%; }
  .featured-scroll .featured-card__body { display: none; }

  .featured-card__photo    { aspect-ratio: 774 / 464; border-radius: 0.5556cqw; }
  .featured-card__services { top: 0.8333cqw; left: 0.8333cqw; gap: 0.5556cqw; } /* 12 inset, 8 gap @1440 */
  /* Sync with the sticky panel: only the active card's photo is full opacity; the rest dim. Scroll column
     only (not project listings). featured_case_controller toggles .is-active on the active card. */
  .featured-scroll .featured-card__photo,
  .featured-scroll .featured-card__services .ds-tag { opacity: 0.3; transition: opacity 0.5s ease; } /* dim the photo + the tags. Opacity ON the .ds-tag (which carries the backdrop-filter), NOT its wrapper — a wrapper opacity<1 forms a group and the tag's blur loses its backdrop. On the tag itself the backdrop is sampled before opacity composits, so the blur survives. */
  .featured-scroll .featured-card.is-active .featured-card__photo,
  .featured-scroll .featured-card.is-active .featured-card__services .ds-tag { opacity: 1; }
  /* sticky panel: text block pinned top, stat pinned bottom-left (48px insets via the section padding + panel height) */
  .featured-card__body     { height: 100%; justify-content: space-between; gap: 0; }
  .featured-card__content  { gap: 1.1111cqw; max-width: 27.2222cqw; } /* 16 — meta ↔ title; text container ~392px @1440 */
  .featured-card__cats     { gap: 0.8333cqw; } /* 12 */
  .featured-card__cats .featured-card__cat { font-size: 0.6944cqw; } /* 10 */
  .featured-card__titleblock { gap: 1.1111cqw; } /* 16 @1440 (was 32) */
  .featured-card__title    { font-size: 3.0556cqw; max-width: 23.3333cqw; } /* ~336px @1440 */
  .featured-card__desc     { font-size: 0.9722cqw; } /* 14 (was 12) */
  .featured-card__stat     { flex-direction: column; gap: 0.8333cqw; }
  .featured-card__stat-num { font-size: 4.1667cqw; }
  .featured-card__stat-label.about-stat-label { font-size: 0.9722cqw; width: 18.0556cqw; } /* 14; w260 @1440 — compound selector beats the later .about-stat-label on the same element */
  .featured-cta            { align-self: stretch; width: 100%; }
}

/* MOBILE band (< 640) — 375 artboard × viewport. value_vw = px / 375 × 100 */
.about-section   { padding-block: 16cqw; gap: 12.8cqw; }       /* py 60 / gap 48 @375 */
.about-statement { font-size: 7.4667cqw; line-height: 100%; width: 91.4667cqw; } /* 28 / 343 @375 */
/* CMS line break (cms_text hide_br_on_mobile): the client's <br> applies on tablet+, dropped on mobile so a
   narrow column never orphans a word. reveal="lines" respects the display:none break. Mirrors the old hidden-md:block. */
.cms-br-mobile-hide { display: none; }
@media (min-width: 640px) { .cms-br-mobile-hide { display: block; } }
.about-stats     { width: 91.4667cqw; row-gap: 8.5333cqw; }    /* 343 / 32 @375 (stacked) */
.about-stat      { gap: 2.6667cqw; }                          /* 10 @375 */
.about-stat-num  { font-size: 11.7333cqw; line-height: 90%; } /* 44 @375 */
.about-stat-label{ font-size: 3.2cqw; }                       /* 12 @375 */

/* TABLET band (≥ 640) — 768 artboard × viewport. value_vw = px / 768 × 100 */
@media (min-width: 640px) {
  .about-section   { padding-block: 10.4167cqw; gap: 7.8125cqw; } /* py 80 / gap 60 @768 */
  .about-statement { font-size: 5.7292cqw; line-height: 90%; width: 96cqw; } /* 44 @768; width pushed 704→~737 (96cqw, ~2% gutter each side) — max before overflow (+30% would exceed the screen, per request) */
  .about-stats     { width: 91.6667cqw; row-gap: 0; }         /* 704 @768 (3-col row) */
  .about-stat      { gap: 1.3021cqw; }                        /* 10 @768 */
  .about-stat-num  { font-size: 5.7292cqw; }                  /* 44 @768 */
  .about-stat-label{ font-size: 1.5625cqw; }                  /* 12 @768 */
}

/* DESKTOP band (≥ 1024) — 1440 artboard × viewport, uncapped. value_vw = px / 1440 × 100 */
@media (min-width: 1024px) {
  .about-section   { padding-block: 8.3333cqw; gap: 5.5556cqw; } /* py 120 / gap 80 @1440 */
  .about-statement { font-size: 4.1667cqw; width: 83.2cqw; }  /* 60 @1440; width 64cqw +30% per request (~1198px @1440). Font + width both scale by cqw, capped at 1920. Re-check the manual <br> breaks don't self-wrap at the new width. */
  .about-stats     { width: 44.7222cqw; }                     /* 644 @1440 */
  .about-stat      { gap: 0.6944cqw; }                        /* 10 @1440 */
  .about-stat-num  { font-size: 3.0556cqw; }                  /* 44 @1440 */
  .about-stat-label{ font-size: 0.8333cqw; }                  /* 12 @1440 */
}

/* ── Seamless marquee (Section-LogosStrip, Section-Awards) ───────────────────
   TWO identical .marquee__group tracks side by side; each animates translateX(0 → -100%)
   of its OWN width, so the loop is pixel-exact (no -50% sub-pixel jump). marquee_controller
   sets --marquee-duration = groupWidth / speed so the px/sec speed is consistent. Each
   group must be ≥ the viewport (render enough copies) so no empty gap appears. */
@keyframes marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-100%); }
}
.marquee { display: flex; width: 100%; overflow: hidden; }
.marquee--light { opacity: 0.7; mix-blend-mode: difference; } /* light surface (About): inverts the white logos to dark, same as Paper */
.marquee__group {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  animation: marquee var(--marquee-duration, 40s) linear infinite;
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
  .marquee__group { animation: none; }
}

/* Marquee logos — fluid per artboard (375/768/1440), bands 640/1024, so they scale with the
   viewport like the rest of the site (height 48/56/64; client gap 48/56/64; award gap ×1.5). */
.marquee-logo         { height: 12.8cqw; width: auto; flex-shrink: 0; object-fit: contain; margin-right: 9.6cqw; } /* gap 36 @375 (48 −25%) */
/* Awards logos share the Clients logo styling EXACTLY — same height + same gap (the base margin-right, which
   neither overrides). One rule for both so they can never drift. Images still come from each section's own CMS. */
.marquee-logo--clients,
.marquee-logo--awards  { height: 11.52cqw; }   /* 43.2 @375 */
@media (min-width: 640px) {
  .marquee-logo         { height: 7.292cqw; margin-right: 7.292cqw; }
  .marquee-logo--clients,
  .marquee-logo--awards { height: 6.5628cqw; } /* 50.4 @768 */
}
@media (min-width: 1024px) {
  .marquee-logo         { height: 4.4444cqw; margin-right: 4.4444cqw; }
  .marquee-logo--clients,
  .marquee-logo--awards { height: 4cqw; } /* 57.6 @1440 */
}

/* ── Section-ContactCTA (shared) — "Work with us". Fluid per artboard (375/768/1440), bands 640/1024.
   Desktop: cursor-follow "contact us" pill on hover over the headline (card-hover + .cursor-pill — hidden
   <1024); adaptive: a static .contact-cta__btn instead. Reuses .about-display (title) + .about-stat-label
   (sub). .contact-cta__gl is a reserved layer for a future WebGL colour-flow background (plain base now). */

/* MOBILE (< 640) — /375 */
.contact-cta {
  /* Mobile/tablet: normal flow — the footer just scrolls after it (no sticky). Desktop only: full-screen
     sticky reveal with the footer scrolling over it (see @1024). */
  position: relative; overflow: clip; background: #0B0B0B;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding-block: 42.6667cqw; padding-inline: 4.2667cqw; /* mobile EXCEPTION: no fixed height, 160 top/bottom */
}
.contact-cta__gl      { position: absolute; inset: 0; z-index: 0; pointer-events: none; } /* future WebGL canvas mounts here */
.contact-cta__content { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; gap: 6.4cqw; }
.contact-cta__group   { display: flex; flex-direction: column; align-items: center; gap: 4.2667cqw; }
.contact-cta__headline { position: relative; display: inline-block; text-decoration: none; color: inherit; }
.contact-cta__title   { font-size: 16cqw; line-height: 80%; opacity: 0.9; max-width: 69.0667cqw; text-align: center; }
.contact-cta__sub     { font-size: 3.7333cqw; text-align: center; max-width: 82.4cqw; color: rgba(255, 255, 255, 0.8); } /* 14 @375 (was 12 — unified to 14 mobile like the other section subtitles). 0.8 overrides about-stat-label's 0.70 */
/* The CTA is the shared button component (.contact-cta__cta = the rendered button); only its
   desktop visibility is overridden here (desktop uses the hover pill instead). */

/* TABLET (≥ 640) — /768 */
@media (min-width: 640px) {
  .contact-cta        { min-height: 58.3333cqw; padding-block: 15.625cqw; padding-inline: 4.1667cqw; }
  .contact-cta__content { gap: 3.125cqw; }
  .contact-cta__group { gap: 2.0833cqw; }
  .contact-cta__title { font-size: 11.4583cqw; max-width: 91.6667cqw; }
  .contact-cta__sub   { font-size: 1.8229cqw; max-width: 41.6667cqw; } /* 14 (was 12) */
}

/* DESKTOP (≥ 1024) — /1440, uncapped */
@media (min-width: 1024px) {
  /* Desktop sticky reveal: full-screen, pins to the top, footer scrolls over it. */
  .contact-cta        { position: sticky; top: 0; z-index: 0; height: 100vh; height: 100dvh; padding-block: 8.3333cqw; padding-inline: 11.25cqw; }
  .contact-cta__content { gap: 1.6667cqw; }
  .contact-cta__group { gap: 1.1111cqw; }
  .contact-cta__title { font-size: 11.1111cqw; max-width: 64.1667cqw; transition: transform 0.525s cubic-bezier(0.4, 0, 0.2, 1); transform-origin: center; will-change: transform; } /* desktop only */
  /* Hover: headline grows 160 → 172 (scale 1.075) smoothly. transform (not font-size) so there's no reflow /
     line-break shift. `.is-hovered` is toggled by the hover-grow controller (real mouse only, ≥1024) — NOT
     CSS :hover, which sticks on a touch TAP and leaked the effect onto tablet/mobile. */
  .contact-cta__headline.is-hovered .contact-cta__title { transform: scale(1.05); } /* 160 → 168 */
  .contact-cta__sub   { font-size: 1.1111cqw; max-width: none; } /* 16 */
  .contact-cta__cta   { display: none; } /* desktop uses the cursor-follow hover pill instead */
}

/* Contact hover pill = light translucent variant of .glass-pill (white 20% + blur), black Geist Mono label. */
.glass-pill--contact { background: rgba(255, 255, 255, 0.2); }
.glass-pill--contact .glass-pill__label { color: #000; font-family: var(--font-mono); }

/* ── Site footer (shared) — fluid per artboard (375/768/1440), bands 640/1024.
   Desktop (≥1024): 100vh; logo|columns row at top, newsletter|legal row at bottom, space-between.
   Tablet (640–1023): auto height, logo above 3 columns, newsletter above legal (stacked).
   Mobile (<640): auto height, columns stacked, legal stacked. The 1px divider stays fixed (hairline). */

/* MOBILE (< 640) — /375 */
.site-footer        { position: relative; display: flex; flex-direction: column; background: #0B0B0B; padding: 8.5333cqw 4.2667cqw 8.5333cqw; gap: 12.8cqw; } /* mobile pt 32, sides 16, pb 32. Normal flow on mobile/tablet (z-index/overlay only on desktop @1024) */
/* Full-bleed dark bg to the screen edges (no gutters; also needed so the footer covers the full-bleed
   contact-cta in the gutters when it scrolls over it above 1920). Content stays capped. */
.site-footer::before { content: ""; position: absolute; top: 0; bottom: 0; left: calc(50% - 50vw); width: 100vw; background: #0B0B0B; z-index: -1; pointer-events: none; }
.site-footer__top   { display: flex; flex-direction: column; gap: 12.8cqw; align-self: stretch; }
.footer-cols        { display: flex; flex-direction: row; flex-wrap: wrap; column-gap: 0; row-gap: 8.5333cqw; align-self: stretch; } /* mobile: Company|Services row, Contact wraps below */
.footer-col         { display: flex; flex-direction: column; align-items: flex-start; gap: 3.2cqw; flex: 1 1 45%; }
.footer-col__label  { font-family: var(--font-mono); font-size: 3.2cqw; line-height: 140%; text-transform: uppercase; opacity: 0.4; color: #fff; }
.footer-link        { font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 50; font-size: 3.2cqw; line-height: 93.7%; text-transform: uppercase; color: #fff; text-decoration: none; }
.footer-link:hover  { opacity: 0.6; }

.site-footer__bottom { display: flex; flex-direction: column; gap: 8.5333cqw; align-self: stretch; }
.footer-news        { display: flex; flex-direction: column; align-items: flex-start; gap: 4.2667cqw; }
.footer-news__title { font-size: 5.3333cqw; line-height: 110%; opacity: 0.9; max-width: 57.6cqw; }
/* Email-capture field — sizes from the footer artboard (48h, radius 8, padding 15/16, glass 7%);
   state behaviour from DS · 08 Form Fields → Email Capture. States: Default (chevron 40%, inactive),
   Focus (1px white border + white caret), Filled (valid email → chevron 100% + clickable),
   Loading (input 50% + spinner), Success ("You're subscribed." + check), Error (red border + message).
   Filled/loading/success/error toggled by newsletter_controller; focus is CSS. */
.footer-email-form  { display: flex; flex-direction: column; align-items: flex-start; gap: 2.1333cqw; }
.footer-email {
  display: flex; align-items: center; justify-content: space-between; align-self: stretch;
  width: 71.7333cqw; height: 12.8cqw; border-radius: 2.1333cqw; padding: 4cqw 4.2667cqw;
  background: rgba(255, 255, 255, 0.07); backdrop-filter: blur(14.7px); -webkit-backdrop-filter: blur(14.7px);
  transition: box-shadow 0.15s ease;
}
.footer-email:focus-within { box-shadow: inset 0 0 0 1px #fff; } /* Focus — 1px white border (inset, no reflow) */
.footer-email__input { flex: 1; min-width: 0; background: transparent; border: 0; outline: none; caret-color: #fff; font-family: var(--font-body); font-size: 3.2cqw; line-height: 140%; color: #fff; text-overflow: ellipsis; }
.footer-email__input::placeholder { color: rgba(255, 255, 255, 0.4); }
.footer-email__success { display: none; flex: 1; min-width: 0; font-family: var(--font-body); font-size: 3.2cqw; line-height: 140%; color: #fff; }
.footer-email__submit { display: flex; align-items: center; justify-content: center; background: none; border: 0; padding: 0; flex-shrink: 0; color: #fff; opacity: 0.4; pointer-events: none; cursor: pointer; transition: opacity 0.15s ease; } /* Default — chevron 40%, inactive */
.footer-email__input:not(:placeholder-shown):valid ~ .footer-email__submit { opacity: 1; pointer-events: auto; } /* Filled — valid email lifts chevron to 100% + clickable */
.footer-email__icon { width: auto; height: 2.6667cqw; display: none; } /* size by height so all 3 icons match the chevron */
.footer-email__icon path, .footer-email__icon circle { vector-effect: non-scaling-stroke; } /* uniform 1.5px stroke across viewBoxes */
.footer-email__icon--chevron { display: block; } /* default visible icon */
.footer-email__message { font-family: var(--font-body); font-size: 3.2cqw; line-height: 140%; color: #FF6B6B; } /* 12 body — unified form text */
.footer-email__message[hidden] { display: none; }

/* Newsletter states (toggled on the form by newsletter_controller). */
.footer-email-form.is-loading .footer-email__input  { opacity: 0.5; }
.footer-email-form.is-loading .footer-email__submit  { opacity: 1; pointer-events: none; }
.footer-email-form.is-loading .footer-email__icon--chevron { display: none; }
.footer-email-form.is-loading .footer-email__icon--spinner { display: block; animation: footer-email-spin 0.8s linear infinite; }
.footer-email-form.is-success .footer-email__input   { display: none; }
.footer-email-form.is-success .footer-email__success { display: block; }
.footer-email-form.is-success .footer-email__submit  { opacity: 1; pointer-events: none; }
.footer-email-form.is-success .footer-email__icon--chevron { display: none; }
.footer-email-form.is-success .footer-email__icon--check   { display: block; }
.footer-email-form.is-error .footer-email { box-shadow: inset 0 0 0 1px #FF6B6B; }
@keyframes footer-email-spin { to { transform: rotate(360deg); } }

.footer-legal       { display: flex; flex-direction: column; align-items: flex-start; gap: 3.2cqw; align-self: stretch; }
.footer-copy        { font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; font-size: 2.6667cqw; line-height: 140%; text-transform: uppercase; letter-spacing: 0.1em; opacity: 0.4; color: #fff; }
.footer-legal__links { display: flex; align-items: center; gap: 4.2667cqw; }
.footer-legal__link { font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; font-size: 2.6667cqw; line-height: 140%; text-transform: uppercase; letter-spacing: 0.1em; color: #fff; text-decoration: none; white-space: nowrap; }
.footer-legal__link:hover { opacity: 0.6; }

.footer-divider     { align-self: stretch; height: 1px; background: rgba(255, 255, 255, 0.1); flex-shrink: 0; } /* 1px hairline — stays fixed */
.footer-wordmark    { width: 100%; height: auto; aspect-ratio: 139.492 / 16.1; display: block; } /* keep wordmark proportions (no horizontal stretch) */

/* TABLET (≥ 640) — /768 */
@media (min-width: 640px) {
  .site-footer        { padding: 4.1667cqw; gap: 7.8125cqw; }
  .site-footer__top   { gap: 7.8125cqw; }
  .footer-cols        { flex-wrap: nowrap; column-gap: 1.0417cqw; row-gap: 0; } /* 3 across */
  .footer-col         { flex: 1 1 0; gap: 1.5625cqw; }
  .footer-col__label  { font-size: 1.5625cqw; }
  .footer-link        { font-size: 1.5625cqw; }
  .site-footer__bottom { gap: 4.1667cqw; }
  .footer-news        { gap: 2.0833cqw; }
  .footer-news__title { font-size: 2.6042cqw; max-width: 22.9167cqw; }
  .footer-email-form  { gap: 1.0417cqw; }
  .footer-email       { width: 35.026cqw; height: 6.25cqw; border-radius: 1.0417cqw; padding: 1.9531cqw 2.0833cqw; }
  .footer-email__input, .footer-email__success { font-size: 1.5625cqw; } /* 12 */
  .footer-email__message { font-size: 1.5625cqw; } /* 12 */
  .footer-email__icon { height: 1.3021cqw; }
  .footer-legal       { flex-direction: row; align-items: center; justify-content: space-between; gap: 2.0833cqw; }
  .footer-copy        { font-size: 1.3021cqw; flex: 1; }
  .footer-legal__links { gap: 2.0833cqw; }
  .footer-legal__link { font-size: 1.3021cqw; }
}

/* DESKTOP (≥ 1024) — /1440, 100vh */
@media (min-width: 1024px) {
  .site-footer        { position: relative; z-index: 1; min-height: calc(100vh - 4.4444cqw); padding: 3.3333cqw 1.6667cqw; gap: 0; justify-content: space-between; } /* z-index 1 + opaque bg → scrolls OVER the sticky .contact-cta. Height = 100vh − header (4.4444cqw bar) so the fixed header never overlaps footer content at full scroll. */
  .site-footer__top   { flex-direction: row; justify-content: space-between; align-items: flex-start; gap: 1.6667cqw; }
  .footer-cols        { flex-direction: row; width: 44.1667cqw; gap: 1.6667cqw; flex-shrink: 0; }
  .footer-col         { gap: 0.8333cqw; }
  .footer-col__label  { font-size: 0.8333cqw; }
  .footer-link        { font-size: 0.8333cqw; }
  .site-footer__bottom { gap: 3.3333cqw; }
  .footer-news        { flex: 1; gap: 1.1111cqw; order: -1; } /* newsletter sits LEFT of the columns on desktop */
  .footer-news__title { font-size: 1.6667cqw; max-width: 15cqw; }
  .footer-email-form  { gap: 0.5556cqw; align-self: stretch; }
  .footer-email       { width: 18.6806cqw; height: 3.3333cqw; border-radius: 0.5556cqw; padding: 1.0417cqw 1.1111cqw; }
  .footer-email__input, .footer-email__success { font-size: 0.8333cqw; } /* 12 */
  .footer-email__message { font-size: 0.8333cqw; } /* 12 */
  .footer-email__icon { height: 0.6944cqw; }
  .footer-legal       { align-self: stretch; gap: 1.1111cqw; } /* full-width row: copyright left, Privacy/Terms right */
  .footer-copy        { font-size: 0.6944cqw; }
  .footer-legal__links { gap: 1.1111cqw; }
  .footer-legal__link { font-size: 0.6944cqw; }
}

/* ── Reusable WebGL backdrop (gl_backdrop_controller) — fills a positioned/clipped parent, sits
   behind content. The radial gradient is the static fallback (WebGL missing); when the shader runs
   the opaque canvas covers it. Reduced-motion renders a single static GL frame (handled in JS). */
.gl-backdrop {
  position: absolute; inset: 0; overflow: clip; pointer-events: none; z-index: 0;
  background: radial-gradient(90% 70% at 50% 100%, var(--gl-a, #3BACEA), var(--gl-b, #4D61FE) 42%, var(--gl-base, #0B0B0B) 78%);
}
.gl-backdrop__canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; opacity: 0.9; }

/* ════════════════════════════════════════════════════════════════════════════════════════════
   Site header (DS · 13 Nav Menu). Fixed overlay; fluid per artboard (375/768/1440), bands 640/1024.
   Theme: default dark (light content); .site-header--light inverts on light surfaces (instant — no
   colour animation on the nav items, kept consistent across links / logo / button / Services).
   ════════════════════════════════════════════════════════════════════════════════════════════ */
html.nav-locked { overflow: hidden; }

.site-header { position: fixed; top: 0; left: 0; right: 0; z-index: 50; color: #fff; }

/* Surface = the translucent blurred body shared by the bar + dropdown (grows on hover). */
.site-header__surface { position: relative; z-index: 2;
  background: rgba(0, 0, 0, 0.10); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
  border-bottom: 0.5px solid rgba(255, 255, 255, 0.10);
  transition: background 0.25s ease, border-color 0.25s ease; }

/* Bar (layout only — the surface carries the background) */
.site-header__bar { display: flex; align-items: center; justify-content: space-between;
  height: 17.0667cqw; padding-inline: 4.2667cqw; }
.site-header__left { display: flex; align-items: center; gap: 12.8cqw; }
.site-header__home { display: inline-flex; align-items: center; color: inherit; }
.ds-logo { display: inline-flex; align-items: center; gap: 3.7333cqw; color: inherit; }
.ds-logo__mark { width: 6.4cqw; height: auto; }
.ds-logo__wordmark { height: 3.4667cqw; width: auto; }

/* Inline nav (≥640) */
.site-header__nav { display: none; align-items: center; gap: 7.4667cqw; }
.site-header__services { display: inline-flex; align-items: center; gap: 1.0667cqw; background: none; border: 0; padding: 0; color: inherit; transition: opacity 0.2s ease; }
.site-header__caret { width: 1.6cqw; height: auto; transition: transform 0.25s ease; }
.site-header.is-services-open .site-header__caret { transform: rotate(180deg); }
.site-header__nav .ds-nav-link, .site-header__services { opacity: 0.7; }
.site-header__nav .ds-nav-link:hover, .site-header__services:hover { opacity: 1; }

.site-header__right { display: flex; align-items: center; gap: 3.2cqw; }
.site-header__cta { display: none; }
.site-header__burger { display: inline-flex; align-items: center; justify-content: center; width: 8.5333cqw; height: 8.5333cqw; background: none; border: 1px solid rgba(255, 255, 255, 0.20); border-radius: 1.0667cqw; padding: 0; color: inherit; cursor: pointer; }
.site-header__burger-icon { width: 3.7333cqw; height: auto; }
.site-header__close-icon { width: 3.7333cqw; height: auto; display: none; }
.site-header.is-drawer-open .site-header__burger-icon { display: none; }
.site-header.is-drawer-open .site-header__close-icon { display: block; }

/* Services dropdown (≥640) — animated height (grid-rows 0fr→1fr) */
.site-header__dropdown { display: none; }
.site-header__dropdown-clip { overflow: hidden; min-height: 0; }
.site-header__dropdown-grid { display: flex; gap: 0.5556cqw; background: transparent; }
.service-card { position: relative; display: flex; flex-direction: column; justify-content: space-between;
  flex: 1; min-width: 0; height: 11.1111cqw; padding: 1.6667cqw; border-radius: 0.5556cqw; background: #181818;
  gap: 0.8333cqw; text-decoration: none; color: inherit;
  transition: background-color 0.15s cubic-bezier(0.4, 0, 0.2, 1); } /* matches buttons' transition-colors (150ms) */
.service-card__title { font-size: 1.25cqw; line-height: 80%; opacity: 0.9; }
.service-card__desc { font-size: 3.7333cqw; line-height: 160%; opacity: 0.7; font-family: var(--font-body); color: #FFFFFFCC; } /* 14 mobile base (tablet/desktop overridden to 14 below) */

/* Mobile drawer (<640) */
.site-header__drawer { position: fixed; inset: 0; background: #0B0B0B; z-index: 1; overflow: clip;
  display: flex; flex-direction: column; justify-content: flex-start;
  padding: 25.6cqw 4.2667cqw 8.5333cqw; gap: 0; /* top = bar 64 + nav py-8 32; sides 16; bottom 32 */
  clip-path: inset(0 0 100% 0); transition: clip-path 0.35s ease; pointer-events: none; }
.site-header.is-drawer-open .site-header__drawer { clip-path: inset(0 0 0 0); pointer-events: auto; }
.site-header.is-drawer-open .site-header__surface { background: rgba(0, 0, 0, 0.10); border-bottom-color: transparent; } /* drawer open: dark bar, no line */
/* GL canvas 200% wide, left edge at 0 → figure centre lands on the right edge (right half clipped by
   the drawer); bottom 65%. Drawer overflow:clip + body overflow-x:clip → no horizontal scroll. */
.site-header__drawer-gl { position: absolute; left: 0; width: 200%; bottom: 0; height: 65%; z-index: 0; pointer-events: none; }
.site-header__drawer-nav { position: relative; z-index: 1; display: flex; flex-direction: column; flex: 1; }
/* Big nav rows (Projects/Blog/About) — 44px, NO dividers (updated design). */
.site-header__drawer-row { display: flex; align-items: center; justify-content: space-between; gap: 2.1333cqw;
  color: inherit; text-decoration: none; font-size: 11.7333cqw; line-height: 80%; padding-top: 2.6667cqw; padding-bottom: 2.1333cqw; }
.site-header__drawer-group { display: flex; flex-direction: column; } /* wraps Services row + sub */
.site-header__drawer-services { display: flex; align-items: center; justify-content: space-between; gap: 2.1333cqw;
  background: none; border: 0; padding: 2.6667cqw 0 2.1333cqw; color: inherit; cursor: pointer; } /* same pt/pb as the big rows → equal spacing when collapsed */
.site-header__drawer-label { display: flex; align-items: flex-start; gap: 2.1333cqw; }
.site-header__drawer-label .about-display { font-size: 11.7333cqw; line-height: 80%; }
.site-header__drawer-count { font-size: 3.2cqw; line-height: 140%; text-transform: uppercase; letter-spacing: 0.1em; color: rgba(255, 255, 255, 0.7); font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; position: relative; top: -0.8cqw; } /* nudged up ~3px to sit on the cap height */
.site-header__drawer-services .site-header__caret { width: 3.7333cqw; }
.site-header__drawer-sub { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.3s ease; } /* closed by default */
.site-header.is-services-open .site-header__drawer-sub { grid-template-rows: 1fr; }
.site-header__drawer-sub-inner { overflow: hidden; min-height: 0; } /* NO padding here — padding wouldn't collapse to 0 (caused the peek + uneven gap) */
.site-header__drawer-sublink { display: flex; align-items: center; font-size: 3.7333cqw; padding-block: 2.6667cqw; color: #fff; } /* 14 @375; py-2.5, no dividers (drawer is mobile <640 only) */
.site-header__drawer-sub-inner > :first-child { padding-top: 4.2667cqw; }   /* gap above the sub-list (inside overflow → collapses) */
.site-header__drawer-sub-inner > :last-child  { padding-bottom: 8.5333cqw; } /* gap below the sub-list (16 + 16 extra = 32 @375) */
.site-header__drawer-cta { margin-top: auto; position: relative; z-index: 1; }

/* TABLET (≥640): inline nav, dropdown = 2×2 grid */
@media (min-width: 640px) {
  .site-header__bar { height: 8.3333cqw; padding-inline: 3.125cqw; }
  .site-header__left { gap: 6.25cqw; }
  .ds-logo { gap: 1.8229cqw; }
  .ds-logo__mark { width: 3.125cqw; }
  .ds-logo__wordmark { height: 1.6927cqw; }
  .site-header__nav { display: flex; gap: 3.6458cqw; }
  .site-header__services { gap: 0.5208cqw; }
  .site-header__caret { width: 0.78125cqw; }
  .site-header__right { gap: 0; }
  .site-header__cta { display: inline-flex; }
  .site-header__burger { display: none; }
  .site-header__drawer { display: none; }
  .site-header__dropdown { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.3s ease; } /* transparent — the surface provides the blurred body; only the cards are #0B0B0B */
  .site-header.is-services-open .site-header__dropdown { grid-template-rows: 1fr; }
  .site-header__dropdown-grid { flex-wrap: wrap; gap: 1.0417cqw; padding: 1.0417cqw 3.125cqw 3.125cqw; }
  .service-card { flex: 1 1 45%; height: 23.4375cqw; padding: 3.125cqw; border-radius: 1.0417cqw; gap: 1.5625cqw; }
  .service-card__title { font-size: 3.125cqw; }
  .service-card__desc { font-size: 1.8229cqw; } /* 14 (was 12) */
}

/* DESKTOP (≥1024): dropdown = single row of 4 */
@media (min-width: 1024px) {
  .site-header__bar { height: 4.4444cqw; padding-inline: 1.6667cqw; }
  .site-header__left { gap: 3.3333cqw; }
  .ds-logo { gap: 0.9722cqw; }
  .ds-logo__mark { width: 1.6667cqw; }
  .ds-logo__wordmark { height: 0.9028cqw; }
  .site-header__nav { gap: 1.9444cqw; }
  .site-header__services { gap: 0.2778cqw; }
  .site-header__caret { width: 0.4167cqw; }
  .site-header__dropdown-grid { flex-wrap: nowrap; gap: 0.5556cqw; padding: 1.1111cqw 1.6667cqw 1.6667cqw; }
  .service-card { flex: 1 1 0; height: 12.5cqw; padding: 1.6667cqw; border-radius: 0.5556cqw; gap: 0.8333cqw; } /* height 180 (was 160) */
  .service-card:hover { background: #111111; } /* desktop-only hover (gated by the ≥1024 media block), smooth via the base transition */
  .service-card__title { font-size: 1.25cqw; }
  .service-card__desc { font-size: 0.9722cqw; } /* 14 (was 12) */
}

/* Light theme — inverts on light surfaces (desktop/tablet). Mobile drawer stays dark (no recolour). */
.site-header--light { color: #0B0B0B; }
.site-header--light .site-header__surface { background: rgba(255, 255, 255, 0.55); border-bottom-color: rgba(0, 0, 0, 0.10); }
.site-header--light .site-header__burger { border-color: rgba(0, 0, 0, 0.25); }
.site-header--light .ds-btn { background: #0B0B0B; color: #fff; }
.site-header--light .ds-btn:hover { background: #000; }

/* Mobile drawer is always a dark surface inside → force dark-theme (light) content even when the page
   section under the bar is light. Without this, dark text/logo/close-icon on the dark drawer are invisible.
   (Higher specificity than .site-header--light, so it wins while the drawer is open.) */
.site-header.is-drawer-open { color: #fff; }
.site-header.is-drawer-open .site-header__burger { border-color: rgba(255, 255, 255, 0.20); }
.site-header.is-drawer-open .ds-btn { background: #E9E8E7; color: rgba(0, 0, 0, 0.9); }
.site-header.is-drawer-open .ds-btn:hover { background: #fff; }

/* ── Section "Meet the team" (About) — light surface. Fluid per artboard (375/768/1440), bands 640/1024.
   Desktop: swap photo (left) + names list (right), Services-like hover. Tablet/mobile: card grid.
   The "view linkedin" cursor pill = light glass variant (.glass-pill--linkedin). */
.glass-pill--linkedin { background: rgba(0, 0, 0, 0.10); }
.glass-pill--linkedin .glass-pill__label { color: #000; font-family: var(--font-mono); }

/* MOBILE (< 640) — /375 */
.team-section { display: flex; flex-direction: column; align-items: flex-start; background: #fff; padding: 16cqw 4.2667cqw; gap: 8.5333cqw; position: relative; } /* mobile py 60 (was 80) */
/* Light sections: extend the white background to the screen edges (no black gutters above 1920) WITHOUT
   moving the left-aligned content — a full-bleed ::before behind everything (z-index:-1). */
.team-section::before, .wwm-section::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: calc(50% - 50vw); width: 100vw;
  background: #fff; z-index: -1; pointer-events: none;
}
.team-head { display: flex; flex-direction: column; align-items: flex-start; gap: 4.2667cqw; }
.team-head__title { font-size: 11.7333cqw; line-height: 80%; opacity: 0.9; }
.team-head__sub { font-size: 3.7333cqw; line-height: 160%; opacity: 0.8; color: #000; font-family: var(--font-body); } /* 14 */
.team-desktop { display: none; }
.team-grid { display: grid; grid-template-columns: 1fr; gap: 8.5333cqw; align-self: stretch; }
.team-card { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 5.3333cqw; text-decoration: none; color: inherit; } /* relative → positioning context for the cursor-follow "Show Bio" pill (desktop) */
.team-card--clickable { cursor: pointer; } /* whole card toggles the bio (card-hover sets cursor:none on desktop hover, where the pill takes over) */
.team-card__photo { position: relative; display: block; width: 100%; aspect-ratio: 17 / 20; border-radius: 2.1333cqw; overflow: clip; background: #1c1c1c; }
.team-card__photo > img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; display: block; transform: scale(1.02); } /* absolute inset:0 → always fills the box exactly. Direct child only, so it does NOT catch the LinkedIn icon nested in .team-card__li */
.team-card__text { display: flex; flex-direction: column; align-items: flex-start; gap: 2.1333cqw; }
.team-card__name { font-size: 11.7333cqw; line-height: 90%; }
.team-card__role { font-size: 3.2cqw; line-height: 140%; text-transform: uppercase; letter-spacing: 0.1em; color: rgba(0,0,0,0.7); font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; }

/* TABLET (≥ 640) — /768 */
@media (min-width: 640px) {
  .team-section { padding: 10.4167cqw 4.1667cqw; gap: 7.8125cqw; }
  .team-head { gap: 2.0833cqw; }
  .team-head__title { font-size: 7.8125cqw; }
  .team-head__sub { font-size: 1.8229cqw; max-width: 53.385cqw; }
  .team-grid { grid-template-columns: 1fr 1fr; gap: 3.125cqw; }
  .team-card { gap: 2.6042cqw; }
  .team-card__photo { border-radius: 1.0417cqw; }
  .team-card__text { gap: 1.0417cqw; }
  .team-card__name { font-size: 5.7292cqw; }
  .team-card__role { font-size: 1.8229cqw; }
}

/* DESKTOP (≥ 1024) — /1440 */
@media (min-width: 1024px) {
  .team-section { padding: 8.3333cqw 1.6667cqw; gap: 5.5556cqw; }
  .team-head { gap: 1.1111cqw; }
  .team-head__title { font-size: 6.1111cqw; }
  .team-head__sub { font-size: 1.1111cqw; max-width: 28.472cqw; } /* 16 */
  .team-grid { display: none; }
  .team-desktop { display: flex; align-items: flex-start; gap: 9.5833cqw; align-self: stretch; }
  .team-photo { position: sticky; top: 8.3333cqw; align-self: flex-start; width: 30cqw; height: 37.6389cqw; border-radius: 0.5556cqw; overflow: clip; flex-shrink: 0; background: #1c1c1c; } /* sticky at 120px so the photo stays visible while scrolling a long list */
  .team-photo__img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; display: block; transform: scale(1.02); }
  .team-list { flex: 1; min-width: 0; display: flex; flex-direction: column; }
  .team-row { display: flex; align-items: flex-end; gap: 1.6667cqw; padding-block: 1.3889cqw; border-bottom: 1px solid rgba(0,0,0,0.10); text-decoration: none; color: inherit; position: relative; transition: opacity 0.2s ease; }
  .team-list li:last-child .team-row { border-bottom: none; } /* no trailing underline under the last person (dynamic — follows the list length) */
  .team-row__name { flex: 1; min-width: 0; font-size: 3.0556cqw; line-height: 90%; transition: opacity 0.2s ease; }
  .team-row.is-active .team-row__name { opacity: 0.5; }
  .team-row--static { cursor: default; } /* no linkedin_url → not clickable, keep the default arrow (no text I-beam) */
  .team-row__role { flex-shrink: 0; width: 22.0833cqw; font-size: 1.6667cqw; line-height: 140%; color: rgba(0,0,0,0.7); font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; }
}

/* ── Team — GRID variant (sections/about/_02_team_grid, Paper alt 3ZXV). Same light section + .team-card
   as the swap-list version; desktop is a standard 4-column grid with a centred header. Tablet/mobile reuse
   the .team-card sizing (1 col / 2 col). Fluid per band. */
.team-section--grid .team-head { align-self: center; align-items: center; text-align: center; } /* GRID variant: header centred on EVERY band (desktop adds max-width below) */
.team-cards { display: grid; grid-template-columns: 1fr; gap: 8.5333cqw; align-self: stretch; } /* mobile 1 col */

@media (min-width: 640px) { /* tablet — 2 col (= original card grid) */
  .team-cards { grid-template-columns: 1fr 1fr; gap: 3.125cqw; }
}
@media (min-width: 1024px) { /* desktop — 5-col grid (Paper alt) + centred header */
  .team-section--grid .team-head { align-self: center; align-items: center; text-align: center; max-width: 77.5cqw; } /* 1116, centred */
  .team-cards { grid-template-columns: repeat(5, 1fr); gap: 1.6667cqw; } /* 24 — gap unchanged from 4-up */
  .team-cards .team-card { gap: 1.3889cqw; } /* 20 */
  .team-cards .team-card__photo { aspect-ratio: 159 / 200; border-radius: 0.5556cqw; } /* 318×400; r8 */
  .team-cards .team-card__text { gap: 0.5556cqw; } /* 8 */
  .team-cards .team-card__name { font-size: 3.0556cqw; } /* 44 */
  .team-cards .team-card__role { font-size: 0.9722cqw; } /* 14 (overridden to 12 in the expandable-card block below) */
}

/* ── Team GRID card — expandable bio (About, Paper 6E9R/6EA3 desktop · 6ECS/6ED4 tablet · 6EDS/6EEG mobile).
   The card is an accordion ITEM: name + a +/- toggle (reuses .svc-faq__icon, recoloured black) expands the
   bio (same grid-rows reveal as FAQ). Photo links to LinkedIn — desktop via the cursor "view linkedin" pill
   (card-hover); tablet/mobile via a square LinkedIn button top-left (no hover). Toggle + bio render only when
   a bio exists. This block is LAST in source so it wins over the .team-cards rules above at equal specificity.
   MOBILE base (÷375). */
.team-cards .team-card__photo { border-radius: 3.2cqw; } /* rounded-xl 12 @375 */
.team-card__li { position: absolute; top: 3.2cqw; left: 3.2cqw; z-index: 2; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; width: 8.5333cqw; height: 8.5333cqw; border-radius: 1.0667cqw; background: #E8E8E8; -webkit-backdrop-filter: blur(3.2cqw); backdrop-filter: blur(3.2cqw); } /* 32×32 r4, top-left 12 @375 — all breakpoints (square LinkedIn button) */
.team-card__li-icon { width: 4.2667cqw; height: 4.2667cqw; object-fit: contain; display: block; } /* 16 @375, LinkedIn glyph from Paper (6EGB-0), in a 32 button */
.team-cards .team-card__text { gap: 0; } /* head + bio; the bio's top space lives inside the clip so it collapses when closed */
.team-card__head { display: flex; flex-direction: column; align-items: flex-start; align-self: stretch; gap: 2.1333cqw; } /* 8 name-row↔role */
.team-card__name-row { display: flex; align-items: flex-start; justify-content: space-between; align-self: stretch; gap: 3.2cqw; } /* 12 */
.team-cards .team-card__name { flex: 1; min-width: 0; }
.team-card__toggle { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 6.4cqw; height: 6.4cqw; padding: 0; background: none; border: 0; cursor: pointer; } /* 24×24 box @375 */
.team-card .svc-faq__icon { width: 4.8cqw; height: 4.8cqw; } /* 18 — override the FAQ icon size */
.team-card .svc-faq__icon::before, .team-card .svc-faq__icon::after { background: #000; } /* black +/- on the light card */
.team-card.is-open .svc-faq__icon::after { transform: translate(-50%, -50%) scaleY(0); } /* + → − on open */
.team-cards .team-card__role { font-size: 3.7333cqw; } /* 14 @375 (macet tablet/mobile) */
.team-card__bio { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.3s ease; align-self: stretch; }
.team-card.is-open .team-card__bio { grid-template-rows: 1fr; }
.team-card__bio-clip { overflow: hidden; min-height: 0; }
.team-card__bio-text { padding-top: 4.2667cqw; font-family: var(--font-body); font-size: 3.7333cqw; line-height: 150%; opacity: 0.7; color: #000; } /* 16 gap (collapses when closed) + 14 bio @375 */

@media (min-width: 640px) { /* tablet ÷768 */
  .team-cards .team-card__photo { border-radius: 1.0417cqw; } /* rounded-lg 8 */
  .team-card__li { top: 1.5625cqw; left: 1.5625cqw; width: 4.1667cqw; height: 4.1667cqw; border-radius: 0.5208cqw; -webkit-backdrop-filter: blur(1.5625cqw); backdrop-filter: blur(1.5625cqw); } /* 32 r4 top-left 12 */
  .team-card__li-icon { width: 2.0833cqw; height: 2.0833cqw; } /* 16 @768 */
  .team-card__head { gap: 1.0417cqw; } /* 8 */
  .team-card__name-row { gap: 1.5625cqw; } /* 12 */
  .team-card__toggle { width: 3.125cqw; height: 3.125cqw; } /* 24 */
  .team-card .svc-faq__icon { width: 2.3438cqw; height: 2.3438cqw; } /* 18 */
  .team-cards .team-card__role { font-size: 1.8229cqw; } /* 14 */
  .team-card__bio-text { padding-top: 2.0833cqw; font-size: 1.8229cqw; } /* 16 + 14 */
}

@media (min-width: 1024px) { /* desktop ÷1440 — cursor pill instead of the button */
  .team-cards .team-card__photo { border-radius: 0.5556cqw; } /* rounded-lg 8 */
  .team-card__li { top: 0.8333cqw; left: 0.8333cqw; width: 2.2222cqw; height: 2.2222cqw; border-radius: 0.2778cqw; -webkit-backdrop-filter: blur(0.8333cqw); backdrop-filter: blur(0.8333cqw); } /* 32 r4 top-left 12 @1440 — shown on desktop too now */
  .team-card__li-icon { width: 1.1111cqw; height: 1.1111cqw; } /* 16 @1440 */
  .team-card__head { gap: 0.5556cqw; } /* 8 */
  .team-card__name-row { gap: 0.8333cqw; } /* 12 */
  .team-card__toggle { display: none; } /* desktop: +/- hidden — the hover "Show Bio" pill + whole-card click replace it */
  .team-card .svc-faq__icon { width: 1.25cqw; height: 1.25cqw; } /* 18 */
  .team-cards .team-card__role { font-size: 0.8333cqw; } /* 12 (desktop macet) */
  .team-card__bio-text { padding-top: 1.1111cqw; font-size: 0.9722cqw; } /* 16 + 14 */
}

/* ── Section-WhatWeMake (About) — capabilities preview. Fluid per Paper artboard (375/768/1440),
   bands 640/1024. Desktop = sticky tabs + swappable content; tablet/mobile = single-open accordion.
   Light surface. Base = mobile. Reuses .about-display for all titles/items, var(--font-body) for desc. */
.wwm-section { display: flex; flex-direction: column; align-items: flex-start; background: #fff; padding: 16cqw 4.2667cqw; gap: 8.5333cqw; position: relative; } /* mobile py 60 (was 80); position:relative for the full-bleed ::before bg */
.wwm-heading { font-size: 11.7333cqw; line-height: 80%; opacity: 0.9; }

/* numbers 01–04 (tabs + accordion) — Roboto Flex medium, condensed, uppercase, tracked */
.wwm-num { font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; opacity: 0.5; color: #000; font-size: 3.2cqw; flex-shrink: 0; }

/* description — body font; mobile band */
.wwm-desc { font-family: var(--font-body); color: #000; font-size: 3.7333cqw; line-height: 160%; opacity: 0.8; } /* 14 */

/* desktop tabs hidden on adaptive; accordion shown */
.wwm-desktop { display: none; }
.wwm-accordion { display: block; align-self: stretch; width: 100%; }

/* accordion (mobile band) */
.wwm-acc-item { display: flex; flex-direction: column; border-top: 1px solid rgba(0,0,0,0.10); padding-block: 6.4cqw; }
.wwm-acc-header { display: flex; align-items: flex-start; gap: 3.2cqw; width: 100%; background: none; border: 0; padding: 0; cursor: pointer; text-align: left; }
.wwm-acc-title { font-size: 9.6cqw; line-height: 80%; color: #000; }
.wwm-acc-body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.3s ease; }
.wwm-acc-item.is-open .wwm-acc-body { grid-template-rows: 1fr; }
.wwm-acc-body-clip { overflow: hidden; min-height: 0; } /* the grid item: NO padding here, so a closed row collapses to exactly 0 (was leaving residual space below the title) */
.wwm-acc-body-inner { display: flex; flex-direction: column; gap: 6.4cqw; padding-top: 6.4cqw; }
.wwm-acc-cols { display: block; }
.wwm-acc-col { flex: 1; list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.wwm-acc-row { padding-block: 2.1333cqw; font-size: 5.3333cqw; line-height: 110%; border-top: 1px solid rgba(0,0,0,0.10); color: #000; } /* pad8 @375 */
.wwm-acc-btn { margin-top: 8.5333cqw; }

/* TABLET (≥ 640) — /768 */
@media (min-width: 640px) {
  .wwm-section { padding: 10.4167cqw 4.1667cqw; gap: 7.8125cqw; }
  .wwm-heading { font-size: 7.8125cqw; }
  .wwm-num { font-size: 1.5625cqw; }
  .wwm-desc { font-size: 1.8229cqw; max-width: 62.5cqw; }
  .wwm-acc-item { padding-block: 4.1667cqw; }
  .wwm-acc-header { gap: 1.5625cqw; }
  .wwm-acc-title { font-size: 5.7292cqw; }
  .wwm-acc-body-inner { gap: 4.1667cqw; padding-top: 4.1667cqw; }
  .wwm-acc-cols { display: flex; gap: 2.0833cqw; }
  .wwm-acc-row { padding-block: 1.5625cqw; font-size: 2.6042cqw; } /* pad12 font20 */
  .wwm-acc-btn { margin-top: 4.1667cqw; }
}

/* DESKTOP (≥ 1024) — /1440. Accordion off; sticky tabs + swappable content on. */
@media (min-width: 1024px) {
  .wwm-section { padding: 8.3333cqw 1.6667cqw; gap: 5.5556cqw; }
  .wwm-heading { font-size: 6.1111cqw; }
  .wwm-num { font-size: 0.8333cqw; }
  .wwm-accordion { display: none; }
  .wwm-desktop { display: flex; align-self: stretch; width: 100%; gap: 1.6667cqw; align-items: flex-start; }

  .wwm-tabs-col { flex: 1; position: sticky; top: 8.3333cqw; align-self: flex-start; height: calc(100vh - 11.6667cqw); display: flex; flex-direction: column; justify-content: space-between; } /* 120 top / 168 (120+48) — pins the button bottom-left, mirrors .featured-sticky */
  .wwm-tabs { display: flex; flex-direction: column; gap: 0.8333cqw; }
  .wwm-tab { display: flex; align-items: flex-start; gap: 0.8333cqw; width: 100%; background: none; border: 0; padding: 0; cursor: pointer; text-align: left; }
  /* Hover/active logic (mirrors Services): the SELECTED tab is full (black), every other dims to 0.3.
     While hovering the list, the HOVERED tab is full instead and the rest (incl. the selected) dim. */
  .wwm-tab .wwm-num { width: 1.6667cqw; opacity: 0.3; transition: opacity 0.2s ease; }
  .wwm-tab__title { font-size: 4.1667cqw; line-height: 80%; opacity: 0.3; color: #000; transition: opacity 0.2s ease; }
  .wwm-tab.is-active .wwm-num        { opacity: 0.7; }
  .wwm-tab.is-active .wwm-tab__title { opacity: 0.9; }
  .wwm-tabs:hover .wwm-num           { opacity: 0.3; }
  .wwm-tabs:hover .wwm-tab__title    { opacity: 0.3; }
  .wwm-tabs:hover .wwm-tab:hover .wwm-num        { opacity: 0.7; }
  .wwm-tabs:hover .wwm-tab:hover .wwm-tab__title { opacity: 0.9; }

  .wwm-content { flex: 1; }
  .wwm-panel { display: none; }
  .wwm-panel.is-active { display: flex; flex-direction: column; gap: 2.2222cqw; } /* desc↔list 32 (was 48) */
  .wwm-desc { font-size: 0.9722cqw; line-height: 160%; opacity: 0.7; max-width: 27.986cqw; } /* 14 */
  .wwm-cols { display: flex; gap: 3.3333cqw; }
  .wwm-col { flex: 1; list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
  .wwm-item { padding-block: 0.5556cqw; font-size: 1.3889cqw; line-height: 110%; color: #000; } /* pad8 font20 (was 12/24) */
}

/* ── Section-Service · Intro (service pages) — centred statement: big headline (about-display) + a Geist
   supporting line, on the dark surface. Fluid per Paper artboard (375/768/1440), bands 640/1024. Base = mobile. */
.svc-intro { display: flex; flex-direction: column; align-items: center; padding: 16cqw 4.2667cqw; }
.svc-intro__head { display: flex; flex-direction: column; align-items: center; gap: 4.2667cqw; align-self: stretch; }
.svc-intro__title { font-size: 6.4cqw; line-height: 100%; max-width: 100%; } /* 24 @375 (Paper 5OU8) */
.svc-intro__sub { font-family: var(--font-body); font-size: 3.7333cqw; line-height: 160%; max-width: 100%; } /* 160 — matches .ds-body / the standard descriptive-text line-height */

@media (min-width: 640px) {
  .svc-intro { padding: 10.4167cqw 4.1667cqw; }
  .svc-intro__head { gap: 2.0833cqw; }
  .svc-intro__title { font-size: 4.1667cqw; line-height: 90%; max-width: 73.6979cqw; } /* 32; w566 @768 (Paper 5OOE) */
  .svc-intro__sub { font-size: 1.8229cqw; max-width: 55.7292cqw; } /* 14; w428 @768 */
}

@media (min-width: 1024px) {
  .svc-intro { padding: 8.3333cqw 11.25cqw; }
  .svc-intro__head { gap: 1.1111cqw; }
  .svc-intro__title { font-size: 3.3333cqw; /* 48 */ line-height: 90%; max-width: 56.5278cqw; /* 814 */ }
  .svc-intro__sub { font-size: 1.1111cqw; max-width: 42.5cqw; } /* 16; w612 @1440 (Paper 6JOB) */
}

/* ── DS icon button (carousel arrows) — white square + chevron, hover/active. Fluid per band (40px). */
.ds-icon-btn { display: inline-flex; align-items: center; justify-content: center; background: #fff; color: #000; border: 0; cursor: pointer; width: 8.5333cqw; height: 8.5333cqw; border-radius: 1.0667cqw; transition: background-color 0.2s ease; } /* square, sized to the standard button height (.ds-btn = 32px per band) */
.ds-icon-btn:hover { background: #E9E8E7; }
.ds-icon-btn:active { background: #D4D3D2; } /* pressed = a touch darker, stays in place (no transform — matches the standard button) */
.ds-icon-btn__icon { width: 2.1333cqw; height: auto; }
.ds-icon-btn__icon--flip { transform: rotate(180deg); }
@media (min-width: 640px) {
  .ds-icon-btn { width: 4.1667cqw; height: 4.1667cqw; border-radius: 0.5208cqw; }
  .ds-icon-btn__icon { width: 1.0417cqw; }
}
@media (min-width: 1024px) {
  .ds-icon-btn { width: 2.2222cqw; height: 2.2222cqw; border-radius: 0.2778cqw; }
  .ds-icon-btn__icon { width: 0.5556cqw; }
}

/* ── Photo Carousel (shared/_photo_carousel) — centred, infinite, draggable carousel. Active image =
   content width, neighbours peek at the edges; track is translated by the carousel controller. Fluid
   per artboard (375/768/1440), bands 640/1024. Base = mobile. Used by the Service gallery and the
   Project page. `.photo-carousel--flush` drops the vertical padding (Project stacks sections directly). */
.photo-carousel { display: flex; flex-direction: column; align-items: center; background: #0B0B0B; padding-block: 16cqw; gap: 8.5333cqw; }
.photo-carousel--flush { padding-block: 0; }

/* ── Composable gallery (shared/_gallery) — full / pair / trio rows, image-or-video cells. Replaces the carousel
   on Service + Project pages. Gaps 24 / 16 / 8 per band (rows + cells, equal). Cell aspect-ratios fix the row
   height and scale per band. Mobile (< 640) = one column. The gallery FILLS its container (width:100% + stretch,
   so it never collapses inside a flex-center section like .proj-overview); the SIDE GUTTER is provided by the
   container — the project section already pads, and the service page wraps it in .gallery-section. ── */
.gallery { display: flex; flex-direction: column; gap: 2.1333cqw; width: 100%; align-self: stretch; box-sizing: border-box; } /* 8 gap @375 */
.gallery-section { padding-inline: 4.2667cqw; } /* service-page side gutter: 16 @375 */
.gallery-row { display: grid; grid-template-columns: 1fr; gap: 2.1333cqw; } /* mobile: every row 1 col */
.gallery-cell { position: relative; overflow: clip; border-radius: 2.1333cqw; background: #1c1c1c; margin: 0; aspect-ratio: 3 / 2; } /* full/pair landscape on mobile */
.gallery-row--trio .gallery-cell { aspect-ratio: 4 / 5; } /* portrait (Instagram 1200×1500) */
.gallery-row--quad .gallery-cell { aspect-ratio: 1 / 1; } /* square — 4-up stacks to 1 col on mobile, still square */
.gallery-media { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; display: block; transform: scale(1.02); } /* cover fills the cell completely; max-width:none defeats the global img cap; scale 1.02 (cell clips) kills any sub-pixel edge — no grey strips, ever */
@media (min-width: 640px) {
  .gallery { gap: 2.0833cqw; } /* 16 gap @768 */
  .gallery-section { padding-inline: 4.1667cqw; } /* 32 @768 */
  .gallery-row { gap: 2.0833cqw; }
  .gallery-row--pair { grid-template-columns: 1fr 1fr; }
  .gallery-row--trio { grid-template-columns: 1fr 1fr 1fr; }
  .gallery-row--triowide { grid-template-columns: 1fr 1fr 1fr; }
  .gallery-row--quad { grid-template-columns: 1fr 1fr 1fr 1fr; }
  .gallery-cell { border-radius: 1.0417cqw; }
  .gallery-row--full .gallery-cell { aspect-ratio: 16 / 9; }
  .gallery-row--pair .gallery-cell { aspect-ratio: 3 / 2; }
  .gallery-row--triowide .gallery-cell { aspect-ratio: 3 / 2; } /* same landscape ratio as pair, 3 across */
  .gallery-row--quad .gallery-cell { aspect-ratio: 1 / 1; } /* square, 4 across */
  .gallery-row--trio .gallery-cell { aspect-ratio: 4 / 5; }
}
@media (min-width: 1024px) {
  .gallery { gap: 1.6667cqw; } /* 24 gap @1440 */
  .gallery-section { padding-inline: 3.3333cqw; } /* 48 @1440 */
  .gallery-row { gap: 1.6667cqw; }
  .gallery-cell { border-radius: 0.5556cqw; }
}
.photo-carousel__stage { position: relative; width: 100%; }
.photo-carousel__viewport { width: 100%; overflow: hidden; cursor: grab; touch-action: pan-y; }
.photo-carousel.is-dragging .photo-carousel__viewport { cursor: grabbing; }
.photo-carousel__track { display: flex; gap: 2.1333cqw; will-change: transform; }
.photo-carousel__slide { flex: 0 0 91.4667cqw; width: 91.4667cqw; aspect-ratio: 1116 / 620; border-radius: 2.1333cqw; overflow: hidden; background: #1c1c1c; opacity: 0.3; transition: opacity 0.3s ease; } /* side previews dimmed */
.photo-carousel__slide.is-active { opacity: 1; } /* centred slide full opacity (set by carousel controller) */
.photo-carousel__slide img { width: 100%; height: 100%; max-width: none; object-fit: cover; display: block; transform: scale(1.02); user-select: none; -webkit-user-drag: none; pointer-events: none; }
.photo-carousel__dots { display: flex; align-items: center; gap: 1.0667cqw; }
.photo-carousel__dot { width: 6.4cqw; height: 0.5333cqw; border-radius: 1px; background: rgba(255,255,255,0.10); transition: background-color 0.3s ease; }
.photo-carousel__dot.is-active { background: #fff; }
.photo-carousel__arrow { display: none; } /* no arrows anywhere: desktop = cursor prev/next pill, tablet/mobile = swipe + dots */

@media (min-width: 640px) {
  .photo-carousel { padding-block: 10.4167cqw; gap: 4.1667cqw; }
  .photo-carousel--flush { padding-block: 0; }
  .photo-carousel__track { gap: 2.0833cqw; }
  .photo-carousel__slide { flex-basis: 91.667cqw; width: 91.667cqw; border-radius: 1.0417cqw; }
  .photo-carousel__dots { gap: 0.5208cqw; }
  .photo-carousel__dot { width: 3.125cqw; height: 0.2604cqw; }
}

@media (min-width: 1024px) {
  .photo-carousel { padding-block: 8.3333cqw; gap: 2.2222cqw; }
  .photo-carousel--flush { padding-block: 0; }
  .photo-carousel__track { gap: 1.6667cqw; }
  .photo-carousel__slide { flex-basis: 77.5cqw; width: 77.5cqw; border-radius: 0.5556cqw; }
  .photo-carousel__dots { gap: 0.2778cqw; }
  .photo-carousel__dot { width: 1.6667cqw; height: 0.1389cqw; }
}

/* ── Work Showcase (shared/_work_showcase) — heading + a vertical list of relevant projects as wide
   cards (components/project_showcase_card) + a "See all" CTA. Shared by the Service page (work for
   that service) and the Project page (Similar Work). Fluid per artboard (375/768/1440), bands 640/1024. */
.work-showcase { display: flex; flex-direction: column; align-items: center; background: #0B0B0B; padding: 16cqw 4.2667cqw; gap: 10.6667cqw; }
.work-showcase__head { display: flex; flex-direction: column; align-items: center; gap: 4.2667cqw; }
.work-showcase__title { font-size: 11.7333cqw; line-height: 80%; max-width: 64cqw; } /* mobile: narrower so "Related Projects" wraps to two lines (was 91.4667 → near edge-to-edge one line) */
.work-showcase__sub { font-family: var(--font-body); font-size: 3.7333cqw; line-height: 160%; opacity: 0.8; max-width: 91.4667cqw; }
.work-showcase__list { display: flex; flex-direction: column; align-self: stretch; gap: 16cqw; }
.work-showcase__cta { align-self: stretch; }

/* project showcase card (the reusable piece) */
.proj-card { position: relative; display: flex; flex-direction: column; gap: 6.4cqw; align-self: stretch; text-decoration: none; color: inherit; }
.proj-card__media { position: relative; width: 100%; aspect-ratio: 16 / 9; border-radius: 2.1333cqw; overflow: hidden; background: #1c1c1c; }
.proj-card__media img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; transform: scale(1.02); }
.proj-card__services { position: absolute; top: 3.2cqw; left: 3.2cqw; z-index: 2; display: flex; align-items: center; gap: 2.1333cqw; } /* service pills on the image top-left; 12 inset, 8 gap @375 */
.proj-card__main { display: flex; flex-direction: column; gap: 6.4cqw; }
.proj-card__body { display: flex; flex-direction: column; align-items: flex-start; }
.proj-card__cats { display: flex; flex-wrap: wrap; align-items: center; gap: 3.2cqw; margin-bottom: 4.2667cqw; } /* pills + tags, gap 12; mb 16 = meta↔title (matches FeaturedCase) */
.proj-card__cat { font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; font-size: 2.6667cqw; color: rgba(255,255,255,0.7); white-space: nowrap; } /* 10 */
.proj-card__title { font-size: 6.4cqw; line-height: 90%; opacity: 0.9; margin-bottom: 3.2cqw; align-self: stretch; } /* mb 12 → title↔meta */
.proj-card__desc { font-family: var(--font-body); font-size: 3.7333cqw; line-height: 160%; opacity: 0.8; align-self: stretch; }
.proj-card__stat { display: flex; align-items: flex-start; gap: 4.2667cqw; }
.proj-card__stat-num { font-size: 9.6cqw; line-height: 90%; flex-shrink: 0; }
.proj-card__stat-label { font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; font-size: 3.2cqw; color: rgba(255,255,255,0.7); width: 56cqw; flex-shrink: 0; } /* 12; w210 @375 */

@media (min-width: 640px) {
  .work-showcase { padding: 10.4167cqw 4.1667cqw; gap: 7.8125cqw; }
  .work-showcase__head { gap: 2.0833cqw; }
  .work-showcase__title { font-size: 7.8125cqw; max-width: 58.3333cqw; }
  .work-showcase__sub { font-size: 1.8229cqw; max-width: 91.667cqw; } /* 14 */
  .work-showcase__list { gap: 7.8125cqw; }

  .proj-card { gap: 4.1667cqw; }
  .proj-card__media { border-radius: 1.0417cqw; }
  .proj-card__services { top: 1.5625cqw; left: 1.5625cqw; gap: 1.0417cqw; } /* 12 inset, 8 gap @768 */
  .proj-card__main { gap: 4.1667cqw; }
  .proj-card__cats { gap: 1.5625cqw; margin-bottom: 2.0833cqw; } /* gap 12; mb 16 (meta↔title) */
  .proj-card__cat { font-size: 1.3021cqw; } /* 10 */
  .proj-card__title { font-size: 5.7292cqw; margin-bottom: 1.5625cqw; } /* 12 */
  .proj-card__desc { font-size: 1.8229cqw; max-width: 60.8073cqw; } /* 14 */
  .proj-card__stat { gap: 2.0833cqw; }
  .proj-card__stat-num { font-size: 5.7292cqw; }
  .proj-card__stat-label { font-size: 1.8229cqw; width: 33.8542cqw; } /* 14; w260 @768 */
}

@media (min-width: 1024px) {
  .work-showcase { padding: 8.3333cqw 1.6667cqw; gap: 5.5556cqw; }
  .work-showcase__head { gap: 1.1111cqw; }
  .work-showcase__title { font-size: 6.1111cqw; max-width: 35cqw; }
  .work-showcase__sub { font-size: 1.1111cqw; max-width: 26.6667cqw; } /* 16 */
  .work-showcase__list { gap: 6.9444cqw; } /* 100 @1440 (card spacing) */
  .work-showcase__cta { align-self: flex-start; }

  .proj-card { flex-direction: row-reverse; align-items: center; gap: 1.6667cqw; }
  .proj-card__media { width: 45.8333cqw; aspect-ratio: 5 / 3; flex-shrink: 0; border-radius: 0.5556cqw; }
  .proj-card__services { top: 0.8333cqw; left: 0.8333cqw; gap: 0.5556cqw; } /* 12 inset, 8 gap @1440 */
  .proj-card__main { flex: 1; align-self: stretch; align-items: flex-start; justify-content: space-between; gap: 0; }
  .proj-card__body { max-width: 27.7778cqw; }
  .proj-card__cats { gap: 0.8333cqw; margin-bottom: 1.1111cqw; } /* gap 12; mb 16 (meta↔title) */
  .proj-card__cat { font-size: 0.6944cqw; } /* 10 */
  .proj-card__title { font-size: 3.0556cqw; margin-bottom: 2.2222cqw; } /* 32 → title↔desc (unified with FeaturedCase desktop) */
  .proj-card__desc { font-size: 0.9722cqw; max-width: 27.2222cqw; }
  .proj-card__stat { flex-direction: column; gap: 0.8333cqw; }
  .proj-card__stat-num { font-size: 3.0556cqw; }
  .proj-card__stat-label { font-size: 0.9722cqw; width: 18.0556cqw; font-variation-settings: "wght" 500, "wdth" 50; } /* w260 @1440 */
}

/* ── Section-Service · Capabilities — the capabilities included in THIS service, two-column list (one
   column on mobile). Items are 1px-divider rows. Fluid per artboard (375/768/1440), bands 640/1024. */
.svc-caps { display: flex; flex-direction: column; align-items: flex-start; background: #0B0B0B; padding: 16cqw 4.2667cqw; gap: 10.6667cqw; }
.svc-caps__title { font-size: 11.7333cqw; line-height: 80%; opacity: 0.9; }
.svc-caps__cols { display: flex; flex-direction: column; align-self: stretch; }
.svc-caps__col { display: flex; flex-direction: column; flex: 1; list-style: none; margin: 0; padding: 0; }
.svc-caps__item { display: flex; align-items: flex-start; padding: 2.1333cqw 0; border-bottom: 1px solid rgba(255,255,255,0.10); font-size: 5.3333cqw; line-height: 110%; } /* pad8 @375 */
/* Dividers BETWEEN tags only — no underline under the last. Mobile stacks the two columns, so only the
   very last tag drops its rule there (the left column's last stays as the seam divider). */
.svc-caps__col:last-child .svc-caps__item:last-child { border-bottom: none; }
.svc-caps__cta { align-self: flex-start; }

@media (min-width: 640px) {
  .svc-caps { padding: 10.4167cqw 4.1667cqw; gap: 7.8125cqw; }
  .svc-caps__title { font-size: 7.8125cqw; }
  .svc-caps__cols { flex-direction: row; gap: 4.1667cqw; }
  .svc-caps__item { padding: 1.5625cqw 0; font-size: 2.6042cqw; } /* pad12 font20 */
  .svc-caps__col .svc-caps__item:last-child { border-bottom: none; } /* 2 columns side by side — drop the rule under BOTH columns' last tag */
}

@media (min-width: 1024px) {
  .svc-caps { padding: 8.3333cqw 1.6667cqw; gap: 5.5556cqw; }
  .svc-caps__title { font-size: 6.1111cqw; }
  .svc-caps__cols { gap: 1.6667cqw; }
  .svc-caps__item { padding: 0.5556cqw 0 0.5556cqw; font-size: 1.3889cqw; } /* pt8 pb8 font20 (was pt12 font24) */
}

/* ── Section-Service · FAQ — left label + "FAQ" title, right accordion of Q&A. Desktop = 2 columns;
   tablet/mobile stacked. Closed by default; +/- icon (CSS) flips to – when open; answer collapses via
   grid-rows. Fluid per artboard (375/768/1440), bands 640/1024. Base = mobile. */
.svc-faq { display: flex; flex-direction: column; align-items: center; background: #0B0B0B; padding: 16cqw 4.2667cqw; gap: 10.6667cqw; }
.svc-faq__head { display: flex; flex-direction: column; align-items: flex-start; gap: 4.2667cqw; align-self: stretch; }
.svc-faq__label { font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; font-size: 3.2cqw; color: rgba(255,255,255,0.7); }
.svc-faq__title { font-size: 11.7333cqw; line-height: 80%; opacity: 0.9; }
.svc-faq__list { display: flex; flex-direction: column; align-self: stretch; }
.svc-faq__item { display: flex; flex-direction: column; border-top: 1px solid rgba(255,255,255,0.15); }
.svc-faq__item:first-child { border-top: 0; } /* no line above the first question or below the last */
/* Padding lives on the BUTTON (not the item) so the whole question row — full height — is the click target. */
.svc-faq__q { display: flex; align-items: center; justify-content: space-between; gap: 8.5333cqw; width: 100%; background: none; border: 0; padding: 6.4cqw 0; cursor: pointer; text-align: left; } /* clickable plaque: 24 top/bottom @375 (open & closed) */
.svc-faq__q-text { flex: 1; font-size: 5.3333cqw; line-height: 110%; }
.svc-faq__icon { position: relative; width: 4.8cqw; height: 4.8cqw; flex-shrink: 0; }
.svc-faq__icon::before, .svc-faq__icon::after { content: ""; position: absolute; top: 50%; left: 50%; background: #fff; transform: translate(-50%, -50%); }
.svc-faq__icon::before { width: 100%; height: 1.5px; } /* horizontal bar (the – ) */
.svc-faq__icon::after  { width: 1.5px; height: 100%; transition: transform 0.25s ease; } /* vertical bar (makes the + ) */
.svc-faq__item.is-open .svc-faq__icon::after { transform: translate(-50%, -50%) scaleY(0); } /* + → – when open */
.svc-faq__a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.3s ease; }
.svc-faq__item.is-open .svc-faq__a { grid-template-rows: 1fr; }
.svc-faq__a-clip { overflow: hidden; min-height: 0; }
.svc-faq__a-text { padding-bottom: 8.5333cqw; font-family: var(--font-body); font-size: 3.7333cqw; line-height: 160%; color: rgba(255,255,255,0.8); } /* gap above = button's bottom padding; this pad = space below the answer */
.faq-link { color: inherit; text-decoration: underline; text-underline-offset: 0.2em; } /* email in an answer — same text style, just clickable */

@media (min-width: 640px) {
  .svc-faq { padding: 10.4167cqw 4.1667cqw; gap: 7.8125cqw; }
  .svc-faq__head { gap: 2.0833cqw; }
  .svc-faq__label { font-size: 1.5625cqw; }
  .svc-faq__title { font-size: 7.8125cqw; }
  .svc-faq__q { gap: 11.4583cqw; padding-block: 3.125cqw; } /* 24 */
  .svc-faq__q-text { font-size: 2.6042cqw; } /* 20 */
  .svc-faq__icon { width: 2.3438cqw; height: 2.3438cqw; }
  .svc-faq__a-text { padding-bottom: 4.1667cqw; font-size: 1.8229cqw; max-width: 61.4583cqw; }
}

@media (min-width: 1024px) {
  .svc-faq { flex-direction: row; align-items: flex-start; justify-content: center; padding: 8.3333cqw 1.6667cqw; gap: 1.6667cqw; }
  .svc-faq__head { flex: 1; gap: 1.1111cqw; align-self: auto; }
  .svc-faq__label { font-size: 0.8333cqw; }
  .svc-faq__title { font-size: 6.1111cqw; }
  .svc-faq__list { flex: 1; align-self: auto; }
  .svc-faq__q { gap: 6.1111cqw; padding-block: 1.6667cqw; } /* 24 */
  .svc-faq__q-text { font-size: 1.3889cqw; } /* 20 */
  .svc-faq__icon { width: 1.25cqw; height: 1.25cqw; }
  .svc-faq__a-text { padding-bottom: 2.2222cqw; font-size: 0.9722cqw; max-width: 32.7778cqw; }
}

/* ── Page-Projects · Index — title + service filter tabs + sort dropdown + grid of project cards
   (reuses .proj-card). One controller (projects-filter). Fluid per artboard (375/768/1440), bands 640/1024. */
.projects-index { display: flex; flex-direction: column; align-items: center; background: #0B0B0B; padding: 32cqw 4.2667cqw 16cqw; gap: 10.6667cqw; } /* mobile top = 120px */
.projects-index__title { font-size: 11.7333cqw; line-height: 80%; opacity: 0.9; text-align: center; }
.projects-index__body { display: flex; flex-direction: column; align-self: stretch; gap: 6.4cqw; }

.projects-filter { display: flex; align-items: center; gap: 3.2cqw; align-self: stretch; }
.projects-filter__tabs { position: relative; flex: 1; min-width: 0; height: 8.5333cqw; }
.projects-filter__tabs-inner { display: flex; align-items: center; gap: 2.1333cqw; height: 100%; overflow-x: auto; scrollbar-width: none; padding-right: 12.8cqw; } /* trailing room = fade width, so the last tab clears the gradient when scrolled to the end */
.projects-filter__tabs-inner::-webkit-scrollbar { display: none; }
.projects-filter__tab { flex-shrink: 0; display: inline-flex; align-items: center; height: 8.5333cqw; padding-inline: 3.2cqw; border-radius: 1.0667cqw; border: 0; cursor: pointer; background: rgba(255,255,255,0.10); color: rgba(255,255,255,0.9); font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 50; text-transform: uppercase; font-size: 3.2cqw; line-height: 93.7%; white-space: nowrap; transition: background-color 0.2s ease, color 0.2s ease; }
.projects-filter__tab:hover { background: rgba(255,255,255,0.18); }
.projects-filter__tab:active { background: rgba(255,255,255,0.26); }
.projects-filter__tab.is-active { background: #fff; color: rgba(0,0,0,0.9); }
.projects-filter__tab.is-active:hover { background: #E9E8E7; }
.projects-filter__tab.is-active:active { background: #DADADA; }
.projects-filter__fade { position: absolute; right: 0; top: 0; height: 100%; width: 12.8cqw; pointer-events: none; background: linear-gradient(90deg, rgba(11,11,11,0), #0B0B0B); }

.projects-sort { position: relative; flex-shrink: 0; }
/* Sort control HIDDEN site-wide (Projects + Articles) — per client, not needed yet. The markup + blog-index/
   projects-filter controllers stay intact (default sort still applies); delete this one rule to restore it. */
.projects-sort { display: none; }
.projects-sort__btn { display: inline-flex; align-items: center; justify-content: center; width: 8.5333cqw; height: 8.5333cqw; border-radius: 1.0667cqw; background: transparent; border: 1px solid rgba(255,255,255,0.20); color: #fff; cursor: pointer; transition: background-color 0.2s ease, color 0.2s ease; }
.projects-sort__btn:hover { background: rgba(255,255,255,0.10); }
.projects-index.is-sort-open .projects-sort__btn { background: #fff; color: #000; }
.projects-sort__icon { width: 3.7333cqw; height: auto; }
.projects-sort__menu { position: absolute; right: 0; top: calc(100% + 2.1333cqw); min-width: 53.3333cqw; background: #1A1A1A; border: 1px solid rgba(255,255,255,0.10); border-radius: 2.1333cqw; overflow: hidden; z-index: 20; opacity: 0; visibility: hidden; transform: translateY(-6px); transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s; }
.projects-index.is-sort-open .projects-sort__menu { opacity: 1; visibility: visible; transform: translateY(0); }
.projects-sort__option { display: flex; align-items: center; justify-content: space-between; gap: 2.1333cqw; width: 100%; height: 10.6667cqw; padding-inline: 4.2667cqw; background: none; border: 0; cursor: pointer; font-family: var(--font-body); font-size: 3.2cqw; color: #fff; text-align: left; transition: background-color 0.15s ease; }
.projects-sort__option:hover { background: rgba(255,255,255,0.06); }
.projects-sort__check { width: 3.2cqw; height: auto; opacity: 0; flex-shrink: 0; }
.projects-sort__option.is-active .projects-sort__check { opacity: 1; }

.projects-grid { display: flex; flex-direction: column; align-self: stretch; gap: 16cqw; }

@media (min-width: 640px) {
  .projects-index { padding: 20.8333cqw 4.1667cqw 10.4167cqw; gap: 7.8125cqw; } /* tablet top = 160px */
  .projects-index__title { font-size: 11.4583cqw; }
  .projects-index__body { gap: 4.1667cqw; }
  .projects-filter { gap: 1.5625cqw; }
  .projects-filter__tabs { height: 4.1667cqw; }
  .projects-filter__tabs-inner { gap: 1.0417cqw; padding-right: 6.25cqw; }
  .projects-filter__tab { height: 4.1667cqw; padding-inline: 1.5625cqw; border-radius: 0.5208cqw; font-size: 1.5625cqw; }
  .projects-filter__fade { width: 6.25cqw; }
  .projects-sort__btn { width: 4.1667cqw; height: 4.1667cqw; border-radius: 0.5208cqw; }
  .projects-sort__icon { width: 1.8229cqw; }
  .projects-sort__menu { top: calc(100% + 1.0417cqw); min-width: 31.25cqw; border-radius: 1.0417cqw; }
  .projects-sort__option { height: 5.2083cqw; padding-inline: 2.0833cqw; font-size: 1.5625cqw; gap: 1.0417cqw; }
  .projects-sort__check { width: 1.5625cqw; }
  .projects-grid { gap: 7.8125cqw; }
}

@media (min-width: 1024px) {
  .projects-index { padding: 11.1111cqw 1.6667cqw 8.3333cqw; gap: 8.3333cqw; }
  .projects-index__title { font-size: 9.0278cqw; } /* 130 @1440 (was 160) */
  .projects-index__body { gap: 3.3333cqw; }
  .projects-filter { gap: 0.8333cqw; }
  .projects-filter__tabs { height: 2.2222cqw; }
  .projects-filter__tabs-inner { gap: 0.5556cqw; padding-right: 3.3333cqw; }
  .projects-filter__tab { height: 2.2222cqw; padding-inline: 0.8333cqw; border-radius: 0.2778cqw; font-size: 0.8333cqw; }
  .projects-filter__fade { width: 3.3333cqw; }
  .projects-sort__btn { width: 2.2222cqw; height: 2.2222cqw; border-radius: 0.2778cqw; }
  .projects-sort__icon { width: 0.9722cqw; }
  .projects-sort__menu { top: calc(100% + 0.5556cqw); min-width: 13.8889cqw; border-radius: 0.5556cqw; }
  .projects-sort__option { height: 2.7778cqw; padding-inline: 1.1111cqw; font-size: 0.8333cqw; gap: 0.5556cqw; }
  .projects-sort__check { width: 0.8333cqw; }
  .projects-grid { gap: 6.9444cqw; } /* 100 @1440 (card spacing) */
}

/* ── Section-Project-Hero (project detail page, /projects/:slug) — Paper 6EYR/6FRF (desktop) ·
   6F1O (tablet) · 6F2D (mobile). DESKTOP: cover fills the fold (bottom 24px above the viewport edge);
   breadcrumb overlaid top-left, tags + title overlaid bottom-left (dark scrims for legibility); summary +
   stats below on scroll. >1920 (scaling capped) the cover locks to the design ratio instead of growing
   taller. TABLET/MOBILE: cover is a fixed-height card (not stretched); crumbs above, tags + title + summary
   + stats below. Fluid per band (375/768/1440). Per-gap margins (gaps differ between consecutive items, so
   no single section `gap`). Reuses .about-display (title + stat numbers) and var(--font-body) (Geist). */
.proj-detail {
  display: flex; flex-direction: column; align-items: flex-start;
  position: relative; background: #0B0B0B;
  padding: 23.4667cqw 4.2667cqw 3.2cqw;  /* pt88 (header64+24) px16 pb12 @375 */
}
/* no overflow clip — the cover's blurred glow halo bleeds to the screen edges (dark section, gutters blend);
   horizontal page scroll stays clipped by html{overflow-x:clip} */
.proj-detail__cover-wrap { display: flex; flex-direction: column; align-items: flex-start; align-self: stretch; position: relative; }

.proj-detail__crumbs { display: flex; align-items: center; gap: 2.1333cqw; z-index: 3; } /* 8 */

/* Shared meta label: Roboto Flex medium wdth55, uppercase, 0.1em, 140%. */
.proj-detail__meta {
  font-family: var(--font-display); font-weight: 500; font-variation-settings: "wght" 500, "wdth" 55;
  text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; white-space: nowrap;
  color: #fff; font-size: 3.2cqw; /* 12 @375 */
}
.proj-detail__meta--dim { color: rgba(255, 255, 255, 0.5); } /* "/" + breadcrumb current */
.proj-detail__meta--tag { color: rgba(255, 255, 255, 0.7); } /* display tags */
.proj-detail__meta--tag, .proj-detail__meta--loc { display: inline-flex; align-items: center; height: 8.5333cqw; font-size: 2.6667cqw; } /* 10; h32 = pill height so a wrapped plain-text tag sits on its own line with even spacing (not stuck to the row above) @375 */
.proj-detail__crumb-link { transition: opacity 0.2s ease; }
.proj-detail__crumb-link:hover { opacity: 0.7; }

/* Cover: fixed-height card on m/t (NOT stretched); fills the fold on desktop. Glow = a blurred dimmed copy
   behind, bleeding out for an ambient halo (m/t only). */
.proj-detail__cover { position: relative; align-self: stretch; height: 57.0667cqw; margin-top: 6.4cqw; } /* h214; 24 crumbs↔cover @375 */
.proj-detail__cover-img { position: relative; z-index: 1; width: 100%; height: 100%; overflow: clip; border-radius: 2.1333cqw; background-size: cover; background-position: 50% 50.439%; } /* r8 */
.proj-detail__cover-media { display: block; width: 100%; height: 100%; max-width: none; object-fit: cover; transform: scale(1.02); } /* hero <video> fills the cover; scale 1.02 (parent clips) kills any edge strip */
.proj-detail__glow {
  position: absolute; z-index: 0; left: 0; right: 0; top: 8%; bottom: 8%;
  border-radius: 2.1333cqw; opacity: 0.5; pointer-events: none;
  background-size: cover; background-position: 50% 50.439%; filter: blur(9.6cqw); /* 36 @375 */
}
.proj-detail__scrim { display: none; } /* desktop only */

.proj-detail__titleblock { display: flex; flex-direction: column; align-items: flex-start; align-self: stretch; margin-top: 8.5333cqw; } /* 32 cover↔tags @375 */
.proj-detail__meta-row { display: flex; flex-wrap: wrap; align-items: center; gap: 4.2667cqw; } /* 16 = 8 + 8 extra between the services group and the tags group @375 */
.proj-detail__services, .proj-detail__tags { display: flex; flex-wrap: wrap; align-items: center; gap: 2.1333cqw; } /* 8 within each group (matches the project card) @375 */
.proj-detail__pill {
  display: inline-flex; align-items: center;
  background: rgba(255, 255, 255, 0.07); -webkit-backdrop-filter: blur(3.92cqw); backdrop-filter: blur(3.92cqw); /* 14.7 */
  font-family: var(--font-body); line-height: 160%; color: #fff; white-space: nowrap;
  height: 8.5333cqw; padding: 0 4.2667cqw; border-radius: 2.1333cqw; font-size: 3.2cqw; /* h32 px16 r8 t12 @375 */
}
.proj-detail__title { opacity: 0.9; text-transform: uppercase; letter-spacing: 0.02em; line-height: 80%; color: #fff; font-size: 11.7333cqw; margin-top: 6.4cqw; } /* 44; 24 tags↔title @375 (.about-display = axes) */

.proj-detail__summary {
  font-family: var(--font-body); opacity: 0.8; color: #fff; line-height: 160%;
  font-size: 3.7333cqw; max-width: 100%; margin-top: 5.3333cqw; /* 14; 20 title↔summary @375 */
}

.proj-detail__stats { display: flex; flex-direction: column; align-items: stretch; align-self: stretch; gap: 8.5333cqw; margin-top: 8.5333cqw; } /* mobile: stacked, 32 between; 32 summary↔stats @375 */
.proj-detail__stat { display: flex; flex-direction: column; align-items: flex-start; gap: 3.2cqw; padding-right: 3.2cqw; } /* 12 number↔label; pr12 @375 */
.proj-detail__stat-number { color: #fff; line-height: 90%; font-size: 9.6cqw; } /* 36 @375 (.about-display = axes) */
.proj-detail__stat-label { color: rgba(255, 255, 255, 0.5); white-space: normal; font-size: 3.7333cqw; max-width: 74.6667cqw; } /* 14; label max 280 @375 */

@media (min-width: 640px) { /* tablet ÷768 */
  .proj-detail { padding: 12.5cqw 4.1667cqw 1.5625cqw; } /* pt96 (header64+32) px32 pb12 */
  .proj-detail__crumbs { gap: 1.0417cqw; } /* 8 */
  .proj-detail__meta { font-size: 1.5625cqw; } /* 12 */
  .proj-detail__meta--tag, .proj-detail__meta--loc { height: 4.1667cqw; font-size: 1.3021cqw; } /* 10; h32 (matches pill) */
  .proj-detail__cover { height: 57.2917cqw; margin-top: 4.1667cqw; } /* h440; 32 crumbs↔cover */
  .proj-detail__cover-img, .proj-detail__glow { border-radius: 1.0417cqw; } /* r8 */
  .proj-detail__glow { filter: blur(9.375cqw); } /* 72 */
  .proj-detail__titleblock { margin-top: 5.2083cqw; } /* 40 cover↔tags */
  .proj-detail__meta-row { gap: 2.0833cqw; } /* 16 between groups @768 */
  .proj-detail__services, .proj-detail__tags { gap: 1.0417cqw; } /* 8 within each group @768 */
  .proj-detail__pill { height: 4.1667cqw; padding: 0 2.0833cqw; border-radius: 1.0417cqw; font-size: 1.5625cqw; -webkit-backdrop-filter: blur(1.9141cqw); backdrop-filter: blur(1.9141cqw); } /* h32 px16 r8 t12 b14.7 */
  .proj-detail__title { font-size: 7.8125cqw; margin-top: 5.2083cqw; } /* 60; 40 tags↔title */
  .proj-detail__summary { font-size: 1.8229cqw; max-width: 54.1667cqw; margin-top: 2.6042cqw; } /* 14; 416; 20 title↔summary */
  .proj-detail__stats { flex-direction: row; align-items: flex-start; gap: 1.5625cqw; margin-top: 5.2083cqw; } /* row; 12 between; 40 summary↔stats */
  .proj-detail__stat { flex: 1; gap: 2.0833cqw; padding-right: 0; } /* 16 number↔label */
  .proj-detail__stat-number { font-size: 5.7292cqw; } /* 44 */
  .proj-detail__stat-label { font-size: 1.8229cqw; max-width: 36.4583cqw; } /* 14; label max 280 */
}

@media (min-width: 1024px) { /* desktop ÷1440 — cover fills the fold; crumbs + tags + title overlaid */
  .proj-detail { padding: 6.1111cqw 1.6667cqw 0.8333cqw; } /* pt88 (header64+24) px24 pb12 */
  .proj-detail__cover-wrap {
    position: relative; align-self: stretch;
    height: calc(100dvh - 7.7778cqw); /* fold: 100dvh − header(4.4444=64) − topgap(1.6667=24) − bottomgap(1.6667=24) */
    border-radius: 0.5556cqw; overflow: clip; /* r8 */
  }
  .proj-detail__crumbs { position: absolute; top: 1.9444cqw; left: 1.9444cqw; gap: 0.5556cqw; } /* 28,28; gap8 */
  .proj-detail__meta { font-size: 0.8333cqw; } /* 12 */
  .proj-detail__meta--tag, .proj-detail__meta--loc { height: 2.2222cqw; font-size: 0.8333cqw; } /* 12; h32 (matches pill), desktop location = 12 */
  .proj-detail__cover { position: absolute; inset: 0; height: auto; margin: 0; }
  .proj-detail__cover-img { border-radius: 0; } /* the wrap clips */
  .proj-detail__glow { display: none; } /* cover fills the fold — no halo on desktop */
  .proj-detail__scrim { display: block; position: absolute; left: 0; right: 0; z-index: 2; opacity: 0.75; pointer-events: none; }
  .proj-detail__scrim--top { top: 0; height: 8.3333cqw; background: linear-gradient(180deg, rgba(10,10,10,0.9) 0%, rgba(10,10,10,0) 100%); } /* 120 */
  .proj-detail__scrim--bottom { bottom: 0; height: 16.6667cqw; background: linear-gradient(0deg, rgba(10,10,10,0.9) 0%, rgba(10,10,10,0) 100%); } /* 240 */
  .proj-detail__titleblock { position: absolute; left: 1.9444cqw; bottom: 1.9444cqw; z-index: 3; align-self: auto; margin-top: 0; width: auto; } /* 28,28 */
  .proj-detail__meta-row { gap: 1.1111cqw; } /* 16 between groups @1440 */
  .proj-detail__services, .proj-detail__tags { gap: 0.5556cqw; } /* 8 within each group @1440 */
  .proj-detail__pill { height: 2.2222cqw; padding: 0 1.1111cqw; border-radius: 0.5556cqw; font-size: 0.8333cqw; -webkit-backdrop-filter: blur(1.0208cqw); backdrop-filter: blur(1.0208cqw); } /* h32 px16 r8 t12 b14.7 */
  .proj-detail__title { font-size: 6.1111cqw; margin-top: 1.3889cqw; } /* 88; 20 tags↔title */
  .proj-detail__summary { font-size: 0.9722cqw; max-width: 39.5833cqw; margin-top: 2.7778cqw; } /* 14; 570; 40 cover↔summary */
  .proj-detail__stats { gap: 1.6667cqw; align-self: flex-start; width: 47.5cqw; margin-top: 2.7778cqw; } /* 24 between; w684; 40 summary↔stats */
  .proj-detail__stat { gap: 1.6667cqw; padding-right: 0; } /* 24 number↔label */
  .proj-detail__stat-number { font-size: 4.1667cqw; } /* 60 */
  .proj-detail__stat-label { font-size: 0.8333cqw; max-width: 19.4444cqw; } /* 12; label max 280 */
}

/* ≥1920 (cqw scale freezes here — the .page-scale container caps at 1920 with side gutters): stop growing the
   cover with viewport height. Lock it to the design ratio (1392/640) at the capped column width, so it stays a
   wide hero instead of a tall narrow crop. max-height keeps it inside the fold on short windows. */
@media (min-width: 1920px) {
  .proj-detail__cover-wrap { height: auto; aspect-ratio: 1392 / 640; max-height: calc(100dvh - 7.7778cqw); }
}

/* ── Project detail · shared text block (Overview + Result) — heading + body prose from the
   Project CMS (markdown). Fluid per band (375/768/1440), 640/1024. Heading: Roboto Flex medium
   wdth55 uppercase (no tracking). Body: Geist, white/80, 160%. gap heading↔body = 24 every band. */
.proj-textblock { display: flex; flex-direction: column; align-items: flex-start; align-self: stretch; gap: 6.4cqw; } /* 24 */
.proj-heading {
  font-family: var(--font-display);
  font-weight: 500;
  font-variation-settings: "wght" 500, "wdth" 55;
  text-transform: uppercase;
  line-height: 140%;
  color: #fff;
  font-size: 5.3333cqw; /* 20 @375 */
}
.proj-body {
  font-family: var(--font-body);
  line-height: 160%;
  color: rgba(255, 255, 255, 0.8); /* #FFFFFFCC */
  font-size: 4.2667cqw; /* 16 @375 */
  max-width: 100%;
}
.proj-body p { margin: 0; }
.proj-body p + p { margin-top: 1.6em; } /* blank-line gap between paragraphs (≈ the design <br><br>) */

/* Section-Overview wrapper — text block + the same auto-laid gallery as Section-Result (reuses .proj-result__*). */
.proj-overview { display: flex; flex-direction: column; align-items: center; background: #0B0B0B; overflow: clip; gap: 10.6667cqw; padding: 16cqw 4.2667cqw 0; } /* g40 pt60 px16 pb0 @375 — bottom 0 so Result's top padding alone is the gap (no double gap) */

/* Section-Result — text block + auto-laid photo gallery from the Project CMS (result_gallery).
   Layout rule: first photo full-width (16:9); the rest in 50/50 rows (3:2 each); a trailing odd
   photo spans full-width (16:9). Mobile: every tile stacks full-width in one column (16:9). */
.proj-result { display: flex; flex-direction: column; align-items: center; background: #0B0B0B; overflow: clip; gap: 10.6667cqw; padding: 16cqw 4.2667cqw; } /* g40 py60 px16 @375 */
.proj-result__gallery { display: flex; flex-direction: column; align-self: stretch; gap: 3.2cqw; } /* 12 */
.proj-result__row { display: flex; flex-direction: column; gap: 3.2cqw; align-self: stretch; } /* 12 — mobile stacks */
.proj-result__tile { align-self: stretch; border-radius: 2.1333cqw; overflow: hidden; background: #181818; } /* r8 */
.proj-result__tile img, .proj-result__tile video { display: block; width: 100%; height: 100%; max-width: none; object-fit: cover; transform: scale(1.02); }
.proj-result__tile--full { aspect-ratio: 16 / 9; }
.proj-result__tile--half { aspect-ratio: 16 / 9; } /* mobile: uniform full-width stack */

@media (min-width: 640px) { /* tablet ÷768 */
  .proj-textblock { gap: 3.125cqw; } /* 24 */
  .proj-heading { font-size: 3.125cqw; } /* 24 */
  .proj-body { font-size: 2.0833cqw; } /* 16 */
  .proj-overview { gap: 7.8125cqw; padding: 10.4167cqw 4.1667cqw 0; } /* g60 pt80 px32 pb0 */
  .proj-result { gap: 7.8125cqw; padding: 10.4167cqw 4.1667cqw; } /* g60 py80 px32 */
  .proj-result__gallery { gap: 2.0833cqw; } /* 16 */
  .proj-result__row { flex-direction: row; align-items: flex-start; gap: 2.0833cqw; } /* 16 — pairs side by side */
  .proj-result__tile { flex: 1; align-self: auto; border-radius: 1.5625cqw; } /* r12 */
  .proj-result__tile--half { aspect-ratio: 3 / 2; }
}

@media (min-width: 1024px) { /* desktop ÷1440 */
  .proj-textblock { gap: 1.6667cqw; } /* 24 */
  .proj-heading { font-size: 1.6667cqw; } /* 24 */
  .proj-body { font-size: 1.1111cqw; max-width: 53.75cqw; } /* 16; w-193.5=774 */
  .proj-overview { gap: 4.4444cqw; padding: 5.5556cqw 1.6667cqw 0; } /* g64 pt80 px24 pb0 */
  .proj-result { gap: 4.4444cqw; padding: 5.5556cqw 1.6667cqw 8.3333cqw; } /* g64 pt80 px24 pb120 */
  .proj-result__gallery { gap: 1.6667cqw; } /* 24 */
  .proj-result__row { gap: 1.6667cqw; } /* 24 */
  .proj-result__tile { border-radius: 0.8333cqw; } /* r12 */
}

/* ── Page Hero (shared/_page_hero) — simple centered title + uppercase subtitle, no image/animation.
   Reuses .about-display (title) + .about-stat-label (subtitle). Fluid per artboard (375/768/1440),
   bands 640/1024. Base = mobile. For Capabilities, For Agencies, Privacy, Terms, etc. */
.page-hero { display: flex; flex-direction: column; align-items: center; background: #0B0B0B; position: relative; padding: 32cqw 4.2667cqw 16cqw; } /* pt120 px16 pb60 @375; no clip → full-bleed ::before bg (inherits dark/light variant) */
.page-hero__inner { display: flex; flex-direction: column; align-items: center; align-self: stretch; gap: 4.2667cqw; } /* 16 title↔sub @375 */
.page-hero__title { color: #fff; opacity: 0.9; line-height: 80%; text-align: center; max-width: 100%; font-size: 11.7333cqw; } /* 44 @375 (.about-display = axes) */
.page-hero__sub { text-align: center; color: rgba(255,255,255,0.7); } /* dark surface; font + width from .hero-sub (single source); owns align/colour only */

/* light surface (Blog) */
.page-hero--light { background: #fff; }
/* Full-bleed background to the screen edges (no gutters above 1920) for these capped light/flex sections.
   background-color: inherit picks up each section's own colour (white for blog/page-hero-light, etc.);
   content stays capped because only the ::before bleeds. */
.blog-featured::before, .blog-index::before, .blog-newsletter::before, .page-hero::before,
.article-header::before, .article-body::before, .fa-why::before, .fa-quote::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: calc(50% - 50vw); width: 100vw;
  background-color: inherit; z-index: -1; pointer-events: none;
}
.page-hero--light .page-hero__title { color: #000; }
/* body subtitle variant (Geist sentence case, not the uppercase meta) */
.page-hero--light .page-hero__sub { color: rgba(0,0,0,0.7); } /* light surface (Blog) → dark subtitle */

/* compact variant (Blog "Compact Light") — tighter, no bottom padding; own per-band scale */
.page-hero--compact { padding: 32cqw 4.2667cqw 0; } /* pt120 px16 pb0 @375 (top matches standard page-hero) */
.page-hero--compact .page-hero__inner { gap: 4.2667cqw; } /* 16 */
/* page-hero subtitle width now unified via .hero-sub (all bands) */

@media (min-width: 640px) { /* tablet ÷768 */
  .page-hero { padding: 20.8333cqw 4.1667cqw 10.4167cqw; } /* pt160 px32 pb80 */
  .page-hero__inner { gap: 2.0833cqw; } /* 16 title↔sub @768 */
  .page-hero__title { font-size: 11.4583cqw; } /* 88 */
  .page-hero--compact { padding: 20.8333cqw 4.1667cqw 0; } /* pt160 px32 pb0 (top matches standard page-hero) */
  .page-hero--compact .page-hero__inner { gap: 2.0833cqw; } /* 16 */
}

@media (min-width: 1024px) { /* desktop ÷1440 */
  .page-hero { padding: 11.1111cqw 11.25cqw 5.5556cqw; } /* pt160 px162 pb80 */
  .page-hero__inner { gap: 1.1111cqw; } /* 16 title↔sub @1440 */
  .page-hero__title { max-width: 67.2222cqw; font-size: 9.0278cqw; } /* 968/1440; 130 @1440 (was 160) */
  .page-hero--compact { padding: 11.1111cqw 0 0; } /* pt160 px0 pb0 */
  .page-hero--compact .page-hero__inner { gap: 1.1111cqw; } /* 16 */
  .page-hero--compact .page-hero__title { max-width: 100%; } /* font inherits base scale (160) */
}

/* ── Capabilities list (sections/capabilities/01_list) — data from capabilities_helper. Desktop (≥1024):
   left sticky nav + right stacked category blocks, scroll-spy active state (capabilities-scroll). Tablet/
   mobile (<1024): single-open accordion (accordion controller). Dark surface. Reuses .about-display
   (titles/items). Fluid per artboard (375/768/1440), bands 640/1024. Base = mobile. */
.cap-list { display: block; align-self: stretch; width: 100%; background: #0B0B0B; padding: 0 4.2667cqw 16cqw; } /* mobile: no top padding, px16, pb60 */
.cap-list__desktop { display: none; }
.cap-acc { display: block; }

/* number 01–04 — Roboto Flex medium condensed, uppercase, tracked (shared nav + accordion) */
.cap-nav__num { font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; opacity: 0.5; color: #fff; font-size: 3.2cqw; flex-shrink: 0; } /* 12 */

/* description (shared) — Geist, white/70 */
.cap-desc { font-family: var(--font-body); color: rgba(255,255,255,0.7); font-size: 3.7333cqw; line-height: 160%; } /* 14 @375 */

/* item rows (shared) — about-display supplies the axes/uppercase */
.cap-col { flex: 1; list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.cap-item { padding-block: 2.1333cqw; font-size: 5.3333cqw; line-height: 110%; color: #fff; border-bottom: 1px solid rgba(255,255,255,0.10); } /* pad8 font20 @375 */

/* accordion (mobile band) */
.cap-acc__item { display: flex; flex-direction: column; border-top: 1px solid rgba(255,255,255,0.10); padding-block: 6.4cqw; } /* 24 */
.cap-acc__item:first-child { border-top: 0; } /* no line above the first category (Creative) */
.cap-acc__header { display: flex; align-items: flex-start; gap: 3.2cqw; width: 100%; background: none; border: 0; padding: 0; cursor: pointer; text-align: left; } /* 12 */
.cap-acc__title { font-size: 9.6cqw; line-height: 80%; opacity: 0.9; color: #fff; } /* 36 */
.cap-acc__body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.3s ease; }
.cap-acc__item.is-open .cap-acc__body { grid-template-rows: 1fr; }
.cap-acc__clip { overflow: hidden; min-height: 0; } /* the grid item: NO padding, so a closed row collapses to exactly 0 */
.cap-acc__inner { display: flex; flex-direction: column; gap: 6.4cqw; padding-top: 6.4cqw; } /* 24 */
.cap-acc__cols { display: block; } /* mobile: the two lists stack into one column */

@media (min-width: 640px) { /* tablet ÷768 */
  .cap-list { padding: 10.4167cqw 4.1667cqw; } /* py80 px32 */
  .cap-nav__num { font-size: 1.5625cqw; } /* 12 */
  .cap-desc { font-size: 1.8229cqw; max-width: 62.5cqw; } /* 14 */
  .cap-item { padding-block: 1.5625cqw; font-size: 2.6042cqw; } /* pad12 font20 */
  .cap-acc__item { padding-block: 4.1667cqw; } /* 32 */
  .cap-acc__header { gap: 1.5625cqw; } /* 12 */
  .cap-acc__title { font-size: 5.7292cqw; } /* 44 */
  .cap-acc__inner { gap: 4.1667cqw; padding-top: 4.1667cqw; } /* 32 */
  .cap-acc__cols { display: flex; gap: 2.0833cqw; } /* 16 — two columns */
}

@media (min-width: 1024px) { /* desktop ÷1440 — accordion off; sticky nav + scroll-spy on */
  .cap-list { padding: 8.3333cqw 1.6667cqw; } /* py120 px24 */
  .cap-acc { display: none; }
  .cap-list__desktop { display: flex; align-items: flex-start; align-self: stretch; width: 100%; gap: 1.6667cqw; } /* 24 */

  .cap-nav { flex: 1; position: sticky; top: 8.3333cqw; align-self: flex-start; display: flex; flex-direction: column; gap: 0.8333cqw; } /* top120, gap12 */
  .cap-nav__item { display: flex; align-items: flex-start; gap: 0.8333cqw; width: 100%; background: none; border: 0; padding: 0; cursor: pointer; text-align: left; } /* 12 */
  .cap-nav__num { font-size: 0.8333cqw; width: 1.6667cqw; opacity: 0.5; transition: opacity 0.2s ease; } /* 12; fixed slot 24 */
  .cap-nav__item.is-active .cap-nav__num, .cap-nav__item:hover .cap-nav__num { opacity: 0.7; }
  .cap-nav__title { font-size: 3.0556cqw; line-height: 80%; color: #fff; opacity: 0.5; transition: opacity 0.2s ease; } /* 44 */
  .cap-nav__item.is-active .cap-nav__title, .cap-nav__item:hover .cap-nav__title { opacity: 0.9; }

  .cap-blocks { flex: 1; display: flex; flex-direction: column; gap: 5.5556cqw; } /* 80 between blocks */
  .cap-block { display: flex; flex-direction: column; gap: 2.2222cqw; scroll-margin-top: 8.3333cqw; } /* desc↔list 32 (was 48); offset120 for scroll-to */
  .cap-desc { font-size: 0.9722cqw; max-width: 31.1111cqw; } /* 14; 448 */
  .cap-cols { display: flex; gap: 1.6667cqw; } /* 24 — two columns */
  .cap-item { padding-block: 0.5556cqw; font-size: 1.3889cqw; } /* pad8 font20 (was 12/24) */
}

/* ── FAQ page (sections/faq/01_list) — reuses the .cap-list shell + the .svc-faq accordion. Each desktop
   block holds a small category label (.svc-faq__label, 12 all bands) above its question accordions; on
   mobile the category accordion header is the label. Bulleted answers keep their line breaks — scoped to
   the FAQ page so the Service / For-Agencies FAQ sections (single-paragraph answers) are unaffected.
   Section padding matches the Paper FAQ macet (5RF2/5RF3/5RF4), which differs from Capabilities: mobile has
   a top pad (60) and desktop side pad is 48 (vs 24). Overrides via .faq-list keep Capabilities untouched. */
.cap-list .svc-faq__a-text { white-space: pre-line; }
.faq-list { padding: 16cqw 4.2667cqw; } /* mobile: pt60 pb60 px16 (cap-list base had pt0) */
@media (min-width: 640px)  { .faq-list { padding: 10.4167cqw 4.1667cqw; } } /* tablet: pb80 px32 */
/* FAQ hero = non-compact page-hero (matches Paper on mobile/tablet: pt120/px16/pb60 + pt160/px32/pb80),
   but with NO bottom padding on desktop. */
@media (min-width: 1024px) {
  .faq-list  { padding: 8.3333cqw 1.6667cqw; } /* desktop: pb120, side padding 24 (site-wide standard) */
  .faq-block { gap: 1.6667cqw; }               /* label ↔ questions 24 (Paper desktop; cap-block was 32) */
  .page-hero--faq { padding-bottom: 0; }
}

/* ── Section-WhyAgencies (For Agencies) — centred heading + subtitle, then 6 numbered reason cards.
   Light surface. Desktop/tablet two columns, mobile one (CSS grid). Reuses .about-display (heading +
   numbers) and var(--font-body) (Geist). Fluid per artboard (375/768/1440), bands 640/1024. Base = mobile. */
.fa-why { display: flex; flex-direction: column; background: #fff; position: relative; padding: 16cqw 4.2667cqw; gap: 10.6667cqw; } /* mobile py 60 px16 gap40 @375; no clip → full-bleed ::before bg */
.fa-why__head { display: flex; flex-direction: column; align-items: center; align-self: stretch; gap: 4.2667cqw; } /* 16 */
.fa-why__title { color: #000; opacity: 0.9; line-height: 80%; text-align: center; font-size: 11.7333cqw; max-width: 100%; } /* 44 */
.fa-why__sub { font-family: var(--font-body); color: rgba(0,0,0,0.8); line-height: 160%; text-align: center; font-size: 3.7333cqw; max-width: 100%; } /* 14 */
.fa-why__grid { display: grid; grid-template-columns: 1fr; align-self: stretch; gap: 6.4cqw; } /* mobile 1 col, gap24 */
.fa-why__card { display: flex; flex-direction: column; justify-content: space-between; gap: 6.4cqw; min-height: 60cqw; background: #F5F5F5; border-radius: 3.2cqw; padding: 7.4667cqw; } /* grey card: title+desc top, number pinned bottom; r12 p28; min-h ~225 @375 */
.fa-why__body { display: flex; flex-direction: column; align-items: flex-start; gap: 3.2cqw; } /* 12 */
.fa-why__card-title { color: #000; line-height: 110%; font-size: 6.4cqw; } /* 24; about-display = Roboto bold uppercase */
.fa-why__card-desc { font-family: var(--font-body); color: rgba(0,0,0,0.8); line-height: 160%; align-self: stretch; font-size: 3.7333cqw; } /* 14 */
.fa-why__num { color: #000; opacity: 0.1; line-height: 90%; font-size: 11.7333cqw; } /* 44, faded */

@media (min-width: 640px) { /* tablet ÷768 */
  .fa-why { padding: 15.625cqw 4.1667cqw; gap: 7.8125cqw; } /* py120 px32 gap60 */
  .fa-why__head { gap: 2.0833cqw; } /* 16 */
  .fa-why__title { font-size: 7.8125cqw; max-width: 78.125cqw; } /* 60; 600 */
  .fa-why__sub { font-size: 1.8229cqw; max-width: 57.2917cqw; } /* 14; 440 */
  .fa-why__grid { grid-template-columns: 1fr 1fr; gap: 3.125cqw; } /* 2 col, gap24 */
  .fa-why__card { gap: 3.125cqw; min-height: 0; border-radius: 1.5625cqw; padding: 3.6458cqw; } /* r12 p28; grid-stretch equalises each row */
  .fa-why__body { gap: 1.5625cqw; } /* 12 */
  .fa-why__card-title { font-size: 3.125cqw; } /* 24 */
  .fa-why__card-desc { font-size: 1.8229cqw; } /* 14 */
  .fa-why__num { font-size: 5.7292cqw; } /* 44 */
}

@media (min-width: 1024px) { /* desktop ÷1440 */
  .fa-why { padding: 8.3333cqw 1.6667cqw; gap: 5.5556cqw; } /* py120 px24 gap80 */
  .fa-why__head { gap: 1.1111cqw; } /* 16 */
  .fa-why__title { font-size: 6.1111cqw; max-width: 61.1111cqw; } /* 88; 880 → 2 lines, WITH on line 2 */
  .fa-why__sub { font-size: 1.1111cqw; max-width: 29.5833cqw; } /* 16; 426 */
  .fa-why__grid { grid-template-columns: 1fr 1fr 1fr; gap: 1.6667cqw; } /* 3 col, gap24 */
  .fa-why__card { gap: 1.6667cqw; min-height: 18.5417cqw; border-radius: 0.8333cqw; padding: 1.9444cqw; } /* r12 p28; min-h 267 */
  .fa-why__body { gap: 0.8333cqw; } /* 12 */
  .fa-why__card-title { font-size: 1.6667cqw; max-width: 23.3333cqw; } /* 24; 336 */
  .fa-why__card-desc { font-size: 0.9722cqw; } /* 14 */
  .fa-why__num { font-size: 3.0556cqw; } /* 44 */
}

/* ── Section-Testimonial (For Agencies, Paper 690N/69AB/69AR) — centred client quote on a LIGHT surface:
   kicker → large display quote → name/role → brand logo. The logo is the white Spotify PNG turned dark on
   white via mix-blend-difference + opacity (same asset as the Awards card). Reuses .about-display for the
   quote (Roboto Flex display axes, uppercase). Fluid per artboard (375/768/1440), bands 640/1024. Base =
   mobile. position:relative for the full-bleed ::before bg (grouped above). */
.fa-quote { display: flex; flex-direction: column; align-items: center; background: #fff; position: relative; padding: 16cqw 4.2667cqw; gap: 12.8cqw; } /* mobile py60 px16 gap48 @375 */
.fa-quote__inner { display: flex; flex-direction: column; align-items: center; align-self: stretch; gap: 4.2667cqw; } /* 16 */
.fa-quote__kicker { font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; color: rgba(0,0,0,0.7); font-size: 3.7333cqw; } /* 14; Roboto Flex wdth55, tracked, #000B3 */
.fa-quote__text { color: #0A0A0A; line-height: 90%; text-align: center; width: 100%; font-size: 6.4cqw; } /* 24 @375; uppercase via .about-display */
.fa-quote__by { display: flex; flex-direction: column; align-items: center; text-align: center; } /* name/role flush, no gap; centred (role can wrap to 2 lines) */
.fa-quote__name { font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; color: #0A0A0A; font-size: 3.7333cqw; } /* 14 */
.fa-quote__role { font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; opacity: 0.8; color: #0A0A0A; font-size: 3.2cqw; } /* 12 @375 */
.fa-quote__logo { width: 30.1333cqw; height: 8.5333cqw; background-image: url("/media/images/for_agencies/spotify-trusted.png"); background-size: 135.593%; background-position: center; background-repeat: no-repeat; mix-blend-mode: difference; opacity: 0.8; } /* 113×32 @375. Pure-white Spotify asset from Paper, keyed onto the white surface via mix-blend-difference + opacity 0.8 (per Paper, bg-size 135.593%). Own file (not the Awards transparent PNG, whose logo is grey → looked too light here). */

@media (min-width: 640px) { /* tablet ÷768 */
  .fa-quote { padding: 10.4167cqw 4.1667cqw; gap: 7.8125cqw; } /* py80 px32 gap60 */
  .fa-quote__inner { gap: 3.125cqw; } /* 24 */
  .fa-quote__kicker { font-size: 1.8229cqw; } /* 14 */
  .fa-quote__text { font-size: 5.7292cqw; } /* 44 */
  .fa-quote__name { font-size: 1.8229cqw; } /* 14 */
  .fa-quote__role { font-size: 1.8229cqw; } /* 14 */
  .fa-quote__logo { width: 19.7917cqw; height: 5.7292cqw; } /* 152×44 */
}

@media (min-width: 1024px) { /* desktop ÷1440 */
  .fa-quote { padding: 8.3333cqw 3.3333cqw; gap: 3.3333cqw; } /* py120 px48 gap48 */
  .fa-quote__inner { gap: 1.6667cqw; } /* 24 */
  .fa-quote__kicker { font-size: 0.9722cqw; } /* 14 */
  .fa-quote__text { font-size: 3.0556cqw; max-width: 72.0833cqw; } /* 44; quote measure 1038, centred */
  .fa-quote__name { font-size: 0.9722cqw; } /* 14 */
  .fa-quote__role { font-size: 0.9722cqw; } /* 14 */
  .fa-quote__logo { width: 10.5556cqw; height: 3.0556cqw; } /* 152×44 */
}

/* ── Section-FeaturedArticle (Blog) — one highlighted post as a wide card. Desktop (≥1024, 62RG): text
   left / image right; left column justify-between (meta pinned to the bottom). Tablet (62LN) / mobile
   (5J7X): stacked — TEXT on top, image below. Bottom row: author left ↔ date · read-time right. Light
   surface (#F5F5F5 card on white). Whole card is a link (cursor "Read the article" pill on desktop hover).
   Reuses .about-display. Fluid per artboard (375/768/1440), bands 640/1024. Base = mobile. */
.blog-featured { display: flex; flex-direction: column; align-items: center; background: #fff; position: relative; padding: 10.6667cqw 4.2667cqw 0; } /* pt40 px16 pb0 @375; no clip → full-bleed ::before bg */
.blog-featured__card { position: relative; display: flex; flex-direction: column; align-self: stretch; gap: 4.2667cqw; background: #F5F5F5; border-radius: 4.2667cqw; padding: 4.2667cqw; text-decoration: none; color: inherit; } /* gap16 r16 p16 — text top, image below; link */
.blog-featured__media { position: relative; align-self: stretch; aspect-ratio: 311 / 200; border-radius: 2.1333cqw; overflow: hidden; background: #e5e5e5; } /* r8 */
.blog-featured__media img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; transform: scale(1.02); }
.blog-featured__tags { position: absolute; top: 3.2cqw; left: 3.2cqw; z-index: 2; display: flex; align-items: center; gap: 2.1333cqw; } /* category glass tags on the cover top-left; 12 inset, 8 gap @375 */
.blog-featured__body { display: flex; flex-direction: column; justify-content: flex-start; flex: 1; gap: 6.4cqw; } /* 24 */
.blog-featured__text { display: flex; flex-direction: column; align-items: flex-start; gap: 5.3333cqw; } /* 20 */
.blog-featured__cats { display: flex; align-items: flex-start; flex-wrap: wrap; gap: 3.2cqw; } /* 12 */
.blog-featured__cat { font-family: var(--font-display); font-weight: 500; font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; color: rgba(0,0,0,0.7); font-size: 3.2cqw; white-space: nowrap; } /* 12 */
.blog-featured__title { color: #000; opacity: 0.9; line-height: 110%; font-size: 6.4cqw; max-width: 72.5333cqw; } /* 24; 272 */
.blog-featured__dek { font-family: var(--font-body); font-weight: 500; color: rgba(0,0,0,0.7); line-height: 160%; font-size: 3.7333cqw; max-width: 100%; } /* 14 */
.blog-featured__foot { align-self: stretch; } /* no divider, no top padding (per design) */
.blog-featured__meta { display: flex; align-items: center; justify-content: space-between; width: 100%; gap: 2.4cqw; opacity: 0.6; } /* author ←→ date·read; 9 */
.blog-featured__meta-right { display: flex; align-items: center; gap: 2.4cqw; } /* 9 */
.blog-featured__meta span { font-family: var(--font-display); font-weight: 500; font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; font-size: 3.2cqw; color: #000; white-space: nowrap; } /* 12 */
.blog-featured__dot { width: 1.0667cqw; height: 1.0667cqw; border-radius: 50%; background: #000; flex-shrink: 0; } /* 4 */

@media (min-width: 640px) { /* tablet ÷768 — stacked: text top, image below */
  .blog-featured { padding: 7.8125cqw 4.1667cqw 0; } /* pt60 px32 */
  .blog-featured__card { gap: 3.125cqw; border-radius: 2.0833cqw; padding: 3.125cqw; } /* gap24 r16 p24 */
  .blog-featured__media { aspect-ratio: 656 / 360; border-radius: 1.0417cqw; } /* r8 */
  .blog-featured__tags { top: 1.5625cqw; left: 1.5625cqw; gap: 1.0417cqw; } /* 12 inset, 8 gap @768 */
  .blog-featured__body { gap: 3.125cqw; } /* 24 */
  .blog-featured__text { gap: 2.6042cqw; } /* 20 */
  .blog-featured__cats { gap: 1.5625cqw; } /* 12 */
  .blog-featured__cat { font-size: 1.5625cqw; } /* 12 */
  .blog-featured__title { font-size: 3.125cqw; max-width: 42.1875cqw; } /* 24; 324 */
  .blog-featured__dek { font-size: 1.8229cqw; max-width: 42.1875cqw; } /* 14; 324 */
  .blog-featured__meta { gap: 1.1719cqw; } /* 9 */
  .blog-featured__meta-right { gap: 1.1719cqw; } /* 9 */
  .blog-featured__meta span { font-size: 1.8229cqw; } /* 14 */
  .blog-featured__dot { width: 0.5208cqw; height: 0.5208cqw; } /* 4 */
}

@media (min-width: 1024px) { /* desktop ÷1440 — 62RG: text left, image right */
  .blog-featured { padding: 5.5556cqw 1.6667cqw 0; } /* pt80 px24 pb0 */
  .blog-featured__card { flex-direction: row; gap: 1.6667cqw; border-radius: 1.1111cqw; padding: 1.9444cqw; } /* gap24 r16 p28 */
  .blog-featured__media { align-self: auto; aspect-ratio: auto; width: 43.8889cqw; height: 28.4722cqw; flex-shrink: 0; border-radius: 0.5556cqw; } /* w632 h410 r8 */
  .blog-featured__tags { top: 0.8333cqw; left: 0.8333cqw; gap: 0.5556cqw; } /* 12 inset, 8 gap @1440 */
  .blog-featured__body { justify-content: space-between; gap: 5.5556cqw; } /* meta pinned bottom; 80 */
  .blog-featured__text { gap: 1.1111cqw; } /* 16 */
  .blog-featured__cats { gap: 0.8333cqw; } /* 12 */
  .blog-featured__cat { font-size: 0.8333cqw; } /* 12 */
  .blog-featured__title { font-size: 1.6667cqw; max-width: 18.8889cqw; } /* 24; 272 */
  .blog-featured__dek { font-size: 0.9722cqw; max-width: 22.5cqw; } /* 14; 324 */
  .blog-featured__meta { gap: 0.625cqw; } /* 9 */
  .blog-featured__meta-right { gap: 0.625cqw; } /* 9 */
  .blog-featured__meta span { font-size: 0.9722cqw; } /* 14 */
  .blog-featured__dot { width: 0.2778cqw; height: 0.2778cqw; } /* 4 */
}

/* ── blog_card LIGHT variant — dark text for light surfaces (Blog index). Base card is white-on-dark
   (Home blog preview); --light flips the text/meta to black. */
.blog-card--light .blog-card__title    { color: #000; }
.blog-card--light .blog-card__dek      { color: #000; }
.blog-card--light .blog-card__cat      { color: rgba(0,0,0,0.7); }
.blog-card--light .blog-card__meta span { color: #000; }
.blog-card--light .blog-card__dot      { background: #000; }

/* ── Section-Blog index (Blog page) — filter tabs (by category) + sort + grid of light article cards +
   pagination. Light surface. Reuses the projects filter UI (.projects-filter / .projects-sort) recoloured
   for light, and components/blog_card (--light). Grid: 1 col mobile, 2 tablet, 3 desktop. Client-side
   filter + sort + responsive pagination (blog-index controller). Fluid per band (375/768/1440). */
.blog-index { display: flex; flex-direction: column; align-items: center; background: #fff; position: relative; padding: 16cqw 4.2667cqw; gap: 10.6667cqw; } /* py60 px16 gap40 @375; no clip → full-bleed ::before bg */
.blog-index__bar { align-self: stretch; }

/* light recolour of the reused projects filter/sort UI */
.blog-index .projects-filter__tab { background: rgba(10,10,10,0.08); color: #0A0A0A; }
.blog-index .projects-filter__tab:hover { background: rgba(10,10,10,0.14); }
.blog-index .projects-filter__tab:active { background: rgba(10,10,10,0.20); }
.blog-index .projects-filter__tab.is-active { background: #0A0A0A; color: #fff; }
.blog-index .projects-filter__tab.is-active:hover { background: #1A1A1A; }
.blog-index .projects-filter__tab.is-active:active { background: #2A2A2A; }
.blog-index .projects-filter__fade { background: linear-gradient(90deg, rgba(255,255,255,0), #fff); }
.blog-index .projects-sort__btn { border-color: rgba(0,0,0,0.20); color: #0A0A0A; }
.blog-index .projects-sort__btn:hover { background: rgba(0,0,0,0.06); }
.blog-index.is-sort-open .projects-sort__btn { background: #0A0A0A; color: #fff; }
.blog-index .projects-sort__menu { background: #fff; border-color: rgba(0,0,0,0.10); }
.blog-index.is-sort-open .projects-sort__menu { opacity: 1; visibility: visible; transform: translateY(0); } /* show on open (projects scoped its own .projects-index) */
.blog-index .projects-sort__option { color: #0A0A0A; }
.blog-index .projects-sort__option:hover { background: rgba(0,0,0,0.05); }

/* grid */
.blog-index__grid { display: grid; grid-template-columns: 1fr; align-self: stretch; column-gap: 0; row-gap: 12.8cqw; scroll-margin-top: 32cqw; } /* 1 col, row48 @375; page-change scroll lands 120px below the bar */
.blog-index__cell { display: flex; min-width: 0; }
.blog-index__cell > .blog-card { flex: 1; min-width: 0; }

/* pagination */
.blog-index__pagination { display: flex; align-items: center; justify-content: center; gap: 1.0667cqw; } /* 4 */
.blog-index__page { display: inline-flex; align-items: center; justify-content: center; width: 8.5333cqw; height: 8.5333cqw; border-radius: 1.0667cqw; border: 0; background: none; cursor: pointer; font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 50; text-transform: uppercase; font-size: 3.2cqw; line-height: 93.7%; color: #0A0A0A; opacity: 0.5; transition: opacity 0.2s ease, outline-color 0.2s ease; } /* size32 r4 t12 */
.blog-index__page:hover:not(.is-active):not(.blog-index__page--gap) { opacity: 0.85; }
.blog-index__page.is-active { opacity: 1; outline: 1px solid rgba(10,10,10,0.20); outline-offset: -1px; }
.blog-index__page--gap { cursor: default; }

@media (min-width: 640px) { /* tablet ÷768 — 2-col grid */
  .blog-index { padding: 10.4167cqw 4.1667cqw; gap: 6.25cqw; } /* py80 px32 gap48 */
  .blog-index__grid { grid-template-columns: 1fr 1fr; column-gap: 3.125cqw; row-gap: 6.25cqw; scroll-margin-top: 20.8333cqw; } /* col24 row48; scroll offset 160 */
  .blog-index__pagination { gap: 0.5208cqw; } /* 4 */
  .blog-index__page { width: 4.1667cqw; height: 4.1667cqw; border-radius: 0.5208cqw; font-size: 1.5625cqw; } /* size32 r4 t12 */
}

@media (min-width: 1024px) { /* desktop ÷1440 — 3-col grid */
  .blog-index { padding: 8.3333cqw 1.6667cqw; gap: 3.3333cqw; } /* py120 px24 gap48 */
  .blog-index__grid { grid-template-columns: repeat(3, 1fr); column-gap: 1.6667cqw; row-gap: 3.3333cqw; scroll-margin-top: 11.1111cqw; } /* col24 row48; scroll offset 160 */
  .blog-index__pagination { gap: 0.2778cqw; } /* 4 */
  .blog-index__page { width: 2.2222cqw; height: 2.2222cqw; border-radius: 0.2778cqw; font-size: 0.8333cqw; } /* size32 r4 t12 */
}

/* ── Newsletter form — LIGHT variant (Blog newsletter) + hover. Reuses .footer-email* (shared/_newsletter_form).
   Footer = dark default; --light recolours for white surfaces. Field height/behaviour stay the footer's. */
.footer-email:hover { background: rgba(255,255,255,0.10); } /* hover affordance (footer/dark) */
.footer-email-form--light { align-self: center; align-items: center; } /* don't stretch; centre the field (footer form stretches + is flex-start) */
.footer-email-form--light .footer-email { background: rgba(10,10,10,0.08); align-self: auto; } /* width inherits the footer field; don't stretch to full width */
.footer-email-form--light .footer-email:hover { background: rgba(10,10,10,0.12); }
.footer-email-form--light .footer-email:focus-within { box-shadow: inset 0 0 0 1px #0A0A0A; }
.footer-email-form--light .footer-email__input { color: #0A0A0A; caret-color: #0A0A0A; }
.footer-email-form--light .footer-email__input::placeholder { color: rgba(10,10,10,0.4); }
.footer-email-form--light .footer-email__success { color: #0A0A0A; }
.footer-email-form--light .footer-email__submit { color: #0A0A0A; }

/* ── Section-Blog newsletter — centred heading + the shared newsletter form (light) on white. Fluid
   per artboard (375/768/1440), bands 640/1024. Base = mobile. */
.blog-newsletter { display: flex; flex-direction: column; align-items: center; background: #fff; position: relative; padding: 16cqw 4.2667cqw; } /* py60 px16 @375; no clip → full-bleed ::before bg */
.blog-newsletter__inner { display: flex; flex-direction: column; align-items: center; gap: 6.4cqw; } /* 24 */
.blog-newsletter__title { font-size: 6.4cqw; line-height: 110%; text-align: center; color: #0A0A0A; max-width: 95.4667cqw; } /* 24; 358 */

@media (min-width: 640px) { /* tablet ÷768 */
  .blog-newsletter { padding: 10.4167cqw 4.1667cqw; } /* py80 px32 */
  .blog-newsletter__inner { gap: 3.125cqw; } /* 24 */
  .blog-newsletter__title { font-size: 3.125cqw; max-width: 46.6146cqw; } /* 24; 358 */
}

@media (min-width: 1024px) { /* desktop ÷1440 */
  .blog-newsletter { padding: 0 1.6667cqw 8.3333cqw; } /* pt0 px24 pb120 */
  .blog-newsletter__inner { gap: 1.6667cqw; } /* 24 */
  .blog-newsletter__title { font-size: 1.6667cqw; max-width: 24.8611cqw; } /* 24; 358 */
}

/* ── Contact page (sections/contact/01_form) — "Contact us" + lead form (→ Lead) + locations, over the
   reusable WebGL backdrop (shared/_gl_backdrop). Dark surface. DS form fields (text / select / textarea)
   with required asterisks; states CSS-only (focus border, :user-invalid red, filled). Fluid per artboard
   (375/768/1440), bands 640/1024. Base = mobile. */
.contact { position: relative; display: flex; flex-direction: column; align-items: center; background: #0B0B0B; overflow: clip; padding: 32cqw 4.2667cqw 16cqw; gap: 10.6667cqw; } /* pt120 px16 pb60 gap40 @375 */
.contact__bg { position: absolute; inset: 0; z-index: 0; }
.contact__bg .gl-backdrop { position: absolute; inset: 0; width: 100%; height: 100%; }
.contact__head, .contact-form, .contact__locations { position: relative; z-index: 1; }

.contact__head { display: flex; flex-direction: column; align-items: center; align-self: stretch; gap: 4.2667cqw; } /* 16 */
.contact__title { color: #fff; opacity: 0.9; line-height: 80%; text-align: center; font-size: 11.7333cqw; } /* 44 */
.contact__sub { color: rgba(255,255,255,0.8); text-align: center; } /* font + width via .hero-sub */
.contact__link { color: #fff; text-decoration: underline; text-underline-offset: 2px; }

.contact-form { display: flex; flex-direction: column; align-items: center; gap: 1.0667cqw; width: 91.4667cqw; } /* gap4; mobile full */
.contact-form__fields { display: flex; flex-direction: column; align-self: stretch; gap: 1.0667cqw; } /* 4 */
.contact-form__row { display: flex; flex-direction: column; align-self: stretch; gap: 1.0667cqw; } /* mobile: Name/Email stacked */

.contact-field-group { display: flex; flex-direction: column; align-self: stretch; gap: 1.0667cqw; } /* field + error below; 4 */
.contact-field { position: relative; display: flex; align-items: center; align-self: stretch; flex: none; min-width: 0; height: 17.0667cqw; border-radius: 2.1333cqw; background: rgba(255,255,255,0.07); backdrop-filter: blur(14.7px); -webkit-backdrop-filter: blur(14.7px); transition: box-shadow 0.15s ease; } /* h64 r8 — flex:none so column fields keep their height; flex:1 (row only) splits Name/Email */
.contact-field:hover { background: rgba(255,255,255,0.10); }
.contact-field:focus-within { box-shadow: inset 0 0 0 1px #fff; }
.contact-field:has(.contact-field__input:user-invalid) { box-shadow: inset 0 0 0 1px #FF6B6B; }
/* DS error state — red border (above) + red asterisk + message below (Geist Mono, uppercase). */
.contact-field__error { display: none; font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.04em; line-height: 140%; color: #FF6B6B; padding-left: 2.1333cqw; font-size: 2.9333cqw; } /* 11 @375; pl8 */
.contact-field-group:has(.contact-field__input:user-invalid) .contact-field__error { display: block; }
.contact-field-group:has(.contact-field__input:user-invalid) .contact-field__req { color: #FF6B6B; opacity: 1; }
.contact-field--textarea { align-items: stretch; height: 45.8667cqw; } /* 172 */
.contact-field--select { backdrop-filter: none; -webkit-backdrop-filter: none; } /* drop the field's own blur so the descendant menu's backdrop-filter works (nested backdrop-filter = empty backdrop) */
.contact-field__input { flex: 1; min-width: 0; height: 100%; background: transparent; border: 0; outline: none; caret-color: #fff; font-family: var(--font-body); font-size: 3.7333cqw; line-height: 140%; color: #fff; padding: 0 12.8cqw 0 6.4cqw; } /* 14; pr48 pl24; height:100% → whole field clickable */
.contact-field__input::placeholder { color: rgba(255,255,255,0.4); }
/* Autofill: Chrome/WebKit forces a pale OPAQUE background on the input that covers the glass field as a
   sharp rectangle (no radius, no blur). It can't be overridden with `background` — so clip that forced
   background to the text glyphs (background-clip: text), keeping the field itself transparent so the glass
   wrapper shows through. text-fill-color keeps our white text; the long transition defers the page-load
   autofill tint too. The wrapper (.contact-field) keeps its bg/radius/blur, so the glass look is intact. */
.contact-field__input:-webkit-autofill,
.contact-field__input:-webkit-autofill:hover,
.contact-field__input:-webkit-autofill:focus,
.contact-field__input:-webkit-autofill:active {
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: #fff;
  caret-color: #fff;
  transition: background-color 9999s ease-out 0s;
}
.contact-field--textarea .contact-field__input { padding: 4cqw 12.8cqw 4cqw 6.4cqw; line-height: 160%; resize: none; height: 100%; } /* py15 */
.contact-field__req { position: absolute; right: 4.8cqw; top: 50%; transform: translateY(-50%); width: 2.1333cqw; height: auto; color: #fff; opacity: 0.4; pointer-events: none; } /* 8 @ right18 */
.contact-field--textarea .contact-field__req { top: 5.8667cqw; transform: none; } /* top22 */

/* Budget-tier custom dropdown (DS Select/Dropdown) — trigger looks like the field; menu = #1A1A1A list. */
.contact-field__trigger { display: flex; align-items: center; justify-content: space-between; gap: 3.2cqw; width: 100%; height: 100%; background: none; border: 0; cursor: pointer; padding: 0 4.8cqw 0 6.4cqw; } /* pl24 pr18 */
.contact-field__value { font-family: var(--font-body); font-size: 3.7333cqw; line-height: 140%; color: rgba(255,255,255,0.4); } /* 14 — placeholder grey */
.contact-field--select.is-selected .contact-field__value { color: #fff; }
.contact-field__chevron { width: 1.6cqw; height: auto; color: #fff; opacity: 0.6; flex-shrink: 0; transition: transform 0.2s ease; } /* 6 — same as the services-menu caret */
.contact-field--select.is-open .contact-field__chevron { transform: rotate(180deg); }
.contact-field__menu { position: absolute; left: 0; right: 0; top: calc(100% + 1.0667cqw); background: rgba(255,255,255,0.07); backdrop-filter: blur(14.7px); -webkit-backdrop-filter: blur(14.7px); border: 1px solid rgba(255,255,255,0.12); border-radius: 2.1333cqw; overflow: clip; z-index: 20; opacity: 0; visibility: hidden; transform: translateY(-6px); transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s; } /* translucent tone, like the fields */
.contact-field--select.is-open { z-index: 30; } /* lift above later fields (each has its own backdrop-filter stacking context) */
.contact-field--select.is-open .contact-field__menu { opacity: 1; visibility: visible; transform: translateY(0); }
.contact-field__option { display: flex; align-items: center; justify-content: space-between; gap: 3.2cqw; width: 100%; height: 10.6667cqw; padding: 0 4.8cqw; background: none; border: 0; cursor: pointer; text-align: left; font-family: var(--font-body); font-size: 3.7333cqw; line-height: 140%; color: rgba(255,255,255,0.8); transition: background-color 0.15s ease, color 0.15s ease; } /* h40 px18 t14 */
.contact-field__option:hover { background: rgba(255,255,255,0.08); color: #fff; }
.contact-field__option.is-selected { background: rgba(255,255,255,0.12); color: #fff; font-weight: 600; }
.contact-field__check { width: 3.7333cqw; height: auto; color: #fff; opacity: 0; flex-shrink: 0; } /* 14 */
.contact-field__option.is-selected .contact-field__check { opacity: 1; }

/* Submit uses the DS button (components/_button, primary, full_width) — no bespoke styles. */

.contact__locations { display: flex; flex-direction: column; align-items: center; align-self: stretch; gap: 5.3333cqw; } /* 20 */
.contact__loc-label { font-family: var(--font-display); font-weight: 500; font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; color: rgba(255,255,255,0.8); font-size: 3.2cqw; } /* 12 */
.contact__loc-list { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1.0667cqw; } /* mobile: stacked, vertical gap 4 */
.contact__loc-list span { color: #fff; line-height: 110%; font-size: 6.4cqw; } /* about-display (class) — 24 @375; only size/line-height/colour here so the display axes win */

@media (min-width: 640px) { /* tablet ÷768 */
  .contact { padding: 20.8333cqw 4.1667cqw 10.4167cqw; gap: 7.8125cqw; } /* pt160 px32 pb80 gap60 */
  .contact__head { gap: 2.0833cqw; }
  .contact__sub { max-width: 47.9167cqw; } /* Contact-only override: 368 @768 (−60 vs the shared .hero-sub 428) */
  .contact__title { font-size: 11.4583cqw; } /* 88 */
  .contact-form { width: 56.25cqw; gap: 0.5208cqw; } /* 432; 4 */
  .contact-form__fields { gap: 0.5208cqw; }
  .contact-form__row { flex-direction: row; gap: 0.5208cqw; } /* Name + Email side by side */
  .contact-form__row .contact-field-group { flex: 1 1 0; min-width: 0; } /* split the row evenly; min-width:0 so the error text can't widen it */
  .contact-field-group { gap: 0.5208cqw; }
  .contact-field__error { font-size: 1.4323cqw; padding-left: 1.0417cqw; } /* 11; pl8 */
  .contact-field { height: 8.3333cqw; border-radius: 1.0417cqw; } /* 64 r8 */
  .contact-field--textarea { height: 22.3958cqw; } /* 172 */
  .contact-field__input { font-size: 1.8229cqw; padding: 0 6.25cqw 0 3.125cqw; } /* 14; pr48 pl24 */
  .contact-field--textarea .contact-field__input { padding: 1.9531cqw 6.25cqw 1.9531cqw 3.125cqw; }
  .contact-field__req { right: 2.3438cqw; width: 1.0417cqw; } /* 18; 8 */
  .contact-field--textarea .contact-field__req { top: 2.8646cqw; }
  .contact-field__trigger { gap: 1.5625cqw; padding: 0 2.3438cqw 0 3.125cqw; } /* pl24 pr18 */
  .contact-field__value { font-size: 1.8229cqw; } /* 14 */
  .contact-field__chevron { width: 0.78125cqw; } /* 6 */
  .contact-field__menu { top: calc(100% + 0.5208cqw); border-radius: 1.0417cqw; }
  .contact-field__option { height: 5.2083cqw; padding: 0 2.3438cqw; gap: 1.5625cqw; font-size: 1.8229cqw; } /* h40 px18 t14 */
  .contact-field__check { width: 1.8229cqw; } /* 14 */
  .contact__locations { gap: 2.6042cqw; }
  .contact__loc-label { font-size: 1.5625cqw; }
  .contact__loc-list { flex-direction: row; gap: 3.125cqw; } /* tablet: row, gap 24 */
  .contact__loc-list span { font-size: 3.125cqw; } /* 24 @768 */
}

@media (min-width: 1024px) { /* desktop ÷1440 */
  .contact { padding: 11.1111cqw 11.25cqw 5.5556cqw; gap: 5.5556cqw; } /* pt160 px162 pb80 gap80 */
  .contact__head { gap: 1.1111cqw; }
  .contact__sub { max-width: 36.25cqw; } /* Contact-only override: 522 @1440 (−90 vs the shared .hero-sub 612) */
  .contact__title { font-size: 9.0278cqw; } /* 130 @1440 (was 160) */
  .contact-form { width: 30cqw; gap: 0.2778cqw; } /* 432; 4 */
  .contact-form__fields { gap: 0.2778cqw; }
  .contact-form__row { gap: 0.2778cqw; }
  .contact-field-group { gap: 0.2778cqw; }
  .contact-field__error { font-size: 0.7639cqw; padding-left: 0.5556cqw; } /* 11; pl8 */
  .contact-field { height: 4.4444cqw; border-radius: 0.5556cqw; } /* 64 r8 */
  .contact-field--textarea { height: 11.9444cqw; } /* 172 */
  .contact-field__input { font-size: 0.9722cqw; padding: 0 3.3333cqw 0 1.6667cqw; } /* 14; pr48 pl24 */
  .contact-field--textarea .contact-field__input { padding: 1.0417cqw 3.3333cqw 1.0417cqw 1.6667cqw; }
  .contact-field__req { right: 1.25cqw; width: 0.5556cqw; } /* 18; 8 */
  .contact-field--textarea .contact-field__req { top: 1.5278cqw; }
  .contact-field__trigger { gap: 0.8333cqw; padding: 0 1.25cqw 0 1.6667cqw; } /* pl24 pr18 */
  .contact-field__value { font-size: 0.9722cqw; } /* 14 */
  .contact-field__chevron { width: 0.4167cqw; } /* 6 */
  .contact-field__menu { top: calc(100% + 0.2778cqw); border-radius: 0.5556cqw; }
  .contact-field__option { height: 2.7778cqw; padding: 0 1.25cqw; gap: 0.8333cqw; font-size: 0.9722cqw; } /* h40 px18 t14 */
  .contact-field__check { width: 0.9722cqw; } /* 14 */
  .contact__locations { gap: 1.3889cqw; }
  .contact__loc-label { font-size: 0.8333cqw; }
  .contact__loc-list { gap: 1.6667cqw; } /* desktop: row, gap 24 */
  .contact__loc-list span { font-size: 1.6667cqw; } /* 24 @1440 */
}

/* ── Contact · Thank-you block (variant "thanks" of sections/contact/01_contact) — check circle +
   "Thank you" + line, centred, in place of the form. Fluid per artboard (375/768/1440). Base = mobile. */
.contact-thanks { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; gap: 6.4cqw; padding-block: 6.4cqw; } /* gap24 py24 @375 */
.contact-thanks__icon { display: flex; align-items: center; justify-content: center; flex-shrink: 0; width: 17.0667cqw; height: 17.0667cqw; border-radius: 50%; border: 1px solid rgba(255,255,255,0.20); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); } /* 64 */
.contact-thanks__icon svg { width: 6.4cqw; height: auto; } /* 24 */
.contact-thanks__text { display: flex; flex-direction: column; align-items: center; gap: 3.2cqw; } /* 12 */
.contact-thanks__title { color: #fff; line-height: 90%; text-align: center; font-size: 9.6cqw; } /* 36 @375 */
.contact-thanks__sub { font-family: var(--font-body); color: rgba(255,255,255,0.8); line-height: 160%; text-align: center; font-size: 3.7333cqw; max-width: 63.7333cqw; } /* 14; 239 (mobile keeps py) */

@media (min-width: 640px) { /* tablet ÷768 */
  .contact-thanks { gap: 3.125cqw; padding-block: 0; } /* py removed (tablet) */
  .contact-thanks__icon { width: 8.3333cqw; height: 8.3333cqw; } /* 64 */
  .contact-thanks__icon svg { width: 3.125cqw; } /* 24 */
  .contact-thanks__text { gap: 1.5625cqw; } /* 12 */
  .contact-thanks__title { font-size: 5.7292cqw; } /* 44 */
  .contact-thanks__sub { font-size: 1.8229cqw; max-width: 41.4063cqw; } /* 14; 318 */
}

@media (min-width: 1024px) { /* desktop ÷1440 */
  .contact-thanks { gap: 1.6667cqw; padding-block: 0; } /* py removed (desktop) */
  .contact-thanks__icon { width: 4.4444cqw; height: 4.4444cqw; } /* 64 */
  .contact-thanks__icon svg { width: 1.6667cqw; } /* 24 */
  .contact-thanks__text { gap: 0.8333cqw; } /* 12 */
  .contact-thanks__title { font-size: 3.0556cqw; } /* 44 */
  .contact-thanks__sub { font-size: 1.1111cqw; max-width: 22.0833cqw; } /* 16; 318 */
}

/* ── 404 / Not-found (sections/errors/404) — full-viewport centred 404 + message + two DS buttons over
   the reusable WebGL backdrop. Dark. Reuses .about-display + components/_button. Fluid per band. Base = mobile. */
.notfound { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; min-height: 100dvh; background: #0B0B0B; overflow: clip; padding-inline: 4.2667cqw; } /* px16 @375 */
.notfound__bg { position: absolute; inset: 0; z-index: 0; }
.notfound__bg .gl-backdrop { position: absolute; inset: 0; width: 100%; height: 100%; }
.notfound__inner { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; gap: 6.4cqw; max-width: 100%; } /* gap24 */
.notfound__code { color: #fff; opacity: 0.9; line-height: 80%; text-align: center; font-size: 11.7333cqw; } /* 44 @375 */
.notfound__text { display: flex; flex-direction: column; align-items: center; gap: 3.2cqw; } /* 12 */
.notfound__headline { color: #fff; line-height: 90%; text-align: center; font-size: 6.4cqw; } /* 24 */
.notfound__sub { font-family: var(--font-body); color: rgba(255,255,255,0.8); line-height: 160%; text-align: center; font-size: 3.7333cqw; max-width: 70.4cqw; } /* 14; 264 */
.notfound__actions { display: flex; flex-direction: column; align-items: stretch; align-self: stretch; justify-content: center; gap: 2.1333cqw; } /* mobile: stacked full-width; 8 */
.notfound__actions .ds-btn { width: 100%; } /* mobile full-width buttons */

@media (min-width: 640px) { /* tablet ÷768 */
  .notfound { padding-inline: 4.1667cqw; } /* 32 */
  .notfound__inner { gap: 3.125cqw; } /* 24 */
  .notfound__code { font-size: 11.4583cqw; } /* 88 */
  .notfound__text { gap: 1.5625cqw; } /* 12 */
  .notfound__headline { font-size: 3.125cqw; } /* 24 */
  .notfound__sub { font-size: 1.8229cqw; max-width: 34.375cqw; } /* 14; 264 */
  .notfound__actions { flex-direction: row; align-items: center; align-self: auto; gap: 1.0417cqw; } /* 8 — row */
  .notfound__actions .ds-btn { width: auto; }
}

@media (min-width: 1024px) { /* desktop ÷1440 */
  .notfound { padding-inline: 11.25cqw; } /* 162 */
  .notfound__inner { gap: 2.2222cqw; max-width: 58.3333cqw; } /* 32; 840 */
  .notfound__code { font-size: 11.1111cqw; } /* 160 */
  .notfound__text { gap: 0.8333cqw; } /* 12 */
  .notfound__headline { font-size: 1.6667cqw; } /* 24 */
  .notfound__sub { font-size: 1.1111cqw; max-width: 18.3333cqw; } /* 16; 264 */
  .notfound__actions { gap: 0.5556cqw; } /* 8 */
}

/* ── Legal pages (sections/legal/_content — Privacy / Terms). Left-aligned display title + intro line,
   then a uniform running-copy column (white-space: pre-line). Dark. Reuses .about-display + var(--font-body).
   Fluid per band (375/768/1440), switches 640/1024. Base = mobile. */
.legal { display: flex; flex-direction: column; background: #0B0B0B; overflow: clip;
  padding-top: 32cqw; padding-bottom: 16cqw; padding-inline: 4.2667cqw; gap: 10.6667cqw; } /* pt120 pb60 px16 gap40 @375 */
.legal__header { display: flex; flex-direction: column; align-items: flex-start; gap: 4.2667cqw; } /* 16 */
.legal__title { color: #fff; line-height: 85%; font-size: 11.7333cqw; } /* 44 @375 */
.legal__intro { font-family: var(--font-body); color: #fff; line-height: 160%; font-size: 3.7333cqw; } /* 14 */
.legal__copy { font-family: var(--font-body); color: #fff; line-height: 7.4667cqw; font-size: 4.5333cqw; } /* lh28 fs17 @375 */
/* Real-HTML formatting for the legal copy (headings / bold / bullets). All spacing in em so it scales with
   the per-band font-size below. */
.legal__copy > :first-child { margin-top: 0; }
.legal__copy p { margin: 1em 0 0; }
.legal__copy h2 { font-weight: 600; font-size: 1.45em; line-height: 1.2; margin: 2.2em 0 0; }
.legal__copy h3 { font-weight: 600; font-size: 1.12em; line-height: 1.3; margin: 1.6em 0 0; }
.legal__copy ul { margin: 1em 0 0; padding-left: 1.3em; list-style: disc; }
.legal__copy li { margin-top: 0.4em; line-height: 1.5; }
.legal__copy li:first-child { margin-top: 0; }
.legal__copy li::marker { color: rgba(255,255,255,0.45); }
.legal__copy strong, .legal__copy b { font-weight: 600; }
.legal__copy em, .legal__copy i { font-style: italic; }
.legal__copy a { color: inherit; text-decoration: underline; text-underline-offset: 0.15em; }

@media (min-width: 640px) { /* tablet ÷768 */
  .legal { padding-top: 20.8333cqw; padding-bottom: 10.4167cqw; padding-inline: 4.1667cqw; gap: 7.8125cqw; } /* pt160 pb80 px32 gap60 */
  .legal__header { gap: 2.0833cqw; } /* 16 */
  .legal__title { font-size: 7.8125cqw; } /* 60 */
  .legal__intro { font-size: 1.8229cqw; max-width: 78.125cqw; } /* 14; 600 */
  .legal__copy { line-height: 3.6458cqw; font-size: 2.2135cqw; } /* lh28 fs17 */
}

@media (min-width: 1024px) { /* desktop ÷1440 */
  .legal { padding-top: 11.1111cqw; padding-bottom: 5.5556cqw; padding-inline: 1.6667cqw; gap: 5.5556cqw; } /* pt160 pb80 px24 gap80 */
  .legal__header { gap: 1.1111cqw; } /* 16 */
  .legal__title { font-size: 7.7778cqw; } /* 112 */
  .legal__intro { font-size: 0.9722cqw; max-width: 31.1111cqw; } /* 14; 448 */
  .legal__copy { line-height: 1.9444cqw; font-size: 1.1806cqw; max-width: 53.75cqw; } /* lh28 fs17; body column 774 */
}

/* ── Article body (ActionText / Trix render) — sections/article/_body renders <%= post.body %> inside
   .article-content. Light surface, near-black ink. Styles extracted from Paper "Blog Article Template"
   Chapter headings reuse the .about-display axes (Roboto Flex wdth55, uppercase). Vertical rhythm uses
   em (band-independent): within-block ≈1.5×body, chapter break larger before H1>H2>H3.
   Trix wraps content in .trix-content, so selectors are descendants of .article-content.
   Fluid per band — sizes from Paper 5K32/5K0L/5JY4: H1 36/48/60, H2 28/40/44, H3 20/28/32, body 16. */
.article-content { color: #0A0A0A; font-family: var(--font-body); max-width: 100%; font-size: 4.2667cqw; } /* 16 @375 */
/* INTERNAL review marker — "Content to add" callout injected into an article body during content review.
   Amber, dashed, obviously a placeholder. Remove the callouts (and this rule) before launch. em-based so it
   rides the already-fluid .article-content font-size. */
.article-content .article-todo { background: #FFF4D6; border: 0.12em dashed #E0A400; border-radius: 0.5em; padding: 0.9em 1.1em; margin: 0 0 1.5em; color: #5C4400; font-family: var(--font-body); }
.article-content .article-todo > strong { display: block; margin-bottom: 0.5em; letter-spacing: 0.02em; }
.article-content .article-todo ul { margin: 0; padding-left: 1.3em; list-style: disc; }
.article-content .article-todo li { line-height: 150%; }
/* Paragraphs — Geist 16, line-height 160%. (Trix emits paragraphs as <div>, not <p>.) */
.article-content p { line-height: 160%; font-weight: 400; }

/* ── Vertical rhythm (owl pattern). Trix emits <div> paragraphs + <h1/2/3> / <blockquote> / <ul> / <ol>
   / <figure> as direct children of .trix-content. Uniform gap WITHIN a chapter; a larger gap BEFORE a
   heading (chapter break: H1 > H2 > H3). Blank-line paragraphs render as REAL blank lines (full WYSIWYG —
   what you type is what you get; stray blanks show so the author trims them). Heading em scales per band. */
.article-content .trix-content > * { margin: 0; }
.article-content .trix-content > * + * { margin-top: 1.5em; }     /* within-chapter ≈ 24px (body em) */
.article-content .trix-content > * + h2 { margin-top: 1.3333em; } /* chapter break ≈ 80px (60×1.333) */
.article-content .trix-content > * + h3 { margin-top: 1.2727em; } /* subsection ≈ 56px (44×1.273) */
.article-content .trix-content > * + h4 { margin-top: 1.25em; }   /* sub-subsection ≈ 40px (32×1.25) */
/* Full WYSIWYG: a blank line renders as a real blank line (one line tall). margin-top:0 keeps the owl off
   the blank itself, so ONE blank line = the normal gap + one extra line (not doubled); each extra blank
   line adds another line. */
.article-content .trix-content > div:empty,
.article-content .trix-content > div:has(> br:only-child) { min-height: 1.6em; margin-top: 0; }
/* Collapse trailing line breaks Trix leaves at the end of a block (they add empty lines before the next
   block, e.g. a list). Covers a single <br> and a trailing <br><br> pair; the owl owns the real gap. */
.article-content .trix-content br:last-child,
.article-content .trix-content br:has(+ br:last-child) { display: none; }

/* Body headings — the article title is the page's <h1>, so the body starts at <h2> (chapter, in the TOC),
   then <h3> / <h4>. Trix emits these via trix_setup_controller. Same display axes as .about-display. */
.article-content h2,
.article-content h3,
.article-content h4,
.article-content blockquote {
  font-family: var(--font-display);
  font-variation-settings: "wght" 700, "wdth" 55, "GRAD" -200, "XOPQ" 95,
    "XTRA" 470, "YOPQ" 80, "YTDE" -200, "YTFI" 740, "YTLC" 510, "YTUC" 710;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: #0A0A0A;
}
.article-content h2 { line-height: 90%; font-size: 9.6cqw; } /* 36 @375 — spacing via owl above */
.article-content h3 { line-height: 90%; font-size: 7.4667cqw; } /* 28 */
.article-content h4 { line-height: 90%; font-size: 5.3333cqw; } /* 20 */
/* Anchored TOC jumps land 120px below the viewport top (clears the fixed nav). */
.article-content h2, .article-content h3, .article-content h4 { scroll-margin-top: 120px; }

/* Blockquote = pull-quote (Paper 5K0A): big uppercase display. Spacing via owl above. */
.article-content blockquote { line-height: 90%; font-size: 7.4667cqw; } /* 28 @375 */
/* Kill actiontext.css's default Trix blockquote (grey left bar + indent) — we don't want it. */
.article-content .trix-content blockquote { border: 0; margin-left: 0; padding-left: 0; }
/* Optional author line — split off the quote by article_quotes_controller (convention: last line of the
   quote starting with "—"). Rendered small + muted + sentence-case, sitting tight under the quote so the
   quote + author read as one block (Paper 5K0A). Overrides the blockquote's display/uppercase styling. */
.article-content blockquote .article-quote__cite {
  display: block; margin-top: 0.5em;
  font-family: var(--font-body); font-weight: 400; font-style: normal;
  font-variation-settings: normal; /* reset the quote's inherited wght 700 — author = normal body weight */
  text-transform: none; letter-spacing: normal; line-height: 160%;
  color: rgba(10, 10, 10, 0.55); font-size: 4.2667cqw; /* 16 @375 — matches body (don't inherit the quote size) */
}

/* Lists — numbered + bulleted (Paper has a numbered list; bulleted mirrors it). Outer spacing via owl. */
.article-content ul,
.article-content ol { padding-left: 1.4em; line-height: 160%; }
.article-content ul { list-style: disc; }
.article-content ol { list-style: decimal; }
.article-content li + li { margin-top: 0.25em; } /* 4px at 16px body */
.article-content li::marker { color: rgba(10,10,10,0.5); }
/* Nested lists — tight, indented, no big top gap; vary marker by depth */
.article-content li > ul,
.article-content li > ol { margin: 0.25em 0 0; padding-left: 1.2em; }
.article-content ul ul { list-style: circle; }
.article-content ul ul ul { list-style: square; }

/* Inline emphasis */
.article-content strong, .article-content b { font-weight: 600; }
.article-content em, .article-content i { font-style: italic; }

/* Links */
.article-content a { color: inherit; text-decoration: underline; text-underline-offset: 0.15em; transition: opacity 0.2s ease; }
.article-content a:hover { opacity: 0.6; }

/* In-text images (Trix attachments via Active Storage) — outer spacing via owl above. */
.article-content img,
.article-content figure img { display: block; max-width: 100%; height: auto; border-radius: 3.2cqw; } /* 12 @375 */
/* Image attachments are inline <action-text-attachment> wrapping a <figure>. Two browser-default problems:
   (1) the attachment is inline → the image glues to the paragraph text it shares a <div> with; (2) <figure>
   carries the UA default `margin: 1em 40px` → the image + caption are indented ~40px off the left edge
   (looks like the caption "drifted right"). Fix: block attachment with air above, and reset the figure
   margin so image + caption pin to the left like everything else. */
.article-content .trix-content action-text-attachment { display: block; margin-top: 1.5em; }
.article-content .trix-content figure.attachment { margin: 0; text-align: left; }
/* `.attachment__caption` ships its own `text-align: center` (Trix/Action Text default, from the gem) — beat
   it with a higher-specificity selector so the caption pins left under the image. */
.article-content .trix-content figcaption.attachment__caption { margin-top: 0.6em; font-size: 0.8em; color: rgba(10,10,10,0.6); text-align: left; }

@media (min-width: 640px) { /* tablet ÷768 — exact Paper values (5K0L) */
  .article-content { font-size: 2.0833cqw; } /* body 16 */
  .article-content h2 { font-size: 6.25cqw; } /* 48 */
  .article-content h3 { font-size: 5.2083cqw; } /* 40 */
  .article-content h4 { font-size: 3.6458cqw; } /* 28 */
  .article-content blockquote { font-size: 5.2083cqw; } /* 40 */
  .article-content blockquote .article-quote__cite { font-size: 2.0833cqw; } /* 16 */
  .article-content img,
  .article-content figure img { border-radius: 1.5625cqw; } /* 12 */
}

@media (min-width: 1024px) { /* desktop ÷1440 — exact Paper values (5JY4) */
  .article-content { font-size: 1.1111cqw; max-width: 53.75cqw; } /* body 16; content column 774 */
  .article-content h2 { font-size: 4.1667cqw; } /* 60 */
  .article-content h3 { font-size: 3.0556cqw; } /* 44 */
  .article-content h4 { font-size: 2.2222cqw; } /* 32 */
  .article-content blockquote { font-size: 3.0556cqw; } /* 44 */
  .article-content blockquote .article-quote__cite { font-size: 1.1111cqw; } /* 16 — matches body */
  .article-content img,
  .article-content figure img { border-radius: 0.8333cqw; } /* 12 */
}

/* ── DS Tag (components/_tag) — Paper "Tag · Field Note": glass chip, Geist 12 sentence-case,
   h32 / radius8 / px12, blur 14.7. Fluid per band. Default = dark surface (white glass + white text);
   --light = on white backgrounds (black glass + black text). --active = filled. Base = mobile ÷375. */
.ds-tag { display: inline-flex; align-items: center; gap: 1.6cqw; flex-shrink: 0; white-space: nowrap;
  font-family: var(--font-body); font-weight: 400; line-height: 160%;
  height: 8.5333cqw; padding-inline: 3.2cqw; border-radius: 2.1333cqw; font-size: 3.2cqw; /* 32 / 12 / 8 / 12 @375 */
  background: rgba(255,255,255,0.07); color: #fff;
  -webkit-backdrop-filter: blur(3.92cqw); backdrop-filter: blur(3.92cqw); } /* 14.7 */
.ds-tag--light  { background: rgba(10,10,10,0.07); color: #0A0A0A; }
.ds-tag--active { background: #fff; color: #0A0A0A; }
.ds-tag--light.ds-tag--active { background: #0A0A0A; color: #fff; }
.ds-tag__dot { width: 1.6cqw; height: 1.6cqw; border-radius: 50%; background: var(--accent); flex-shrink: 0; } /* 6 */

@media (min-width: 640px) { /* tablet ÷768 */
  .ds-tag { gap: 0.7813cqw; height: 4.1667cqw; padding-inline: 1.5625cqw; border-radius: 1.0417cqw; font-size: 1.5625cqw;
    -webkit-backdrop-filter: blur(1.9141cqw); backdrop-filter: blur(1.9141cqw); }
  .ds-tag__dot { width: 0.7813cqw; height: 0.7813cqw; }
}
@media (min-width: 1024px) { /* desktop ÷1440 */
  .ds-tag { gap: 0.4167cqw; height: 2.2222cqw; padding-inline: 0.8333cqw; border-radius: 0.5556cqw; font-size: 0.8333cqw;
    -webkit-backdrop-filter: blur(1.0208cqw); backdrop-filter: blur(1.0208cqw); }
  .ds-tag__dot { width: 0.4167cqw; height: 0.4167cqw; }
}

/* ── Article header (sections/article/_01_header — Paper 5JWA-0) — LIGHT surface: breadcrumb +
   display title + category + meta (author · date · read-time) + full-bleed hero image. Clears the
   fixed site nav via top padding (160/160/120). Title reuses .about-display. Fluid per band. Base = mobile. */
.article-header { display: flex; flex-direction: column; align-items: flex-start; position: relative; background: #FFFFFF;
  padding: 32cqw 4.2667cqw 3.2cqw; gap: 8.5333cqw; } /* pt120 px16 pb12 gap32 @375 */
.article-header__wrap { display: flex; flex-direction: column; align-items: flex-start; align-self: stretch; gap: 6.4cqw; } /* title → tag: 24 @375 */
.article-header__titles { display: flex; flex-direction: column; align-items: flex-start; align-self: stretch; gap: 5.3333cqw; } /* 20 */

/* Breadcrumb — Blog / <title>, single line (current crumb truncates) */
.article-header__crumbs { display: flex; align-items: center; align-self: stretch; gap: 2.1333cqw; overflow: clip; } /* 8 */
.article-header__crumb { font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; color: #0A0A0A; opacity: 0.8; font-size: 3.2cqw; } /* 12 @375 */
.article-header__crumb--link, .article-header__crumb--sep { flex-shrink: 0; }
.article-header__crumb--link { transition: opacity 0.2s ease; }
.article-header__crumb--link:hover { opacity: 1; }
.article-header__crumb--current { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.article-header__title { color: #0A0A0A; line-height: 80%; font-size: 11.7333cqw; } /* 44 @375 (.about-display = axes + ls 0.02em) */

/* Meta row — DS tag (left) + author/date/read-time (40%). Mobile: stacked (tag above the meta line). */
.article-header__meta { display: flex; flex-direction: column; align-items: flex-start; align-self: stretch; gap: 6.4cqw; } /* mobile stacked; gap 24 */
.article-header__meta-inner { display: flex; align-items: center; opacity: 0.6; gap: 2.4cqw; } /* 9 — flat dot-separated row, hugs content (left on mobile, right of the tag on ≥640) */
.article-header__meta-inner span { font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; color: #000; font-size: 3.7333cqw; } /* 14 */
.article-header__dot { width: 1.0667cqw; height: 1.0667cqw; border-radius: 50%; background: #000; flex-shrink: 0; } /* 4 */

.article-header__hero { align-self: stretch; height: 53.3333cqw; border-radius: 2.1333cqw; background-size: cover; background-position: center; } /* h200 r8 @375 */

@media (min-width: 640px) { /* tablet ÷768 */
  .article-header { padding: 20.8333cqw 4.1667cqw 1.5625cqw; gap: 5.2083cqw; } /* pt160 px32 pb12 gap40 */
  .article-header__wrap { gap: 4.1667cqw; } /* title → tag: 32 @768 */
  .article-header__titles { gap: 2.6042cqw; } /* 20 */
  .article-header__crumbs { gap: 1.0417cqw; } /* 8 */
  .article-header__crumb { font-size: 1.5625cqw; } /* 12 */
  .article-header__title { font-size: 7.8125cqw; } /* 60 */
  .article-header__meta { flex-direction: row; align-items: center; justify-content: space-between; gap: 3.125cqw; } /* 24 — tag left, meta right */
  .article-header__meta-inner { gap: 1.1719cqw; } /* 9 */
  .article-header__meta-inner span { font-size: 1.8229cqw; } /* 14 */
  .article-header__dot { width: 0.5208cqw; height: 0.5208cqw; } /* 4 */
  .article-header__hero { height: 52.0833cqw; border-radius: 1.0417cqw; } /* h400 r8 */
}

@media (min-width: 1024px) { /* desktop ÷1440 */
  .article-header { padding: 11.1111cqw 1.6667cqw 4.4444cqw; gap: 2.7778cqw; } /* pt160 px24 pb64 gap40 */
  .article-header__wrap { gap: 2.7778cqw; } /* 40 */
  .article-header__titles { gap: 1.3889cqw; } /* 20 */
  .article-header__crumbs { gap: 0.5556cqw; } /* 8 */
  .article-header__crumb { font-size: 0.8333cqw; } /* 12 */
  .article-header__title { font-size: 6.1111cqw; max-width: 64.0278cqw; } /* 88; w-922 */
  .article-header__meta { gap: 1.6667cqw; } /* 24 (row from ≥640) */
  .article-header__meta-inner { gap: 0.625cqw; } /* 9 */
  .article-header__meta-inner span { font-size: 0.9722cqw; } /* 14 */
  .article-header__dot { width: 0.2778cqw; height: 0.2778cqw; } /* 4 */
  .article-header__hero { height: 42.5cqw; border-radius: 0.5556cqw; } /* h612 r8 */
}

/* ── Article body (sections/article/_body — Paper 5JY4) — light surface below the header. Desktop:
   774 content column (Trix render + share + newsletter) left, 318 sticky TOC right. Tablet/mobile:
   single column, TOC hidden. Header owns the title + top spacing. Base = mobile. */
.article-body { display: flex; flex-direction: column; align-items: stretch; background: #FFFFFF; color: #0A0A0A; position: relative;
  padding: 10.6667cqw 4.2667cqw 16cqw; } /* pt40 px16 pb60 @375 — top is the gap from the hero */
.article-body__main { display: flex; flex-direction: column; align-items: flex-start; gap: 12.8cqw; } /* 48 between content / share / newsletter */

/* In-article TOC — desktop only (hidden below 1024) */
.article-toc { display: none; }

/* Share row — "Share" + DS secondary buttons (light) with logos */
.article-share { display: flex; align-items: center; flex-wrap: wrap; gap: 2.1333cqw; } /* 8 (matches 404 actions) */
.article-share__label { font-family: var(--font-display); font-variation-settings: "wght" 500, "wdth" 55; text-transform: uppercase; letter-spacing: 0.1em; line-height: 140%; color: #0A0A0A; opacity: 0.8; font-size: 3.2cqw; } /* 12 */
.ds-btn__icon { width: 1.3em; height: 1.3em; flex-shrink: 0; }

@media (min-width: 640px) { /* tablet ÷768 */
  .article-body { padding: 7.8125cqw 4.1667cqw 10.4167cqw; } /* pt60 px32 pb80 */
  .article-body__main { gap: 7.8125cqw; } /* 60 */
  .article-share { gap: 1.0417cqw; } /* 8 */
  .article-share__label { font-size: 1.5625cqw; } /* 12 */
}

@media (min-width: 1024px) { /* desktop ÷1440 */
  .article-body { flex-direction: row; align-items: flex-start; justify-content: space-between; gap: 1.6667cqw;
    padding: 4.4444cqw 1.6667cqw 8.3333cqw; } /* pt64 px24 pb120 gap24 */
  .article-body__main { width: 53.75cqw; flex-shrink: 0; gap: 5.5556cqw; } /* 774; 80 */
  .article-share { gap: 0.5556cqw; } /* 8 */
  .article-share__label { font-size: 0.8333cqw; } /* 12 */

  /* Sticky TOC (right rail) */
  .article-toc { display: block; width: 22.0833cqw; flex-shrink: 0; position: sticky; top: 8.3333cqw; align-self: flex-start; } /* 318; top120 */
  .article-toc--empty { display: none; }
  .article-toc__inner { display: flex; align-items: flex-start; gap: 1.6667cqw; } /* 24 */
  .article-toc__track { position: relative; align-self: stretch; width: 2px; flex-shrink: 0; }
  .article-toc__track::before { content: ""; position: absolute; left: 0; top: 0; width: 1px; height: 100%; background: #DDDDDD; }
  .article-toc__indicator { position: absolute; left: 0; top: 0; z-index: 1; width: 2px; height: 0; background: #181818; transition: transform 0.25s ease, height 0.25s ease; } /* 2px active marker, over the 1px rail (Paper w-0.5) */
  .article-toc__list { display: flex; flex-direction: column; flex: 1; list-style: none; margin: 0; padding: 0; }
  .article-toc__item { padding-bottom: 0.8333cqw; border-bottom: 1px solid rgba(10,10,10,0.1); } /* 12 */
  .article-toc__item + .article-toc__item { padding-top: 0.8333cqw; } /* 12 */
  .article-toc__link { display: block; font-family: var(--font-body); font-size: 0.9722cqw; line-height: 160%; color: #0A0A0A; opacity: 0.7; transition: opacity 0.2s ease; } /* 14 */
  .article-toc__link:hover { opacity: 1; }
  .article-toc__link.is-active { opacity: 1; }
}

/* Kill page-level horizontal scroll globally (the <body> clip alone wasn't catching the hero's 156% mask /
   scale-110 backdrop on the static lg:sticky stage). clip on X keeps Y scrollable + sticky working. */
html { overflow-x: clip; overscroll-behavior: none; scrollbar-gutter: stable; } /* overscroll-behavior: kill the trackpad rubber-band bounce; scrollbar-gutter: reserve the scrollbar's space permanently so locking scroll (image lightbox / video modal / nav drawer) never shifts the layout when the bar disappears. No effect on macOS overlay scrollbars (which don't take space anyway). */

/* Lenis smooth scroll (smooth_scroll controller) — required base CSS. The `lenis`/`lenis-smooth` classes are
   added to <html> while Lenis runs. `scroll-behavior: auto` disables native smooth-scroll that would fight
   Lenis; height auto keeps the document scroller normal; [data-lenis-prevent] opts a nested scroller out. */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }
.lenis.lenis-scrolling iframe { pointer-events: none; }

/* Turbo Drive navigation progress bar (the blue bar at the top during page transitions) — hidden for now. */
.turbo-progress-bar { display: none; }

/* ─────────────────────────────────────────────────────────────────────────────────────────────────────
   REVEAL-ON-VIEW ANIMATIONS — the project's single, shared reveal primitive (driven by reveal_controller).
   Supportive, not loud. Distances in `em` so they scale with the element's own font size.
   Variants (set via data-reveal):
     • mask  — text slides up from behind a clip ("parallax text" for headings / line reveal for small copy).
     • rise  — element drifts up a little while fading in (default for cards, blocks).
     • fade  — opacity only (media / where transform is owned by another controller, e.g. the hero card).
   Timing: each item waits  --reveal-base (group offset) + --reveal-i (DOM index, set by JS) × step.
   Hidden state is gated on .reveal-on (JS present) and disabled under reduced motion.                      */
:root { --reveal-step: 0.09s; --reveal-ease: cubic-bezier(0.22, 1, 0.36, 1); }

/* hidden start state */
.reveal-on [data-reveal]:not([data-reveal~="mask"]) { opacity: 0; transition: opacity 0.7s ease, transform 0.9s var(--reveal-ease); transition-delay: calc(var(--reveal-base, 0s) + var(--reveal-i, 0) * var(--reveal-step)); }
.reveal-on [data-reveal~="rise"] { transform: translateY(1.6em); }
.reveal-on [data-reveal~="media"] { transform: translateY(28px) scale(0.965); } /* media rises + grows into place while fading in */
.reveal-on [data-reveal~="mask"] { overflow: clip; padding-bottom: 0.12em; margin-bottom: -0.12em; } /* pad/-margin so descenders aren't clipped */
.reveal-line { display: block; } /* a split line (data-reveal="lines" → per-line masks) stacks vertically */
.reveal-on [data-reveal~="mask"] > * { display: block; opacity: 0; transform: translateY(110%); transition: transform 1s var(--reveal-ease), opacity 0.8s ease; transition-delay: calc(var(--reveal-base, 0s) + var(--reveal-i, 0) * var(--reveal-step)); } /* slide up from behind the clip + soft fade */

/* revealed state (.is-in added to the container, or to the element itself) */
/* `.is-in` is set on each ITEM (not the container) so reveal never leaks to a nested reveal container's
   items (e.g. cards inside a revealed FeaturedCase column). Item-self selectors only. */
.reveal-on [data-reveal].is-in:not([data-reveal~="mask"]) { opacity: 1; transform: none; }
.reveal-on [data-reveal~="mask"].is-in > * { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal-on [data-reveal], .reveal-on [data-reveal] > * { opacity: 1 !important; transform: none !important; }
}
/* The big footer wordmark reveals LAST, a bit later (+0.3s delay) and a bit slower (+0.2s duration). */
.reveal-on .footer-wordmark[data-reveal] { transition: opacity 1.4s ease, transform 1.6s var(--reveal-ease); transition-delay: 0.21s; }

/* FeaturedCase reveal split by band:
   • Desktop (≥1024) — the whole photo column fades in as ONE block; individual cards are NOT revealed. */
@media (min-width: 1024px) {
  /* Inner card items don't individually animate on desktop (the column block-fades). transform:none also keeps
     the glass tags' backdrop-filter intact. The PHOTO keeps its active/dim opacity (lives on the child). */
  /* The services wrapper stays opacity:1 + transform:none (no group → the tags' backdrop-filter keeps its
     backdrop). The tags' dim lives on .ds-tag itself (above), so it isn't a [data-reveal] concern here. */
  .reveal-on .featured-card [data-reveal]:not(.featured-card__photo) { opacity: 1 !important; transform: none !important; }
  .reveal-on .featured-scroll .featured-card__photo[data-reveal] { opacity: 0.3 !important; transform: none !important; }
  .reveal-on .featured-scroll .featured-card.is-active .featured-card__photo[data-reveal] { opacity: 1 !important; }
}
/* • Tablet/mobile (<1024) — each card reveals one-by-one as it enters; the column block-fade is cancelled. */
@media (max-width: 1023px) {
  .reveal-on .featured-scroll[data-reveal] { opacity: 1 !important; transform: none !important; }
}

/* ── Home Hero — ALT version (sections/home/_01_hero_v2). Desktop: scroll effect (hero_scroll_v2 sets
   height 250vh; stage is lg:sticky lg:h-screen). Tablet/mobile: NO 100vh — standard hero top/bottom
   padding (clears the fixed nav), content flows; the square video sits under the text. */
/* z-index lifts the hero above the next section so its blurred backdrop (which overflows the stage
   vertically — overflow-y:visible) bleeds OVER the top of the logos strip instead of being cut. We do NOT
   clip the section here — that would re-clip the vertical bleed. Horizontal overflow (156% mask, scale-110
   backdrop) is caught globally by `html { overflow-x: clip }` instead. */
.hero-v2 { position: relative; z-index: 1; padding-top: 32cqw; padding-bottom: 0; } /* mobile pt 120; no bottom pad (next block provides the gap) */
@media (min-width: 640px)  { .hero-v2 { padding-top: 20.8333cqw; } } /* tablet pt 160 */
@media (min-width: 1024px) { .hero-v2 { padding-block: 0; } }        /* desktop: scroll effect uses full height */

/* Home hero v2 Play button — mobile: icon-only square; tablet+/desktop: labelled glass pill (mirrors
   .glass-pill / --icon scaling exactly). All per-band cqw so it scales with the viewport (was fixed px,
   so it didn't scale). The desktop hero-video controller animates only its position/opacity, not its size. */
.hero-play {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 9.6cqw; height: 9.6cqw; border-radius: 1.6cqw; /* 36 / 6 @375 */
  background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); color: #fff;
}
.hero-play__icon { width: 3.2cqw; height: 3.2cqw; flex-shrink: 0; } /* 12 @375 */
@media (min-width: 640px) { /* tablet — still the icon-only square (like mobile), own 768 anchor */
  .hero-play { width: 6.25cqw; height: 6.25cqw; border-radius: 1.0417cqw; } /* 48 / 8 @768 */
  .hero-play__icon { width: 2.0833cqw; height: 2.0833cqw; } /* 16 @768 */
}
@media (min-width: 1024px) { /* desktop only → labelled glass pill (matches .glass-pill--icon desktop) */
  .hero-play { width: auto; height: auto; gap: 0.5556cqw; border-radius: 0.4167cqw; padding: 0.5556cqw 0.8333cqw 0.5556cqw 0.5556cqw; }
  .hero-play__icon { width: 0.8333cqw; height: 0.8333cqw; } /* 12 @1440 */
}

/* Gallery video cell (Projects, video: :popup) — the poster fills the cell, this button is the click target,
   and .play-badge sits centred. The whole area is clickable → opens the showreel modal. A subtle scale-up of
   the badge on hover signals "click to play" (no cursor pill; the page cursor is unchanged). */
.gallery-video, .gallery-photo { position: absolute; inset: 0; width: 100%; height: 100%; display: block; margin: 0; padding: 0; border: 0; background: transparent; cursor: pointer; }
.play-badge {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 9.6cqw; height: 9.6cqw; border-radius: 1.6cqw; /* 36 / 6 @375 — icon-only square, like hero mobile */
  background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); color: #fff;
  transition: transform 200ms ease, background-color 200ms ease; pointer-events: none;
}
.play-badge__icon { width: 3.2cqw; height: 3.2cqw; flex-shrink: 0; } /* 12 @375 */
.gallery-video:hover .play-badge { transform: translate(-50%, -50%) scale(1.12); background: rgba(0, 0, 0, 0.8); }
/* Lazy Vimeo preview (video: :preview) — injected over the poster by vimeo_preview_controller when the cell
   nears the viewport, faded in on load. pointer-events:none so a click passes through to open the modal.
   z-index layers it above the poster and below the play badge. background=1 embeds fill the frame. */
.gallery-preview-iframe { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 100%; height: 100%; border: 0; z-index: 1; pointer-events: none; opacity: 0; transition: opacity 400ms ease; } /* JS oversizes width/height to COVER the cell (cell clips overflow); 100% is the pre-measure fallback */
.gallery-preview-iframe.is-loaded { opacity: 1; }
.gallery-video .play-badge { z-index: 2; }
/* Media zooms ~2% on hover (video posters AND clickable photos), same easing as the badge (base scale 1.02 is
   the overscan → hover 1.04). Signals the cell is clickable (video → modal, photo → lightbox). */
.gallery-video .gallery-media, .gallery-photo .gallery-media { transition: transform 200ms ease; }
.gallery-video:hover .gallery-media, .gallery-photo:hover .gallery-media { transform: scale(1.04); }
@media (min-width: 640px) { /* tablet ÷768 */
  .play-badge { width: 6.25cqw; height: 6.25cqw; border-radius: 1.0417cqw; } /* 48 / 8 @768 */
  .play-badge__icon { width: 2.0833cqw; height: 2.0833cqw; } /* 16 @768 */
}
@media (min-width: 1024px) { /* desktop ÷1440 — stays an icon-only square (not a pill) */
  .play-badge { width: 3.3333cqw; height: 3.3333cqw; border-radius: 0.5556cqw; } /* 48 / 8 @1440 */
  .play-badge__icon { width: 1.1111cqw; height: 1.1111cqw; } /* 16 @1440 */
}

/* ── Showreel video modal (video_modal controller, shared/_video_modal). The heavy Vimeo iframe is injected
   on open, removed on close. Rendered OUTSIDE .page-scale (cqw falls back to the viewport), so desktop sizes
   are wrapped in min(cqw, px@1920) to cap at 1920 like the rest of the site. Overlay + 16:9 box mirror
   proofofwork.studio; the controls are SQUARE GLASS buttons sized to the DS button height (32px/band, r4). */
.vmodal-overlay {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.9);
  opacity: 0; visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s ease;
}
.vmodal-overlay.is-active { opacity: 1; visibility: visible; }
/* Box takes the REAL video aspect ratio (--vmodal-ar, set by the controller from the Vimeo SDK — default 16:9),
   then is contained inside the viewport: width is the smaller of 90vw, a 1200px cap, and the width that keeps
   height ≤ 85vh (85vh × ar). So a wide video is width-bound and a vertical one height-bound — no letterbox,
   and the controls (anchored to this box) land on the video's actual corners for any ratio. */
.vmodal { position: relative; --vmodal-ar: 1.7778; aspect-ratio: var(--vmodal-ar); width: min(90vw, 1200px, calc(85vh * var(--vmodal-ar))); }
.vmodal__iframe { width: 100%; height: 100%; border: 0; border-radius: 8px; pointer-events: none; } /* video is inert — only the dim backdrop and the X button close the modal */
.vmodal__close-btn { position: absolute; right: 12px; top: 12px; z-index: 3; } /* X — top-right of the video, same offset as the controls (mirrored to the top) */
.vmodal__controls { position: absolute; right: 12px; bottom: 12px; z-index: 3; display: flex; gap: 10px; } /* tablet/mobile: 12px from the VIDEO box's bottom-right corner */
.vmodal__controls[hidden] { display: none; }
.vmodal__ctrl {
  display: inline-flex; align-items: center; justify-content: center;
  width: 8.5333cqw; height: 8.5333cqw; border-radius: 1.0667cqw; /* 32 / 4 @375 — DS button height, square */
  background: rgba(0, 0, 0, 0.6); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 0; cursor: pointer; transition: background-color 0.2s ease;
}
.vmodal__ctrl:hover { background: rgba(0, 0, 0, 0.85); }
.vmodal__icon { width: 3.7333cqw; height: 3.7333cqw; fill: #fff; display: block; } /* 14 @375 */
.vmodal__icon[hidden] { display: none; }
@media (min-width: 640px) {
  .vmodal__ctrl { width: 4.1667cqw; height: 4.1667cqw; border-radius: 0.5208cqw; } /* 32 / 4 @768 */
  .vmodal__icon { width: 1.8229cqw; height: 1.8229cqw; } /* 14 @768 */
}
@media (min-width: 1024px) {
  .vmodal__controls { position: absolute; right: 20px; bottom: 20px; } /* desktop: back onto the video box (pow) */
  .vmodal__close-btn { right: 20px; top: 20px; } /* X mirrors the controls' desktop offset */
  .vmodal__ctrl { width: min(2.2222cqw, 42.67px); height: min(2.2222cqw, 42.67px); border-radius: min(0.2778cqw, 5.33px); } /* 32 / 4 @1440, capped @1920 */
  .vmodal__icon { width: min(0.9722cqw, 18.67px); height: min(0.9722cqw, 18.67px); } /* 14 @1440 */
}

/* ── Image lightbox (image_lightbox controller, shared/_image_lightbox). Same dim overlay + DS glass close
   button as the video modal; reuses .vmodal__ctrl / .vmodal__icon for the X. The full (uncropped) photo is
   fitted to the viewport — as large as it goes while staying fully visible (contain), so it never looks tiny. */
.imgbox-overlay {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.9);
  opacity: 0; visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s ease;
}
.imgbox-overlay.is-active { opacity: 1; visibility: visible; }
.imgbox { position: relative; margin: 0; display: flex; max-width: 92vw; max-height: 92vh; } /* shrink-wraps the image so the X sits at the photo's corner */
.imgbox__img { display: block; max-width: 92vw; max-height: 92vh; width: auto; height: auto; object-fit: contain; border-radius: 8px; } /* fit-to-screen, large by whichever side binds (tall photos → full height) */
.imgbox__close { position: absolute; right: 12px; top: 12px; z-index: 3; } /* DS glass X (.vmodal__ctrl), top-right of the photo */
@media (min-width: 1024px) { .imgbox__close { right: 20px; top: 20px; } }

/* Draft-preview ribbon — shown only on admin preview renders (@preview), so a preview is never mistaken for
   the live, published page. Fixed, above everything, non-interactive. */
.preview-ribbon { position: fixed; left: 50%; bottom: 16px; transform: translateX(-50%); z-index: 10001; pointer-events: none; background: #b45309; color: #fff; font: 500 12px/1 system-ui, -apple-system, sans-serif; letter-spacing: 0.04em; text-transform: uppercase; padding: 9px 16px; border-radius: 999px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35); }

/* Shared media hero v2 (About / Service / For Agencies) — same responsive shape as .hero-v2: tablet/mobile
   drop the 100vh for a standard hero TOP padding (content flows); desktop uses the full scroll height.
   NO bottom padding — the next block's own top padding is the only gap (avoids a doubled gap). */
.hero-media-v2 { position: relative; z-index: 1; padding-top: 32cqw; padding-bottom: 16cqw; } /* mobile top 120; bottom 60 = next section's bottom pad (desktop image stays flush) */
/* Extend the section background to the screen edges (no gutters above 1920) without moving the
   JS-centred content (which assumes a 1920-wide stage). background:inherit picks up the section's own
   colour — white for the light (About / For Agencies) hero, dark for the Service hero. */
.hero-media-v2::before { content: ""; position: absolute; top: 0; bottom: 0; left: calc(50% - 50vw); width: 100vw; background-color: inherit; z-index: -1; pointer-events: none; }
@media (min-width: 640px)  { .hero-media-v2 { padding-top: 20.8333cqw; padding-bottom: 10.4167cqw; } } /* tablet pt 160; bottom 80 = next section's bottom pad */
@media (min-width: 1024px) { .hero-media-v2 { padding-top: 0; padding-bottom: 0; } } /* desktop: scroll height; no bottom pad */
/* Blurred backdrop of the hero image — same image, behind the card (full card width, 70% height, centred).
   The hero-media-v2 controller sets width/height/left/top inline to track the card as it scroll-grows; here
   only the look: cover the box, soft-blur it, 75% opacity. Fixed-px blur per band (32 / 64 / 110). */
.hero-media-v2__blur { position: absolute; z-index: 0; pointer-events: none; background-size: cover; background-position: center; opacity: 0; transition: opacity 0.5s ease; filter: blur(32px); }
.hero-media-v2__blur.is-shown { opacity: 0.75; } /* revealed only after the main image loads (controller) — never paints before it */
@media (min-width: 640px)  { .hero-media-v2__blur { filter: blur(64px); } }
@media (min-width: 1024px) { .hero-media-v2__blur { filter: blur(110px); } .hero-media-v2__blur.is-shown { opacity: 0.65; } } /* desktop: lighter (0.65), taller (85% — set in controller) */

/* ── Custom cursor (DESKTOP ≥1024) — a 10px dot following the mouse; recolours by the section theme under it
   (white on dark, black on light); morphs into the existing glass-pill (reading its label) over any
   hover area. Sizing/padding come from CSS (matches .glass-pill exactly): the label sits in a grid column
   that animates 0fr→1fr, so the dot grows into the pill smoothly without any JS measurement. Managed by
   cursor_controller; per-card pills + the hero play button are hidden while it's active. */
.cursor {
  position: fixed; top: 0; left: 0; z-index: 10000; pointer-events: none; /* above the video modal (9999) so the dot/pill shows over it */
  display: grid; grid-template-columns: 0fr; place-items: center;
  width: auto; min-width: 10px; height: 10px;
  padding: 0; border-radius: 999px; background: #fff; overflow: hidden; opacity: 0;
  transform: translate(-50%, -50%);
  transition: grid-template-columns .35s cubic-bezier(.22,1,.36,1), height .35s cubic-bezier(.22,1,.36,1),
              padding .35s cubic-bezier(.22,1,.36,1), border-radius .35s cubic-bezier(.22,1,.36,1),
              background-color .25s ease, opacity .25s ease;
  will-change: transform;
}
.cursor--visible { opacity: 1; }
.cursor--light   { background: #000; }
/* The cursor lives on <body>, OUTSIDE .page-scale, so cqw here falls back to the viewport (uncapped). Wrap
   each size in min(cqw, px@1920) so it freezes at the 1920 value too — matching the capped on-page pills. */
.cursor__label {
  min-width: 0; overflow: hidden; white-space: nowrap;
  font-family: var(--font-body); font-size: min(0.6944cqw, 13.33px); line-height: 130%;
  text-transform: uppercase; color: #fff; opacity: 0; transition: opacity .2s ease;
}
.cursor--pill { /* matches .glass-pill desktop: padding 0.5556/0.8333cqw, radius 0.4167cqw, black 60% + blur */
  grid-template-columns: 1fr; min-width: 0; height: min(2.0139cqw, 38.67px); /* 29 = label 13 + 16 pad */
  padding: min(0.5556cqw, 10.67px) min(0.8333cqw, 16px); border-radius: min(0.4167cqw, 8px);
  background: rgba(0, 0, 0, 0.6); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
.cursor--pill .cursor__label { opacity: 1; }
/* Over a LIGHT section the morphed pill is white glass + black label (instead of black) — matches the
   light-surface design (e.g. What We Make / capabilities). .cursor--light is set by the cursor controller. */
.cursor--light.cursor--pill { background: rgba(255, 255, 255, 0.2); }
.cursor--light.cursor--pill .cursor__label { color: #000; }
/* Carousel prev/next: a chevron next to the label (‹ Prev / Next ›), colour follows the label (currentColor). */
.cursor--dir-prev .cursor__label, .cursor--dir-next .cursor__label { display: inline-flex; align-items: center; gap: 0.5em; }
.cursor--dir-next .cursor__label::after { content: ""; flex-shrink: 0; width: 0.36em; height: 0.36em; border-top: 1.5px solid currentColor; border-right: 1.5px solid currentColor; transform: rotate(45deg); }
.cursor--dir-prev .cursor__label::before { content: ""; flex-shrink: 0; width: 0.36em; height: 0.36em; border-top: 1.5px solid currentColor; border-left: 1.5px solid currentColor; transform: rotate(-45deg); }

@media (min-width: 1024px) {
  body.has-custom-cursor *:not(input):not(textarea):not([contenteditable]) { cursor: none; }
  body.has-custom-cursor .cursor-pill { display: none !important; } /* the dot replaces the per-card pills */
  body.has-custom-cursor [data-hero-video-target="playButton"] { display: none !important; } /* …and the hero play pill (the card itself stays clickable) */
}

/* ── Scale cap at 1920 (cqw freeze) ──────────────────────────────────────────────────────────────────
   All fluid sizing uses cqw (1% of the nearest query container). .page-scale wraps the page content; when
   .is-capped (set per page via @scale_capped) it caps at 1920 and centres, so cqw — and therefore every
   font/space/size — freezes above 1920 while the content stays centred (page bg fills the side gutters).
   Uncapped pages keep .page-scale as a plain wrapper; with no container, cqw falls back to the viewport,
   i.e. behaves exactly like the old vw. Below 1920 the capped pages are pixel-identical too (container =
   viewport). The fixed header is outside .page-scale, so it gets its own cap on its inner surface. */
.page-scale.is-capped { container-type: inline-size; max-width: 1920px; margin-inline: auto; }
/* Header: the surface (blurred dark bg) stays FULL-WIDTH to the screen edges; only the inner .site-header__cap
   caps the content (bar + dropdown) at 1920 centred + provides the cqw container for its sizing. */
.scale-capped .site-header__cap { container-type: inline-size; max-width: 1920px; margin-inline: auto; }

/* Full-bleed: break an element out of the 1920 .page-scale container to span the whole viewport width
   (50% = half the 1920 container, 50vw = half the viewport → spreads to the screen edges). Below 1920 it's
   a no-op (container = viewport). Use on ambient/marquee/cover layers that should reach the screen edges
   while text content (sized in cqw) stays capped & centred. vw here is intentional (viewport, not cqw). */
.full-bleed { width: 100vw; margin-inline: calc(50% - 50vw); }

/* ───────────────────────────────────────────────────────────────────────────
   Thank-you screen (/thank-you) — Paper 5KJZ-0 (desktop) / 5KKL-0 (tablet) / 5KL7-0 (mobile).
   Min 100vh every band; justify-between keeps THANK YOU + newsletter up top and pins Locations to the
   bottom. Backdrop = the same WebGL beam as the Contact page (shared/_gl_backdrop). Newsletter field
   reuses .footer-email* (shared/_newsletter_form, dark); Locations label reuses .ds-kicker (hero eyebrow).
   Base = mobile ÷375; @640 tablet ÷768; @1024 desktop ÷1440.
   ─────────────────────────────────────────────────────────────────────────── */
.thanks {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: space-between;
  min-height: 100vh; min-height: 100dvh; overflow: clip; background: #0B0B0B;
  padding: 32cqw 4.2667cqw 16cqw; gap: 10.6667cqw; /* pt120 px16 pb60 gap40 @375 */
}
.thanks__bg { position: absolute; inset: 0; z-index: 0; }
.thanks__bg .gl-backdrop { position: absolute; inset: 0; width: 100%; height: 100%; }
.thanks__main { position: relative; z-index: 1; } /* .contact__locations already gets z-index:1 from its own rule */

.thanks__main { display: flex; flex-direction: column; align-items: center; gap: 10.6667cqw; } /* 40 */
.thanks__head { display: flex; flex-direction: column; align-items: center; gap: 4.2667cqw; } /* 16 */
.thanks__title { color: #fff; opacity: 0.9; text-transform: uppercase; line-height: 80%; letter-spacing: 0.02em; text-align: center; font-size: 11.7333cqw; } /* 44 */
.thanks__sub { color: rgba(255,255,255,0.8); text-align: center; } /* font + width via .hero-sub */

.thanks__news { display: flex; flex-direction: column; align-items: center; gap: 4.2667cqw; } /* 16 */
.thanks__news .footer-email-form { align-items: center; } /* centre the field on this dark surface */
.thanks__news-title { color: #fff; opacity: 0.9; text-transform: uppercase; line-height: 110%; text-align: center; max-width: 57.6cqw; font-size: 5.3333cqw; } /* 20; 216 */

@media (min-width: 640px) { /* tablet ÷768 */
  .thanks            { padding: 20.8333cqw 4.1667cqw 10.4167cqw; gap: 7.8125cqw; } /* pt160 px32 pb80 gap60 */
  .thanks__main      { gap: 7.8125cqw; } /* 60 */
  .thanks__head      { gap: 2.0833cqw; } /* 16 */
  .thanks__title     { font-size: 11.4583cqw; } /* 88 */
  .thanks__news      { gap: 2.0833cqw; } /* 16 */
  .thanks__news-title { font-size: 2.6042cqw; max-width: 22.9167cqw; } /* 20; 176 */
}

@media (min-width: 1024px) { /* desktop ÷1440 */
  .thanks            { padding: 11.1111cqw 11.25cqw 5.5556cqw; gap: 5.5556cqw; } /* pt160 px162 pb80 gap80 */
  .thanks__main      { gap: 5.5556cqw; } /* 80 */
  .thanks__head      { gap: 1.1111cqw; } /* 16 */
  .thanks__title     { font-size: 9.0278cqw; } /* 130 @1440 (was 160) */
  .thanks__news      { gap: 1.1111cqw; } /* 16 */
  .thanks__news-title { font-size: 1.6667cqw; max-width: 15cqw; } /* 24; 216 */
}
