/* ==========================================================================
   SHREYANSH DUBEY — PORTFOLIO
   Design system. Everything is driven by the tokens in :root — retune the
   whole site from there.

   Concept: professional archive × curated gallery. Warm paper ground, ink
   type, one muted slate-blue accent, and dark "plates" that frame each
   project exhibit like a print hung on a wall. Typography is sans-led —
   Inter for everything read, Manrope for what is recognised.

   CONTENTS
     1.  Tokens
     2.  Reset & base
     3.  Layout primitives
     4.  Motion (reveal, page-in)
     5.  Header / navigation
     6.  Buttons & links
     7.  Home — hero
     8.  Section furniture (eyebrow, titles, leads)
     8b. Shared lists (taglist, runlist)
     8c. Home — the practice (stance) & services
     9.  Gallery — exhibits (home "Selected work")
     10. THE EXHIBITION — projects.html
     11. About page
     12. Contact page
     13. Case study page — project.html
     14. CTA band & footer
     15. Reduced motion / print
   ========================================================================== */

/* ==========================================================================
   1. TOKENS
   ========================================================================== */
:root {
  /* --- Ground & ink ------------------------------------------------------ */
  --paper:        #f7f5f1;   /* warm ivory page ground */
  --paper-2:      #efece5;   /* recessed band */
  --surface:      #fffdf9;   /* raised surface */
  --ink:          #16181c;   /* primary text */
  --ink-2:        #40454d;   /* secondary text */
  --muted:        #656a73;   /* tertiary text, metadata — 4.6:1 on both grounds */
  --line:         #ded9d0;   /* hairline */
  --line-2:       #c6c0b4;   /* emphasised hairline */

  /* --- Dark (exhibit plates, detail hero) -------------------------------- */
  --dark:         #101319;
  --dark-2:       #191d24;
  --on-dark:      #eeebe4;
  --on-dark-2:    #a7aab1;
  --on-dark-line: rgba(238, 235, 228, 0.18);

  /* --- Accent — one only ------------------------------------------------- */
  --accent:       #2f4f72;   /* deep slate blue */
  --accent-deep:  #223a55;
  --accent-soft:  #e7edf4;

  /* --- Type ---------------------------------------------------------------
     Sans-led. Inter carries everything that is read; Manrope carries what is
     recognised — display lines and titles. The contrast between them is
     deliberate but quiet: same skeleton, slightly wider counters, a little
     more warmth at large sizes. Hierarchy is built from size, weight,
     tracking and space, never from a decorative face.
     ---------------------------------------------------------------------- */
  --font-sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  --font-display: "Manrope", "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;

  /* Scale — a controlled ramp. The steps are close enough to read as one
     system; the top of each clamp is capped so nothing balloons on a 27".  */
  --fs-display: clamp(2.75rem, 6vw, 4.5rem);      /* the name, once */
  --fs-h1:      clamp(2.125rem, 3.6vw, 3.125rem); /* page & case titles */
  --fs-h2:      clamp(1.5rem, 2.2vw, 2rem);       /* section titles */
  --fs-exhibit: clamp(1.375rem, 1.9vw, 1.75rem);  /* exhibit titles */
  --fs-h3:      clamp(1.1875rem, 1.5vw, 1.4375rem); /* sub-headings */
  --fs-lede:    clamp(1.125rem, 1.35vw, 1.3125rem); /* ledes, opening paras */
  --fs-lg:      clamp(1.0625rem, 1.1vw, 1.1875rem); /* long-form body */
  --fs-md:      1.0625rem;   /* 17px — base reading size */
  --fs-base:    1rem;        /* 16px */
  --fs-sm:      0.9375rem;   /* 15px — secondary copy, buttons */
  --fs-xs:      0.8125rem;   /* 13px — labels, eyebrows, metadata */
  --fs-2xs:     0.75rem;     /* 12px — the wordmark role line only */

  /* Weights — four steps, and 700 is reserved for nothing at present. */
  --fw-regular: 400;
  --fw-medium:  500;
  --fw-semi:    600;

  --lh-tight:   1.05;
  --lh-title:   1.18;
  --lh-snug:    1.3;
  --lh-body:    1.65;

  /* Tracking — large sans type needs to be pulled in, small caps opened out. */
  --track-display: -0.032em;
  --track-h1:      -0.026em;
  --track-h2:      -0.018em;
  --track-h3:      -0.012em;
  --track-caps:    0.1em;

  --measure:    66ch;

  /* --- Space & layout ---------------------------------------------------- */
  --gutter:  clamp(1.25rem, 4vw, 4.5rem);
  --shell:   84rem;              /* 1344px — wide enough for a real gallery */
  --shell-narrow: 48rem;
  --grid-gap: clamp(1rem, 2.2vw, 2rem);
  --band:    clamp(4.5rem, 9vw, 9rem);   /* vertical rhythm between bands */
  --header-h: 68px;

  /* --- Motion ------------------------------------------------------------ */
  --ease: cubic-bezier(0.22, 0.68, 0.24, 1);
  --dur:  0.5s;
}

/* ==========================================================================
   2. RESET & BASE
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 1.5rem);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  line-height: var(--lh-body);
  font-feature-settings: "kern" 1, "liga" 1, "cv05" 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img, svg { max-width: 100%; display: block; }

h1, h2, h3, h4 { margin: 0; font-weight: var(--fw-semi); line-height: var(--lh-title); }
p { margin: 0; }
ul, ol, dl, dd { margin: 0; padding: 0; }
li { list-style: none; }

a { color: inherit; text-decoration: none; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

::selection { background: var(--accent); color: #fff; }

.skip-link {
  position: absolute;
  left: var(--gutter);
  top: -4rem;
  z-index: 200;
  background: var(--ink);
  color: var(--paper);
  padding: 0.7rem 1.1rem;
  font-size: var(--fs-sm);
  transition: top 0.18s var(--ease);
}
.skip-link:focus { top: 0.75rem; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

/* The one display line on the site. Set large but held in: semibold rather
   than heavy, tracking pulled in hard, leading tight. */
.display {
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  letter-spacing: var(--track-display);
}

/* ==========================================================================
   3. LAYOUT PRIMITIVES
   ========================================================================== */
.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.shell--narrow { max-width: calc(var(--shell-narrow) + var(--gutter) * 2); }

.band { padding-block: var(--band); }
.band--tight { padding-block: clamp(3rem, 5vw, 5rem); }
.band--recessed {
  background: var(--paper-2);
  border-block: 1px solid var(--line);
}
.band--ink {
  background: var(--dark);
  color: var(--on-dark);
}

.rule {
  height: 1px;
  background: var(--line);
  border: 0;
  margin: 0;
}

.measure { max-width: var(--measure); }

/* ==========================================================================
   4. MOTION
   ========================================================================== */
/* Page-in: a single calm fade. No loaders, no curtains. */
body { animation: page-in 0.55s var(--ease) both; }
@keyframes page-in { from { opacity: 0; } to { opacity: 1; } }

