/* ============================================================
   C.W. DENISON DESIGN CO. — Portfolio
   styles.css  —  hand-written, no framework, no build step.
   Fluid clamp() values reproduce the responsive behaviour of the
   approved design. See TOKENS.md for the flat value list.
   ============================================================ */

/* ---- Design tokens as CSS custom properties ---------------- */
:root {
  /* Color */
  --canvas:        #FBFBFA;  /* page background */
  --canvas-cases:  #F4F4F1;  /* case-study band — slightly darker off-white (v0.43, tunable) */
  --ink:           #14161A;  /* primary text, hairline rules */
  --brand-cyan:    #00C8FF;  /* "C.W. DENISON" lockup line 1 */
  --muted:         #8A8F97;  /* "DESIGN CO.", tagline, meta labels */
  --accent:        #00C8FF;  /* links, section labels, disciplines — the brand cyan (v0.27) */
  --accent-hover:  #00A8D6;  /* link hover — the cyan darkened ~16% */
  --accent-soft:   #00C8FF;  /* accent on dark backgrounds — same cyan (v0.27), token kept for semantics */
  --text-2:        #54585F;  /* secondary body */
  --text-3:        #3A3D44;  /* project summary */
  --text-4:        #2A2D33;  /* overview body */
  --dark:          #101216;  /* dark sections (heroes, footer) */
  --page-blue:     #0099FF;  /* blue pages (Contact + About) — also the fallback under their background images */
  --line:          #E7E7E4;  /* hairline borders */
  --ph-light-txt:  #B4B7B1;  /* placeholder label on light tiles */
  --ph-dark-txt:   #3C424B;  /* placeholder label on dark tiles */

  /* Placeholder stripe fills (swap for real <img> in production) */
  --ph-light: repeating-linear-gradient(135deg,#ECEDEA 0 13px,#F4F5F2 13px 26px);
  --ph-dark:  repeating-linear-gradient(135deg,#15181D 0 14px,#1D2128 14px 28px);

  /* Radii */
  --radius-card: 20px;
  --radius-btn:  2px;

  /* Layout maxima */
  --max-module: 1184px; /* the 4-cell grid module (§4.4) — EVERY home band aligns to this */
  --max-wide:  1600px;  /* outer grid wrapper (inert; .shots caps itself) */
  --max-text:  1500px;  /* project detail pages */
  --max-intro:  900px;  /* centered intro statement — the one narrower exception */

  /* Fluid gutter used as horizontal page padding everywhere */
  --gutter: clamp(20px, 5vw, 56px);
  --grid-gap: clamp(18px, 2vw, 28px);
}

/* ---- Reset ------------------------------------------------- */
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: 'Barlow', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  -webkit-font-smoothing: antialiased;
}
::selection { background: #1466FF; color: #fff; }   /* kept darker than the cyan accent so selected text stays readable */
img { display: block; max-width: 100%; }

a { color: var(--accent); text-decoration: none; transition: color .2s ease; }
a:hover { color: var(--accent-hover); }
a:focus-visible,
button:focus-visible {
  outline: 2px solid #1466FF;   /* kept darker than the cyan accent — a cyan ring wouldn't read on the off-white canvas */
  outline-offset: 3px;
  border-radius: 2px;
}

/* ============================================================
   HEADER / NAV
   ============================================================ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 60;
  background: rgba(251,251,250,0.86);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  padding: 50px var(--gutter);
}

/* Brand lockup */
.brand { line-height: 1; cursor: pointer; background: none; border: 0; padding: 0; text-align: left; }
.brand__line1 { font-size: 23px; font-weight: 700; letter-spacing: 0.1em; color: var(--brand-cyan); }
.brand__line2 { font-size: 24px; font-weight: 500; letter-spacing: 0.1em; color: var(--muted); margin-top: 4px; }

/* (the .tagline "Product Design + Identity + Environment" line was removed
   in the v1.21 nav redesign — the nav now fills the header's right side) */

/* Right-aligned inline nav (§3.1, v1.21): CASE STUDIES · SERVICES · ABOUT ·
   CONTACT — SemiBold 20px, uppercase, 2.4px tracking (0.12em so it scales
   with the fluid size before the ≤720 hamburger takes over). */
.nav {
  display: flex;
  align-items: center;
  margin-left: auto;              /* stays on the right edge even if the header row wraps */
  gap: clamp(12px, 1.5vw, 20px);
  font-size: clamp(15px, 1.6vw, 20px);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1;
}
.nav > a,
.nav__dd-label { color: var(--ink); transition: color .2s ease; }
.nav > a:hover,
.nav__dd-label:hover { color: var(--accent); }
/* the current page's item reads brand cyan (v1.21 — was bold-700;
   set via aria-current in the HTML) */
.nav > a[aria-current="page"] { color: var(--accent); }
.nav__sep { font-weight: 300; color: #b0b0b0; }   /* the | dividers — Barlow Light */

/* CASE STUDIES dropdown (v1.21) — the label is a button, not a link;
   the menu opens on hover / .is-open (click, wired in app.js/project.js)
   and stays open over label + items. */
.nav__dd { position: relative; }
.nav__dd-label {
  appearance: none; -webkit-appearance: none;
  border: 0; background: none; padding: 0;
  font: inherit; letter-spacing: inherit; text-transform: inherit;
  cursor: pointer;
}
.nav__dd-menu {
  position: absolute; top: 100%; left: 50%;
  transform: translateX(-50%);
  padding-top: 14px;              /* hover bridge — the pointer can cross label→card */
  z-index: 70;
  opacity: 0; visibility: hidden;
  transition: opacity .18s ease, visibility 0s linear .18s;
}
.nav__dd:hover .nav__dd-menu,
.nav__dd.is-open .nav__dd-menu {
  opacity: 1; visibility: visible;
  transition: opacity .18s ease;
}
.nav__dd-card {                   /* white card, same recipe as the mobile menu card */
  display: flex; flex-direction: column; gap: 18px;
  background: #fff;
  border-radius: 14px;
  box-shadow: 0 0 6.8px 2.8px rgba(0,0,0,0.08);
  padding: 20px 26px;
  text-transform: none;           /* items read "01 PlayStation", not uppercase */
  white-space: nowrap;
}
.nav__dd-card a { color: var(--ink); }
.nav__dd-num { color: #b0b0b0; margin-right: 10px; }
.nav__dd-card a:hover,
.nav__dd-card a:hover .nav__dd-num { color: var(--accent); }
@media (prefers-reduced-motion: reduce) {
  .nav__dd-menu { transition: none; }
}

/* Hamburger button — hidden on desktop, shown < 720px */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  width: 44px; height: 44px;      /* 44px min hit target */
  border: 0; background: none; cursor: pointer;
  padding: 0;
}
.nav-toggle span {
  display: block; height: 2px; width: 26px;
  background: var(--ink);
  transition: transform .3s ease, opacity .2s ease;
}

/* Full-screen overlay menu (mobile) */
.menu-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: rgba(251,251,250,0.86);   /* frosted panel, matches .site-header */
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: var(--gutter);                       /* card never touches the screen edge */
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity .32s ease, transform .32s ease, visibility 0s linear .32s;
}
body.menu-open .menu-overlay {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity .32s ease, transform .32s ease;
}
body.menu-open { overflow: hidden; }          /* lock scroll while open */
.menu-overlay__links {                        /* the white card (Figma 263:2687, v1.21 — grows to fit its rows) */
  display: flex;
  flex-direction: column;
  background: #fff;
  border-radius: 18.5px;
  box-shadow: 0 0 6.8px 2.8px rgba(0,0,0,0.08);
  width: 300px;
  max-width: calc(100vw - 48px);
}
/* main items (HOME / SERVICES / ABOUT / CONTACT) — Barlow Medium 20px
   uppercase (v1.21, was Light 22px); the CASE STUDIES group header below
   matches them but is not tappable */
.menu-overlay__links > a {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 88px;
  font-size: 20px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #787878;
  text-align: center;
}
/* four hairline rules group the five rows —
   Home | (Case Studies + its two projects) | Services | About | Contact */
.menu-overlay__links > * { position: relative; }
.menu-overlay__links > * + *::before {
  content: "";
  position: absolute;
  top: 0; left: 24px; right: 24px;
  border-top: 1px solid var(--line);
}
.menu-overlay__group {                        /* CASE STUDIES header + the two project links */
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 28px 0 26px;
}
.menu-overlay__group-label {
  font-size: 20px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #787878;
  margin-bottom: 14px;
}
.menu-overlay__proj {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;                           /* full 44px tap target */
  font-size: 20px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--ink);
}
.menu-overlay__num { color: #b0b0b0; margin-right: 10px; }
.menu-overlay a:hover,
.menu-overlay a:active { color: var(--brand-cyan); }
.menu-overlay a:hover .menu-overlay__num,
.menu-overlay a:active .menu-overlay__num { color: var(--brand-cyan); }
.menu-overlay__close {
  position: absolute;
  top: 24px; right: var(--gutter);
  width: 44px; height: 44px;
  border: 0; background: none; color: #787878;
  font-size: 34px; line-height: 1; cursor: pointer;
}

/* ============================================================
   SHARED PRIMITIVES
   ============================================================ */
.label {                                  /* small blue uppercase eyebrow */
  font-size: 13px; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--accent);
}
.label--soft { color: var(--accent-soft); }  /* on dark backgrounds */

/* (image tiles live on the grid module — see THE GRID SYSTEM below) */

/* ============================================================
   HOME — OPENING CAROUSEL BAND (§4.1 #2, replaces the 8-up splash)
   Two full-bleed rows of square tiles in a slow seamless CSS drift —
   top row rightward, bottom row leftward. Decorative, display-only.
   Each row's six tiles render twice, so one set is exactly half the
   track: looping the animation between translateX(-50%) and 0 resets
   with no visible seam. The tile gap lives on each img's margin-right
   (not flex gap) so the half-track period stays exact.
   ============================================================ */
.section { padding-left: var(--gutter); padding-right: var(--gutter); }

.carousel-band {
  overflow: hidden;   /* clip tiles cleanly at both viewport edges */
  /* the retired splash grid's vertical rhythm, kept — band→intro spacing unchanged */
  padding-top: clamp(40px,6vw,72px);
  padding-bottom: clamp(20px,3vw,32px);
}
.carousel-band__row + .carousel-band__row { margin-top: 12px; }   /* tighter than --grid-gap (v1.10, Charlie's call) */
.carousel-band__track {
  display: flex;
  width: max-content;
  will-change: transform;
  animation: carousel-drift 60s linear infinite;
}
/* the top row plays the drift forward (−50% → 0: tiles move RIGHT);
   the bottom row plays the same keyframes in reverse (tiles move LEFT) */
.carousel-band__row--rtl .carousel-band__track { animation-direction: reverse; }
.carousel-band__track img {
  width: clamp(170px, 19vw, 275px);   /* the grid module's cell scale: 275px web / 170px mobile */
  aspect-ratio: 1 / 1;                 /* square, sharp corners — no radius, no border */
  object-fit: cover;
  flex: none;
  margin-right: 12px;   /* fixed, matches the row gap (v1.10) — stays part of the loop period */
}
@keyframes carousel-drift {
  from { transform: translateX(-50%); }
  to   { transform: translateX(0); }
}
@media (prefers-reduced-motion: reduce) {
  .carousel-band__track { animation: none; }   /* tiles stay visible, just static */
}

/* ============================================================
   THE GRID SYSTEM (§4.4) — one square-cell module.
   Web: 275px cells / 28px gutter, capped at 4 cells wide = 1184px
   (4×275 + 3×28), centered; below the cap the cells scale down
   smoothly and never exceed 275px. Mobile (≤720px): 170px cells /
   18px gutter — see the media block below.
   Arrangements (set by app.js/project.js from image count):
     shots--4up  row of four 1×1 cells (5+ wraps)
     shots--3up  one 3×2 lead + two stacked 1×1 cells
                 (+ shots--3up--right: lead flips to the right)
     shots--2up  two 2×2 blocks side by side
     shots--1    a single image filling the full module (4×2, ≈2:1)
     shots--custom1  Grid_Custom_1 — the 6-image case-study module
   ============================================================ */
.shots {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--grid-gap);
  max-width: var(--max-module);   /* the 4-cell cap — cells top out at 275px */
  margin: 0 auto;
}
.shot {
  position: relative; overflow: hidden;
  background: var(--ph-light);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  aspect-ratio: 1 / 1;    /* the square cell */
}
.shot img,
.shot video {   /* video cells (v1.15) fill exactly like image cells */
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
}

