/* ============================================================================
   AFSAR MANSURI — Editorial portfolio
   1  Design tokens
   2  Reset & base
   3  Shared primitives (rules, stars, icons, arrows, reveals)
   4  Top bar
   5  Hero
   6  Selected projects (+ CSS thumbnail mocks)
   7  Skills / Work process / Quote
   8  Contact (+ CSS laptop & mug)
   9  Responsive
   10 Reduced motion
   ========================================================================= */

/* ---------------------------------------------------------------- 1 tokens */
:root {
  --background:     #070707;
  --surface:        #0d0d0d;
  --surface-light:  #141414;
  --primary-red:    #d71920;
  --red-bright:     #ef2a32;
  --deep-red:       #6f090d;
  --text-white:     #f5f5f5;
  --text-grey:      #a6a6a6;
  --text-dim:       #6f6f6f;
  --border:         rgba(255, 255, 255, .16);
  --border-soft:    rgba(255, 255, 255, .09);
  --border-red:     rgba(215, 25, 32, .38);

  --font-display: "Anton", "Haettenschweiler", "Arial Narrow", "Impact", sans-serif;
  /* super-condensed face for the oversized hero word only */
  --font-mega:    "Antonio", "Haettenschweiler", "Arial Narrow", "Impact", sans-serif;
  --font-cond:    "Oswald", "Arial Narrow", "Helvetica Neue", sans-serif;
  --font-body:    "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-script:  "Allura", "Segoe Script", "Brush Script MT", cursive;
  --font-serif:   "Cormorant Garamond", Georgia, "Times New Roman", serif;

  --shell:   1480px;
  --gutter:  clamp(1.25rem, 3.2vw, 2.75rem);

  --ease:    cubic-bezier(.22, .61, .36, 1);
  --ease-out:cubic-bezier(.16, 1, .3, 1);
}

/* ------------------------------------------------------------- 2 reset/base */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--background);
  color: var(--text-white);
  font-family: var(--font-body);
  font-size: clamp(.875rem, .34vw + .78rem, 1rem);
  line-height: 1.6;
  font-weight: 400;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg { display: block; max-width: 100%; }
img { height: auto; }

h1, h2, h3, h4, p, figure, blockquote, dl, dd { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

a { color: inherit; text-decoration: none; }

::selection { background: var(--primary-red); color: #fff; }

:focus-visible {
  outline: 2px solid var(--primary-red);
  outline-offset: 3px;
}

.svg-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--primary-red); color: #fff;
  padding: .7rem 1.2rem; font: 600 .75rem/1 var(--font-cond);
  letter-spacing: .12em; text-transform: uppercase;
}
.skip-link:focus { left: 0; }

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* global film grain -------------------------------------------------------- */
.grain {
  position: fixed; inset: 0; z-index: 60;
  pointer-events: none; opacity: .035;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/><feColorMatrix type='saturate' values='0'/></filter><rect width='160' height='160' filter='url(%23n)'/></svg>");
  mix-blend-mode: overlay;
}

/* ------------------------------------------------------- 3 shared primitives */
.section-title {
  font-family: var(--font-cond);
  font-weight: 600;
  font-size: clamp(1.35rem, 1.65vw + .55rem, 2.05rem);
  letter-spacing: .012em;
  text-transform: uppercase;
  line-height: 1;
  display: flex;
  align-items: center;
  gap: .55em;
  white-space: nowrap;
}

.rule {
  flex: 1 1 auto;
  height: 1px;
  min-width: 1.5rem;
  background: linear-gradient(90deg, var(--border), rgba(255,255,255,.05));
}

.star { width: 1em; height: 1em; fill: var(--primary-red); flex: none; }
.star--inline { width: .62em; height: .62em; }

.link-arrow {
  display: inline-flex; align-items: center; gap: .9rem;
  font-family: var(--font-cond); font-weight: 400;
  font-size: clamp(.68rem, .42vw + .55rem, .8rem);
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-grey);
  transition: color .3s var(--ease);
}
.link-arrow:hover { color: var(--text-white); }

.arrow { width: 2.5rem; height: .75rem; flex: none; overflow: visible; }
.arrow path {
  fill: none; stroke: currentColor; stroke-width: 1.1;
  stroke-linecap: round; stroke-linejoin: round;
}
.link-arrow:hover .arrow { transform: translateX(5px); }
.arrow { transition: transform .35s var(--ease-out); }

.icon-dot, .icon-ring, .star-badge {
  display: inline-grid; place-items: center; flex: none;
  border: 1px solid var(--border-red);
  border-radius: 50%;
}
.icon-dot { width: 1.85rem; height: 1.85rem; }
.icon-dot svg { width: .95rem; height: .95rem; }
.icon-ring { width: 2.85rem; height: 2.85rem; }
.icon-ring svg { width: 1.2rem; height: 1.2rem; }
.icon-dot svg, .icon-ring svg {
  fill: none; stroke: var(--primary-red); stroke-width: 1.4;
  stroke-linecap: round; stroke-linejoin: round;
}

.script { font-family: var(--font-script); font-weight: 400; }

/* scroll reveal ------------------------------------------------------------
   Scoped to .js (set by an inline script in <head>) so a JS failure can never
   leave the page with everything at opacity 0.                             */
.js [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  transition: opacity .9s var(--ease-out), transform .9s var(--ease-out);
  transition-delay: var(--d, 0ms);
  will-change: opacity, transform;
}
.js [data-reveal].is-in { opacity: 1; transform: none; }

/* the oversized word gets a slower, wider reveal of its own */
.js .hero__word[data-reveal] {
  transform: scale(1.055);
  transition-duration: 1.7s;
}
.js .hero__word[data-reveal].is-in { transform: scale(1); }

/* the portrait drifts in horizontally rather than rising */
.js .hero-portrait img[data-reveal] {
  transform: translate3d(52px, 0, 0);
  transition-duration: 1.4s;
  transition-delay: 120ms;
}
.js .hero-portrait img[data-reveal].is-in { transform: none; }

/* ---------------------------------------------------------------- 4 top bar */
.topbar {
  position: relative;
  z-index: 20;
  border-bottom: 1px solid rgba(215, 25, 32, .5);
  background: var(--background);
}

.topbar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: clamp(48px, 4vw, 62px);
  padding-block: .55rem;
}

.topbar__id {
  display: flex; flex-direction: column; gap: .12em;
  font-family: var(--font-cond);
  font-size: clamp(.6rem, .34vw + .5rem, .72rem);
  letter-spacing: .14em; text-transform: uppercase; line-height: 1.25;
}
.topbar__role { color: var(--primary-red); font-weight: 600; }
.topbar__sub  { color: var(--text-white); font-weight: 400; }
/* projects.html only — the name links home. Underline on hover rather than a
   colour change, so the red identity mark stays the red identity mark. */
.topbar__home { display: inline-block; border-bottom: 1px solid transparent; }
.topbar__home:hover { border-bottom-color: var(--primary-red); }
.topbar__home:hover .topbar__role { color: #fff; }

.topbar__status {
  display: flex; align-items: center; gap: .8rem;
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(.6rem, .34vw + .5rem, .72rem);
  letter-spacing: .15em; text-transform: uppercase;
  white-space: nowrap;
}
.topbar__status .star { width: .85rem; height: .85rem; }

/* burger + mobile menu -----------------------------------------------------
   Both are phone-only: the desktop reference has no nav bar at all, so the
   nav links live exclusively inside this panel. */
.burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  width: 34px; height: 30px;
  padding: 0;
  border: 0; background: none; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.burger span {
  display: block; height: 2px; width: 100%;
  background: var(--text-white);
  transition: transform .38s var(--ease-out), opacity .2s linear;
}
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

.mobilenav {
  position: fixed; inset: 0; z-index: 150;
  display: grid; align-content: center; justify-items: start;
  gap: clamp(1.5rem, 6vw, 2.4rem);
  padding: var(--gutter);
  background:
    radial-gradient(90% 60% at 80% 12%, rgba(111, 9, 13, .5), transparent 62%),
    var(--background);
  opacity: 0; visibility: hidden;
  transform: translateY(-10px);
  transition: opacity .35s var(--ease), transform .45s var(--ease-out),
              visibility .35s linear;
}
.mobilenav.is-open { opacity: 1; visibility: visible; transform: none; }

.mobilenav nav { display: grid; gap: clamp(.9rem, 4vw, 1.6rem); }
.mobilenav nav a {
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 12vw, 3.4rem);
  line-height: .95;
  text-transform: uppercase;
  color: var(--text-white);
}
.mobilenav nav a:active { color: var(--primary-red); }

.mobilenav__status {
  display: flex; align-items: center; gap: .7rem;
  font-family: var(--font-cond); font-weight: 500;
  font-size: .74rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-grey);
  padding-top: clamp(.5rem, 3vw, 1rem);
  border-top: 1px solid var(--border-soft);
  width: 100%;
}
.mobilenav__status .star { width: .85rem; height: .85rem; }
.mobilenav__mail {
  font-size: 1rem; color: var(--text-white);
  border-bottom: 1px solid var(--border-red);
  padding-bottom: .2rem;
}

/* ------------------------------------------------------------------ 5 hero */
.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: clamp(560px, 56vw, 880px);
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid rgba(215, 25, 32, .5);
  background:
    radial-gradient(120% 90% at 50% 8%, rgba(111, 9, 13, .45), transparent 62%),
    var(--background);
}

/* oversized PORTFOLIO word -------------------------------------------------
   Boxed to the same rhythm as .shell so its P and final O line up with the
   top bar's "UX/UI DESIGNER" and the freelance star, and stretched to the
   full hero height (the SVG uses preserveAspectRatio="none", so the glyphs
   scale vertically independently of their width). */