/* Scroll reveal — only armed by JS when motion is welcome, so no-JS and
   reduced-motion visitors never meet an element stuck at opacity 0. */
.reveal-on .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
.reveal-on .reveal.is-in { opacity: 1; transform: none; }

/* ==========================================================================
   5. HEADER / NAVIGATION
   ========================================================================== */
.masthead {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(247, 245, 241, 0.88);              /* fallback */
  background: color-mix(in srgb, var(--paper) 86%, transparent);
  backdrop-filter: saturate(150%) blur(10px);
  -webkit-backdrop-filter: saturate(150%) blur(10px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.masthead.is-stuck { border-bottom-color: var(--line); }

.masthead__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--grid-gap);
  min-height: var(--header-h);
}

.wordmark {
  display: inline-flex;
  flex-direction: column;
  line-height: 1.15;
}
.wordmark__name {
  font-size: var(--fs-base);
  font-weight: var(--fw-semi);
  letter-spacing: -0.005em;
}
.wordmark__role {
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.wordmark:hover .wordmark__role { color: var(--accent); }

.nav { display: flex; align-items: center; gap: clamp(1.5rem, 2.8vw, 2.75rem); }
.nav__link {
  position: relative;
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-2);
  padding-block: 0.4rem;
  transition: color 0.25s var(--ease);
}
.nav__link::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.35s var(--ease);
}
.nav__link:hover { color: var(--ink); }
.nav__link:hover::after { transform: scaleX(1); }
.nav__link[aria-current="page"] { color: var(--ink); }
.nav__link[aria-current="page"]::after { transform: scaleX(1); background: var(--accent); }

/* Hamburger — hidden on desktop */
.nav-toggle {
  display: none;
  align-items: center;
  gap: 0.6rem;
  background: none;
  border: 0;
  padding: 0.5rem 0;
  font: inherit;
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink);
  cursor: pointer;
}
.nav-toggle__bars {
  display: grid;
  gap: 4px;
  width: 20px;
}
.nav-toggle__bars span {
  display: block;
  height: 1px;
  background: currentColor;
  transition: transform 0.3s var(--ease), opacity 0.2s var(--ease);
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

@media (max-width: 760px) {
  .nav-toggle { display: inline-flex; }

  .nav {
    position: fixed;
    inset: var(--header-h) 0 0 0;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 0;
    padding: 0 var(--gutter) 15vh;
    background: var(--paper);
    transform: translateY(-8px);
    opacity: 0;
    pointer-events: none;
    visibility: hidden;
    transition: opacity 0.3s var(--ease), transform 0.3s var(--ease), visibility 0.3s;
  }
  .nav.is-open { opacity: 1; transform: none; pointer-events: auto; visibility: visible; }

  .nav__link {
    width: 100%;
    padding: clamp(0.9rem, 3vw, 1.4rem) 0;
    font-family: var(--font-display);
    font-weight: var(--fw-semi);
    font-size: clamp(1.75rem, 6.5vw, 2.25rem);
    letter-spacing: var(--track-h1);
    text-transform: none;
    border-bottom: 1px solid var(--line);
  }
  .nav__link::after { display: none; }
  .nav__link[aria-current="page"] { color: var(--accent); }

  body.nav-open { overflow: hidden; }
}

/* ==========================================================================
   6. BUTTONS & TEXT LINKS
   ========================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.85rem 1.6rem;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  letter-spacing: 0.005em;
  line-height: 1.2;
  border: 1px solid var(--ink);
  background: var(--ink);
  color: var(--paper);
  cursor: pointer;
  transition: background 0.25s var(--ease), color 0.25s var(--ease),
              border-color 0.25s var(--ease);
}
.btn:hover { background: var(--accent); border-color: var(--accent); color: #fff; }

.btn--ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--line-2);
}
.btn--ghost:hover { background: transparent; color: var(--accent); border-color: var(--accent); }

.btn--on-dark {
  background: var(--on-dark);
  border-color: var(--on-dark);
  color: var(--dark);
}
.btn--on-dark:hover { background: transparent; color: var(--on-dark); border-color: var(--on-dark); }

/* Understated arrow link — the site's workhorse call to action */
.arrow-link {
  display: inline-flex;
  align-items: baseline;
  gap: 0.55rem;
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink);
  padding-bottom: 0.35rem;
  border-bottom: 1px solid var(--line-2);
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.arrow-link__arrow { transition: transform 0.35s var(--ease); }
.arrow-link:hover { color: var(--accent); border-color: var(--accent); }
.arrow-link:hover .arrow-link__arrow { transform: translateX(5px); }

.inline-link {
  color: var(--accent);
  border-bottom: 1px solid rgba(47, 79, 114, 0.35);   /* fallback */
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  transition: border-color 0.25s var(--ease);
}
.inline-link:hover { border-bottom-color: var(--accent); }

/* ==========================================================================
   7. HOME — HERO
   ========================================================================== */
.hero {
  position: relative;
  padding-block: clamp(4rem, 11vh, 9rem) clamp(2rem, 4.5vh, 3.5rem);
  overflow: hidden;
}
/* Optional atmospheric backdrop. Swap assets/images/hero.svg for a generated
   image and the hero picks it up with no markup change. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: url("assets/images/hero.svg") center / cover no-repeat;
  opacity: 0.085;
  pointer-events: none;
}
.hero > * { position: relative; }

.hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
  padding-bottom: 1.75rem;
  margin-bottom: clamp(1.75rem, 4vw, 3rem);
  border-bottom: 1px solid var(--line);
}

.hero__name {
  font-size: var(--fs-display);
  line-height: var(--lh-tight);
  /* Held to a measure so the two lines stay a block, not a banner. */
  max-width: 14ch;
  margin-bottom: clamp(1.75rem, 3.5vw, 2.75rem);
}

.hero__body {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3.5rem);
  align-items: end;
}
@media (min-width: 900px) {
  .hero__body { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
}

.hero__statement {
  font-size: var(--fs-lede);
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 40ch;
  text-wrap: pretty;
}
.hero__statement strong { font-weight: var(--fw-semi); color: var(--ink); }

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.75rem;
}

/* Proof strip — first-screen credibility, set as editorial metadata in the
   same language as the About page metrics. Deliberately typeset smaller than
   .metric__value: it sits under the display name and must not compete with it.
   Four items; if a fifth is ever added, drop one. */