/* 1-up — a single image filling the full module: 4 cells wide × 2 tall
   (1184×578 at full size, ≈2:1 — the grid's shape, not 16:9) */
.shots--1 { grid-template-columns: 1fr; }
.shots--1 .shot { aspect-ratio: 1184 / 578; }

/* 2-up — two 2×2 blocks side by side */
.shots--2up .shot { grid-column: span 2; }

/* 3-up — 3×2 lead + two stacked cells; the squares size the rows,
   the lead stretches over both. Lead sits left unless --right. */
.shots--3up .shot--lead { grid-column: 1 / 4; grid-row: 1 / 3; aspect-ratio: auto; }
.shots--3up--right .shot--lead { grid-column: 2 / 5; }

/* 4-up — plain 1×1 cells; the base 4-column grid does the work */

/* Grid_Custom_1 — the 6-image case-study module (§4.2/§4.4, v0.35):
   two wide 2×1 cells set diagonally (cols 1–2 row 1; cols 2–3 row 2)
   + four 1×1 squares. DOM order is reading order — auto-placement in
   the 4-column grid lands each cell in its Figma slot; the squares
   size the rows, the wides stretch to 2 cols × 1 row (578×275 full). */
.shots--custom1 .shot--wide { grid-column: span 2; aspect-ratio: auto; }