.hero__word {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 60%;                     /* word occupies the top 60% of the hero */
  z-index: 0;
  pointer-events: none;
  line-height: 0;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.hero__word svg {
  width: 100%;
  height: 100%;
}
.hero__word text {
  font-family: var(--font-mega);
  /* Antonio is variable 100-700. At this degree of vertical stretch the weight
     axis only moves the stem-to-letter-width ratio from .198 (100) to .256
     (400). NOTE: the viewBox on the <svg> is cropped to this exact weight's
     ink — re-measure it if you change this number. */
  font-weight: 250;
  font-size: 236px;
  fill: url(#wordGrad);
}
.hero__word::after {           /* soft vignette so the word melts into black */
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(88% 105% at 50% 30%, transparent 40%, rgba(7,7,7,.24) 78%, rgba(7,7,7,.58) 100%),
    linear-gradient(180deg, transparent 0%, transparent 54%, rgba(7,7,7,.5) 84%, rgba(7,7,7,.88) 100%);
  pointer-events: none;
}

/* Legibility scrim. With the word running the full height of the hero, the
   intro copy and the stats rail would otherwise sit directly on bright red
   letterforms. This darkens the two outer columns and the base of the hero
   while leaving the centre — where the portrait stands — untouched. It sits
   above the word (z 0) and below the portrait (z 2). */
.hero::after {
  content: "";
  position: absolute; inset: 0; z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(96deg,  rgba(7,7,7,.82) 0%, rgba(7,7,7,.6) 14%, rgba(7,7,7,.2) 28%, transparent 40%),
    linear-gradient(276deg, rgba(7,7,7,.72) 0%, rgba(7,7,7,.4) 11%, rgba(7,7,7,.1) 22%, transparent 32%),
    linear-gradient(0deg,   rgba(7,7,7,.5) 0%, rgba(7,7,7,.12) 15%, transparent 30%);
}

.hero__glow {
  position: absolute; z-index: 0; pointer-events: none;
  left: 50%; top: 8%;
  width: min(70vw, 900px); aspect-ratio: 1;
  transform: translateX(-48%);
  background: radial-gradient(circle, rgba(215,25,32,.20), transparent 62%);
  filter: blur(18px);
}

/* portrait ----------------------------------------------------------------- */
.hero-portrait {
  position: absolute;
  z-index: 2;
  bottom: 0;
  left: 50%;
  /* framed so the subject's head clears the PORTFOLIO word, his silhouette
     starts just past "MANSURI" and stops just short of the stats rail */
  transform: translateX(-40.5%);
  height: 93%;
  display: flex; align-items: flex-end;
  pointer-events: none;
}
.hero-portrait img {
  height: 100%;
  width: auto;
  max-width: none;
  object-fit: contain;
  object-position: bottom center;
  /* cinematic red rim + grounding shadow. Works best with a transparent PNG. */
  filter:
    drop-shadow(-14px 0 26px rgba(215, 25, 32, .30))
    drop-shadow(16px 6px 34px rgba(0, 0, 0, .85))
    contrast(1.04) saturate(1.05);
}
/* base shadow puddle so the figure sits on the black instead of floating */
.hero-portrait::after {
  content: "";
  position: absolute; left: 50%; bottom: -2%;
  width: 118%; height: 26%;
  transform: translateX(-50%);
  background: radial-gradient(50% 50% at 50% 100%, rgba(7,7,7,.95), transparent 72%);
  z-index: 2;
}

/* hero layout -------------------------------------------------------------- */
.hero__grid {
  position: relative;
  z-index: 3;
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 1.24fr) minmax(0, .74fr);
  align-items: end;
  gap: 0 clamp(.5rem, 2vw, 2rem);
  padding-block: clamp(2rem, 4vw, 3.4rem) clamp(1.5rem, 3vw, 2.6rem);
}

.hero__intro { grid-column: 1; min-width: 0; }
.hero__rail  { grid-column: 3; }

.hero__hello {
  /* Allura's ink is ~17% shorter than Sacramento's at the same font-size, so
     these are scaled to keep the previous optical size. letter-spacing must
     stay at 0 — Allura is a connecting script and tracking breaks the joins. */
  font-size: clamp(2.2rem, 3.5vw, 3.55rem);
  line-height: 1;
  letter-spacing: 0;
  color: var(--text-white);
  margin-bottom: clamp(.1rem, .5vw, .35rem);
  text-shadow: 0 2px 18px rgba(0,0,0,.6);
}

.hero__name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(3.15rem, 9.8vw, 9.2rem);
  line-height: 1.02;                 /* open enough to separate the two lines */
  letter-spacing: -.005em;
  text-transform: uppercase;
  margin-bottom: clamp(.7rem, 1.4vw, 1.35rem);
}

/* Solid white, no fill treatment. The one shadow is separation only — the
   name sits directly on the bright red PORTFOLIO word and would otherwise
   lose its edges against it. In em so it scales with the clamp() type. */
.hero__name span {
  display: block;
  color: #fff;
  filter: drop-shadow(0 .05em .11em rgba(0, 0, 0, .78));
}

.hero__title {
  font-family: var(--font-cond);
  font-weight: 600;
  font-size: clamp(.98rem, 1.28vw + .38rem, 1.5rem);
  line-height: 1.16;
  letter-spacing: .015em;
  text-transform: uppercase;
  color: var(--primary-red);
  margin-bottom: clamp(.7rem, 1.2vw, 1.1rem);
}

.hero__lede {
  max-width: 30ch;
  font-size: clamp(.8rem, .42vw + .68rem, .95rem);
  line-height: 1.62;
  color: var(--text-grey);
  margin-bottom: clamp(1.1rem, 2.2vw, 2rem);
}

/* short red rule + CTAs — mobile hero only (see the 640px block) */
.hero__rule, .hero__cta, .hero__sub-cta { display: none; }

.hero__where {
  display: flex; align-items: center; gap: .75rem;
  font-family: var(--font-cond); font-weight: 400;
  font-size: clamp(.64rem, .32vw + .55rem, .78rem);
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-white);
}

/* right rail --------------------------------------------------------------- */
.hero__rail {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: clamp(1.6rem, 6.8vw, 6.4rem);
  align-self: stretch;
}

.hero__tagline {
  display: flex; align-items: flex-start; gap: clamp(.7rem, 1.1vw, 1.15rem);
}
.star-badge { width: clamp(2.2rem, 2.9vw, 3.1rem); aspect-ratio: 1; }
.star-badge svg { width: 42%; height: 42%; fill: var(--text-white); }
.hero__tagline p {
  font-size: clamp(.78rem, .4vw + .66rem, .95rem);
  line-height: 1.5;
  color: var(--text-white);
  max-width: 18ch;
}
/* the rail now carries the current role over the company line, so the first
   line is emphasised and the second drops to the secondary tone */
.hero__tagline p strong {
  display: block; font-weight: 500;
  color: var(--text-white);
}
.hero__tagline p { color: var(--text-grey); }

.stats { display: grid; }
.stat {
  display: flex; align-items: center; gap: clamp(.8rem, 1.6vw, 1.5rem);
  padding-block: clamp(.6rem, 1.35vw, 1.15rem);
  border-bottom: 1px solid var(--border-soft);
}
.stat:first-child { border-top: 1px solid var(--border-soft); }
.stat__num {
  font-family: var(--font-display);
  font-size: clamp(1.7rem, 2.75vw + .35rem, 3.5rem);
  line-height: .9;
  color: var(--primary-red);
  min-width: 2.4ch;
  font-variant-numeric: tabular-nums;
}
.stat__label {
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.6rem, .3vw + .52rem, .74rem);
  letter-spacing: .12em; text-transform: uppercase;
  line-height: 1.35;
  color: var(--text-grey);
}

/* ============================================================================
   6  Shared section furniture (label / title / lede)
   ========================================================================= */
.sec {
  position: relative;
  padding-block: clamp(3rem, 7vw, 6.5rem);
  border-bottom: 1px solid var(--border-soft);
  background: var(--background);
}

.sec__head { margin-bottom: clamp(1.8rem, 4vw, 3.4rem); }
.sec__head--row {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: clamp(1rem, 3vw, 2.5rem); flex-wrap: wrap;
}

.sec__label {
  display: flex; align-items: baseline; gap: .7em;
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(.62rem, .3vw + .54rem, .76rem);
  letter-spacing: .24em; text-transform: uppercase;
  color: var(--primary-red);
  margin-bottom: clamp(.7rem, 1.6vw, 1.2rem);
}
.sec__label-num {
  font-family: var(--font-display); font-weight: 400;
  font-size: 1.9em; line-height: 1;
  letter-spacing: 0;
  color: var(--primary-red);
}
/* the em-dash between number and label, drawn rather than typed so it keeps
   its length independent of the font */
.sec__label-num::after {
  content: ""; display: inline-block;
  width: 1.1em; height: 1px; margin-left: .45em; vertical-align: .3em;
  background: currentColor; opacity: .7;
}

.sec__title {
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(1.6rem, 3.3vw + .3rem, 3.5rem);
  line-height: 1.06;
  letter-spacing: -.012em;
  color: var(--text-white);
  max-width: 20ch;
  text-wrap: balance;
}

.sec__lede {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 26ch), 1fr));
  gap: clamp(.8rem, 2vw, 2.2rem);
  max-width: 76ch;
  margin-top: clamp(1rem, 2.4vw, 1.8rem);
  color: var(--text-grey);
  font-size: clamp(.84rem, .34vw + .74rem, .98rem);
  line-height: 1.68;
}

/* Optional images fade in only once they have actually decoded. Lazy images
   are not requested until they near the viewport, so a missing file would
   otherwise flash its alt text / broken-image icon over the ghost panel
   before the error handler could remove it. Scoped to .js so that with
   JavaScript off the images simply render normally. */
.js img[data-optional] { opacity: 0; transition: opacity .6s var(--ease); }
.js img[data-optional].is-loaded { opacity: 1; }

/* shared "ghost" fallback that shows through when an image is missing ------ */
.brand__ghost, .arch__ghost, .purpose__ghost, .compare__ghost,
.proj-web-ghost, .proj-video-ghost, .proj-brand-ghost, .proj-top-ghost {
  position: absolute; inset: 0; z-index: 0;
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 400;
  text-transform: uppercase; letter-spacing: .02em;
  color: rgba(255, 255, 255, .07);
  background:
    radial-gradient(120% 100% at 72% 12%, rgba(215, 25, 32, .22), transparent 62%),
    linear-gradient(155deg, #131315, #0a0a0b 62%, #101011);
  text-align: center; line-height: 1;
  pointer-events: none;
}

/* ============================================================================
   7  Section 01 — Selected brand collaborations
   ========================================================================= */
/* The section header and the cards share ONE grid, so the header can take the
   left seven columns and the first card can be placed into the space beside it
   rather than leaving that area empty. */
.work-layout {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(.7rem, 1.2vw, 1.15rem);
}
/* the <ul> hands its <li>s straight to .work-layout — role="list" in the markup
   restores the list semantics that display:contents drops in Safari */
.brands { display: contents; }

.sec--work .sec__head {
  grid-column: 1 / 8;
  grid-row: 1;
  align-self: start;
  margin-bottom: 0;
}
/* the copy is already inside a seven-column measure, so its own cap would only
   narrow it twice over */
.sec--work .sec__lede { max-width: none; }

/* Asymmetric placement. Spans are declared per brand so the composition is
   authored rather than emergent — reordering the list will not reflow it.
     row 1   header (7)        | 01 Victoria's Secret (5)
     row 2   02 Warner Bros (7)| 03 Siemens (5, spans rows 2–3)
     row 3   04 AIFF (7)       |
     row 4   05 Delhivery (12)
     row 5   06 L&T Finance (6)| 07 Bank of Baroda (6)                       */
.brand--vs   { grid-column: 8 / -1; grid-row: 1; }
.brand--wb   { grid-column: span 7; }
.brand--sie  { grid-column: span 5; grid-row: span 2; }
.brand--aiff { grid-column: span 7; }
.brand--del  { grid-column: span 12; }
.brand--lt   { grid-column: span 6; }
.brand--bob  { grid-column: span 6; }

.brand__link {
  position: relative;
  display: block;
  width: 100%;
  /* NB: do not add height:100% here. Combined with the aspect-ratio below it
     makes the browser derive WIDTH from height, which blows the card out past
     its grid column. Only the row-spanning card gets an explicit height, and
     that one carries no aspect-ratio. */
  overflow: hidden;
  border: 1px solid var(--border-soft);
  background: var(--surface);
  transition: border-color .5s var(--ease), box-shadow .5s var(--ease),
              transform .5s var(--ease-out);
}
.brand--wb   .brand__link { aspect-ratio: 16 / 8.6; }
.brand--aiff .brand__link { aspect-ratio: 16 / 6.4; }
.brand--del  .brand__link { aspect-ratio: 16 / 5.4; }
.brand--lt   .brand__link,
.brand--bob  .brand__link { aspect-ratio: 16 / 8.4; }

/* The two cards that fill their row instead of setting a ratio: Siemens spans
   two rows, and the feature card takes its height from the header beside it.
   Neither may carry an aspect-ratio — see the note on .brand__link above. */
.brand--sie  .brand__link { height: 100%; }
.brand--vs   .brand__link {
  height: 100%;
  /* keeps the feature card substantial even where the header runs short */
  min-height: clamp(320px, 29vw, 470px);
}

.brand__link:hover,
.brand__link:focus-visible {
  border-color: rgba(215, 25, 32, .55);
  box-shadow: 0 22px 60px -26px rgba(215, 25, 32, .6);
  transform: translateY(-3px);
}

.brand__media { position: absolute; inset: 0; overflow: hidden; }
/* sit the fallback lettering in the upper third, clear of the copy block that
   occupies the bottom of the card */
.brand__ghost { place-items: start center; padding-top: 6%; }
.brand__media img {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .9s var(--ease-out), filter .6s var(--ease);
  filter: saturate(.85) contrast(1.04);
}
.brand__link:hover .brand__media img { transform: scale(1.045); filter: saturate(1) contrast(1.06); }
.brand__ghost { font-size: clamp(2.4rem, 7vw, 6rem); }

/* legibility veil + the deep-red tint that comes up on hover */
.brand__media::after {
  content: ""; position: absolute; inset: 0; z-index: 2;
  background:
    linear-gradient(0deg, rgba(7,7,7,.94) 0%, rgba(7,7,7,.6) 38%, rgba(7,7,7,.12) 68%, transparent 100%),
    linear-gradient(0deg, rgba(111,9,13,0), rgba(111,9,13,0));
  transition: background .55s var(--ease);
}
.brand__link:hover .brand__media::after {
  background:
    linear-gradient(0deg, rgba(7,7,7,.95) 0%, rgba(7,7,7,.68) 42%, rgba(7,7,7,.2) 72%, transparent 100%),
    linear-gradient(0deg, rgba(150,14,20,.34), rgba(111,9,13,.06));
}

/* The body fills the whole card and pushes its content to the bottom, so the
   project number can anchor to the card's top-right instead of hanging off
   the top of a bottom-anchored block (which clipped it on small cards). */
.brand__body {
  position: absolute; inset: 0; z-index: 3;
  display: flex; flex-direction: column; align-items: flex-start;
  justify-content: flex-end;
  gap: .32rem;
  padding: clamp(.9rem, 1.8vw, 1.6rem);
  transition: transform .55s var(--ease-out);
  pointer-events: none;          /* the <a> underneath stays the hit target */
}
.brand__link:hover .brand__body { transform: translateY(-4px); }

.brand__num {
  position: absolute;
  top: clamp(.9rem, 1.8vw, 1.6rem); right: clamp(.9rem, 1.8vw, 1.6rem);
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 2.6vw, 2.9rem); line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px rgba(255, 255, 255, .42);
  transition: color .45s var(--ease), -webkit-text-stroke-color .45s var(--ease);
}
.brand__link:hover .brand__num,
.brand__link:focus-visible .brand__num {
  color: var(--primary-red);
  -webkit-text-stroke-color: transparent;
}