.hero__proof {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0;
  margin-top: clamp(2.25rem, 5vw, 3.5rem);
  border-top: 1px solid var(--line);
}
@media (min-width: 900px) {
  .hero__proof { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.proof {
  padding: clamp(1.1rem, 2.2vw, 1.5rem) var(--grid-gap) clamp(1.1rem, 2.2vw, 1.5rem) 0;
  border-bottom: 1px solid var(--line);
}
@media (min-width: 900px) {
  .proof { border-bottom: 0; }
  .proof + .proof { padding-left: var(--grid-gap); border-left: 1px solid var(--line); }
}
.proof__value {
  display: block;
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  font-size: clamp(1.5rem, 2.2vw, 1.875rem);
  line-height: 1.1;
  letter-spacing: var(--track-h2);
  color: var(--ink);
}
.proof__label {
  display: block;
  font-size: var(--fs-xs);
  line-height: 1.5;
  color: var(--muted);
  margin-top: 0.55rem;
  max-width: 22ch;
}

/* --------------------------------------------------------------------------
   CLIENT WALL — typographic attribution, set in the display face so it
   belongs to this page rather than to eight other companies' brand systems.
   Deliberately NOT logos; see data/projects.js.
   -------------------------------------------------------------------------- */
.clientwall-band { padding-block: clamp(1.75rem, 4vw, 2.75rem); }
.clientwall__label { margin-bottom: clamp(1rem, 2vw, 1.4rem); }
.clientwall {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.65rem clamp(1.25rem, 3vw, 2.5rem);
  border-top: 1px solid var(--line);
  padding-top: clamp(1.1rem, 2.5vw, 1.6rem);
}
.clientwall__item {
  font-family: var(--font-display);
  font-weight: var(--fw-medium);
  font-size: clamp(1rem, 1.3vw, 1.1875rem);
  letter-spacing: var(--track-h3);
  color: var(--ink-2);
  white-space: nowrap;
}

/* Attribution line used wherever a client is credited. The name carries the
   weight; the market/scale descriptor recedes. */
.client-name { color: inherit; font-weight: var(--fw-semi); }
.client-desc { color: inherit; opacity: 0.68; }

/* --------------------------------------------------------------------------
   ENGAGEMENT MODELS — how a client can hire. Two-up on desktop, stacked on
   mobile, divided by the same hairline rules as the rest of the site. Not
   cards: no shadow, no radius, no fill.
   -------------------------------------------------------------------------- */
.engagements {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  border-top: 1px solid var(--line-2);
}
@media (min-width: 760px) {
  .engagements { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .engagement:nth-child(odd) { padding-right: clamp(1.5rem, 3vw, 3rem); }
  .engagement:nth-child(even) {
    padding-left: clamp(1.5rem, 3vw, 3rem);
    border-left: 1px solid var(--line);
  }
}
.engagement {
  padding-block: clamp(1.6rem, 3vw, 2.25rem);
  border-bottom: 1px solid var(--line);
}
.engagement__title {
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  font-size: var(--fs-h3);
  letter-spacing: var(--track-h3);
  line-height: var(--lh-snug);
}
.engagement__shape {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 0.5rem;
}
.engagement__body {
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--ink-2);
  margin-top: 0.9rem;
  max-width: 46ch;
}
.engagement__fit {
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--ink);
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--line);
  max-width: 46ch;
}
.engagements__note {
  font-size: var(--fs-sm);
  color: var(--muted);
  margin-top: clamp(1.25rem, 2.5vw, 1.75rem);
  max-width: 52ch;
}

/* --------------------------------------------------------------------------
   EXECUTIVE SUMMARY — the commercial scan at the head of a case study. A
   definition list, set tight, above the existing narrative.
   -------------------------------------------------------------------------- */
.exec {
  border-top: 1px solid var(--ink);
  border-bottom: 1px solid var(--line);
  padding-block: clamp(1.25rem, 2.5vw, 1.75rem) clamp(1.5rem, 3vw, 2rem);
  margin-bottom: clamp(2rem, 4vw, 3rem);
}
.exec__label { margin-bottom: clamp(1rem, 2vw, 1.35rem); }
.exec__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.55rem 0;
}
.exec__row {
  display: grid;
  grid-template-columns: 7.5rem minmax(0, 1fr);
  gap: 0.75rem;
  align-items: baseline;
  padding-block: 0.3rem;
}
.exec__key {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.exec__val { font-size: var(--fs-sm); color: var(--ink-2); line-height: 1.45; }
.exec__lines {
  margin-top: clamp(1rem, 2vw, 1.35rem);
  padding-top: clamp(1rem, 2vw, 1.35rem);
  border-top: 1px solid var(--line);
  display: grid;
  gap: 0.75rem;
}
.exec__line { display: grid; grid-template-columns: 7.5rem minmax(0, 1fr); gap: 0.75rem; }
.exec__line-key {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
  padding-top: 0.2rem;
}
.exec__line-val { font-size: var(--fs-base); line-height: 1.55; color: var(--ink); }
@media (max-width: 479px) {
  .exec__row, .exec__line { grid-template-columns: minmax(0, 1fr); gap: 0.2rem; }
}

/* Lede under a dark CTA title. */
.cta__lede {
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--on-dark-2);
  max-width: 48ch;
  margin-top: 1rem;
}

/* --------------------------------------------------------------------------
   CONTACT TOPICS — what to approach me about. Rows, not cards: the whole row
   is the target, divided by the same hairlines used everywhere else.
   -------------------------------------------------------------------------- */
.topics__label { margin-bottom: clamp(1rem, 2vw, 1.4rem); }
.topics { border-top: 1px solid var(--line-2); }
.topic { border-bottom: 1px solid var(--line); }
.topic__link {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.3rem;
  padding-block: clamp(1.1rem, 2.2vw, 1.5rem);
  text-decoration: none;
  color: inherit;
  transition: padding-left 180ms ease;
}
@media (min-width: 760px) {
  .topic__link {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.4fr);
    gap: clamp(1.5rem, 3vw, 3rem);
    align-items: baseline;
  }
}
.topic__name {
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  font-size: clamp(1.0625rem, 1.2vw, 1.1875rem);
  letter-spacing: var(--track-h3);
  color: var(--ink);
}
.topic__hint { font-size: var(--fs-sm); line-height: 1.5; color: var(--muted); }
.topic__link:hover .topic__name,
.topic__link:focus-visible .topic__name { color: var(--accent); }
.topic__link:hover { padding-left: 0.4rem; }
@media (prefers-reduced-motion: reduce) {
  .topic__link { transition: none; }
  .topic__link:hover { padding-left: 0; }
}

/* --------------------------------------------------------------------------
   INTAKE FORM — typeset like the rest of the site: hairline rules, no filled
   boxes, no rounded corners, no shadow. Inputs are underlines that darken on
   focus rather than bordered widgets.
   -------------------------------------------------------------------------- */