/* Grid_Custom_1 (flip), v1.21 — the horizontal mirror, used by the Services
   page's alternating sections (§4.4/§4.6): top wide on the RIGHT (cols 3–4),
   bottom wide still cols 2–3. Add .shots--custom1-flip alongside
   .shots--custom1 and order the DOM sq·sq·wide·sq·wide·sq — 4-column
   auto-placement lands every cell in its mirrored slot, so the flip needs
   no extra desktop rules; the ≤720 restack re-orders below. */

/* 3-inline (v1.04) — one row on the module: two 1×1 squares + a 2×1 wide
   (square, square, wide — 275+275+578 at full size; story grid beats) */
.shots--3inline .shot--wide { grid-column: span 2; aspect-ratio: auto; }

/* ============================================================
   HOME — ADDITIONAL WORK: INLINE SHOWCASE SECTIONS (§4.4)
   Display-only — no link, no hover. Sits on the grid module column.
   ============================================================ */
/* the outer wrapper keeps only the .section gutter — the 1184 cap lives on
   each .work-section, so the gutter wraps AROUND the module, never inside it */
.work-sections { padding-top: clamp(56px,7vw,96px); }

/* home page bottom: 200px of clear space between the last content and the
   slim footer (v0.83, Charlie's call) — on <main> so ANY future last section
   inherits it (the last .work-section already zeroes its own margin) */
body.page-home main { padding-bottom: 200px; }
.work-section { max-width: var(--max-module); margin-inline: auto; margin-bottom: clamp(56px,7vw,96px); }
.work-section:last-child { margin-bottom: 0; }
.work-section__caption {
  display: flex; flex-direction: column; gap: 6px;
  border-top: 1px solid #A9A9A9;   /* the hairline rule stays above the category (#A9A9A9 v0.54, matches the case-study rules) */
  padding-top: 12px; margin-top: 13px;
  margin-bottom: 13px;                /* gap before the images below (§4.4 v0.20) */
}
.work-section__disc { font-size: 12px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent); }
.work-section__title { font-size: clamp(19px,1.8vw,24px); font-weight: 700; letter-spacing: -0.01em; margin: 0; }   /* Bold (v0.54, was 600) */

/* ============================================================
   HOME — INTRO STATEMENT
   ============================================================ */
/* v0.44 spacing tighten: top+bottom paddings split — carousel band→intro
   reads 100px desktop (32 carousel-band pb + 68 here), intro→case-study
   top rule 120px (36 here + 84 .cases margin-top) */
.intro { padding: clamp(34px,4.8vw,68px) var(--gutter) clamp(18px,2.5vw,36px); }
.intro__inner { max-width: var(--max-intro); margin: 0 auto; text-align: center; }
.intro__lede {
  font-size: clamp(20px, 2.2vw, 28px);
  font-weight: 600; line-height: 1.5; letter-spacing: -0.01em;   /* Barlow SemiBold (v0.51, was 500) */
  color: var(--brand-cyan);   /* the lockup's cyan (v1.12, Charlie's call — was #B5B5B5) */
  margin: 0 0 clamp(20px,2.5vw,30px);
  text-wrap: pretty;
}
/* (.intro__clients-label removed v0.76 — the "Client List" eyebrow is gone; the lede's bottom margin now sets the gap) */
.intro__clients {
  font-size: clamp(16px, 1.5vw, 19px);
  font-weight: 500; line-height: 1.6;
  color: var(--text-2);
  margin: 0; text-wrap: pretty;
}

/* ============================================================
   HOME — CASE-STUDY SPOTLIGHTS (§4.1 #4, v0.40 — Figma 223:81)
   Editorial blocks on the 1184 column, top to bottom: full-bleed
   hairline · cyan "CASE STUDY 0X" eyebrow · short rule · bold ink
   title · full-width rule · summary · clean 1-up module hero
   (1184×578, no scrim/overlay/CTA). The WHOLE block is one <a> to
   the detail page; blocks are bracketed and divided by hairlines
   that bleed to the viewport edges. Discipline no longer shown.
   ============================================================ */
.cases {
  margin-top: clamp(48px,6vw,84px);
  overflow-x: clip;                    /* clip the 100vw bands/rules (scrollbar width) */
}
.cases__inner {
  max-width: var(--max-module); margin: 0 auto;
  display: flex; flex-direction: column;
  gap: clamp(36px,4.2vw,60px);         /* 60px of page-white between the blocks (v0.48, Figma) */
}

