/* =========================================================================
   Oliver Luo — Portfolio rebuild  ·  MASTER STYLESHEET
   Warm cream canvas + amber accent, League Spartan (display) / Inter (body).
   Light + dark themes, WCAG 2.2 AA.  See README.md §5 for the big picture.

   HOW THIS FILE IS ORGANIZED
     1. Fonts
     2. Design tokens (:root)  ← colors, --wrap/--measure/--img-radius, type scale
        + dark-theme overrides
     3. Reset / base elements
     4. Layout helpers (.wrap, .section)
     5. Components, top to bottom:
        skip link · header/nav · home hero · section intros · work grid + cards ·
        buttons · about · writing · case study (hero, back-nav, meta, body,
        figures, embeds) · contact · footer · Other Works carousel · utilities

   EDITING TIPS
     • Change a token in :root once and the whole site follows.
     • Prefer the --type-* tokens over raw px/rem for any font-size.
     • Responsive breakpoint is 768px everywhere.
   ========================================================================= */

/* ---------- Fonts (self-hosted, variable, latin subset) ---------- */
@font-face {
  font-family: "League Spartan";
  src: url("fonts/league-spartan-latin.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("fonts/inter-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ---------- Design tokens ---------- */
:root {
  /* Warm cream palette (light) */
  --bg:            #efede6;
  --bg-tint:       #e8e5da;
  --surface:       #f7f6f1;
  --surface-2:     #faf9f5;
  --ink:           #1c1b17;
  --ink-soft:      #3a382f;
  --muted:         #55524733;   /* hairlines */
  --muted-text:    #57544a;
  --accent:        #d68a00;     /* decorative amber (borders, fills — not text) */
  --accent-ink:    #8a5600;     /* amber for TEXT on cream — AA (4.6:1 on --bg) */
  --accent-weak:   #d68a0018;
  --highlight-bg:  #f4cf85;     /* marker field (light): amber ... */
  --highlight-ink: #1c1b17;     /* ... with near-black ink (~12:1, AA) */
  --focus:         #1257b8;     /* high-contrast focus ring */
  --shadow:        0 1px 2px rgba(28,27,23,.06), 0 8px 30px rgba(28,27,23,.08);
  --shadow-lg:     0 12px 50px rgba(28,27,23,.18);

  --font-display: "League Spartan", ui-sans-serif, system-ui, "Segoe UI", sans-serif;
  --font-body:    "Inter", ui-sans-serif, system-ui, "Segoe UI", Roboto, sans-serif;

  --wrap:    1280px;   /* max width of page content (nav, grids, case column) */
  --measure:  720px;   /* max width of running body text / case-meta (one place to tune) */
  --gap: clamp(1rem, 2.4vw, 2rem);
  --radius: 14px;
  --radius-sm: 9px;
  --img-radius: 6px;   /* corner radius shared by every image/thumbnail/card */
  --header-h: 68px;

  /* ---- Type scale: Major Third (ratio 1.25), 16px root ----
     Raw steps:  0.64 · 0.8 · 1 · 1.25 · 1.5625 · 1.953 · 2.441 · 3.052 rem
                 (10.24·12.8·16· 20  ·  25   · 31.25 · 39.06 · 48.83 px)
     Semantic tokens below follow [category]-[role]-[size]-[weight]
     (Material Design roles: display / headline / title / body / label). */
  --type-display-lg-semibold: 3.052rem;   /* 48.83px · 600 */
  --type-headline-lg-medium:  2.441rem;   /* 39.06px · 500 */
  --type-title-lg-medium:     1.953rem;   /* 31.25px · 500 */
  --type-title-md-semibold:   1.5625rem;  /* 25px    · 600 */
  --type-title-md-medium:     1.5625rem;  /* 25px    · 500 */
  --type-body-lg-regular:     1.25rem;    /* 20px    · 400 */
  --type-body-md-regular:     1rem;       /* 16px    · 400 */
  --type-label-lg-medium:     1rem;       /* 16px    · 500 */
  --type-label-md-semibold:   0.8rem;     /* 12.8px  · 600 */
  --type-label-md-medium:     0.8rem;     /* 12.8px  · 500 */
  --type-label-sm-medium:     0.64rem;    /* 10.24px · 500 */
}

/* Largest display steps down one notch on small screens so hero titles fit. */
@media (max-width: 600px) {
  :root {
    --type-display-lg-semibold: 2.441rem;  /* 39.06px */
    --type-headline-lg-medium:  1.953rem;  /* 31.25px */
  }
}

:root[data-theme="dark"] {
  --bg:            #16150f;
  --bg-tint:       #1d1c14;
  --surface:       #201f16;
  --surface-2:     #26241a;
  --ink:           #f3f1e6;
  --ink-soft:      #d8d5c6;
  --muted:         #f3f1e626;
  --muted-text:    #a9a595;
  --accent:        #e7ad3d;
  --accent-ink:    #ecb857;    /* AA on dark surfaces */
  --accent-weak:   #e7ad3d1f;
  --highlight-bg:  #71551E;    /* marker field (dark) ... */
  --highlight-ink: #d8d5c6;    /* ... body-text ink on it = 4.72:1 (AA) */
  --focus:         #7fb2ff;
  --shadow:        0 1px 2px rgba(0,0,0,.4), 0 10px 34px rgba(0,0,0,.5);
  --shadow-lg:     0 14px 60px rgba(0,0,0,.6);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:#16150f; --bg-tint:#1d1c14; --surface:#201f16; --surface-2:#26241a;
    --ink:#f3f1e6; --ink-soft:#d8d5c6; --muted:#f3f1e626; --muted-text:#a9a595;
    --accent:#e7ad3d; --accent-ink:#ecb857; --accent-weak:#e7ad3d1f; --focus:#7fb2ff;
    --highlight-bg:#71551E; --highlight-ink:#d8d5c6;
    --shadow:0 1px 2px rgba(0,0,0,.4),0 10px 34px rgba(0,0,0,.5);
    --shadow-lg:0 14px 60px rgba(0,0,0,.6);
  }
}

/* ---------- Reset / base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%; scroll-behavior: smooth;
  /* Always reserve the scrollbar gutter so short pages (Contact) don't shift
     horizontally relative to tall pages that do show a scrollbar. */
  scrollbar-gutter: stable;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--type-body-md-regular);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  /* Sticky footer: short pages (e.g. Contact) push the footer to the viewport bottom */
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}
main { flex: 1 0 auto; }
img, svg, video { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.01em;
  margin: 0 0 .5em;
  color: var(--ink);
}
p { margin: 0 0 1.1em; }
:where(a):focus-visible,
:where(button, input, textarea, [tabindex]):focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ---------- Layout helpers ---------- */
.wrap { width: min(100% - 2.4rem, var(--wrap)); margin-inline: auto; }
.wrap--narrow { width: min(100% - 2.4rem, 760px); margin-inline: auto; }
.section { padding-block: clamp(2.4rem, 5vw, 4rem) clamp(2rem, 4vw, 3.2rem); }
.center { text-align: center; }