.intake {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(1.4rem, 3vw, 1.9rem) clamp(1.5rem, 3vw, 2.5rem);
  border-top: 1px solid var(--line-2);
  padding-top: clamp(1.5rem, 3vw, 2.25rem);
  margin-top: clamp(1rem, 2vw, 1.4rem);
}
@media (min-width: 760px) {
  .intake { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .field--wide { grid-column: 1 / -1; }
}

.field { display: grid; gap: 0.5rem; align-content: start; }
.field__label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.field__label span { color: var(--accent); }

.field__input {
  font-family: inherit;
  font-size: var(--fs-md);
  line-height: 1.5;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line-2);
  border-radius: 0;
  padding: 0.6rem 0 0.55rem;
  width: 100%;
  /* 16px minimum stops iOS Safari zooming the page on focus. */
  min-height: 2.75rem;
  transition: border-color 160ms ease;
  -webkit-appearance: none;
  appearance: none;
}
.field__input::placeholder { color: var(--muted); }
.field__input:hover { border-bottom-color: var(--ink-2); }
.field__input:focus {
  outline: none;
  border-bottom-color: var(--accent);
  box-shadow: 0 1px 0 0 var(--accent);
}
.field__input:focus-visible { outline: 2px solid transparent; }
.field__input[aria-invalid="true"] { border-bottom-color: #9a3b2f; }
.field__input[aria-invalid="true"]:focus { box-shadow: 0 1px 0 0 #9a3b2f; }

.field__textarea { resize: vertical; min-height: 7rem; }

/* Native select arrow removed above, so draw one. */
.field__select {
  background-image:
    linear-gradient(45deg, transparent 50%, var(--ink-2) 50%),
    linear-gradient(135deg, var(--ink-2) 50%, transparent 50%);
  background-position: right 0.75rem center, right 0.4rem center;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 2rem;
  cursor: pointer;
}

.field__hint { font-size: var(--fs-sm); line-height: 1.55; color: var(--muted); max-width: 58ch; }
.field__error { font-size: var(--fs-sm); line-height: 1.5; color: #9a3b2f; }

.intake__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.9rem 1.5rem;
  padding-top: clamp(0.5rem, 1.5vw, 1rem);
}
.intake__note { font-size: var(--fs-sm); color: var(--muted); max-width: 40ch; }
.intake__summary { font-size: var(--fs-sm); color: #9a3b2f; }

/* --------------------------------------------------------------------------
   BOOKING — the Cal.com embed. Kept below the fold of the section and
   collapsed until asked for, so the calendar never dominates the page.
   -------------------------------------------------------------------------- */
.booking__head {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  justify-content: space-between;
  gap: 1.25rem 2rem;
  border-top: 1px solid var(--line-2);
  padding-top: clamp(1.5rem, 3vw, 2.25rem);
}
.booking__lede {
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--ink-2);
  margin-top: 0.65rem;
  max-width: 46ch;
}
.btn--quiet {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--ink);
}
.btn--quiet:hover { background: var(--ink); color: var(--paper); }

.booking__embed {
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
  border-top: 1px solid var(--line);
  padding-top: clamp(1.25rem, 2.5vw, 1.75rem);
  min-height: 34rem;
  width: 100%;
  overflow: hidden;
}
.booking__embed iframe { width: 100% !important; border: 0; }
@media (max-width: 599px) { .booking__embed { min-height: 40rem; } }

.booking__fallback {
  font-size: var(--fs-sm);
  color: var(--muted);
  margin-top: 1.5rem;
}

/* ==========================================================================
   8. SECTION FURNITURE
   ========================================================================== */
.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding-bottom: 1.5rem;
  margin-bottom: clamp(2rem, 4vw, 3.5rem);
  border-bottom: 1px solid var(--line);
}
.eyebrow {
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.band--ink .eyebrow { color: var(--on-dark-2); }

.section-title {
  font-size: var(--fs-h2);
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  letter-spacing: var(--track-h2);
  line-height: var(--lh-title);
  text-wrap: balance;
}
.page-title {
  font-size: var(--fs-h1);
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  letter-spacing: var(--track-h1);
  line-height: var(--lh-tight);
  max-width: 18ch;
  text-wrap: balance;
}

.lede {
  font-size: var(--fs-lede);
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 50ch;
  text-wrap: pretty;
}
.prose { color: var(--ink-2); max-width: var(--measure); text-wrap: pretty; }
.prose + .prose { margin-top: 1.4rem; }

/* Page masthead used on About / Projects / Contact */
.page-head {
  padding-block: clamp(3.5rem, 9vh, 7rem) clamp(2rem, 4vw, 3.5rem);
}
.page-head--tight { padding-block: clamp(3rem, 7vh, 5rem) clamp(1.5rem, 3vw, 2.5rem); }
.page-head__eyebrow { margin-bottom: 1.25rem; }
.page-head__lede { margin-top: clamp(1.5rem, 3vw, 2.25rem); max-width: 54ch; }

/* ==========================================================================
   8b. SHARED LISTS
   Two list treatments used by the exhibition and the case study, so the
   technology stack and the "demonstrates" run read the same everywhere.
   ========================================================================== */

/* Framed tags — the technology stack. Deliberately quiet: this is a
   specification, not a badge wall. */
.taglist {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.5rem;
}
.taglist li {
  font-size: var(--fs-xs);
  line-height: 1.4;
  color: var(--ink-2);
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--line);
  background: var(--surface);
}

/* Inline run, separated by hairline dots — the "demonstrates" line */
.runlist {
  display: flex;
  flex-wrap: wrap;
  column-gap: 0.8rem;
  row-gap: 0.35rem;
  font-size: var(--fs-sm);
  color: var(--ink-2);
}
.runlist li { display: inline-flex; align-items: baseline; }
.runlist li:not(:last-child)::after {
  content: "";
  display: inline-block;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: var(--line-2);
  margin-left: 0.8rem;
  transform: translateY(-0.25em);
}

/* ==========================================================================
   8c. HOME — THE PRACTICE (stance) & SERVICES
   Numbered editorial rows. Rules and numerals carry the hierarchy; there are
   no cards anywhere in this system.
   ========================================================================== */
.stance {
  display: grid;
  gap: 0;
  margin-top: clamp(2.5rem, 5vw, 4rem);
  border-top: 1px solid var(--line);
}
@media (min-width: 860px) {
  .stance { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: clamp(2rem, 4vw, 4rem); }
}
.stance__item {
  display: grid;
  grid-template-columns: 3rem minmax(0, 1fr);
  gap: 0 clamp(1rem, 2vw, 1.75rem);
  padding-block: clamp(1.5rem, 3vw, 2.25rem);
  border-bottom: 1px solid var(--line);
}
.stance__num {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  color: var(--muted);
  padding-top: 0.35rem;
}
.stance__title {
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  font-size: var(--fs-h3);
  letter-spacing: var(--track-h3);
  line-height: var(--lh-snug);
}
.stance__body {
  grid-column: 2;
  margin-top: 0.6rem;
  font-size: var(--fs-base);
  color: var(--ink-2);
  max-width: 46ch;
}