.brand__industry {
  font-family: var(--font-cond); font-weight: 400;
  font-size: clamp(.58rem, .26vw + .52rem, .7rem);
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--primary-red);
}
.brand__name {
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(1.1rem, 1.5vw + .5rem, 2.05rem);
  line-height: 1.06; letter-spacing: -.008em;
  color: var(--text-white);
}
.brand__project {
  font-size: clamp(.76rem, .3vw + .68rem, .9rem);
  color: var(--text-grey);
}
.brand__desc {
  font-size: clamp(.76rem, .3vw + .68rem, .88rem);
  line-height: 1.6; color: var(--text-grey);
  max-width: 46ch;
}
.brand__role {
  display: grid; gap: .1rem;
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.6rem, .24vw + .55rem, .72rem);
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-dim);
}
.brand__role em { font-style: normal; color: var(--text-grey); }

.brand__cta {
  display: inline-flex; align-items: center; gap: .7rem;
  margin-top: .35rem;
  font-family: var(--font-cond); font-weight: 400;
  font-size: clamp(.6rem, .26vw + .55rem, .72rem);
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--text-white);
}
.brand__cta .arrow { width: 1.9rem; }
.brand__link:hover .brand__cta .arrow { transform: translateX(7px); }

/* Extended copy is progressive: on pointer devices it is held back until
   hover/focus, on touch it is always visible so nothing is hover-only. */
@media (hover: hover) and (min-width: 861px) {
  .brand__desc, .brand__role {
    opacity: 0;
    max-height: 0;
    overflow: hidden;
    transform: translateY(6px);
    transition: opacity .45s var(--ease), max-height .55s var(--ease),
                transform .5s var(--ease-out);
  }
  .brand__link:hover .brand__desc,
  .brand__link:hover .brand__role,
  .brand__link:focus-visible .brand__desc,
  .brand__link:focus-visible .brand__role {
    opacity: 1; max-height: 11rem; transform: none;
  }
  /* The two compact cards only have room for one of the two, and the credit
     block is the more useful half — it carries who the work was produced
     through, which the description does not. */
  .brand--lt .brand__desc,
  .brand--bob .brand__desc { display: none; }
}

/* ============================================================================
   8  Section 02 — Work with purpose (BMC Schools)
   ========================================================================= */
.sec--purpose {
  background:
    radial-gradient(80% 60% at 88% 4%, rgba(111, 9, 13, .26), transparent 62%),
    var(--background);
}

.purpose {
  display: grid;
  grid-template-columns: minmax(0, 1.28fr) minmax(0, .92fr);
  gap: clamp(1.4rem, 3vw, 3rem);
  align-items: start;
}

.purpose__frame {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border: 1px solid var(--border-soft);
  background: var(--surface);
}
.purpose__frame img,
.purpose__video {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%; object-fit: cover;
}
.purpose__video { z-index: 2; opacity: 0; transition: opacity .5s var(--ease); }
.purpose__frame.is-playing .purpose__video { opacity: 1; }
.purpose__ghost {
  font-size: clamp(1.4rem, 3.4vw, 3rem);
  line-height: 1.08;
  color: rgba(255,255,255,.09);
}
.purpose__frame-cap {
  position: absolute; left: 0; bottom: 0; z-index: 3;
  padding: .7em 1.1em;
  font-family: var(--font-cond); font-weight: 400;
  font-size: clamp(.58rem, .26vw + .52rem, .7rem);
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--text-white);
  background: linear-gradient(0deg, rgba(7,7,7,.9), transparent);
  width: 100%;
}

.purpose__copy { display: grid; gap: clamp(.6rem, 1.4vw, .95rem); }
.purpose__title {
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(1.3rem, 1.9vw + .5rem, 2.3rem);
  line-height: 1.08; color: var(--text-white);
}
.purpose__sub {
  font-family: var(--font-cond); font-weight: 400;
  font-size: clamp(.66rem, .3vw + .58rem, .8rem);
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--primary-red);
  margin-bottom: .3rem;
}
.purpose__copy p {
  font-size: clamp(.82rem, .32vw + .73rem, .95rem);
  line-height: 1.68; color: var(--text-grey);
}
.purpose__copy em { font-style: normal; color: var(--text-white); }

.purpose__scope {
  display: flex; flex-wrap: wrap; gap: .45rem;
  margin-top: .5rem;
}
.purpose__scope dt {
  width: 100%;
  font-family: var(--font-cond); font-weight: 400;
  font-size: clamp(.58rem, .26vw + .52rem, .7rem);
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: .3rem;
}
.purpose__scope dd {
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.6rem, .26vw + .55rem, .72rem);
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-grey);
  padding: .5em 1em;
  border: 1px solid var(--border-soft);
}
.purpose__link { margin-top: .8rem; color: var(--text-white); }

.purpose__strip {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(.6rem, 1.1vw, 1rem);
  margin-top: clamp(.6rem, 1.6vw, 1.2rem);
}
.purpose__cell { position: relative; }
.purpose__cell picture {
  display: block; position: relative;
  aspect-ratio: 4 / 3; overflow: hidden;
  border: 1px solid var(--border-soft);
  background:
    radial-gradient(110% 100% at 70% 10%, rgba(215,25,32,.16), transparent 64%),
    linear-gradient(155deg, #131315, #0a0a0b);
}
.purpose__cell img { width: 100%; height: 100%; object-fit: cover; }

/* ============================================================================
   9  Section 03 — Across disciplines
   Expansion is CSS-only (:hover / :focus-within) so it survives JS being off.
   ========================================================================= */
.disc {
  display: flex;
  gap: clamp(.5rem, .9vw, .9rem);
  min-height: clamp(320px, 40vw, 480px);
}
.disc__panel {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: clamp(1rem, 1.8vw, 1.7rem);
  overflow: hidden;
  border: 1px solid var(--border-soft);
  background:
    radial-gradient(120% 80% at 50% 100%, rgba(111, 9, 13, .2), transparent 64%),
    var(--surface);
  transition: flex-grow .65s var(--ease-out), border-color .5s var(--ease),
              background .5s var(--ease);
}
.disc__panel:hover,
.disc__panel:focus-within {
  flex-grow: 3.1;
  border-color: rgba(215, 25, 32, .5);
  background:
    radial-gradient(120% 80% at 50% 100%, rgba(150, 14, 20, .34), transparent 66%),
    var(--surface-light);
}

/* ---- category motif -------------------------------------------------------
   A line-art watermark identifying each card's discipline, held to the top
   right corner clear of the title and (on hover) the body copy beneath it.
   Faint at rest so the panel never reads empty, then brightened and set in
   motion once the panel opens. Pure SVG line art — no images. Follows the
   same motif system as the Transformation panels on coloredweb.in so the two
   sites read as family, with this site's red standing in for the purple
   accent.

   .is-open is added by script.js on touch devices, where there is no hover to
   trigger any of this. */
.disc__motif {
  position: absolute;
  top: clamp(1rem, 1.8vw, 1.7rem); right: clamp(1rem, 1.8vw, 1.7rem);
  width: clamp(160px, 85%, 320px); height: auto;
  aspect-ratio: 5 / 4;
  pointer-events: none;
  z-index: 0;
}
/* two-tone ink: .ln strokes and .fl fills, each with a red .vi variant */
.disc__motif .ln {
  fill: none; stroke: #fff; stroke-width: 1.3;
  stroke-linecap: round; stroke-linejoin: round;
  opacity: .12; transition: opacity .6s var(--ease);
}
.disc__motif .ln.vi { stroke: var(--primary-red); opacity: .28; }
.disc__motif .fl {
  fill: #fff; opacity: .11;
  transition: opacity .6s var(--ease), transform .7s var(--ease);
}
.disc__motif .fl.vi { fill: var(--primary-red); opacity: .3; }

.disc__panel:hover .disc__motif .ln,
.disc__panel:focus-within .disc__motif .ln,
.disc__panel.is-open .disc__motif .ln { opacity: .24; }
.disc__panel:hover .disc__motif .ln.vi,
.disc__panel:focus-within .disc__motif .ln.vi,
.disc__panel.is-open .disc__motif .ln.vi { opacity: .6; }
.disc__panel:hover .disc__motif .fl,
.disc__panel:focus-within .disc__motif .fl,
.disc__panel.is-open .disc__motif .fl { opacity: .2; }
.disc__panel:hover .disc__motif .fl.vi,
.disc__panel:focus-within .disc__motif .fl.vi,
.disc__panel.is-open .disc__motif .fl.vi { opacity: .64; }

/* A · digital experiences — a red scan line sweeps the wireframe */
.disc__motif .m-scan { fill: var(--primary-red); opacity: 0; transform-box: fill-box; }
.disc__panel:hover .dm-web .m-scan,
.disc__panel:focus-within .dm-web .m-scan,
.disc__panel.is-open .dm-web .m-scan { opacity: .5; animation: discScan 2.8s ease-in-out infinite; }
@keyframes discScan { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(62px); } }