/* ---------- Skip link ---------- */
.skip-link {
  position: absolute; left: 12px; top: -60px;
  background: var(--ink); color: var(--bg);
  padding: .7rem 1.1rem; border-radius: var(--img-radius); z-index: 200;
  font-family: var(--font-display); font-weight: 500;
  transition: top .18s ease;
}
.skip-link:focus { top: 12px; }

/* ---------- Header / nav ---------- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  -webkit-backdrop-filter: saturate(160%) blur(12px);
  backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid var(--muted);
}
.nav {
  display: flex; align-items: center; gap: 1rem;
  min-height: var(--header-h);
}
.brand {
  display: inline-flex; align-items: center; min-height: 44px;
  font-family: var(--font-display);
  font-weight: 700; font-size: var(--type-body-lg-regular);
  letter-spacing: .16em; text-decoration: none; color: var(--ink);
  text-transform: uppercase; white-space: nowrap;
}
.nav-spacer { flex: 1; }
.nav-links { display: flex; align-items: center; gap: .2rem; list-style: none; margin: 0; padding: 0; }
.nav-links a {
  display: inline-flex; align-items: center; text-decoration: none;
  font-family: var(--font-display); font-weight: 500; text-transform: lowercase;
  font-size: var(--type-label-lg-medium); color: var(--ink-soft);
  padding: 0 .8rem; border-radius: var(--img-radius); min-height: 44px; /* target size */
  transition: color .15s ease, background .15s ease;
}
.nav-links a:hover { color: var(--ink); background: var(--accent-weak); }