/* --- Services: every claim sits next to the exhibits that evidence it ----- */
.services {
  display: grid;
  gap: 0;
  border-top: 1px solid var(--line-2);
}
.service {
  display: grid;
  grid-template-columns: 3rem minmax(0, 1fr);
  gap: 0.75rem clamp(1rem, 2vw, 1.75rem);
  padding-block: clamp(1.75rem, 3.5vw, 2.75rem);
  border-bottom: 1px solid var(--line);
  align-items: start;
}
@media (min-width: 900px) {
  .service {
    grid-template-columns: 3rem minmax(0, 1.45fr) minmax(0, 1fr);
    column-gap: clamp(1.5rem, 3vw, 3.5rem);
  }
}
.service__num {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  color: var(--muted);
  padding-top: 0.4rem;
}
.service__title {
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  font-size: var(--fs-h3);
  letter-spacing: var(--track-h3);
  line-height: var(--lh-snug);
}
.service__body {
  margin-top: 0.75rem;
  color: var(--ink-2);
  max-width: 56ch;
  text-wrap: pretty;
}
.service__proof { grid-column: 2 / -1; }
@media (min-width: 900px) { .service__proof { grid-column: 3; padding-top: 0.4rem; } }
.service__proof-label {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--line);
}
.service__list { display: grid; gap: 0.5rem; margin-top: 0.75rem; }
.service__exhibit {
  display: inline-flex;
  align-items: baseline;
  gap: 0.5rem;
  font-size: var(--fs-sm);
  color: var(--ink);
  border-bottom: 1px solid var(--line-2);
  padding-bottom: 0.15rem;
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.service__exhibit::before { content: "\2192"; color: var(--muted); }
.service__exhibit:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* ==========================================================================
   9. GALLERY — EXHIBITS  (home page "Selected work")
   The 12-column bed. Layout variants are assigned by script.js on a repeating
   six-slot rhythm (full / half / half / wide / half / half), so the gallery
   stays composed at 4 projects or at 30. Each plate links into the exhibition
   at that exhibit.
   ========================================================================== */
.gallery {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(3rem, 6vw, 5.5rem);
}

/* --------------------------------------------------------------------------
   ONE PROJECT LAYOUT — TEXT | IMAGE, ~60/40.

   Every exhibit uses this structure; there is no alternating rhythm. DOM
   order is text -> plate -> cue, which IS the mobile order. On desktop the
   grid lifts the plate into the right column across both rows and drops the
   cue beneath the text, so the text block stays vertically balanced against
   the image without needing a different DOM.
   -------------------------------------------------------------------------- */
.exhibit { border-top: 1px solid var(--line); padding-top: clamp(1.5rem, 3vw, 2.25rem); }

.exhibit__link {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(1.5rem, 3vw, 2rem);
  text-decoration: none;
  color: inherit;
}
@media (min-width: 860px) {
  .exhibit__link {
    grid-template-columns: minmax(0, 6fr) minmax(0, 4fr);
    grid-template-rows: auto 1fr;
    column-gap: clamp(2.5rem, 5vw, 4.5rem);
    row-gap: clamp(1.25rem, 2.5vw, 2rem);
    align-items: start;
  }
  .exhibit__text  { grid-column: 1; grid-row: 1; }
  .exhibit__plate { grid-column: 2; grid-row: 1 / span 2; }
  .exhibit__cue   { grid-column: 1; grid-row: 2; align-self: end; }
}

/* --- The plate -----------------------------------------------------------
   3:2 container, and the artwork is CONTAINED, never cropped. The source
   plates are 16:9 architecture diagrams: cover-cropping them cut the first
   and last stage off the flow, which is the whole point of the diagram. The
   ground matches each plate's own canvas so the letterboxing is invisible.
   -------------------------------------------------------------------------- */
.exhibit__plate {
  position: relative;
  margin: 0;
  aspect-ratio: 3 / 2;
  background: var(--paper-2);
  border: 1px solid var(--line);
  overflow: hidden;
}
.exhibit__image {
  width: 100%;
  height: 100%;
  object-fit: contain;          /* never crop a diagram */
  display: block;
  transition: opacity 0.5s var(--ease);
}
.exhibit__link:hover .exhibit__image { opacity: 0.92; }
@media (prefers-reduced-motion: reduce) {
  .exhibit__image { transition: none; }
}

.exhibit__index {
  position: absolute;
  top: 0.75rem;
  left: 0.85rem;
  z-index: 1;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  color: var(--muted);
}

/* --------------------------------------------------------------------------
   PLATE GROUNDS — the frame behind a contained diagram must match that
   diagram's own canvas, or the letterbox bands read as a mistake. Declared
   per project in data/projects.js (plateGround) and applied to all three
   surfaces: the home gallery, the exhibition stage and the case-study plate.

   Two grounds, one system. Both are :root tokens, and the 1px edge keeps a
   light plate from dissolving into the page.
   -------------------------------------------------------------------------- */
.plate--light { background: #faf8f3; border-color: var(--line); }
.plate--dark  { background: var(--dark); border-color: var(--dark-2); }
.plate--dark .exhibit__index { color: var(--on-dark-2); }

/* --- The text block ------------------------------------------------------- */
.exhibit__cat {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.exhibit__title {
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  font-size: var(--fs-exhibit);
  line-height: var(--lh-title);
  letter-spacing: var(--track-h2);
  margin-top: 0.5rem;
  text-wrap: balance;
}
.exhibit__client { font-size: var(--fs-sm); color: var(--muted); margin-top: 0.5rem; }
.exhibit__summary {
  font-size: var(--fs-md);
  line-height: var(--lh-body);
  color: var(--ink-2);
  margin-top: 1.1rem;
  max-width: 60ch;
}
.exhibit__impact {
  font-size: var(--fs-md);
  line-height: 1.6;
  color: var(--ink);
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
  max-width: 60ch;
}
.exhibit__cue {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink);
  padding-bottom: 0.35rem;
  border-bottom: 1px solid var(--line-2);
  justify-self: start;
  transition: border-color 0.3s var(--ease), color 0.3s var(--ease);
}
.exhibit__link:hover .exhibit__cue,
.exhibit__link:focus-visible .exhibit__cue {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.exhibit__link:focus-visible { outline: 2px solid var(--accent); outline-offset: 6px; }

.gallery__empty { color: var(--muted); }


/* ==========================================================================
   10. THE EXHIBITION  (projects.html)

   One exhibit holds the room at a time. On desktop the plate and the wall
   label sit in an asymmetric two-column spread with a deliberate baseline
   offset — an editorial hang, not a centred card. On mobile the spread
   stacks: label head, plate, story, then the reel.
   ========================================================================== */
.exhibition { padding-bottom: var(--band); }

/* --- Control bar: collections + view swap -------------------------------- */
.exhibition__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.75rem 1.5rem;
  padding-block: 1.1rem;
  border-block: 1px solid var(--line);
}
.exhibition__bar-label {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.collections {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 1.5rem;
  margin-right: auto;
}
.collection {
  background: none;
  border: 0;
  padding: 0.25rem 0;
  font: inherit;
  font-size: var(--fs-sm);
  color: var(--muted);
  cursor: pointer;
  border-bottom: 1px solid transparent;
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.collection:hover { color: var(--ink); }
.collection[aria-pressed="true"] { color: var(--ink); border-bottom-color: var(--accent); }
.collection__count {
  font-size: var(--fs-xs);
  color: var(--muted);
  margin-left: 0.3rem;
  vertical-align: super;
}

.viewswap {
  background: none;
  border: 1px solid var(--line-2);
  padding: 0.42rem 1rem;
  font: inherit;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.25s var(--ease), color 0.25s var(--ease),
              border-color 0.25s var(--ease);
}
.viewswap:hover { border-color: var(--accent); color: var(--accent); }
.viewswap[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }

/* --- The stage ----------------------------------------------------------- */
.stage {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3.5rem);
  padding-block: clamp(2rem, 4.5vw, 3.5rem);
  align-items: start;
}
.stage:focus { outline: none; }
.exhibition.is-index .stage,
.exhibition.is-index .reel { display: none; }

/* Mobile reads in DOM order — head, plate, label — so you know what the
   exhibit is before you see it, and the story follows the visual. */
@media (min-width: 960px) {
  /* Asymmetric hang: the plate takes the larger measure on the left and spans
     both rows; the wall label sits beside it, head aligned to the top edge and
     the story offset below, so the two columns never read as a table. */
  .stage {
    grid-template-columns: minmax(0, 1.42fr) minmax(0, 1fr);
    grid-template-rows: auto 1fr;
    grid-template-areas:
      "plate head"
      "plate label";
    column-gap: clamp(2rem, 4vw, 4rem);
    row-gap: clamp(1.25rem, 2.5vw, 2rem);
  }
  .stage__plate { grid-area: plate; }
  .stage__head  { grid-area: head; }
  .stage__label { grid-area: label; }
}

/* The plate — the exhibit itself, given real room */
.stage__plate {
  position: relative;
  margin: 0;
  overflow: hidden;
  /* Neutral, because the plate family now has both a light and a dark
     ground. A hardcoded --dark here framed the light plates in black. */
  background: var(--paper-2);
  aspect-ratio: 16 / 9;
  border: 1px solid var(--line);
}
@media (max-width: 639px) { .stage__plate { aspect-ratio: 4 / 3; } }

.stage__img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* A missing or undecodable image leaves the frame, never a broken icon. */
.stage__plate.is-plateless::after,
.exhibit__plate.is-plateless::after,
.case-plate__frame.is-plateless::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(
      135deg,
      rgba(238, 235, 228, 0.045) 0 1px,
      transparent 1px 14px
    );
}
.case-plate__frame.is-plateless { position: relative; aspect-ratio: 16 / 9; }

.stage__index {
  position: absolute;
  top: clamp(0.85rem, 1.6vw, 1.4rem);
  left: clamp(0.85rem, 1.6vw, 1.4rem);
  z-index: 2;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  color: var(--on-dark-2);
}
.stage__seal {
  position: absolute;
  right: clamp(0.85rem, 1.6vw, 1.4rem);
  bottom: clamp(0.85rem, 1.6vw, 1.4rem);
  z-index: 2;
  font-size: var(--fs-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--on-dark-2);
  padding: 0.3rem 0.65rem;
  border: 1px solid var(--on-dark-line);
  background: rgba(16, 19, 25, 0.45);
  backdrop-filter: blur(4px);
}

/* The wall label */
.stage__cat {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--accent);
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--line-2);
}
.stage__title {
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  font-size: clamp(1.75rem, 2.6vw, 2.375rem);
  letter-spacing: var(--track-h1);
  line-height: var(--lh-title);
  margin-top: 1.1rem;
  max-width: 20ch;
  text-wrap: balance;
}
.stage__client { margin-top: 0.85rem; font-size: var(--fs-md); color: var(--ink-2); }
.stage__role   { margin-top: 0.3rem;  font-size: var(--fs-sm); color: var(--muted); }