/* B · motion & film — the play ring pulses outward */
.disc__motif .m-pulse {
  fill: none; stroke: var(--primary-red); stroke-width: 1.3; opacity: 0;
  transform-box: fill-box; transform-origin: center;
}
.disc__panel:hover .dm-video .m-pulse,
.disc__panel:focus-within .dm-video .m-pulse,
.disc__panel.is-open .dm-video .m-pulse { animation: discPulse 2.1s ease-out infinite; }
@keyframes discPulse {
  0%   { transform: scale(1);   opacity: .5; }
  70%  { transform: scale(1.7); opacity: 0; }
  100% { opacity: 0; }
}

/* C · brand identity — the concentric rings turn slowly */
.disc__motif .m-spin { transform-box: fill-box; transform-origin: center; }
.disc__panel:hover .dm-brand .m-spin,
.disc__panel:focus-within .dm-brand .m-spin,
.disc__panel.is-open .dm-brand .m-spin { animation: discSpin 24s linear infinite; }
@keyframes discSpin { to { transform: rotate(360deg); } }

/* D · social & ads — bars rise off the baseline, then the trend line draws */
.disc__motif .m-bar { transform-box: fill-box; transform-origin: bottom; transform: scaleY(.5); }
.disc__panel:hover .dm-social .m-bar,
.disc__panel:focus-within .dm-social .m-bar,
.disc__panel.is-open .dm-social .m-bar { transform: scaleY(1); }
.dm-social .m-bar:nth-of-type(1) { transition-delay: .02s; }
.dm-social .m-bar:nth-of-type(2) { transition-delay: .09s; }
.dm-social .m-bar:nth-of-type(3) { transition-delay: .16s; }
.dm-social .m-bar:nth-of-type(4) { transition-delay: .23s; }
.disc__motif .m-trend {
  stroke-dasharray: 1; stroke-dashoffset: 1;
  transition: stroke-dashoffset 1.1s var(--ease) .18s, opacity .6s var(--ease);
}
.disc__panel:hover .dm-social .m-trend,
.disc__panel:focus-within .dm-social .m-trend,
.disc__panel.is-open .dm-social .m-trend { stroke-dashoffset: 0; }

/* Looping motion is decorative; the static artwork alone carries the panel. */
@media (prefers-reduced-motion: reduce) {
  .dm-brand .m-spin, .dm-web .m-scan, .dm-video .m-pulse { animation: none !important; }
}

.disc__title {
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(1rem, 1.25vw + .4rem, 1.65rem);
  line-height: 1.1; letter-spacing: -.005em;
  color: var(--text-white);
}

.disc__body {
  display: grid; gap: .8rem;
  margin-top: .8rem;
  max-width: 40ch;
}
.disc__body p {
  font-size: clamp(.78rem, .3vw + .7rem, .9rem);
  line-height: 1.62; color: var(--text-grey);
}

/* The whole panel is the click target, without wrapping each card in a second
   anchor: the existing "View Projects" link grows an overlay that covers the
   card, so the visible link stays exactly where it is and a tap anywhere
   navigates to the same place.

   The insets are deliberately oversized rather than `inset: 0`. Above 1025px
   .disc__body becomes position:absolute, which makes IT the containing block —
   `inset: 0` would then stretch only across the body copy instead of the whole
   card. Overflowing in every direction and letting .disc__panel's own
   overflow:hidden clip it back gives the same rectangle at every breakpoint,
   whichever ancestor happens to be positioned. That clip is what bounds the
   hit area, so it has to stay on the panel. */
.disc__body .link-arrow::after {
  content: "";
  position: absolute;
  inset: -100vh -100vw;
  z-index: 2;
}
/* the pointer should read as "this card is a link" anywhere on it */
.disc__panel { cursor: pointer; }
.disc__panel:hover .link-arrow { color: var(--text-white); }
.disc__panel:hover .link-arrow .arrow { transform: translateX(5px); }
/* On pointer devices the detail is held back until a panel is opened. Touch
   and narrow screens fall through to the stacked layout further down, where
   everything is visible.
   min-width must not dip to 981px (the value used elsewhere on the page):
   the mobile-stack override further down switches at max-width:1024px, and a
   981px floor here would overlap it for 43px. In that overlap the title and
   body below go position:absolute, which would pull them out of the stacked
   column layout entirely and collapse each panel to its padding. */
@media (hover: hover) and (min-width: 1025px) {
  /* Anchor the title a FIXED distance from the panel's bottom edge instead of
     letting it sit directly above the body copy in normal flow. The body's
     height varies with how much each card's description wraps to, and since
     it still occupies layout space while hidden (opacity alone doesn't
     collapse it), that variance was pushing the title to a different height
     on every card. Reserving one constant block for the body — regardless of
     its real height — pins the title to the same spot on all four. */
  .disc__panel { --disc-reserve: 9rem; }
  .disc__title {
    position: absolute;
    left: clamp(1rem, 1.8vw, 1.7rem); right: clamp(1rem, 1.8vw, 1.7rem);
    bottom: calc(clamp(1rem, 1.8vw, 1.7rem) + var(--disc-reserve));
    white-space: nowrap;
  }
  .disc__body {
    position: absolute;
    left: clamp(1rem, 1.8vw, 1.7rem); right: clamp(1rem, 1.8vw, 1.7rem);
    bottom: clamp(1rem, 1.8vw, 1.7rem);
    margin-top: 0;
    opacity: 0;
    transform: translateY(10px);
    transition: opacity .5s var(--ease), transform .55s var(--ease-out);
  }
  .disc__panel:hover .disc__body,
  .disc__panel:focus-within .disc__body { opacity: 1; transform: none; }
}

/* ============================================================================
   10  Section 04 — Career journey
   ========================================================================= */
.cv { --cv-gap: clamp(2rem, 4vw, 3.4rem); display: grid; gap: var(--cv-gap); }

.cv__row {
  display: grid;
  grid-template-columns: minmax(0, .68fr) minmax(0, 1fr) minmax(0, 1.2fr);
  gap: clamp(1rem, 2.6vw, 2.8rem);
  align-items: start;
}

/* Every range stays on ONE line. The widest is "2026 — Present", so the type
   scales off that: nowrap plus a ceiling low enough that the longest range
   still fits its column. Without nowrap the shorter all-digit ranges fitted
   and the two longer ones broke onto a second line, which read as a bug. */
.cv__years {
  display: flex; flex-wrap: nowrap; align-items: baseline; gap: .1em .28em;
  white-space: nowrap;
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(1.4rem, 1.9vw + .2rem, 2.5rem);
  line-height: .96;
  color: var(--text-dim);
  transition: color .8s var(--ease);
}
.cv__row.is-in .cv__years { color: var(--text-grey); }
.cv__row--current .cv__years,
.cv__row--current.is-in .cv__years { color: var(--text-white); }
.cv__dash { color: var(--primary-red); }

/* the spine: a hairline down the left of the middle column, with a red
   segment that fills as each row reveals */
.cv__what {
  position: relative;
  padding-left: clamp(1.1rem, 2vw, 1.9rem);
}
.cv__what::before,
.cv__what::after {
  content: ""; position: absolute; left: 0; top: .35em; width: 1px;
}
.cv__what::before { bottom: calc(-1 * var(--cv-gap)); background: var(--border-soft); }
.cv__what::after  { height: 0; background: var(--primary-red); transition: height 1.1s var(--ease-out) .15s; }
.cv__row.is-in .cv__what::after { height: calc(100% - .35em); }
.cv__row:last-child .cv__what::before { bottom: auto; height: calc(100% - .35em); }

/* Only the current row carries a dot — on the past rows it marked nothing the
   spine wasn't already saying, so the markup was dropped there. */
.cv__dot {
  position: absolute; left: 0; top: .35em;
  width: 9px; height: 9px; border-radius: 50%;
  transform: translateX(-4px);
  background: var(--primary-red);
  border: 1px solid var(--primary-red);
  box-shadow: 0 0 0 4px rgba(215, 25, 32, .18), 0 0 18px rgba(215, 25, 32, .7);
}

.cv__role {
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(1rem, 1.1vw + .45rem, 1.45rem);
  line-height: 1.14; color: var(--text-white);
}
.cv__org {
  font-size: clamp(.8rem, .3vw + .72rem, .92rem);
  color: var(--primary-red);
  margin-top: .2rem;
}
.cv__meta {
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.62rem, .26vw + .56rem, .74rem);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-dim);
  margin-top: .15rem;
}

.cv__note p {
  font-size: clamp(.82rem, .32vw + .73rem, .95rem);
  line-height: 1.68; color: var(--text-grey);
  max-width: 52ch;
}
.cv__caps {
  display: flex; flex-wrap: wrap; gap: .4rem;
  margin-top: .9rem;
}
.cv__caps li {
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.58rem, .24vw + .53rem, .7rem);
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-grey);
  padding: .45em .9em;
  border: 1px solid var(--border-soft);
}
/* Both labels are <p> inside .cv__note, so they have to out-specify
   `.cv__note p` (0-1-1) or they inherit body copy's size and colour and the
   whole note flattens into one grey block. Hence the .cv__note prefix.
   Three levels, three colours: description = grey body copy, "Current focus"
   = red (it only appears on the live chapter), "Selected work" = dim, since
   it is just a structural label above the links. */
.cv__note .cv__focus-label,
.cv__note .cv__selected-label {
  font-family: var(--font-cond); font-weight: 400;
  font-size: clamp(.58rem, .24vw + .53rem, .7rem);
  line-height: 1.3;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--text-dim);
  margin-top: 1rem;
}
.cv__note .cv__focus-label { color: var(--primary-red); }
.cv__selected { margin-top: 1.1rem; padding-top: 1rem; border-top: 1px solid var(--border-soft); }
.cv__note .cv__selected-label { margin-top: 0; margin-bottom: .55rem; }
.cv__selected-list { display: flex; flex-wrap: wrap; gap: .35rem .9rem; }
.cv__selected-list a {
  font-size: clamp(.74rem, .28vw + .67rem, .86rem);
  color: var(--text-grey);
  border-bottom: 1px solid transparent;
  transition: color .3s var(--ease), border-color .3s var(--ease);
}
.cv__selected-list a:hover,
.cv__selected-list a:focus-visible { color: var(--text-white); border-bottom-color: var(--primary-red); }

/* ============================================================================
   11  Section 05 — Education (deliberately light)
   ========================================================================= */