/* Active indicator is a PAINTED underline (text-decoration), not a layout box —
   so the text stays vertically centred in the bar and never shifts between
   states. Small offset = tight gap. The brand uses the same treatment. */
.nav-links a[aria-current="page"], .brand[aria-current="page"] {
  color: var(--accent-ink);
  text-decoration: underline; text-decoration-color: var(--accent-ink);
  text-decoration-thickness: 2px; text-underline-offset: 5px;
}

.icon-btn {
  display: inline-grid; place-items: center;
  width: 44px; height: 44px; border-radius: 10px;
  background: transparent; border: 1px solid var(--muted);
  color: var(--ink); cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}
.icon-btn:hover { background: var(--accent-weak); border-color: var(--accent); }
.icon-btn svg { width: 20px; height: 20px; }
.theme-toggle .moon { display: none; }
:root[data-theme="dark"] .theme-toggle .sun { display: none; }
:root[data-theme="dark"] .theme-toggle .moon { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .sun { display: none; }
  :root:not([data-theme="light"]) .theme-toggle .moon { display: block; }
}

.nav-toggle { display: none; }

/* Mobile nav — hamburger + full-width dropdown at/below the 768px breakpoint. */
@media (max-width: 768px) {
  .nav-toggle { display: inline-grid; order: -2; }        /* hamburger first (left) */
  .brand { order: -1; }                                    /* then the wordmark */
  .theme-toggle { margin-left: auto; }                     /* toggle pushed to the right */
  .nav-spacer { display: none; }
  .nav-links {
    position: fixed; inset: var(--header-h) 0 auto 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--surface);
    border-bottom: 1px solid var(--muted);
    padding: .5rem 1.2rem 1.2rem;
    box-shadow: var(--shadow);
    transform: translateY(-8px); opacity: 0; pointer-events: none;
    transition: opacity .18s ease, transform .18s ease;
  }
  .nav-links.open { transform: none; opacity: 1; pointer-events: auto; }
  /* Plain text links in the dropdown — no rounded button fill and no dividers;
     keep the typeface, colour and the active underline. */
  .nav-links a { padding: .8rem .4rem; min-height: 0; border-radius: 0; }
  .nav-links a:hover { background: none; }
}

/* ---------- Hero (home) ----------
   Top padding matches .section-lead so the title lines up with every other page. */
.home-hero { padding-block: clamp(1.4rem, 3vw, 2.4rem) clamp(1rem, 2vw, 1.6rem); }
.home-hero-grid { display: grid; }
.home-featured { padding-top: clamp(1rem, 2vw, 1.6rem); }   /* tighten gap under the hero */
/* Tighter gap between the "Featured projects" heading and the tiles below. */
.home-featured .section-head { margin-bottom: clamp(.8rem, 1.8vw, 1.2rem); }
.home-hero h1 { font-size: var(--type-display-lg-semibold); max-width: 18ch; font-weight: 600; }
/* Intro copy (italic, a touch below Body Large). First sentence names the roles. */
.home-hero .lede {
  font-size: 1.125rem; color: var(--ink-soft); font-style: italic;
  max-width: 58ch; margin-top: 1.1rem; line-height: 1.55;
}
.home-hero .lede + .lede { margin-top: 1.2rem; }   /* extra gap between the two sentences */
.role-hl { color: var(--accent-ink); font-weight: 700; }
.home-cta { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: 2.2rem; }