/* The four questions, answered before anyone clicks anything */
.stage__story { margin-top: 0; }
@media (max-width: 959px) { .stage__story { margin-top: 0.5rem; } }
.stage__act { padding-block: 1.1rem; border-top: 1px solid var(--line); }
.stage__act-key {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.55rem;
}
.stage__act-body { font-size: var(--fs-base); line-height: 1.6; color: var(--ink-2); }
.stage__act--impact .stage__act-body { color: var(--ink); }

.stage__stack, .stage__demo { padding-block: 1.1rem; border-top: 1px solid var(--line); }
.stage__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.75rem;
  margin-top: clamp(1.5rem, 3vw, 2rem);
  padding-top: clamp(1.25rem, 2.5vw, 1.75rem);
  border-top: 1px solid var(--ink);
}

/* Direction-aware entrance. Purely supportive — the exhibit is already in the
   DOM before this runs, so a cancelled transition never hides content. */
.stage__plate, .stage__head, .stage__label {
  transition: opacity 0.42s var(--ease), transform 0.42s var(--ease);
}
.stage.from-right .stage__plate,
.stage.from-right .stage__head,
.stage.from-right .stage__label { opacity: 0; transform: translateX(26px); }
.stage.from-left  .stage__plate,
.stage.from-left  .stage__head,
.stage.from-left  .stage__label { opacity: 0; transform: translateX(-26px); }
.stage.is-in .stage__plate,
.stage.is-in .stage__head,
.stage.is-in .stage__label { opacity: 1; transform: none; }
.stage.is-in .stage__head  { transition-delay: 0.05s; }
.stage.is-in .stage__label { transition-delay: 0.09s; }