.sec--edu { padding-block: clamp(2rem, 4.5vw, 3.6rem); }
.edu {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(1rem, 3vw, 2.5rem);
  padding: clamp(1.2rem, 2.6vw, 2.2rem) clamp(1.2rem, 2.6vw, 2.4rem);
  overflow: hidden;
  border: 1px solid var(--border-soft);
  background:
    radial-gradient(90% 140% at 96% 50%, rgba(111, 9, 13, .2), transparent 60%),
    var(--surface);
}
.edu__ghost {
  position: absolute; right: clamp(-.5rem, 1vw, 1rem); top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(3.4rem, 12vw, 9rem);
  line-height: .8; letter-spacing: -.02em;
  color: rgba(255, 255, 255, .045);
  pointer-events: none; user-select: none;
}
.edu__body { position: relative; z-index: 1; }
.edu__body .sec__label { margin-bottom: .6rem; }
.edu__degree {
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(1.2rem, 1.7vw + .5rem, 2rem);
  line-height: 1.1; color: var(--text-white);
}
.edu__org {
  font-size: clamp(.8rem, .3vw + .72rem, .92rem);
  color: var(--primary-red);
  margin-top: .15rem;
}
.edu__desc {
  font-size: clamp(.8rem, .3vw + .72rem, .92rem);
  line-height: 1.66; color: var(--text-grey);
  max-width: 54ch; margin-top: .5rem;
}
.edu__tag {
  position: relative; z-index: 1;
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.58rem, .24vw + .53rem, .7rem);
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--text-dim);
  padding-left: 3.2rem;
  white-space: nowrap;
}
.edu__tag::before {
  content: ""; position: absolute; left: 0; top: 50%;
  width: 2.6rem; height: 1px; background: var(--primary-red);
}

/* ============================================================================
   12  Section 06 — Generative AI
   ========================================================================= */
.compare { margin-bottom: clamp(1.6rem, 3.4vw, 2.8rem); }
.compare__stage {
  position: relative;
  aspect-ratio: 16 / 8.6;
  overflow: hidden;
  border: 1px solid var(--border-soft);
  background: var(--surface);
}
.compare__stage:focus-within { outline: 2px solid var(--primary-red); outline-offset: 3px; }
.compare__layer { position: absolute; inset: 0; }
.compare__layer img { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; object-fit: cover; }
/* the two fallback labels are pushed to opposite sides so they do not collide
   across the wipe line while the real images are still missing */
.compare__ghost { font-size: clamp(1rem, 2.4vw, 2rem); }
.compare__layer--before .compare__ghost { place-items: center start; padding-left: 7%; }
.compare__layer--after  .compare__ghost { place-items: center end;   padding-right: 7%; }
/* The "before" layer is clipped to the slider position.
   z-index is load-bearing, not cosmetic: clip-path makes this layer a
   STACKING CONTEXT, so it paints atomically at its own z-index. Its sibling
   --after has no clip-path and so creates no stacking context, which promotes
   that layer's <img> (z-index: 1, set above) into the shared parent context.
   Left at z-index auto the clipped layer therefore sits at level 0 and the
   after image paints straight over the whole of it — the wipe looks dead and
   only the "after" shot is ever visible, at every slider position. Anything
   above 1 fixes it; 2 keeps it under the handle (3) and the range (4). */
.compare__layer--before {
  clip-path: inset(0 calc(100% - var(--pos, 50%)) 0 0);
  z-index: 2;
}
.compare__handle {
  position: absolute; top: 0; bottom: 0; left: var(--pos, 50%); z-index: 3;
  width: 2px; margin-left: -1px;
  background: var(--primary-red);
  box-shadow: 0 0 18px rgba(215, 25, 32, .8);
  pointer-events: none;
}
.compare__handle::after {
  content: ""; position: absolute; top: 50%; left: 50%;
  width: 2.4rem; height: 2.4rem; transform: translate(-50%, -50%);
  border: 1px solid var(--primary-red); border-radius: 50%;
  background: rgba(7, 7, 7, .6);
}
.compare__range {
  position: absolute; inset: 0; z-index: 4;
  width: 100%; height: 100%; margin: 0;
  opacity: 0; cursor: ew-resize;
  -webkit-appearance: none; appearance: none; background: none;
}
.compare__cap {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: .5rem 1.5rem;
  margin-top: .8rem;
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.6rem, .26vw + .55rem, .72rem);
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-dim);
}
.compare__cap b { color: var(--primary-red); font-weight: 500; }

.ai-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: clamp(.7rem, 1.2vw, 1.15rem);
}
.ai-card {
  padding: clamp(1rem, 1.8vw, 1.6rem);
  border: 1px solid var(--border-soft);
  background: var(--surface);
  transition: border-color .4s var(--ease), background-color .4s var(--ease);
}
.ai-card:hover { border-color: rgba(215, 25, 32, .45); background: var(--surface-light); }
.ai-card h3 {
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(.95rem, .8vw + .5rem, 1.2rem);
  line-height: 1.14; color: var(--text-white);
  margin-bottom: .5rem;
}
.ai-card p {
  font-size: clamp(.78rem, .3vw + .7rem, .88rem);
  line-height: 1.62; color: var(--text-grey);
}
.ai-card__meta {
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.6rem, .24vw + .55rem, .7rem) !important;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-dim) !important;
  margin-top: .55rem;
}
.ai-card__meta span { color: var(--primary-red); }

/* ============================================================================
   13  Section 07 — Work archive
   ========================================================================= */
.filters {
  display: flex; flex-wrap: wrap; gap: .45rem;
  margin-bottom: clamp(1rem, 2.2vw, 1.6rem);
}
.filters__btn {
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.6rem, .26vw + .55rem, .72rem);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-grey);
  padding: .6em 1.15em;
  border: 1px solid var(--border-soft);
  background: none; cursor: pointer;
  transition: color .3s var(--ease), border-color .3s var(--ease),
              background-color .3s var(--ease);
}
.filters__btn:hover { color: var(--text-white); border-color: rgba(215, 25, 32, .5); }
.filters__btn.is-active {
  color: #fff;
  border-color: var(--primary-red);
  background: rgba(215, 25, 32, .16);
}
.filters__status {
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.58rem, .24vw + .53rem, .7rem);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: clamp(.8rem, 1.8vw, 1.3rem);
  min-height: 1em;
}

.archive {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 13.5rem), 1fr));
  gap: clamp(.7rem, 1.2vw, 1.15rem);
}
.arch__link { display: block; }
.arch__thumb {
  position: relative; display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border: 1px solid var(--border-soft);
  background: var(--surface);
  transition: border-color .4s var(--ease);
}
.arch__thumb--tall { aspect-ratio: 3 / 4; }
.arch__thumb--wide { aspect-ratio: 16 / 9; }
.arch__thumb img {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .8s var(--ease-out);
}
.arch__ghost { font-size: clamp(1.4rem, 3.4vw, 2.6rem); }
.arch__link:hover .arch__thumb { border-color: rgba(215, 25, 32, .5); }
.arch__link:hover .arch__thumb img { transform: scale(1.05); }

.arch__meta { display: grid; gap: .1rem; padding-top: .6rem; }
.arch__meta b {
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(.8rem, .3vw + .72rem, .95rem);
  color: var(--text-white);
}
.arch__meta em {
  font-style: normal;
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.6rem, .24vw + .55rem, .7rem);
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-dim);
}
.arch__year { font-size: .7rem; color: var(--primary-red); letter-spacing: .1em; }

/* ============================================================================
   14  Section 08 — Perspective
   ========================================================================= */
.sec--persp {
  background:
    radial-gradient(70% 90% at 14% 10%, rgba(111, 9, 13, .3), transparent 62%),
    var(--background);
}
.persp {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) minmax(0, .78fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: end;
}
.persp .sec__label { grid-column: 1 / -1; }
.persp__statement {
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(1.75rem, 4.4vw + .3rem, 4.6rem);
  line-height: 1.04;
  letter-spacing: -.018em;
  color: var(--text-white);
  text-wrap: balance;
}
.persp__accent { color: var(--primary-red); }
.persp__side { display: grid; gap: .9rem; padding-bottom: .4rem; }
.persp__side p {
  font-size: clamp(.84rem, .32vw + .75rem, .98rem);
  line-height: 1.7; color: var(--text-grey);
}
.persp__star { width: 1.15rem; height: 1.15rem; }

/* ============================================================================
   15  Section 09 — Professional contact
   ========================================================================= */
.sec--contact { border-bottom: 0; }
.contact {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
  gap: clamp(1.6rem, 4vw, 4rem);
  align-items: start;
}
.contact__lede {
  max-width: 42ch; margin-top: clamp(.9rem, 2vw, 1.4rem);
  font-size: clamp(.84rem, .32vw + .75rem, .98rem);
  line-height: 1.7; color: var(--text-grey);
}
.contact__now {
  display: grid; gap: .1rem;
  margin-top: clamp(1rem, 2.2vw, 1.5rem);
  padding-left: 1rem;
  border-left: 2px solid var(--primary-red);
  font-family: var(--font-cond);
  font-size: clamp(.68rem, .28vw + .6rem, .8rem);
  letter-spacing: .12em; text-transform: uppercase;
}
.contact__now span:first-child { color: var(--text-white); font-weight: 500; }
.contact__now span:last-child  { color: var(--text-dim); font-weight: 300; }

.contact__actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: .7rem 1.1rem;
  margin-top: clamp(1.3rem, 2.8vw, 2rem);
}
.btn {
  display: inline-flex; align-items: center; gap: .8rem;
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(.66rem, .28vw + .58rem, .78rem);
  letter-spacing: .18em; text-transform: uppercase;
  padding: 1em 1.5em;
  border: 1px solid transparent;
  transition: background-color .35s var(--ease), border-color .35s var(--ease),
              color .35s var(--ease), box-shadow .35s var(--ease);
}
.btn--primary {
  color: #fff;
  border-color: var(--primary-red);
  background: rgba(215, 25, 32, .16);
  box-shadow: 0 0 26px -6px rgba(215, 25, 32, .6);
}
.btn--primary:hover { background: var(--primary-red); box-shadow: 0 0 34px -4px rgba(215, 25, 32, .85); }
.btn--primary .arrow { width: 1.9rem; }
.btn--primary:hover .arrow { transform: translateX(5px); }
.btn--ghost { color: var(--text-white); border-color: var(--border); }
.btn--ghost:hover { border-color: var(--primary-red); background: rgba(215, 25, 32, .1); }
.btn--text {
  padding-inline: 0; color: var(--text-grey);
  border-bottom: 1px solid var(--border-soft);
}
.btn--text:hover { color: var(--text-white); border-bottom-color: var(--primary-red); }

.contact__list { display: grid; gap: clamp(.2rem, .5vw, .5rem); }
.contact__list li {
  display: flex; align-items: center; gap: clamp(.8rem, 1.3vw, 1.2rem);
  padding-block: clamp(.55rem, 1vw, .9rem);
  border-bottom: 1px solid rgba(215, 25, 32, .28);
}
.contact__list li:last-child { border-bottom: 0; }
.contact__list .icon-ring { transition: background-color .4s var(--ease), box-shadow .4s var(--ease); }
.contact__list li:hover .icon-ring {
  background: rgba(215, 25, 32, .14);
  box-shadow: 0 0 20px -6px rgba(215, 25, 32, .85);
}
.contact__row { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.contact__row em {
  font-style: normal;
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.6rem, .28vw + .53rem, .72rem);
  letter-spacing: .1em; text-transform: uppercase; color: var(--text-dim);
}
.contact__row a, .contact__row .plain {
  font-size: clamp(.8rem, .4vw + .68rem, .95rem);
  color: var(--text-white);
  overflow-wrap: anywhere;
  transition: color .3s var(--ease);
}
.contact__row a:hover { color: var(--primary-red); }

/* ============================================================================
   17  Footer
   ========================================================================= */