.case-block {
  display: block; position: relative;
  color: var(--ink); cursor: pointer;
  padding: clamp(36px,4.2vw,60px) 0 clamp(45px,5.6vw,80px);   /* rule→eyebrow 60 / image→bottom rule 80 (desktop, v0.47) */
}
/* Each block is its own full-bleed band (v0.48) behind the content —
   between blocks the page canvas shows through the 60px gap.
   (v0.49: the top/bottom bracket rules are removed — Charlie trying
   the bare band; restore with border-top/bottom 1px var(--ink)) */
.case-block::before {
  content: ""; position: absolute;
  top: 0; bottom: 0; left: calc(50% - 50vw); width: 100vw;
  background: var(--canvas-cases);
  z-index: -1;
}
/* eyebrow + View Case Study pill on one row (v0.55, Figma 224:83) —
   pill vertically centered on the eyebrow, right edge on the hero's */
.case-block__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  margin: 0 0 clamp(18px,2.1vw,30px);   /* v0.45 — all in-block gaps 30px desktop */
}
.case-block__eyebrow {
  font-size: clamp(12px,1.9vw,19px); font-weight: 600;   /* v0.50 — was 32px desktop, −40% */
  letter-spacing: 0.11em; text-transform: uppercase;
  color: var(--accent);
  margin: 0;
}
.case-block__pill {
  display: inline-flex; align-items: center; justify-content: center;
  height: 38px; min-width: 229px; padding: 0 27px;   /* 229×38 (Figma 224:83) */
  background: #F0F0F0; border-radius: 67px;
  font-size: 15px; font-weight: 600; letter-spacing: 0.11em;
  text-transform: uppercase; white-space: nowrap;
  color: var(--accent);                 /* brand cyan — Figma's #00C8E9 unified per v0.27 */
  transition: background .2s ease;
}
.case-block:hover .case-block__pill { background: #E7E7E4; }   /* subtle — tunable */
.case-block__rule-short { width: 152px; max-width: 60%; height: 1px; background: #A9A9A9; margin: 0 0 clamp(20px,2.1vw,30px); }   /* v0.50 — was 254px, −40% with the eyebrow; #A9A9A9 v0.53 */
.case-block__title {
  font-size: clamp(30px,4.4vw,48px); font-weight: 700;
  letter-spacing: 0.01em; line-height: 1.05;
  color: var(--ink); margin: 0 0 clamp(20px,2.1vw,30px);
  transition: color .2s ease;
}
.case-block:hover .case-block__title { color: var(--accent-hover); }   /* subtle hover — tunable */
.case-block__rule-full { height: 1px; background: #A9A9A9; margin: 0 0 clamp(20px,2.1vw,30px); }   /* #A9A9A9 v0.53 */
.case-block__summary {
  font-size: clamp(18px,2vw,24px); font-weight: 400;
  line-height: 1.45; letter-spacing: 0.01em;
  color: var(--text-3);                       /* same voice as the detail-page lede */
  max-width: none;                            /* full 1184 column — summary sits on ~2 lines (v0.42) */
  margin: 0 0 clamp(31px,3.5vw,50px);   /* summary→hero 50px desktop (v0.44) */
}
.case-block__img {
  aspect-ratio: 1184 / 578;            /* the 1-up grid module (§4.4) — not 16:9 */
  border: 1px solid var(--line); background: var(--ph-light);
  border-radius: var(--radius-card); overflow: hidden;
}
.case-block__img img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* per-image crop nudges (v0.52) — cover crops centered by default;
   shift a specific spotlight hero within its frame here */
.case-block__img img[src*="playstation_top_1"] {
  object-position: calc(50% - 5px) calc(50% - 5px);   /* 5px left, 5px up */
  transform: scale(1.02);                             /* +2% zoom (v0.56) — frame clips the overflow */
}
/* .hero__fill survives the v0.40 spotlight redesign — project.html's
   fallback hero (.proj-hero) still uses it for its image/placeholder */
.hero__fill {
  position: absolute; inset: 0;
  background: var(--ph-dark);
  display: flex; align-items: center; justify-content: center;
}
.hero__fill span { font-size: 12px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ph-dark-txt); }
.hero__fill img { width: 100%; height: 100%; object-fit: cover; }

/* ============================================================
   SLIM FOOTER (§3.4) — colophon + Contact link only; the form and
   email live on contact.html.
   ============================================================ */
.footer-slim {
  background: var(--dark); color: #fff;
  padding: clamp(28px,4vw,44px) var(--gutter);
  margin-top: 0;
}
.footer-slim__inner {
  max-width: var(--max-module); margin: 0 auto;
  display: flex; flex-wrap: wrap; gap: 12px 32px;
  align-items: center; justify-content: space-between;
}
.footer-slim__colophon {
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; color: rgba(255,255,255,0.4);
}
.footer-slim__contact {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 14px; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; color: #fff;
}
.footer-slim__contact:hover { color: var(--accent-soft); }

/* ============================================================
   PROJECT DETAIL PAGE
   ============================================================ */
.proj-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding: 14px var(--gutter);
  border-bottom: 1px solid var(--line);
}
.back-link {
  display: inline-flex; align-items: center; gap: 9px; cursor: pointer;
  font-size: 13px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink); background: none; border: 0; padding: 0;
}
.back-link:hover { color: var(--accent); }
.proj-bar__id { font-size: 12px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }

.proj-head { padding: clamp(28px,4vw,52px) var(--gutter) 0; max-width: var(--max-text); margin: 0 auto; }
.proj-head .label { display: block; margin-bottom: 16px; }
.proj-title { font-size: clamp(40px,7vw,74px); font-weight: 700; line-height: 0.98; letter-spacing: -0.035em; margin: 0 0 clamp(20px,3vw,32px); }   /* 74px = 92px −20% desktop cap; Bold everywhere (v0.57) */
.proj-lede { font-size: clamp(19px,2vw,27px); font-weight: 400; line-height: 1.4; letter-spacing: -0.01em; color: var(--text-3); max-width: 75ch; margin: 0 0 clamp(32px,5vw,52px); }   /* 75ch → lede sits on two lines on desktop (v0.58; was 40ch/4 lines) */

.proj-hero-wrap { padding: 0 var(--gutter); }
.proj-hero {
  position: relative; overflow: hidden;
  border: 1px solid var(--line); background: var(--dark);
  min-height: clamp(360px,60vh,700px);
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-card);
}
.proj-hero .hero__fill { }
.proj-hero span { position: relative; font-size: 12px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ph-dark-txt); }