/* --- The reel: previous / position / next -------------------------------- */
.reel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 1rem;
  padding-block: clamp(1.25rem, 2.5vw, 1.75rem);
  border-top: 1px solid var(--line-2);
}
.reel__step {
  display: inline-flex;
  align-items: center;
  gap: 0.9rem;
  background: none;
  border: 0;
  padding: 0.5rem 0;
  font: inherit;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
  min-width: 0;
  transition: color 0.25s var(--ease);
}
.reel__step--next { justify-self: end; text-align: right; }
.reel__step[disabled] { opacity: 0.35; cursor: default; }
.reel__step:not([disabled]):hover { color: var(--accent); }
.reel__arrow { font-size: 1.25rem; line-height: 1; transition: transform 0.3s var(--ease); }
.reel__step--prev:not([disabled]):hover .reel__arrow { transform: translateX(-5px); }
.reel__step--next:not([disabled]):hover .reel__arrow { transform: translateX(5px); }
.reel__meta { display: grid; gap: 0.2rem; min-width: 0; }
.reel__dir {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.reel__title {
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  font-size: clamp(0.9375rem, 1.1vw, 1.0625rem);
  letter-spacing: var(--track-h3);
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.reel__rail { display: grid; justify-items: center; gap: 0.7rem; }
.reel__count {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  color: var(--muted);
  white-space: nowrap;
}
.ticks { display: flex; align-items: center; gap: 0.5rem; }
.tick {
  display: block;
  width: 26px;
  height: 24px;                    /* touch-sized hit area, hairline appearance */
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
  position: relative;
}
.tick::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: 1px;
  background: var(--line-2);
  transition: background 0.25s var(--ease), height 0.25s var(--ease);
}
.tick:hover::after { background: var(--ink-2); }
.tick.is-current::after { background: var(--accent); height: 2px; }

@media (max-width: 719px) {
  .reel { grid-template-columns: auto 1fr auto; gap: 0.75rem; }
  .reel__meta { display: none; }
  .reel__step {
    justify-content: center;
    width: 48px; height: 48px;
    border: 1px solid var(--line-2);
  }
  .reel__step--next { justify-self: end; }
  .ticks { flex-wrap: wrap; justify-content: center; }
  /* 20px wide + 8px gap = 28px pitch, so the targets stay comfortably
     tappable even though the mark itself is a hairline. */
  .tick { width: 20px; }
}

/* --- The index: the whole archive, as a catalogue ------------------------ */
.index-view { padding-block: clamp(1.5rem, 3vw, 2.5rem); }
.index { border-top: 1px solid var(--line-2); }
.index__row { border-bottom: 1px solid var(--line); }
.index__hit {
  display: grid;
  grid-template-columns: 2.5rem minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 0.35rem 1.25rem;
  width: 100%;
  padding-block: clamp(1.1rem, 2.2vw, 1.6rem);
  background: none;
  border: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
@media (min-width: 900px) {
  .index__hit {
    grid-template-columns: 2.5rem minmax(0, 1.6fr) minmax(0, 0.8fr) minmax(0, 1fr) 1.5rem;
    align-items: center;
  }
}
.index__num {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  color: var(--muted);
}
.index__main { display: grid; gap: 0.25rem; min-width: 0; }
.index__title {
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  font-size: clamp(1.125rem, 1.4vw, 1.3125rem);
  letter-spacing: var(--track-h3);
  line-height: 1.25;
  transition: color 0.25s var(--ease);
}
.index__client { font-size: var(--fs-sm); color: var(--muted); }
.index__cat {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.index__impact { font-size: var(--fs-sm); color: var(--accent); }
.index__cue { color: var(--muted); transition: transform 0.3s var(--ease), color 0.25s var(--ease); }
@media (max-width: 899px) {
  .index__cat, .index__cue { grid-column: 2; }
  .index__impact { grid-column: 2; }
}
.index__hit:hover .index__title { color: var(--accent); }
.index__hit:hover .index__cue { color: var(--accent); transform: translateX(5px); }

/* ==========================================================================
   11. ABOUT PAGE
   ========================================================================== */
.about-grid {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4.5rem);
  align-items: start;
}
@media (min-width: 900px) {
  .about-grid { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); }
}

.portrait {
  position: relative;
  background: var(--dark);
  overflow: hidden;
  aspect-ratio: 4 / 5;
}
.portrait img { width: 100%; height: 100%; object-fit: cover; object-position: center 18%; }
/* Currently unused — the name caption under the About portrait was removed as
   redundant. Kept (and now centred) so restoring one line of HTML brings it
   back looking right. */
.portrait__caption {
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 0.9rem;
  text-align: center;
}

/* Metrics as editorial metadata, not cards */
.metrics {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0;
  border-top: 1px solid var(--line);
}
@media (min-width: 900px) {
  .metrics { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.metric {
  padding: clamp(1.5rem, 3vw, 2.25rem) var(--grid-gap) clamp(1.5rem, 3vw, 2.25rem) 0;
  border-bottom: 1px solid var(--line);
}
@media (min-width: 900px) {
  .metric { border-bottom: 0; }
  .metric + .metric { padding-left: var(--grid-gap); border-left: 1px solid var(--line); }
}
.metric__value {
  display: block;
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  font-size: clamp(2rem, 3.1vw, 2.625rem);
  line-height: 1.1;
  letter-spacing: var(--track-h1);
  color: var(--ink);
}
.metric__label {
  display: block;
  font-size: var(--fs-sm);
  color: var(--muted);
  margin-top: 0.65rem;
  max-width: 18ch;
}

/* Capability index — skills as a typeset index, not a bag of pills */
.capabilities {
  display: grid;
  gap: 0;
  border-top: 1px solid var(--line);
}
.capability {
  display: grid;
  gap: 0.75rem var(--grid-gap);
  padding-block: clamp(1.5rem, 3vw, 2.25rem);
  border-bottom: 1px solid var(--line);
}
@media (min-width: 800px) {
  .capability { grid-template-columns: minmax(0, 16rem) minmax(0, 1fr); align-items: baseline; }
}
.capability__name {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.capability__items {
  display: flex;
  flex-wrap: wrap;
  column-gap: 0.85rem;
  row-gap: 0.4rem;
  font-size: var(--fs-md);
  color: var(--ink);
}
.capability__items li { display: inline-flex; align-items: baseline; }
.capability__items li:not(:last-child)::after {
  content: "";
  display: inline-block;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: var(--line-2);
  margin-left: 0.85rem;
  transform: translateY(-0.25em);
}

/* Domain / industry run */
.domains {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  font-family: var(--font-display);
  font-weight: var(--fw-medium);
  font-size: clamp(1.125rem, 1.6vw, 1.4375rem);
  letter-spacing: var(--track-h3);
  line-height: 1.4;
  color: var(--ink);
}
.domains li::after {
  content: " / ";
  color: var(--line-2);
  padding-left: 0.5rem;
}
.domains li:last-child::after { content: ""; }

/* ==========================================================================
   12. CONTACT PAGE
   ========================================================================== */
.contact-list { border-top: 1px solid var(--line); }
.contact-row {
  display: grid;
  gap: 0.35rem 2rem;
  padding-block: clamp(1.4rem, 3vw, 2rem);
  border-bottom: 1px solid var(--line);
}
@media (min-width: 700px) {
  .contact-row { grid-template-columns: minmax(0, 10rem) minmax(0, 1fr); align-items: baseline; }
}
.contact-row__label {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.contact-row__value {
  font-family: var(--font-display);
  font-weight: var(--fw-medium);
  font-size: clamp(1.125rem, 1.7vw, 1.4375rem);
  letter-spacing: var(--track-h3);
  line-height: var(--lh-snug);
  word-break: break-word;
}
a.contact-row__value {
  display: inline-block;
  border-bottom: 1px solid transparent;
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
}
a.contact-row__value:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* ==========================================================================
   13. CASE STUDY PAGE  (project.html)
   The four acts — problem, approach, solution, impact — set as a numbered
   editorial narrative, with the exhibit plate shown at full width rather than
   dimmed behind text. The visual is the work; it shouldn't be wallpaper.
   ========================================================================== */
.case-hero {
  background: var(--dark);
  color: var(--on-dark);
}
.case-hero__inner {
  padding-block: clamp(3.5rem, 12vh, 7rem) clamp(2.5rem, 6vh, 4rem);
}
.case-hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--on-dark-2);
  margin-bottom: clamp(1.25rem, 3vw, 2rem);
}
.case-hero__meta li { display: inline-flex; align-items: center; gap: 1.25rem; }
.case-hero__meta li:not(:last-child)::after {
  content: "";
  width: 1px; height: 0.9em;
  background: var(--on-dark-line);
}
.case-hero__title {
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  font-size: var(--fs-h1);
  letter-spacing: var(--track-h1);
  line-height: var(--lh-tight);
  max-width: 20ch;
  text-wrap: balance;
}
.case-hero__client {
  margin-top: clamp(1rem, 2.5vw, 1.5rem);
  font-size: var(--fs-lg);
  color: var(--on-dark-2);
}
.case-hero__role {
  margin-top: 0.5rem;
  font-size: var(--fs-sm);
  color: var(--on-dark-2);
  opacity: 0.85;
}

/* The plate, full-bleed and undimmed */
.case-plate { margin: 0; background: var(--paper-2); }
.case-plate__frame { background: var(--paper-2); overflow: hidden; }
.case-plate__frame img { width: 100%; height: auto; display: block; }
.case-plate__caption {
  padding-block: 0.9rem 1.25rem;
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--paper);
}

.case {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4.5rem);
  align-items: start;
}
@media (min-width: 960px) {
  .case { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
}

/* --- The four acts -------------------------------------------------------- */
.act {
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 1fr);
  gap: 0 clamp(1rem, 2vw, 1.75rem);
  padding-block: clamp(1.75rem, 3.5vw, 2.5rem);
  border-top: 1px solid var(--line);
}
.act:first-child { border-top: 0; padding-top: 0; }
.act__key {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  color: var(--line-2);
  padding-top: 0.5rem;
}
.act__heading {
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  font-size: var(--fs-h3);
  letter-spacing: var(--track-h3);
  line-height: var(--lh-snug);
  margin-bottom: 1rem;
  text-wrap: balance;
}
.act__body { font-size: var(--fs-lg); line-height: var(--lh-body); color: var(--ink-2); max-width: var(--measure); text-wrap: pretty; }
@media (max-width: 599px) {
  .act { grid-template-columns: 1fr; }
  .act__key { padding-top: 0; margin-bottom: 0.6rem; }
}

/* The emphasised fragment of an impact sentence */
.metric-mark { font-style: normal; font-weight: var(--fw-semi); color: var(--accent); }

.case__aside {
  position: sticky;
  top: calc(var(--header-h) + 2rem);
  border-top: 1px solid var(--ink);
  padding-top: 1.5rem;
}
@media (max-width: 959px) { .case__aside { position: static; } }

.spec { padding-block: 1.1rem; border-bottom: 1px solid var(--line); }
.spec__key {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.spec__val { margin-top: 0.4rem; font-size: var(--fs-base); color: var(--ink); }
.spec .taglist { margin-top: 0.6rem; }

/* --- What this demonstrates ---------------------------------------------- */
.demolist {
  display: grid;
  gap: 0;
  border-top: 1px solid var(--line-2);
}
@media (min-width: 800px) {
  .demolist { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: clamp(2rem, 4vw, 4rem); }
}
.demolist__item {
  display: grid;
  grid-template-columns: 2.5rem minmax(0, 1fr);
  gap: 0 1rem;
  align-items: baseline;
  padding-block: clamp(1.1rem, 2.2vw, 1.5rem);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-md);
  color: var(--ink);
}
.demolist__num {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  color: var(--muted);
}

.confidential-note {
  margin-top: 1.75rem;
  padding: 1.1rem 1.25rem;
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--ink-2);
  background: var(--accent-soft);
  border-left: 2px solid var(--accent);
}