.foot {
  border-top: 1px solid rgba(215, 25, 32, .32);
  padding-block: clamp(1.6rem, 3.4vw, 2.6rem);
  background: var(--background);
}
.foot__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
  align-items: start;
  gap: clamp(1rem, 3vw, 2.5rem);
}
.foot__name {
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(.95rem, .6vw + .7rem, 1.15rem);
  letter-spacing: .02em; color: var(--text-white);
}
.foot__role, .foot__disc {
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.6rem, .26vw + .55rem, .72rem);
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-dim);
}
.foot__role { color: var(--primary-red); }
.foot__line {
  align-self: center;
  font-size: clamp(.76rem, .3vw + .68rem, .88rem);
  color: var(--text-grey);
  max-width: 34ch;
}
.foot__links {
  display: flex; flex-wrap: wrap; gap: .6rem 1.4rem;
  font-family: var(--font-cond); font-weight: 400;
  font-size: clamp(.62rem, .26vw + .56rem, .74rem);
  letter-spacing: .16em; text-transform: uppercase;
}
.foot__links a {
  color: var(--text-grey);
  border-bottom: 1px solid transparent;
  padding-block: .2rem;
  transition: color .3s var(--ease), border-color .3s var(--ease);
}
.foot__links a:hover { color: var(--text-white); border-bottom-color: var(--primary-red); }
.foot__legal {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: .4rem 1.5rem;
  margin-top: clamp(1rem, 2.4vw, 1.8rem);
  padding-top: clamp(.8rem, 1.8vw, 1.2rem);
  border-top: 1px solid var(--border-soft);
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.58rem, .24vw + .53rem, .7rem);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-dim);
}

/* ------------------------------------------------------------ 9 responsive */

/* wide laptops — keep the editorial ratio but ease the type */
@media (max-width: 1200px) {
  .hero__grid { grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr) minmax(0, .8fr); }
  .hero-portrait { transform: translateX(-44%); height: 88%; }
}