/* Grid_Custom_1 slot — sits where the hero does (between the lede and
   the meta); js/project.js unhides it for 6-image case studies.
   Shares the head/info text column and pins the grid to its LEFT edge
   (title, eyebrow, lede, meta all line up; whitespace falls right) —
   the home-page .shots stay centered, this is detail-page only. */
.proj-shots6 { max-width: var(--max-text); margin: 0 auto; padding: 0 var(--gutter); }
.proj-shots6 .shots { margin-inline: 0; }   /* overrides the base margin:0 auto; module cap kept */

/* Optional statement (v0.94) — big Barlow Bold Italic pull-quote under
   the image grid; the <p> caps at the grid module width (1184) and reads left */
.proj-statement { max-width: var(--max-text); margin: clamp(36px,4.2vw,60px) auto 0; padding: 0 var(--gutter); }
.proj-statement p {
  max-width: var(--max-module);
  font-weight: 700; font-style: italic;
  font-size: clamp(34px,4.9vw,64px);   /* 64px desktop */
  line-height: 1.15; letter-spacing: -0.01em;
  text-align: left; color: var(--ink);
  margin: 0;
}
/* optional logo under the statement (v0.95) — width set by JS to 35% of
   the file's natural size (50% at v0.95, v0.98); never wider than the module column on mobile */
.proj-statement img { display: block; margin-top: clamp(24px,3vw,40px); max-width: 100%; height: auto; }

/* Optional image band (v0.61) — declared per-project via bandImage in
   data/projects.js; sits 120px below the image grid at the module width,
   left-aligned with it. Bare image: no border/radius (transparent PNGs). */
.proj-band { max-width: var(--max-text); margin: 120px auto 0; padding: 0 var(--gutter); }   /* 120px below the grid (90 + 30, v0.63) */
.proj-band img { display: block; width: 100%; max-width: var(--max-module); height: auto; }
.proj-band:not([hidden]) + .proj-info { padding-top: 80px; }   /* overview sits 80px below the band (40 + 40, v0.69) */

/* Detail-page story sections (§4.2, v0.71) — repeating image + copy below the overview */
.proj-info:has(+ .proj-story:not([hidden])) { padding-bottom: 0; }   /* overview→first image reads 80px (fallback: toggle a body class from project.js if :has is a concern) */
.proj-story { max-width: var(--max-text); margin: 0 auto; padding: 0 var(--gutter); }
.proj-story__section { margin-top: 80px; }                 /* overview→first image + section→section, 80px (tunable) */
.proj-story__figure {
  display: block; width: 100%; max-width: var(--max-module);
  padding: 0; border: 0; background: #fff; cursor: zoom-in;   /* white, not the stripe placeholder — casestudy_1's transparent corners would let stripes peek (v0.72) */
  border-radius: var(--radius-card); overflow: hidden;
  aspect-ratio: 1184 / 578;
  box-shadow: 0 10px 30px rgba(20,22,26,0.08);   /* subtle lift, replaces the shadow Figma used to bake into casestudy_1 (v0.72, tunable) */
}
.proj-story__figure img { width: 100%; height: 100%; object-fit: cover; display: block; }
.proj-story__copy { max-width: 1006px; margin-top: 50px; }  /* image→copy 50px, tighter than the 80px section rhythm so the copy reads with its image (v0.73, tunable); reuse .proj-overview for the label+lead style */
.proj-story .shots { margin-inline: 0; }    /* grid beats (v0.99) left-align with the story column, like .proj-shots6 */
.proj-story .shots button.shot {            /* tappable grid cells (v1.17) — keep the .shot look, lose the button chrome */
  appearance: none; -webkit-appearance: none;
  padding: 0; font: inherit; cursor: pointer;
  display: block; width: 100%;
}
.proj-overview .label { font-size: 15px; }   /* overview + story eyebrows at 15px, +2 over the base 13px (v0.74–0.75) — the head discipline eyebrow stays 13px */