/* Prev / next exhibit — auto-wired from the data, so it scales */
.exhibit-nav {
  display: grid;
  gap: 1px;
  background: var(--line);
  border-block: 1px solid var(--line);
}
@media (min-width: 700px) { .exhibit-nav { grid-template-columns: 1fr 1fr; } }
.exhibit-nav__item {
  display: block;
  background: var(--paper);
  padding: clamp(1.75rem, 4vw, 2.75rem) var(--gutter);
  transition: background 0.3s var(--ease);
}
.exhibit-nav__item:hover { background: var(--surface); }
.exhibit-nav__item--next { text-align: left; }
@media (min-width: 700px) { .exhibit-nav__item--next { text-align: right; } }
.exhibit-nav__dir {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--muted);
}
.exhibit-nav__title {
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  font-size: clamp(1.125rem, 1.4vw, 1.3125rem);
  letter-spacing: var(--track-h3);
  line-height: var(--lh-snug);
  margin-top: 0.5rem;
  transition: color 0.25s var(--ease);
}
.exhibit-nav__item:hover .exhibit-nav__title { color: var(--accent); }

/* ==========================================================================
   14. CTA BAND & FOOTER
   ========================================================================== */
.cta {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3rem);
  align-items: end;
}
@media (min-width: 860px) { .cta { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); } }
.cta__title {
  font-family: var(--font-display);
  font-weight: var(--fw-semi);
  font-size: var(--fs-h1);
  letter-spacing: var(--track-h1);
  line-height: var(--lh-tight);
  max-width: 17ch;
  text-wrap: balance;
}
.cta__actions { display: flex; flex-wrap: wrap; gap: 1rem 1.5rem; align-items: center; }
.band--ink .arrow-link { color: var(--on-dark); border-color: var(--on-dark-line); }
.band--ink .arrow-link:hover { color: #fff; border-color: var(--on-dark); }

.colophon {
  border-top: 1px solid var(--line);
  padding-block: clamp(2.5rem, 5vw, 4rem);
}
.colophon__quote {
  font-family: var(--font-display);
  font-weight: var(--fw-medium);
  font-size: clamp(1rem, 1.15vw, 1.125rem);
  letter-spacing: var(--track-h3);
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 56ch;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}
.colophon__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  font-size: var(--fs-sm);
  color: var(--muted);
}
.colophon__links { display: flex; flex-wrap: wrap; gap: 1.5rem; }
.colophon__links a { transition: color 0.25s var(--ease); }
.colophon__links a:hover { color: var(--ink); }

/* ==========================================================================
   15. REDUCED MOTION / PRINT
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  body { animation: none; opacity: 1; }
}

@media print {
  .masthead, .nav-toggle, .cta, .exhibit-nav, .skip-link,
  .exhibition__bar, .reel, .stage__actions { display: none !important; }
  body { background: #fff; color: #000; }
  .exhibit__plate, .portrait, .case-plate, .stage__plate { display: none; }
  .case-hero { background: #fff; color: #000; }
  .case-hero__title, .case-hero__client, .case-hero__meta, .case-hero__role { color: #000; }
  /* Print the whole archive, not just the exhibit that happened to be open. */
  .exhibition.is-index .stage { display: grid !important; }
  .stage { grid-template-columns: 1fr !important; grid-template-areas: none !important; }
  a::after { content: " (" attr(href) ")"; font-size: 0.75em; color: #555; }
}