/* ---------- Section intro ---------- */
.section-head { margin-bottom: clamp(1.4rem, 3vw, 2.4rem); }
.section-head .eyebrow {
  font-family: var(--font-display); font-weight: 500;
  text-transform: uppercase; letter-spacing: .22em;
  font-size: var(--type-label-md-medium); color: var(--accent-ink); margin-bottom: .6rem;
}
/* Every page's first title uses the same display H1 (display-lg, 600). */
.section-head h1 { font-size: var(--type-display-lg-semibold); font-weight: 600; }
.section-head h2 { font-size: var(--type-title-lg-medium); }   /* e.g. home "Selected projects" */
.section-head p { color: var(--ink-soft); margin-top: .2rem; font-size: var(--type-body-md-regular); }

/* Page-lead section: trims the space above the page title (Product, Filmmaking…) */
.section-lead { padding-block: clamp(1.4rem, 3vw, 2.4rem) clamp(2rem, 4vw, 3.2rem); }

/* ---------- Work grid ----------
   Two even tiles per row (halved gutter); collapses to one on narrow screens. */
.grid {
  display: grid; gap: clamp(.5rem, 1vw, .8rem);
  /* minmax(0,1fr) lets both tracks shrink evenly (a nowrap description can't set
     a min-content floor), so every grid shrinks smoothly like Filmmaking. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (max-width: 768px) { .grid { grid-template-columns: 1fr; } }
.card {
  position: relative; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--muted);
  overflow: clip; border-radius: var(--img-radius);      /* soft 8px corners on the tile */
  text-decoration: none; color: var(--ink);
  transition: box-shadow .22s ease, border-color .22s ease;
}
/* Hover: elevation + a stronger border (mirrors the focus affordance), no size change */
.card:hover { box-shadow: var(--shadow); border-color: var(--accent); }
.card:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
/* Fixed-ratio crop: absolutely-positioned image so a tall/short source is always
   cropped to the exact same box as every other thumbnail (Product, Art, etc.). */
.card-media { display: block; position: relative; aspect-ratio: 2 / 1; background: var(--bg-tint); overflow: hidden; }
.card-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.card-body { padding: .9rem 1.05rem 1rem; display: flex; flex-direction: column; gap: .2rem; flex: 1; }
.card-title { font-family: var(--font-display); font-weight: 600; font-size: var(--type-title-md-semibold); }
/* single line keeps every tile the same short height */
.card-desc { color: var(--muted-text); font-size: var(--type-body-md-regular); line-height: 1.4; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card-tag {
  align-self: flex-start; margin-top: .6rem;
  font-family: var(--font-display); font-size: var(--type-label-md-medium); font-weight: 500;
  text-transform: uppercase; letter-spacing: .12em;
  color: var(--accent-ink); background: var(--accent-weak);
  padding: .25rem .6rem; border-radius: 999px;
}
.card--soon .card-media img { filter: saturate(.85); }

/* ---------- Buttons ----------
   Two variants, amber throughout. Primary = solid amber; Secondary (.btn--ghost)
   = the same amber as an outline that fills on hover. Both use a fixed dark ink
   for text (amber is a light colour in both themes) so contrast stays AA. */
.btn {
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--font-display); font-weight: 500; font-size: var(--type-label-lg-medium);
  text-decoration: none; cursor: pointer;
  padding: .8rem 1.4rem; min-height: 48px; border-radius: 999px;
  border: 1px solid transparent;
  transition: background .15s ease, color .15s ease, border-color .15s ease, box-shadow .15s ease;
}
/* Primary: solid deep amber + WHITE text (bright amber can't carry white at AA,
   so the fill is deepened to #9c6100 → white 5.16:1); darker on hover. No border. */