/* ---- tablet ---- */
@media (max-width: 1024px) {
  :root { --shell: 900px; }

  .hero { min-height: clamp(500px, 72vw, 680px); }

  /* display:contents lets the rail's two blocks be placed independently:
     the tagline joins the intro column, the stats stay bottom-right clear
     of the portrait. */
  .hero__grid {
    grid-template-columns: minmax(0, 1.14fr) minmax(0, .86fr);
    align-items: end;
    align-content: end;          /* pack the rows against the hero baseline */
    gap: 0 clamp(1rem, 3vw, 2rem);
  }
  .hero__intro { grid-column: 1; grid-row: 1; }
  .hero__rail  { display: contents; }
  .hero__tagline {
    grid-column: 1; grid-row: 2;
    margin-top: clamp(1.1rem, 3vw, 1.9rem);
    max-width: 30ch;
  }
  .hero__tagline p { max-width: none; }
  .stats { grid-column: 2; grid-row: 1 / span 2; align-self: end; }

  /* the intro column is wider here, so the left scrim has to reach further
     across before it releases the word */
  .hero::after {
    background:
      linear-gradient(96deg, rgba(7,7,7,.92) 0%, rgba(7,7,7,.80) 22%, rgba(7,7,7,.45) 44%, rgba(7,7,7,.12) 62%, transparent 74%),
      linear-gradient(0deg,  rgba(7,7,7,.60) 0%, rgba(7,7,7,.18) 18%, transparent 34%);
  }

  .hero-portrait {
    left: auto; right: -6%;
    transform: none;
    height: 78%;
    opacity: .85;
  }
  .hero__name { font-size: clamp(3rem, 10.5vw, 6rem); }
  .hero__lede { max-width: 34ch; }

  /* ---- post-hero sections at tablet ---- */

  /* brand grid drops from a 12-col composition to a 6-col one; the spans are
     re-authored rather than left to collapse arbitrarily. The header goes back
     to full width — there is no longer a wide enough gap beside it to fill. */
  .work-layout { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .sec--work .sec__head {
    grid-column: 1 / -1; grid-row: auto;
    margin-bottom: clamp(.6rem, 2vw, 1.4rem);
  }
  .brand--vs, .brand--wb, .brand--del { grid-column: span 6; }
  .brand--vs   { grid-row: auto; }
  .brand--sie  { grid-column: span 3; grid-row: auto; }
  .brand--aiff { grid-column: span 3; }
  .brand--lt, .brand--bob { grid-column: span 3; }
  /* height:auto releases the row fills so the ratios can take over again */
  .brand--sie  .brand__link { height: auto; aspect-ratio: 4 / 4.6; }
  .brand--vs   .brand__link { height: auto; min-height: 0; aspect-ratio: 16 / 9.4; }
  .brand--aiff .brand__link { aspect-ratio: 4 / 4.6; }
  .brand--del  .brand__link { aspect-ratio: 16 / 8; }

  .purpose { grid-template-columns: minmax(0, 1fr); }
  .purpose__strip { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  /* the four discipline columns become a stacked list: everything visible,
     nothing depending on hover */
  .disc { flex-direction: column; min-height: 0; }
  .disc__panel { flex: none; }
  .disc__title { white-space: normal; }
  /* A stacked panel is a fraction of the height of a desktop column, so the
     watermark has to shrink with it. At the desktop 85% it measured 286x229
     inside a 338x155 panel — half of it clipped away by the panel's own
     overflow, and what was left read as a background texture rather than a
     motif sitting in the corner.

     The panel then reserves that column on its right: on the tall desktop
     cards the copy sits far below the motif and never meets it, but once the
     panel collapses to ~155px the description wraps straight through the
     artwork. Padding the text back is what keeps both readable. */
  .disc__panel {
    --disc-motif-w: clamp(84px, 27%, 140px);
    padding-right: calc(var(--disc-motif-w) + clamp(1rem, 1.8vw, 1.7rem) + .6rem);
  }
  .disc__motif { width: var(--disc-motif-w); }

  .cv__row { grid-template-columns: minmax(0, .5fr) minmax(0, 1fr); }
  .cv__note { grid-column: 2; padding-left: clamp(1.1rem, 2vw, 1.9rem); }

  .persp { grid-template-columns: minmax(0, 1fr); }
  .contact { grid-template-columns: minmax(0, 1fr); }
  .foot__inner { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .foot__line { grid-column: 1 / -1; order: 3; }
}

/* ---- large phone / small tablet ---- */
@media (max-width: 860px) {
  .sec__head--row { align-items: flex-start; }
  .purpose__strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .edu { grid-template-columns: minmax(0, 1fr); }
  .edu__tag { padding-left: 0; padding-top: 1rem; }
  .edu__tag::before { top: 0; width: 2.6rem; }
}

/* ---- mobile ---- */
@media (max-width: 640px) {
  :root { --gutter: 1.15rem; }

  /* above .mobilenav (150) so the burger stays tappable to close the menu */
  .topbar { z-index: 200; background: transparent; }
  .topbar__inner { align-items: center; gap: .75rem; }
  .topbar__id { font-size: .7rem; }
  .topbar__status { display: none; }
  .burger { display: flex; }

  /* ---- mobile hero ------------------------------------------------------
     Per the supplied phone design the hero stops being one stacked layer:
     the portrait comes OUT of absolute positioning into the flow, at full
     opacity, as the top block — and the copy sits below it rather than over
     it. Everything after this re-anchors around that. */
  .hero {
    display: block;
    min-height: auto;
    padding-bottom: clamp(1.5rem, 6vw, 2.5rem);
  }
  .hero__word text { letter-spacing: 0; }

  /* the word is now a band behind the portrait's head, not the whole hero */
  .hero__word { top: 2%; height: 27%; }

  /* nothing sits on the word any more, so the scrim only has to sink the
     lower half of the hero to black behind the copy */
  .hero::after {
    background: linear-gradient(180deg,
      rgba(7,7,7,.08) 0%, rgba(7,7,7,.24) 20%, rgba(7,7,7,.7) 42%, rgba(7,7,7,.96) 60%);
  }
  .hero__glow { top: 1%; width: 118vw; transform: translateX(-46%); }

  .hero-portrait {
    position: relative;
    left: auto; right: auto; bottom: auto;
    transform: none;
    display: block;
    height: auto;
    opacity: 1;
    z-index: 2;
    padding-top: clamp(1rem, 5vw, 1.8rem);
  }
  .hero-portrait::after { display: none; }      /* the mask below replaces it */
  .hero-portrait img {
    width: 93%;
    height: auto;
    margin-left: auto;
    margin-right: -4%;
    filter:
      drop-shadow(-12px 0 30px rgba(215, 25, 32, .45))
      contrast(1.05) saturate(1.05);
    /* dissolve the cropped chest into the black instead of ending on a hard
       horizontal edge above the copy */
    -webkit-mask-image: linear-gradient(180deg, #000 52%, rgba(0,0,0,.5) 76%, transparent 92%);
            mask-image: linear-gradient(180deg, #000 52%, rgba(0,0,0,.5) 76%, transparent 92%);
  }

  .hero__grid {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(1.2rem, 5vw, 1.9rem);
    padding-top: 0;
    margin-top: clamp(-7rem, -24vw, -3rem);     /* tuck the copy into the fade */
  }
  .hero__intro   { grid-column: 1; grid-row: 1; }
  .hero__tagline { grid-column: 1; grid-row: 2; margin-top: 0; }

  /* The three figures sit SIDE BY SIDE on phones. Stacked they read as three
     unrelated rows and eat most of a screen; in a row they read as one band of
     credentials. Each stat turns into a column (number over label) and the
     borders move to the outside of the band plus dividers between cells. */
  .stats {
    grid-column: 1; grid-row: 3;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    border-top: 1px solid var(--border-soft);
    border-bottom: 1px solid var(--border-soft);
  }
  .stat {
    flex-direction: column; align-items: flex-start;
    gap: .3rem;
    padding-block: clamp(.65rem, 3vw, .95rem);
    padding-inline: 0 .5rem;
    border-bottom: 0;
  }
  .stat + .stat {
    border-left: 1px solid var(--border-soft);
    padding-inline-start: clamp(.55rem, 3.2vw, .95rem);
  }
  .stat:first-child { border-top: 0; }

  .hero__hello { font-size: clamp(1.6rem, 7vw, 2.4rem); }
  .hero__name  { font-size: clamp(2.9rem, 17.4vw, 5rem); }
  .hero__title { font-size: clamp(1.05rem, 4.9vw, 1.5rem); }
  /* the design sets the paragraph on a narrower measure than the rest of the
     copy rather than letting it run gutter to gutter */
  .hero__lede  { max-width: 36ch; }
  .hero__tagline p { max-width: 26ch; }
  /* min-width is what kept the numbers aligned in the stacked list; in three
     narrow columns it only forces overflow, so it goes */
  .stat__num { min-width: 0; font-size: clamp(1.45rem, 7.6vw, 2.3rem); }
  .stat__label { font-size: clamp(.52rem, 2.4vw, .66rem); letter-spacing: .1em; }

  /* short red rule between the red subtitle and the paragraph */
  .hero__rule {
    display: block;
    width: 2.4rem; height: 3px;
    background: var(--primary-red);
    margin-bottom: clamp(.9rem, 4vw, 1.3rem);
  }

  .hero__cta {
    display: flex; align-items: center; justify-content: center;
    position: relative;
    width: 100%;
    margin-top: clamp(1.1rem, 5vw, 1.7rem);
    padding: 1.05em 3.2em 1.05em 1.4em;
    border: 1px solid var(--primary-red);
    border-radius: 6px;
    font-family: var(--font-cond); font-weight: 500;
    font-size: clamp(.78rem, 3.4vw, .95rem);
    letter-spacing: .22em; text-transform: uppercase;
    color: var(--text-white);
    background: linear-gradient(180deg, rgba(215,25,32,.10), rgba(215,25,32,.02));
    box-shadow: 0 0 26px -4px rgba(215, 25, 32, .55),
                inset 0 0 22px rgba(215, 25, 32, .12);
    transition: background-color .35s var(--ease), box-shadow .35s var(--ease);
  }
  .hero__cta .arrow {
    position: absolute; right: 1.3em;
    width: 1.6rem; color: var(--primary-red);
  }
  .hero__cta:active {
    background: rgba(215, 25, 32, .22);
    box-shadow: 0 0 34px -4px rgba(215, 25, 32, .8);
  }

  /* quiet secondary link under the CTA — deliberately not a second button */
  .hero__sub-cta {
    display: block;
    margin-top: clamp(.8rem, 3.5vw, 1.1rem);
    text-align: center;
    font-family: var(--font-cond); font-weight: 300;
    font-size: clamp(.66rem, 3vw, .78rem);
    letter-spacing: .18em; text-transform: uppercase;
    color: var(--text-grey);
    padding-block: .4rem;
  }
  .hero__sub-cta:active { color: var(--text-white); }

  /* ---- post-hero sections on phones ---- */

  /* one column, but the ratios stay varied so the page keeps its rhythm */
  .work-layout { grid-template-columns: minmax(0, 1fr); }
  .sec--work .sec__head { grid-column: 1; }
  .brand--wb, .brand--sie, .brand--del, .brand--vs,
  .brand--aiff, .brand--lt, .brand--bob { grid-column: span 1; grid-row: auto; }
  .brand--wb   .brand__link { aspect-ratio: 16 / 11; }
  .brand--sie  .brand__link { height: auto; aspect-ratio: 16 / 13; }
  .brand--del  .brand__link { aspect-ratio: 16 / 11; }
  .brand--vs   .brand__link { height: auto; min-height: 0; aspect-ratio: 16 / 12; }
  .brand--lt   .brand__link,
  .brand--bob  .brand__link { aspect-ratio: 16 / 11; }
  .brand--aiff .brand__link { aspect-ratio: 16 / 10; }

  .purpose__strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .purpose__frame { aspect-ratio: 4 / 3; }

  /* the timeline collapses to a single column: years sit above the role, and
     the note keeps the same spine indent so nothing overlaps */
  .cv__row { grid-template-columns: minmax(0, 1fr); gap: .8rem; }
  .cv__years { font-size: clamp(1.6rem, 9vw, 2.6rem); }
  .cv__note { grid-column: 1; padding-left: clamp(1.1rem, 4vw, 1.9rem); }

  .archive { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .arch__thumb, .arch__thumb--tall, .arch__thumb--wide { aspect-ratio: 4 / 3; }

  .contact__actions .btn { width: 100%; justify-content: center; }
  .btn--text { width: auto !important; }

  .foot__inner { grid-template-columns: minmax(0, 1fr); }
  .foot__line { order: 0; }
}

@media (max-width: 400px) {
  .archive { grid-template-columns: minmax(0, 1fr); }
  .cv__caps li, .purpose__scope dd { padding: .45em .8em; }
  .filters__btn { padding: .55em .9em; }
}

/* --------------------------------------------------------- 10 reduced motion */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
}

/* print — not a priority, but keep it from producing 40 black pages */
@media print {
  .grain, .hero__glow, .stage { display: none; }
  body { background: #fff; color: #000; }
}

/* ============================================================================
   11  Projects page (projects.html)
   Self-contained block kept separate from the numbered homepage sections
   above — everything it needs (tokens, ghost panel, .filters, .link-arrow,
   .cv__caps chip, ::selection etc.) is already shared from earlier in this
   file; only the page-specific card types are defined here.
   ========================================================================= */

/* ---- page intro ---- */
.projhero {
  position: relative;
  padding-block: clamp(2.6rem, 7vw, 5.5rem) clamp(2rem, 5vw, 3.5rem);
  border-bottom: 1px solid var(--border-soft);
  background:
    radial-gradient(70% 55% at 85% 0%, rgba(111, 9, 13, .32), transparent 62%),
    var(--background);
}
.projhero__eyebrow {
  display: flex; align-items: center; gap: .7em;
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(.62rem, .3vw + .54rem, .76rem);
  letter-spacing: .24em; text-transform: uppercase;
  color: var(--primary-red);
  margin-bottom: clamp(.9rem, 2vw, 1.4rem);
}
.projhero__eyebrow .star-badge { width: 1.7rem; }
.projhero__title {
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(1.9rem, 4vw + .3rem, 4.1rem);
  line-height: 1.05; letter-spacing: -.012em;
  color: var(--text-white);
  max-width: 22ch;
}
.projhero__title .accent { color: var(--primary-red); }
.projhero__lede {
  margin-top: clamp(1rem, 2.4vw, 1.6rem);
  max-width: 58ch;
  color: var(--text-grey);
  font-size: clamp(.86rem, .34vw + .76rem, 1rem);
  line-height: 1.68;
}

/* ---- filter row + panels ---- */
.sec--projects { padding-top: clamp(2.2rem, 5vw, 3.6rem); }
.proj-section-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: clamp(1rem, 3vw, 2rem); flex-wrap: wrap;
  margin-bottom: clamp(1.4rem, 3vw, 2.2rem);
}
.proj-panel-title {
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(1.25rem, 1.7vw + .4rem, 2rem);
  line-height: 1.1; color: var(--text-white);
}
.proj-count {
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.62rem, .26vw + .56rem, .74rem);
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-dim);
  flex: none;
}
/* Spacing between panels is a flex gap, not a sibling margin: a sibling
   combinator (.proj-panel + .proj-panel) still matches a [hidden] panel, so
   filtering down to one category left it carrying margin meant for the panel
   stacked below a VISIBLE predecessor — a big gap under "Videos" but none
   under "Websites", since Websites has no preceding sibling at all. gap only
   ever applies between panels that are actually rendered. */
[data-proj-panels] { display: flex; flex-direction: column; gap: clamp(3.2rem, 7vw, 5.5rem); }

/* ---- top work — one brand per full-width row ----
   Deliberately the widest card type on the page: these seven are the lead
   credentials, so each gets its own row rather than competing in a grid. The
   <ol> carries the running order semantically; the visible numbering is the
   printed .proj-top-num in each corner, the way the homepage brand cards do
   it (the sitewide reset already strips the list markers). */
.proj-top-list { display: grid; gap: clamp(.9rem, 1.8vw, 1.4rem); }
.proj-top-card {
  border: 1px solid var(--border-soft);
  background: var(--surface);
  transition: border-color .4s var(--ease), transform .45s var(--ease-out), box-shadow .45s var(--ease);
}
.proj-top-card:hover,
.proj-top-card:focus-within {
  border-color: rgba(215, 25, 32, .5);
  box-shadow: 0 22px 55px -26px rgba(215, 25, 32, .55);
  transform: translateY(-3px);
}
.proj-top-link {
  display: grid;
  grid-template-columns: minmax(0, .48fr) minmax(0, 1fr);
  align-items: stretch;
}
.proj-top-media { position: relative; overflow: hidden; aspect-ratio: 16 / 10; }
.proj-top-media img {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .7s var(--ease-out);
}
.proj-top-card:hover .proj-top-media img { transform: scale(1.05); }
.proj-top-ghost { font-size: clamp(1.6rem, 4vw, 3rem); }
.proj-top-body {
  position: relative;
  display: flex; flex-direction: column; align-items: flex-start;
  gap: .35rem;
  padding: clamp(1.1rem, 2.4vw, 2rem);
  /* room for the numeral, so a long title never runs under it */
  padding-right: clamp(3.4rem, 6vw, 5.5rem);
}
.proj-top-num {
  position: absolute;
  top: clamp(.9rem, 1.8vw, 1.5rem); right: clamp(.9rem, 1.8vw, 1.5rem);
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 2.4vw, 2.6rem); line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px rgba(255, 255, 255, .42);
  transition: color .45s var(--ease), -webkit-text-stroke-color .45s var(--ease);
}
.proj-top-card:hover .proj-top-num,
.proj-top-card:focus-within .proj-top-num {
  color: var(--primary-red);
  -webkit-text-stroke-color: transparent;
}
.proj-top-industry {
  font-family: var(--font-cond); font-weight: 400;
  font-size: clamp(.58rem, .26vw + .52rem, .7rem);
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--primary-red);
}
.proj-top-title {
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(1.15rem, 1.4vw + .5rem, 1.9rem);
  line-height: 1.06; letter-spacing: -.008em;
  color: var(--text-white);
}
.proj-top-project { font-size: clamp(.76rem, .3vw + .68rem, .9rem); color: var(--text-grey); }
.proj-top-desc {
  font-size: clamp(.76rem, .3vw + .68rem, .88rem);
  line-height: 1.6; color: var(--text-grey);
  max-width: 52ch;
}
.proj-top-credit {
  font-family: var(--font-cond); font-weight: 300;
  font-size: clamp(.6rem, .24vw + .55rem, .72rem);
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-dim);
}
.proj-top-cta { margin-top: auto; padding-top: .7rem; }
.proj-top-card:hover .proj-top-cta { color: var(--text-white); }
.proj-top-card:hover .proj-top-cta .arrow { transform: translateX(5px); }

/* ---- websites ---- */
.proj-web-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.6rem);
}
.proj-web-card {
  border: 1px solid var(--border-soft);
  background: var(--surface);
  transition: border-color .4s var(--ease), transform .45s var(--ease-out), box-shadow .45s var(--ease);
}
.proj-web-card:hover {
  border-color: rgba(215, 25, 32, .5);
  box-shadow: 0 22px 55px -26px rgba(215, 25, 32, .55);
  transform: translateY(-3px);
}
.proj-web-chrome {
  display: flex; align-items: center; gap: .5rem;
  padding: .7rem 1rem;
  border-bottom: 1px solid var(--border-soft);
}
.proj-web-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--text-dim); opacity: .6; }
.proj-web-url {
  margin-left: .4rem;
  font-family: var(--font-cond); font-weight: 300;
  font-size: .68rem; letter-spacing: .04em;
  color: var(--text-dim);
  border: 1px solid var(--border-soft);
  padding: .2em .6em;
}
.proj-web-shot {
  --shot-h: clamp(210px, 26vw, 320px);
  position: relative; height: var(--shot-h); overflow: hidden;
}
/* These are full-length page captures, so the shot is laid in at its natural
   height instead of being cropped to the frame. Hovering then walks it from
   top to bottom like a real page scroll and releasing eases it back up.
   min() stops a capture SHORTER than the frame from sliding down into empty
   space — such a shot simply stays put. */
/* --shot-scroll / --shot-return are written per card by script.js from the
   shot's measured travel, so every capture walks at the same pixels-per-second
   however long the page it came from is. The literals here are the fallback
   for a card whose image never resolved, or with JS off. */