/* Image lightbox (§4.2/§9, v0.71) — above the header (z:60) and menu (z:90) */
.lightbox {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(20px,5vw,56px);
  background: rgba(20,22,26,0.92);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
.lightbox[hidden] { display: none; }
.lightbox__img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; border-radius: var(--radius-card); }
.lightbox__close { position: absolute; top: 24px; right: clamp(20px,5vw,56px); width: 44px; height: 44px; border: 0; background: none; color: #fff; font-size: 34px; line-height: 1; cursor: pointer; }
body.lightbox-open { overflow: hidden; }

/* Mobile story lightbox — assertive enlarge + horizontal scroll (§4.2/§9, v0.77) */
.lightbox__scrollbar, .lightbox__hint { display: none; }   /* desktop: hidden; the stage just centers the contained image */
.lightbox__stage { display: flex; align-items: center; justify-content: center; max-width: 100%; max-height: 100%; }

@media (max-width: 720px) {
  .lightbox { flex-direction: column; gap: 16px; padding: 24px 0 20px; }
  .lightbox__stage {
    width: 100%; height: 78vh; max-width: none; max-height: none;
    overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch;
    touch-action: pan-x; justify-content: flex-start;
    scrollbar-width: none;                       /* hide native — we draw our own */
  }
  .lightbox__stage::-webkit-scrollbar { display: none; }
  .lightbox__img {
    height: 100%; width: auto; max-width: none; max-height: none; flex: 0 0 auto;
    transform: scale(0.55); transform-origin: center;      /* start small; grows to 1 on open (tunable) */
    transition: transform .35s ease;
  }
  .lightbox.is-zoomed .lightbox__img { transform: scale(1); }
  .lightbox__scrollbar {
    display: block; position: relative;
    width: 60%; max-width: 320px; height: 4px;
    background: rgba(255,255,255,0.25); border-radius: 2px;
    opacity: 0; transition: opacity .2s ease .3s;          /* fades in after the zoom */
  }
  .lightbox.is-zoomed .lightbox__scrollbar { opacity: 1; }
  .lightbox__thumb { position: absolute; top: 0; height: 100%; background: var(--accent); border-radius: 2px; width: 30%; left: 0; }
  .lightbox__hint {
    display: flex; align-items: center; justify-content: center; gap: 10px;
    color: var(--accent); font-weight: 600; font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase;
    opacity: 0; transition: opacity .2s ease .3s;
  }
  .lightbox.is-zoomed .lightbox__hint { opacity: 1; }
  .lightbox__close {
    right: auto; left: 50%; transform: translateX(-50%);   /* center horizontally (top set by JS — tracks the image's top edge, v0.79) */
    width: 44px; height: 44px;                              /* tap target stays 44px */
    color: transparent; font-size: 0;                      /* hide the × glyph */
    /* the SVG is a mask so the fill comes from the token — brand cyan, not the asset's baked white (v0.81);
       icon drawn at 26px — 44 −40% (v0.80); path relative to css/styles.css */
    background: var(--accent);
    -webkit-mask: url(../assets/home/button-close-x.svg) center / 26px no-repeat;
    mask: url(../assets/home/button-close-x.svg) center / 26px no-repeat;
    z-index: 2;                                            /* above the enlarged image */
  }
}
@media (prefers-reduced-motion: reduce) {
  .lightbox__img { transition: none; transform: none; }    /* no scale-up; image just appears large */
  .lightbox__scrollbar, .lightbox__hint { transition: none; }
}

.proj-info { max-width: var(--max-text); margin: 0 auto; padding: clamp(48px,7vw,96px) var(--gutter); }
/* Role/Client/Discipline meta cells + their ruled grid removed v0.60 —
   the overview now sits alone, left-aligned with the title and image module.
   max-width keeps roughly the measure it had in the old two-column grid (tunable). */
.proj-overview { max-width: 1006px; }   /* 1006 keeps the closing "PlayStation 5." on the second line (v0.65) */
.proj-overview .label { display: block; margin-bottom: 16px; }
/* lead-paragraph rule comes AFTER the base rule so a lone paragraph
   (first AND last) reads as the lead, not the small follow-on style */
.proj-overview p { font-size: 16px; line-height: 1.65; color: var(--text-2); margin: 0 0 18px; }
.proj-overview p:last-of-type { margin-bottom: 0; }
.proj-overview p:first-of-type { font-size: clamp(17px,1.4vw,20px); line-height: 1.6; color: var(--text-4); }
/* story copy: EVERY paragraph reads at the lead size (v1.08), in
   Barlow Medium (v1.09) — the 16px small follow-on style is
   overview-only; multi-paragraph story bodies (v1.00 arrays) stay one size */
.proj-story__copy p { font-size: clamp(17px,1.4vw,20px); font-weight: 500; line-height: 1.6; color: var(--text-4); }
.proj-overview em { font-style: normal; color: var(--ink); }
.nowrap { white-space: nowrap; }   /* keeps word pairs like "PlayStation 5." together (v0.66) */

.proj-gallery { padding: 0 var(--gutter) clamp(48px,7vw,96px); }
.proj-gallery .back-link { margin-top: clamp(40px,5vw,64px); }

/* ============================================================
   BLUE PAGES — Contact + About (§4.3, §4.5)
   Each blue page carries a full-bleed cover background image over
   the flat --page-blue, which stays as the fallback color.
   (url() resolves relative to this CSS file, hence the ../)
   ============================================================ */
body.on-blue { background-color: var(--page-blue); }
/* the image rides a fixed full-viewport layer so it always fills the
   screen and content scrolls over it — a pseudo-element, NOT
   background-attachment:fixed (iOS renders that unreliably) */
body.page-contact::before,
body.page-about::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;                        /* behind all content */
  background-color: var(--page-blue); /* fallback if the image 404s */
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}
body.page-contact::before { background-image: url(../assets/backgrounds/blue_background_1.jpg); }
body.page-about::before   { background-image: url(../assets/backgrounds/blue_background_2.jpg); }