.btn--primary { background: #9c6100; color: #fff; border-color: transparent; }
.btn--primary:hover { background: color-mix(in srgb, #9c6100 86%, #000); box-shadow: var(--shadow); }
/* Secondary: amber outline + amber text (both --accent-ink so the outline itself
   clears the 3:1 non-text minimum); a faint amber wash on hover (mirrors the
   primary's slight darkening). */
.btn--ghost { background: transparent; border-color: var(--accent-ink); color: var(--accent-ink); }
.btn--ghost:hover { background: var(--accent-weak); }
/* Inline arrow icon inside a button — sized to the text (see arrow_svg in build.pl). */
.btn-arrow { width: 1.15em; height: 1.15em; }

/* ---------- About ----------
   Grid areas keep one layout that reflows: on wide screens the title + body sit
   in the left column with the portrait spanning the right; on narrow screens the
   order becomes title → portrait → body. Row-gap = the title→content gap and is
   kept equal to a section page's (the Product-page standard). */
.about-grid {
  display: grid; align-items: start;
  column-gap: clamp(1.6rem, 4vw, 3.4rem); row-gap: 1.5rem;
  grid-template-columns: 1fr;
  grid-template-areas: "title" "portrait" "body";
}
@media (min-width: 769px) {
  .about-grid { grid-template-columns: 1fr 1fr; grid-template-areas: "title portrait" "body portrait"; }
}
.about-title { grid-area: title; margin: 0; font-size: var(--type-display-lg-semibold); font-weight: 600; }
.about-body { grid-area: body; }
/* Portrait — circle-cropped, sitting with generous margin in its column.
   Scrolls with the page (no sticky) so it never overlaps the text in one column. */
.about-portrait {
  grid-area: portrait; max-width: 416px; margin-inline: auto;
  border-radius: 50%; overflow: clip; box-shadow: var(--shadow);
}
.about-portrait img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; }
/* Lead line (Body Large) sits between the H1 and the running Body Medium copy */
.about-lead { font-size: var(--type-body-lg-regular); color: var(--ink); margin-bottom: 1.1rem; }
.about-body p { color: var(--ink-soft); font-size: var(--type-body-md-regular); }
/* Section headers (Education / Work) — orange, all-caps label style. Still <h2>
   so the heading outline (h1 › h2 › h3) stays intact for screen readers. */
/* One divider before each section header (so: before Education, and between
   Education and Work); the after-Work divider sits on .about-cta. No per-item
   rules. */
.about-section {
  font-family: var(--font-display); font-size: var(--type-label-lg-medium); font-weight: 600;
  text-transform: uppercase; letter-spacing: .14em; color: var(--accent-ink);
  margin: 1.2rem 0 1.2rem; padding-top: 1.8rem; border-top: 1px solid var(--muted);
}
.cv-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.cv-list li { display: grid; gap: .3rem; padding: .9rem 0; }
.cv-list li:first-child { padding-top: 0; }
/* Degree / job title — an <h3> (keeps the outline) styled as bold body text. */
.cv-list .role {
  font-family: var(--font-body); font-size: var(--type-body-md-regular); font-weight: 700;
  text-transform: none; letter-spacing: normal; line-height: 1.4; color: var(--ink); margin: 0;
}
.cv-list .org { font-size: var(--type-body-md-regular); color: var(--muted-text); margin: 0; }  /* 16px */
/* Closing divider after the Work section, then the centred button. */
.about-cta { text-align: center; margin-top: 1.2rem; padding-top: 2.4rem; border-top: 1px solid var(--muted); }

/* ---------- Writing ---------- */
/* Same two-column grid as the work pages (single column ≤768px). */
.papers {
  display: grid; gap: clamp(.5rem, 1vw, .8rem); align-items: start;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (max-width: 768px) { .papers { grid-template-columns: 1fr; } }
.paper {
  background: var(--surface); border: 1px solid var(--muted);
  border-radius: var(--img-radius); padding: clamp(1.4rem, 3vw, 2.4rem);
}
.paper h2 { font-size: var(--type-title-md-semibold); font-weight: 600; }
.paper dl { margin: 1.2rem 0 0; }
/* Tight coupling of a label to its description, generous gap before the next one */
.paper dt {
  font-family: var(--font-display); font-size: var(--type-label-md-semibold); font-weight: 600;
  text-transform: uppercase; letter-spacing: .14em; color: var(--accent-ink);
  margin-top: 1.35rem;
}
.paper dl > dt:first-of-type { margin-top: 0; }
.paper dd { margin: .2rem 0 0; color: var(--ink-soft); max-width: 82ch; }
.paper a { color: var(--accent-ink); text-underline-offset: 3px; }

/* ---------- Case study ----------
   One 1080px column. Hero, title, tagline, meta, and every figure span the full
   column; the running body text is a 720px measure centred within that column. */
.case-article { padding-block: clamp(0.8rem, 2vw, 1.6rem) clamp(2rem, 4vw, 3.2rem); }  /* trim space above hero */
.case-wrap { width: min(100% - 2.4rem, var(--wrap)); margin-inline: auto; }

/* Hero image (case studies) sits close to the back-nav below it. */
.case-hero { margin: 0 0 clamp(0.9rem, 2.5vw, 1.4rem); }
.case-hero img {
  display: block; width: 100%; aspect-ratio: 16 / 9;
  object-fit: cover; background: var(--bg-tint); border-radius: var(--img-radius);
}
/* Film hero video gets the same tight gap above the back-nav. */
.case-wrap > .case-embed:first-child { margin-top: 0; margin-bottom: clamp(0.9rem, 2.5vw, 1.4rem); }

/* Header spans the full 1080 column */
.case-head { margin-bottom: clamp(1.8rem, 4vw, 2.6rem); }
.case-head h1 { font-size: var(--type-display-lg-semibold); font-weight: 600; }

/* Back navigation (replaces the old breadcrumb) — a pronounced left arrow (not a
   link) + the linked destination page. The link matches the amber, underlined
   style of an active nav/breadcrumb link. Used on every detail + gallery page. */
.back-nav {
  display: flex; align-items: center; gap: .4rem;
  font-family: var(--font-display); font-weight: 400;
  font-size: var(--type-label-lg-medium);
  margin: 0 0 clamp(1.4rem, 3vw, 2rem);   /* generous gap down to the title */
  color: var(--accent-ink);
}
.back-nav .back-arrow { flex: 0 0 auto; }
.back-nav a {
  color: var(--accent-ink);
  text-decoration: underline; text-decoration-color: var(--accent);
  text-decoration-thickness: 1.5px; text-underline-offset: 3px;
  transition: color .15s ease, text-decoration-color .15s ease;
}
.back-nav a:hover { color: var(--ink); text-decoration-color: currentColor; }
.case-head .tagline { font-size: var(--type-body-md-regular); color: var(--ink-soft); margin-top: .25rem; }

/* Meta shares the 720px body-text measure (centred in the 1080 column).
   Single column of label | value rows; columns fractional; dd runs to the edge. */
.case-meta {
  max-width: var(--measure); margin: 0 auto clamp(2.2rem, 5vw, 3.4rem);
  display: grid; gap: 0; border-top: 1px solid var(--muted);
}
.case-meta .meta-item {
  display: grid; grid-template-columns: 1fr 4fr; gap: .4rem 2rem;   /* dt ~20% : dd ~80% */
  padding: .95rem 0; border-bottom: 1px solid var(--muted);
}
.case-meta dt {
  font-family: var(--font-display); font-size: var(--type-label-md-semibold); font-weight: 600;
  text-transform: uppercase; letter-spacing: .12em; color: var(--accent-ink); padding-top: .15rem;
}
.case-meta dd { margin: 0; color: var(--ink-soft); font-size: var(--type-body-md-regular); line-height: 1.5; }
.case-meta dd a { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 600px) {
  .case-meta .meta-item { grid-template-columns: 1fr; gap: .2rem; }  /* stacks (looks good) */
}

/* Body: full-width column; running text is centred at the shared --measure
   (720px), while figures + captions fill the full column. Every text-level
   child uses the same token, so all body text lines up exactly. */
.case-body > :where(h2, h3, p, ul, ol, blockquote) { max-width: var(--measure); margin-inline: auto; }
.case-body > h2 {
  font-size: var(--type-title-lg-medium); margin-top: 2.4em;
}
.case-body > h2:first-child { margin-top: 0; }
.case-body > h3 { font-size: var(--type-title-md-medium); margin-top: 2em; }
.case-body p, .case-body li { color: var(--ink-soft); }
.case-body ul, .case-body ol { padding-left: 1.2rem; margin: 0 auto 1.2em; display: grid; gap: .5rem; }
.case-body a { color: var(--accent-ink); text-underline-offset: 3px; }

/* Inline highlight — a partial-height "highlighter" band across the lower
   ~45% of the line (not a full block), with no extra space before/after.
   Text keeps the body colour; the band colour is themed (dark #71551E gives
   4.72:1 against the body text — AA). */
.lead-label {
  background-image: linear-gradient(to top, var(--highlight-bg) 45%, transparent 45%);
  border-radius: 0;
  box-decoration-break: clone; -webkit-box-decoration-break: clone;
}

/* Figures fill the column (max 1080), no rounded corners */
/* Embedded video / slide decks — full-width and responsive via a padding-ratio
   box (16:9). The Google Slides variant adds the ~40px control bar height so the
   slide itself renders full-bleed to the column edges (no side letterboxing). */
.case-embed {
  margin: clamp(1.8rem, 4vw, 2.8rem) 0; width: 100%;
  position: relative; height: 0; padding-top: 56.25%;
}
.case-embed--slides { padding-top: calc(56.25% + 36px); }
.case-embed iframe {
  position: absolute; inset: 0; width: 100%; height: 100%;
  border: 1px solid var(--muted); background: var(--bg-tint);
}

.figure { margin: clamp(1.8rem, 4vw, 2.8rem) 0; width: 100%; }
.figure img {
  width: 100%; border-radius: var(--img-radius); border: 1px solid var(--muted);
  background: var(--bg-tint);
}
.figure figcaption {
  margin-top: .7rem; font-size: var(--type-label-md-medium); color: var(--muted-text);
  font-style: italic;
}
/* Video figure — a 16:9 embed framed to look exactly like an image figure. */
.figure--video .figure-video {
  position: relative; width: 100%; height: 0; padding-top: 56.25%;
  border-radius: var(--img-radius); overflow: hidden; border: 1px solid var(--muted);
  background: var(--bg-tint);
}
.figure--video .figure-video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* Two-up figure row (each figure keeps its own caption underneath its image). */
.figure-pair {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(.6rem, 1.6vw, 1.1rem); align-items: start;
  margin: clamp(1.8rem, 4vw, 2.8rem) 0;
}
.figure-pair .figure { margin: 0; }
@media (max-width: 768px) { .figure-pair { grid-template-columns: 1fr; } }

/* Prev/next project nav */
.case-nav {
  display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between;
  border-top: 1px solid var(--muted); margin-top: 3rem; padding-top: 2rem;
}
/* On pages with no body (most films), the nav follows the case-meta directly —
   drop the extra top divider so there isn't a doubled rule after the meta. */
.case-nav--flush { border-top: 0; margin-top: clamp(1.4rem, 3vw, 2rem); padding-top: 0; }

/* ---------- Contact ----------
   A single left-aligned column: the "Say hello!" headline (mailto link) plus a
   row of social icon buttons. (No contact form — email is the call to action.) */
.contact-aside h1 { font-size: var(--type-display-lg-semibold); font-weight: 600; }
.contact-hello { max-width: 22ch; }
.contact-hello a { color: var(--accent-ink); text-decoration: none; }
.contact-hello a:hover { text-decoration: underline; text-underline-offset: 4px; }
.contact-aside p { color: var(--ink-soft); }
.contact-social { display: flex; gap: .55rem; list-style: none; margin: 1.8rem 0 0; padding: 0; }
.contact-social a {
  display: grid; place-items: center; width: 48px; height: 48px;
  border-radius: 12px; color: var(--ink-soft); border: 1px solid var(--muted);
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.contact-social a:hover { color: var(--accent-ink); border-color: var(--accent); background: var(--accent-weak); }
.contact-social svg { width: 22px; height: 22px; }

/* ---------- Footer ---------- */
.site-footer {
  border-top: 1px solid var(--muted); margin-top: clamp(1.4rem, 3vw, 2.4rem);
  padding-block: clamp(1.8rem, 3.5vw, 2.6rem);   /* slightly shorter */
  background: var(--bg-tint);
}
.footer-grid {
  display: flex; flex-wrap: wrap; gap: 1.2rem 2rem;
  align-items: center; justify-content: space-between;
}
.footer-lead { display: grid; gap: .3rem; }
.footer-brand {
  font-family: var(--font-display); font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; font-size: var(--type-body-lg-regular);
  text-decoration: none; color: var(--ink);
}
.footer-copy { margin: 0; color: var(--muted-text); font-size: var(--type-label-md-medium); }
.footer-social { display: flex; gap: .5rem; list-style: none; margin: 0; padding: 0; }
.footer-social a {
  display: grid; place-items: center; width: 44px; height: 44px;
  border-radius: 10px; color: var(--ink-soft); border: 1px solid var(--muted);
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.footer-social a:hover { color: var(--accent-ink); border-color: var(--accent); background: var(--accent-weak); }
.footer-social svg { width: 20px; height: 20px; }

/* ---------- Other Works carousel ----------
   CSS scroll-snap gallery: works as a native swipe/scroll without JS; the
   buttons, counter and thumbnails are progressive enhancements. */
.carousel-head { margin-bottom: clamp(1.2rem, 3vw, 2rem); }
.carousel-head h1 { font-size: var(--type-display-lg-semibold); font-weight: 600; }
.carousel-head p { color: var(--ink-soft); margin-top: .2rem; }

.carousel-viewport {
  overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; -ms-overflow-style: none;
  /* no frame — images sit directly on the page */
}
.carousel-viewport::-webkit-scrollbar { display: none; }
.carousel-track { display: flex; margin: 0; padding: 0; list-style: none; }
.carousel-slide { flex: 0 0 100%; scroll-snap-align: center; }
.carousel-slide figure { margin: 0; display: grid; justify-items: center; gap: .8rem; padding: clamp(1rem, 2.5vw, 2rem); }
.carousel-slide img {
  width: auto; max-width: 100%; height: min(72vh, 760px);
  object-fit: contain; border-radius: var(--img-radius);
}
.carousel-slide figcaption {
  color: var(--muted-text); font-size: var(--type-label-md-medium);
  font-style: italic; text-align: center; max-width: 60ch;
}
.carousel-controls { display: flex; align-items: center; justify-content: center; gap: 1.4rem; margin-top: 1rem; }
.carousel-nav {
  width: 48px; height: 48px; border-radius: 50%; border: 1px solid var(--muted);
  background: var(--surface); color: var(--ink); font-size: 1.6rem; line-height: 1;
  cursor: pointer; display: grid; place-items: center;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.carousel-nav:hover { background: var(--accent-weak); border-color: var(--accent); color: var(--accent-ink); }
.carousel-status {
  font-family: var(--font-display); font-size: var(--type-body-md-regular);
  color: var(--ink-soft); min-width: 6ch; text-align: center; margin: 0;
}
.carousel-thumbs {
  display: flex; gap: .4rem; overflow-x: auto; padding: .9rem 0 .3rem; margin-top: .4rem;
  scrollbar-width: thin;
}
.carousel-thumb {
  flex: 0 0 auto; width: 88px; height: 58px; padding: 0; cursor: pointer;
  border: 2px solid transparent; border-radius: var(--img-radius); overflow: hidden;
  background: var(--bg-tint); opacity: .5; transition: opacity .15s ease, border-color .15s ease;
}
.carousel-thumb img { width: 100%; height: 100%; object-fit: cover; }
.carousel-thumb:hover { opacity: .85; }
.carousel-thumb[aria-current="true"] { opacity: 1; border-color: var(--accent); }

/* ---------- Utilities ---------- */
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.stack > * + * { margin-top: 1.2rem; }
.mt-lg { margin-top: clamp(2.4rem, 6vw, 4rem); }