.proj-web-shot img {
  position: absolute; top: 0; left: 0; z-index: 1;
  width: 100%; height: auto;
  transition: transform var(--shot-return, 1.9s) var(--ease-out);
}
@media (hover: hover) {
  .proj-web-card:hover .proj-web-shot img {
    transform: translateY(min(0px, calc(var(--shot-h) - 100%)));
    transition-duration: var(--shot-scroll, 14s);
    /* linear, NOT --ease-out. That curve is an expo-out — the right shape for
       a 350ms nudge, but over a 20s walk it spends most of the distance in the
       first second and then crawls: measured at 787px in second one before
       easing to a stop. A page being scrolled moves at a constant rate, and
       constant is also what makes the per-card duration above mean anything. */
    transition-timing-function: linear;
  }
}
/* The sitewide reduced-motion rule only collapses the duration, which would
   turn the scroll into an instant jump — hold the shot still instead. */
@media (prefers-reduced-motion: reduce) {
  .proj-web-card:hover .proj-web-shot img { transform: none; }
}
.proj-web-ghost { font-size: clamp(1.6rem, 4vw, 3rem); }
.proj-web-body {
  padding: clamp(1.1rem, 2.2vw, 1.5rem);
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 1rem;
}
.proj-web-industry {
  font-family: var(--font-cond); font-weight: 400;
  font-size: clamp(.58rem, .26vw + .52rem, .68rem);
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--primary-red);
  margin-bottom: .4rem;
}
.proj-web-title {
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(1rem, .9vw + .6rem, 1.3rem);
  color: var(--text-white);
  margin-bottom: .45rem;
}
.proj-web-desc {
  font-size: clamp(.76rem, .3vw + .68rem, .86rem);
  line-height: 1.6; color: var(--text-grey);
  max-width: 40ch;
  margin-bottom: .7rem;
}
.proj-tag-row { margin-top: 0; margin-bottom: .8rem; }
.proj-web-live { flex: none; margin-top: .2rem; }
.proj-web-live .arrow { width: 1.7rem; }

/* ---- videos ---- */
.proj-video-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(.9rem, 1.8vw, 1.4rem);
}
.proj-video-card {
  position: relative;
  border: 1px solid var(--border-soft);
  background: var(--surface);
  cursor: pointer;
  transition: border-color .4s var(--ease), transform .45s var(--ease-out), box-shadow .45s var(--ease);
}
.proj-video-card:hover {
  border-color: rgba(215, 25, 32, .5);
  box-shadow: 0 20px 50px -22px rgba(215, 25, 32, .55);
  transform: translateY(-3px);
}
.proj-video-thumb { position: relative; aspect-ratio: 16 / 9; overflow: hidden; }
.proj-video-thumb img {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .6s var(--ease-out);
}
.proj-video-card:hover .proj-video-thumb img { transform: scale(1.06); }
.proj-video-ghost { font-size: clamp(1.4rem, 3.4vw, 2.6rem); }
.proj-video-thumb::after {
  content: ""; position: absolute; inset: 0; z-index: 2;
  background: linear-gradient(0deg, rgba(7,7,7,.85) 0%, rgba(7,7,7,.15) 55%, rgba(7,7,7,.05) 100%);
}
.proj-play-btn {
  position: absolute; z-index: 3; inset: 0;
  display: grid; place-items: center;
}
.proj-play-btn span {
  width: 3rem; height: 3rem; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(255, 255, 255, .1);
  border: 1px solid rgba(255, 255, 255, .35);
  color: #fff;
  transition: transform .4s var(--ease-out), background-color .3s var(--ease), border-color .3s var(--ease);
}
.proj-video-card:hover .proj-play-btn span {
  transform: scale(1.12);
  background: var(--primary-red);
  border-color: transparent;
}
.proj-video-body { padding: clamp(.9rem, 1.8vw, 1.3rem); }
.proj-video-title {
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(.92rem, .5vw + .7rem, 1.05rem);
  color: var(--text-white);
  margin-bottom: .3rem;
}
.proj-video-desc { font-size: .8rem; line-height: 1.5; color: var(--text-grey); }

/* ---- brand identity ---- */
.proj-brand-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(.9rem, 1.8vw, 1.4rem);
}
.proj-brand-card {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border: 1px solid var(--border-soft);
  background: var(--surface);
  cursor: pointer;
  transition: border-color .4s var(--ease), transform .45s var(--ease-out), box-shadow .45s var(--ease);
}
.proj-brand-card:hover {
  border-color: rgba(215, 25, 32, .5);
  box-shadow: 0 20px 50px -22px rgba(215, 25, 32, .55);
  transform: translateY(-3px);
}
.proj-brand-ghost { font-size: clamp(1.3rem, 3vw, 2.2rem); }
.proj-brand-main {
  position: relative; z-index: 1;
  width: 100%; height: 100%; object-fit: contain;
  padding: 14%;
  transition: transform .5s var(--ease-out);
}
.proj-brand-card:hover .proj-brand-main { transform: scale(1.05); }
.proj-brand-overlay {
  position: absolute; inset: 0; z-index: 2;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: clamp(.9rem, 1.8vw, 1.3rem);
  background: linear-gradient(0deg, rgba(7,7,7,.94) 0%, rgba(7,7,7,.62) 46%, rgba(7,7,7,.06) 100%);
}
.proj-brand-industry {
  font-family: var(--font-cond); font-weight: 400;
  font-size: clamp(.56rem, .24vw + .5rem, .66rem);
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--primary-red);
  margin-bottom: .3rem;
}
.proj-brand-title {
  font-family: var(--font-cond); font-weight: 500;
  font-size: clamp(.92rem, .5vw + .7rem, 1.1rem);
  color: var(--text-white);
  margin-bottom: .55rem;
}
.proj-brand-swatches { display: flex; gap: .35rem; margin-bottom: .6rem; }
.proj-brand-swatches span {
  width: 14px; height: 14px; border-radius: 3px;
  border: 1px solid rgba(255, 255, 255, .25);
}
.proj-brand-view {
  font-family: var(--font-cond); font-weight: 400;
  font-size: .66rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-white);
  opacity: 0; transform: translateY(6px);
  transition: opacity .35s var(--ease), transform .35s var(--ease-out);
}
.proj-brand-card:hover .proj-brand-view,
.proj-brand-card:focus-visible .proj-brand-view { opacity: 1; transform: none; }

/* ---- marketing (masonry) ---- */
.proj-marketing-masonry { column-count: 3; column-gap: clamp(.9rem, 1.8vw, 1.4rem); }
.proj-marketing-card {
  position: relative;
  display: block;
  break-inside: avoid;
  margin-bottom: clamp(.9rem, 1.8vw, 1.4rem);
  overflow: hidden;
  border: 1px solid var(--border-soft);
  background: var(--surface);
  cursor: pointer;
  transition: border-color .4s var(--ease), box-shadow .45s var(--ease);
}
.proj-marketing-card:hover {
  border-color: rgba(215, 25, 32, .5);
  box-shadow: 0 20px 50px -22px rgba(215, 25, 32, .55);
}
.proj-marketing-card img {
  width: 100%; display: block;
  transition: transform .6s var(--ease-out);
}
.proj-marketing-card:hover img { transform: scale(1.04); }
.proj-marketing-overlay {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: clamp(.8rem, 1.6vw, 1.2rem);
  background: linear-gradient(0deg, rgba(7,7,7,.9) 0%, rgba(7,7,7,.1) 60%, transparent 100%);
  opacity: 0; transition: opacity .35s var(--ease);
}
.proj-marketing-card:hover .proj-marketing-overlay,
.proj-marketing-card:focus-visible .proj-marketing-overlay { opacity: 1; }
.proj-marketing-cat {
  font-family: var(--font-cond); font-weight: 400;
  font-size: .6rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--primary-red);
  margin-bottom: .3rem;
}
.proj-marketing-title {
  font-family: var(--font-cond); font-weight: 500;
  font-size: .88rem; color: var(--text-white);
}

/* ---- lightbox (video embeds + enlarged images) ---- */
.proj-lightbox {
  position: fixed; inset: 0; z-index: 300;
  display: grid; place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: rgba(4, 4, 5, .92);
  opacity: 0; visibility: hidden;
  transition: opacity .3s var(--ease), visibility .3s linear;
}
.proj-lightbox.is-open { opacity: 1; visibility: visible; }
.proj-lightbox-inner {
  position: relative;
  width: min(100%, 1040px);
  aspect-ratio: 16 / 9;
  background: #000;
  border: 1px solid var(--border-red);
  box-shadow: 0 40px 100px -30px rgba(0, 0, 0, .8);
}
.proj-lightbox-inner iframe {
  position: absolute; inset: 0; width: 100%; height: 100%; border: 0;
}
.proj-lightbox-inner.is-image {
  width: auto; height: min(100%, 86vh); aspect-ratio: auto;
  background: none; border-color: var(--border-soft);
}
.proj-lightbox-inner.is-image.is-portrait { height: min(100%, 90vh); }
.proj-lightbox-inner.is-image #projLightboxContent,
.proj-lightbox-inner.is-image img {
  height: 100%; width: auto; max-width: 100%;
  display: block; object-fit: contain;
}
.proj-lightbox-close {
  position: absolute; top: -2.6rem; right: 0; z-index: 4;
  width: 2.2rem; height: 2.2rem;
  display: grid; place-items: center;
  border: 1px solid var(--border-soft);
  background: var(--surface);
  color: var(--text-white);
  cursor: pointer;
  transition: border-color .3s var(--ease), color .3s var(--ease);
}
.proj-lightbox-close:hover { border-color: var(--primary-red); color: var(--primary-red); }

@media (max-width: 1024px) {
  .proj-video-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .proj-brand-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .proj-marketing-masonry { column-count: 2; }
}

@media (max-width: 860px) {
  .proj-web-grid { grid-template-columns: minmax(0, 1fr); }
  /* Below this the media column is too narrow to read as an image, so the row
     stacks: cover on top, copy beneath. */
  .proj-top-link { grid-template-columns: minmax(0, 1fr); }
  .proj-top-media { aspect-ratio: 16 / 9; }
  .proj-top-cta { margin-top: .3rem; }
}

@media (max-width: 640px) {
  .projhero__title { font-size: clamp(2rem, 9vw, 3rem); }
  .proj-video-grid { grid-template-columns: minmax(0, 1fr); }
  .proj-brand-grid { grid-template-columns: minmax(0, 1fr); }
  .proj-marketing-masonry { column-count: 1; }
  .proj-web-body { flex-direction: column; }
  .proj-lightbox-inner.is-image { height: min(100%, 78vh); }
  /* "All Work" drops off the mobile filter row — only the named categories
     remain. The underlying filter still defaults to "all" (every project
     shown), this only hides that one pill. */
  [data-proj-filter="all"] { display: none; }

  /* The five that remain go edge to edge on a single row: an even 5-column
     grid rather than the wrapping flex row, which sized each pill to its own
     label and pushed "Marketing" onto a second line. A display:none pill is
     never placed, so the grid lands exactly five across.
     Scoped to the projects filter row — the homepage archive filters share
     .filters and keep their natural widths. */
  [data-proj-filters] {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: .3rem;
  }
  [data-proj-filters] .filters__btn {
    padding: .5em .25em;
    font-size: .58rem;
    letter-spacing: .05em;
    line-height: 1.3;
    text-align: center;
    /* "Brand Identity" is the one label too long for a fifth of a phone
       screen; it wraps inside its own cell, and grid's default stretch keeps
       all five buttons the same height regardless. */
  }
}