/* white-on-blue header (§3.2): blue-tinted frosted bar, white brand + nav (v0.30/Phase 5.13) */
.site-header--on-blue {
  background: rgba(0,153,255,0.62);   /* --page-blue tinted; masks content scrolling under */
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid rgba(255,255,255,0.18);
}
.site-header--on-blue .brand__line1,
.site-header--on-blue .brand__line2 { color: #fff; }
/* the v1.21 nav rendered white-on-blue — hover/current cyan reads fine
   over the blue field (§3.2); the dropdown card stays white with ink items */
.site-header--on-blue .nav > a,
.site-header--on-blue .nav__dd-label { color: #fff; }
.site-header--on-blue .nav > a:hover,
.site-header--on-blue .nav__dd-label:hover { color: var(--accent); }
.site-header--on-blue .nav > a[aria-current="page"] { color: var(--accent); }
.site-header--on-blue .nav-toggle span { background: #fff; }

/* focus rings need to read on the blue field, not accent-on-blue */
body.on-blue a:focus-visible,
body.on-blue button:focus-visible { outline-color: #fff; }

.contact {
  max-width: 860px;
  margin: 0 auto;
  padding: clamp(32px,6vw,72px) var(--gutter) clamp(64px,10vw,120px);
}
.contact__intro {
  color: #fff;
  font-size: clamp(20px,2.2vw,28px);
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: -0.01em;
  margin: 0 0 clamp(28px,4vw,44px);
  text-wrap: pretty;
}

/* the form: three white 8px cards, no gray container (§4.3) */
.contact__form { display: flex; flex-direction: column; gap: 14px; }
.contact__field {
  display: block;
  width: 100%;
  background: #fff;
  color: #1A1A1A;
  border: 0;
  border-radius: 8px;
  padding: 18px 20px;
  font-family: inherit;
  font-size: 17px;
  font-weight: 400;
  line-height: 1.4;
  caret-color: var(--page-blue);   /* the blinking caret is the focus cue */
}
.contact__field:focus { outline: none; }   /* no outline/box on inputs (§4.3) */
.contact__field::placeholder { color: var(--muted); }
.contact__field--message { min-height: 220px; resize: vertical; }

/* Send pill — keeps a visible focus ring for keyboard users (§4.3) */
.contact__send {
  margin-top: 10px;
  width: 188px;                    /* 313 × 0.6 — scaled down 40% in v0.29 */
  max-width: 100%;
  height: 37px;
  background: #fff;                /* white pill, cyan label (v1.33 — was cyan/white, v0.29) */
  color: var(--brand-cyan);
  border: 0;
  border-radius: 66px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: filter .2s ease;
}
.contact__send:hover { filter: brightness(0.95); }   /* slight dim — brighten can't read on white */
.contact__send:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }

/* Inline confirmation + error (§8, Phase 5.25) — the contact voice:
   white at the .contact__intro scale, sitting where the form was.
   No display value here so the [hidden] attribute keeps working. */
.contact__thanks,
.contact__error {
  color: #fff;
  font-size: clamp(20px,2.2vw,28px);
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: -0.01em;
  margin: 0;
  text-wrap: pretty;
}
.contact__error { margin-top: 18px; }   /* sits below the still-visible form */

/* EDIT: the email shown near the form */
.contact__email {
  display: inline-block;
  margin-top: clamp(28px,4vw,40px);
  color: #454545;   /* dark gray (v0.31) — was #fff, which washed out over the image's bright lower band */
  font-size: clamp(18px,2vw,24px);
  font-weight: 500;
  letter-spacing: -0.01em;
}
.contact__email:hover { color: rgba(69,69,69,0.75); }

/* ============================================================
   ABOUT PAGE — blue sibling of Contact (§4.5)
   Centered portrait up top (60px below the header, 40px above
   the copy), then one 860px column centered on the page; the
   copy itself is left-aligned (ragged right). No slim footer.
   ============================================================ */
.about-page {
  max-width: 860px;
  margin-inline: auto;
  padding: 60px var(--gutter) clamp(64px,10vw,120px);
  text-align: left;
}
.about-page__portrait {
  display: block;
  width: 212px;          /* charlie.png is 353×353; shown at 60% (v0.68) */
  max-width: 100%;
  margin: 0 auto 24px;   /* 24px to the name below; the name carries the 40px to the copy (v1.01) */
}
.about-page p.about-page__name {
  /* Full name under the portrait (v1.01): Barlow Regular, all caps,
     always 3px smaller than the copy at every viewport width */
  color: #fff;
  font-size: calc(clamp(20px,2.2vw,28px) - 3px);
  font-weight: 400;
  text-transform: uppercase;
  text-align: center;
  line-height: 1.5;
  letter-spacing: 2px;   /* opened up for legibility (v1.02; the copy keeps -0.01em) */
  margin: 0 0 40px;
}
.about-page p {
  /* Contact-intro type (§4.5): a step up from the old flat 20px */
  color: #fff;
  font-size: clamp(20px,2.2vw,28px);
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: -0.01em;
  margin: 0 0 clamp(20px,2.5vw,30px);
  text-wrap: pretty;
}
.about-page p:last-child { margin-bottom: 0; }

/* ============================================================
   SERVICES PAGE (§4.6, v1.21) — a white page on the §3.1 header, the
   1184 module column and the home slim footer. Grid cells + index
   thumbs render as plain gray placeholders until Charlie's finals
   land — hard-coded in services.html (Services is NOT a PROJECTS
   entry). Sizes marked tunable are dial-by-eye on hardware.
   ============================================================ */
.services { padding: clamp(36px, 5vw, 64px) var(--gutter) clamp(96px, 12vw, 180px); }

/* gray placeholder cell — swap for a real <img> in the .shot when finals land */
.shot--gray { background: #C4C4C4; border: 0; }

/* per-image crop nudge (v1.29–30, Charlie's target crop + dial-in): evi_1
   zooms +20% anchored bottom-right (sheds the photo's flat gray left wall,
   keeps floor + furniture), then rides right 10px and up 12px. The up-shift
   uses object-position (10px element-space × the 1.2 scale = 12px on screen)
   because a translateY would pull the img's bottom edge above the cell and
   expose a stripe of the .shot background; translateX is safe — the scaled
   element overflows the left clip edge by ~96px. */
.shot img[src*="services_evi_1"] {
  transform: translateX(10px) scale(1.2);
  transform-origin: 100% 100%;
  object-position: 50% calc(50% - 10px);
}

/* linked 3-up category overview — each column anchor-jumps to its section */
.svc-index {
  max-width: var(--max-module); margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 275px));   /* grid-cell-size squares */
  justify-content: space-between;
  gap: var(--grid-gap);
}
.svc-index__item { display: block; color: var(--ink); }
.svc-index__thumb {
  display: block; position: relative; overflow: hidden;
  height: 0; padding-bottom: 100%;   /* a true 1:1 square at every width — the padded box
                                        can't be mis-sized; iOS Safari rendered the previous
                                        aspect-ratio + max-width combo non-square (v1.24) */
  /* SHARP corners (v1.26, Charlie's call — was the 20px --radius-card;
     like the home carousel tiles, unlike the .shot grid cells) */
  background: #C4C4C4;                        /* fallback behind the img */
}
.svc-index__thumb img {                       /* the real images, when they land */
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
}
.svc-index__title {
  display: block; margin: 18px 0 14px;
  font-size: clamp(24px, 3vw, 40px);          /* ~40px desktop (tunable) */
  font-weight: 700; line-height: 1.08; letter-spacing: -0.01em;   /* Bold (v1.26, was 600) */
  transition: color .2s ease;
}
.svc-index__item:hover .svc-index__title { color: var(--accent); }
.svc-index__rule { display: block; width: 152px; max-width: 60%; height: 1px; background: #A9A9A9; }

/* centered cyan intro line — the home intro-statement voice (§4.1 #3) */
.svc-lede {
  max-width: var(--max-intro); margin: clamp(56px, 7vw, 96px) auto;
  text-align: center;
  font-size: clamp(20px, 2.2vw, 28px);
  font-weight: 600; line-height: 1.5; letter-spacing: -0.01em;
  color: var(--brand-cyan);
  text-wrap: pretty;
}

/* category section: rule → title → grid → intro → two-column details */
.svc-section {
  max-width: var(--max-module); margin: clamp(64px, 8vw, 110px) auto 0;
  scroll-margin-top: 170px;                   /* anchor jumps clear the sticky header */
}
.svc-section__rule { height: 1px; background: #A9A9A9; margin-bottom: clamp(20px, 2.4vw, 34px); }
.svc-section__title {
  font-size: clamp(34px, 4.6vw, 64px);        /* ~64px desktop */
  font-weight: 700; line-height: 1.05; letter-spacing: -0.01em;   /* Bold (v1.26, was the SemiBold exception) */
  margin: 0 0 clamp(24px, 3vw, 44px);
}
.svc-section__intro {
  font-size: clamp(20px, 2.4vw, 32px);        /* 32px desktop — one measure for all three sections */
  font-weight: 400; line-height: 1.4; letter-spacing: -0.01em;
  color: var(--ink);
  margin: clamp(28px, 3.4vw, 48px) 0 0;
  text-wrap: pretty;
}

/* the one NEW component (§4.6): two columns of service details —
   Bold 18px uppercase cyan header over a 20px Regular body */
.svc-details {
  display: grid; grid-template-columns: 1fr 1fr;
  column-gap: clamp(28px, 5vw, 72px);
  margin-top: clamp(28px, 3.4vw, 48px);
}
.svc-details__col { display: flex; flex-direction: column; gap: clamp(22px, 2.4vw, 32px); }
.svc-item h3 {
  font-size: 18px; font-weight: 700;
  letter-spacing: 0.11em; text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 8px;
}
.svc-item p { font-size: 20px; font-weight: 400; line-height: 1.45; color: var(--ink); margin: 0; }

/* ============================================================
   SCROLL REVEAL (progressive-enhancement; see app.js)
   Elements start hidden ONLY when JS marks them, so no-JS still shows content.
   ============================================================ */
[data-reveal].is-hidden {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity .7s cubic-bezier(.2,.7,.2,1), transform .7s cubic-bezier(.2,.7,.2,1);
}
[data-reveal].is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  [data-reveal].is-hidden { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
}

/* ============================================================
   RESPONSIVE
   ============================================================ */

/* (the ≤1040 tagline-hiding rule retired with the tagline itself, v1.21 —
   the fluid .nav font-size handles the tablet squeeze) */

/* Mobile: swap inline nav for hamburger + overlay */
@media (max-width: 720px) {
  .site-header__inner { padding: 24px var(--gutter); align-items: center; }
  .brand__line1 { font-size: 20px; }
  .brand__line2 { font-size: 20px; }
  .nav { display: none; }              /* hide inline links */
  .nav-toggle { display: flex; }        /* show hamburger */

  /* animate hamburger into an X when menu is open */
  body.menu-open .nav-toggle span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
  body.menu-open .nav-toggle span:nth-child(2) { opacity: 0; }
  body.menu-open .nav-toggle span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }


  /* ---- THE GRID SYSTEM, mobile mode (§4.4, §6): 170px cells ----- */

  /* 3-up restacks Top/Bottom: two squares side by side, the lead
     full width above them — or below when the section is --right */
  .shots--3up { grid-template-columns: repeat(2, 1fr); }
  .shots--3up .shot--lead,
  .shots--3up--right .shot--lead {
    grid-column: 1 / 3;
    grid-row: auto;
    aspect-ratio: 546 / 358;   /* 3×170 + 2×18 by 2×170 + 18 — module ratio */
  }
  .shots--3up--right .shot--lead { order: 2; }

  /* 2-up collapses to a single stacked column; 4-up pairs its
     squares 2-up into a 2×2 (squares never go full-width — Figma
     node 223:49) */
  .shots--2up { grid-template-columns: 1fr; }
  .shots--2up .shot { grid-column: auto; }
  .shots--4up { grid-template-columns: repeat(2, 1fr); }

  /* 1-up keeps the full-module shape at mobile cell math */
  .shots--1 .shot { aspect-ratio: 734 / 358; }   /* 4×170+3×18 by 2×170+18 */

  /* the View Case Study pill scales down with the 12px eyebrow */
  .case-block__pill { height: 30px; min-width: 0; padding: 0 18px; font-size: 11px; }

  /* Grid_Custom_1 restacks on 2 columns: wides go full-width (~2:1),
     squares pair 2-up (Figma node 223:49). `order` regroups the six
     so the stack reads wide 1 → [2·3] → wide 5 → [4·6]; the module is
     always exactly six bare .shot children in reading order, slots 1
     and 5 wide, so nth-child hits the slot-4 and slot-6 squares. */
  .shots--custom1 { grid-template-columns: repeat(2, 1fr); }
  .shots--custom1 .shot--wide { grid-column: 1 / 3; aspect-ratio: 358 / 170; }   /* 2×170+18 by 170 */
  /* 3-inline stacks like custom1: squares pair up, wide goes full-width below */
  .shots--3inline { grid-template-columns: repeat(2, 1fr); }
  .shots--3inline .shot--wide { grid-column: 1 / 3; aspect-ratio: 358 / 170; }
  .shots--custom1 .shot:nth-child(4) { order: 1; }   /* square 4 moves after wide 5 */
  .shots--custom1 .shot:nth-child(6) { order: 2; }   /* square 6 stays last, pairs with 4 */

  /* Grid_Custom_1 (flip) restack (v1.21) — the mirror of the above: the
     flip's DOM is sq·sq·wide·sq·wide·sq, and its stack reads
     [sq1·sq2] → wide 3 → [sq4·sq6] → wide 5 (pair/wide alternation kept) */
  .shots--custom1-flip .shot:nth-child(4) { order: 1; }
  .shots--custom1-flip .shot:nth-child(6) { order: 1; }   /* pairs with square 4 */
  .shots--custom1-flip .shot:nth-child(5) { order: 2; }   /* bottom wide closes the stack */

  /* ---- SERVICES PAGE, mobile (§4.6) ---- */
  /* the 3-up overview stays THREE-ACROSS (v1.24, Figma 274:224 — replaces
     the stacked/170px treatment): the base 3-column grid simply scales
     down (~105–110px squares on a phone); only the title steps to Bold
     15px — the rule's 60% max-width scales itself */
  .svc-index__title { font-size: 15px; font-weight: 700; line-height: 1.2; margin: 10px 0 8px; }
  .svc-section { scroll-margin-top: 100px; }   /* the mobile header is shorter */
  .svc-details { grid-template-columns: 1fr; row-gap: clamp(22px, 2.4vw, 32px); }
}
