/* ============================================================
   Elyne Villamor — main.css
   Editorial, warm, romantic. See design-system/MASTER.md.
   ============================================================ */

/* ---------- 1. Reset ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
body { min-height: 100dvh; line-height: 1.5; }
img, picture, svg, video { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
input, textarea, select { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--rust); outline-offset: 3px; border-radius: 2px; }
::selection { background: var(--rust); color: var(--ivory); }

/* ---------- 2. Tokens ---------- */
:root {
  /* Color */
  --ivory: #F5EFE4;
  --ivory-warm: #EBE1D0;
  --ivory-veil: rgba(245, 239, 228, 0.72);
  --navy: #1E2A47;
  --navy-deep: #141E36;
  --rust: #A84B1C;
  --rust-hover: #8A3C15;
  --terracotta: #C97847;
  --burgundy: #6B1E23;
  --sage: #6D7860;
  --sage-mist: #A9B4A0;
  --ink: #0F1626;

  /* ---- Warm Autumn palette (2026 re-skin) ----
     Neutrals, warms, cools. Espresso is depth only — never the main colour. */
  --wa-cream: #F7F1E4;
  --wa-linen: #D9C9AC;
  --wa-almond: #C7B393;
  --wa-rust: #A84B1C;
  --wa-brick: #A3341A;
  --wa-burnt: #BF7415;
  --wa-caramel: #A96C1E;
  --wa-honey: #E4A31A;
  --wa-teal: #0F5158;
  --wa-olive: #4B6A25;
  --wa-sage: #2E4A3E;
  --wa-espresso: #2C2119;

  /* Ink — the site's main colour. Swap this one line to change it. */
  --wa-ink: var(--wa-sage);
  --wa-ink-soft: #5A6B60;
  --wa-ground: var(--wa-sage);

  /* Paper grain, self-contained */
  --wa-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");

  /* Type */
  --font-wordmark: "Libre Baskerville", Georgia, serif;
  --font-display: "Libre Baskerville", Georgia, serif;
  --font-body: Montserrat, "Helvetica Neue", Arial, sans-serif;
  --font-script: "Playfair Display", Georgia, serif;

  /* ---- Four-face system (2026 re-skin) ----
     Libre Baskerville: CAPS only.  Playfair: never all-caps.
     Poppins: CAPS only, short strings.  Montserrat: all body copy. */
  --wa-display: "Libre Baskerville", Georgia, serif;
  --wa-serif: "Playfair Display", Georgia, serif;
  --wa-label: Poppins, "Helvetica Neue", Arial, sans-serif;
  --wa-body: Montserrat, "Helvetica Neue", Arial, sans-serif;
  /* Long-form body serif. Gentium is the softest of the three we compared —
     rounded terminals and gentle contrast, which gives the eye a rest between
     Libre Baskerville and Playfair. */
  --wa-read: "Gentium Book Plus", Georgia, serif;

  /* Space (4px base) */
  --space-1: 0.25rem; --space-2: 0.5rem;  --space-3: 0.75rem;
  --space-4: 1rem;    --space-5: 1.5rem;  --space-6: 2rem;
  --space-7: 3rem;    --space-8: 4rem;    --space-9: 6rem;
  --space-10: 9rem;   --space-11: 12rem;

  /* Motion */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-inout: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --dur-micro: 200ms;
  --dur-standard: 400ms;
  --dur-expressive: 700ms;
  --dur-hero: 1200ms;

  /* Layout */
  --max-outer: 1440px;
  --max-reading: 1120px;
  --max-prose: 72ch;
  /* Height reserved for the fixed masthead. Inner pages offset their first
     section by this, so it must track the masthead's real height. */
  --nav-height: 112px;

  /* Cinematic hero — WARM near-black (burgundy/rust dominant) */
  --cine-ink: #0C0407;              /* near-black with a burgundy heart */
  --cine-ink-2: #17070C;
  --cine-ink-3: #22101A;
  --cine-warm: #3A0F14;             /* deep burgundy for atmosphere */
  --cine-warm-2: #6B1E23;           /* burgundy mid */
  --cine-warm-3: #A84B1C;           /* rust */
  --cine-mist: rgba(245, 232, 218, 0.9);    /* warm ivory for text */
  --cine-mist-soft: rgba(245, 232, 218, 0.6);
  --cine-mist-faint: rgba(245, 232, 218, 0.18);
  --cine-cyan: #5FC7FF;             /* neon blue — kept only for tiny HUD accents */
  --cine-cyan-hot: #7FD7FF;
  --cine-cyan-glow: rgba(95, 199, 255, 0.55);
  --cine-hairline: rgba(245, 232, 218, 0.14);
}

/* ---------- 3. Base ---------- */
html { scroll-behavior: smooth; }
@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; }
}

body {
  background: var(--ivory);
  color: var(--navy-deep);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.7;
  font-feature-settings: "ss01", "ss02", "cv11";
  overflow-x: hidden;
}

/* Grain texture that lives on top of every ivory surface */
body::before {
  content: "";
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 1;
  opacity: 0.35;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240' viewBox='0 0 240 240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.12  0 0 0 0 0.16  0 0 0 0 0.27  0 0 0 0.08 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}

/* ---------- 4. Typography ---------- */
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 400; color: var(--navy); letter-spacing: -0.01em; }

.eyebrow {
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--navy);
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
}
.eyebrow::before {
  content: "";
  width: 32px; height: 1px;
  background: currentColor;
}
.eyebrow.no-line::before { display: none; }

.display-hero {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(3.5rem, 9vw, 8.5rem);
  line-height: 0.98;
  letter-spacing: -0.02em;
  color: var(--navy-deep);
}
.display-hero em, .italic-accent {
  font-style: italic;
  color: var(--burgundy);
  font-weight: 400;
}

h1, .h1 { font-size: clamp(2.5rem, 5.5vw, 5rem); line-height: 1.05; }
h2, .h2 { font-size: clamp(2rem, 4vw, 3.5rem); line-height: 1.1; }
h3, .h3 { font-size: clamp(1.5rem, 2.4vw, 2.25rem); line-height: 1.2; }

.lead {
  font-family: var(--font-body);
  font-size: clamp(1.125rem, 1.4vw, 1.375rem);
  line-height: 1.55;
  color: var(--navy);
  max-width: 42ch;
}

p { max-width: var(--max-prose); }
p + p { margin-top: 1em; }

/* ---------- 5. Layout ---------- */
.container { width: min(var(--max-outer), 100% - 2 * clamp(1.25rem, 5vw, 4rem)); margin-inline: auto; position: relative; }
.container-reading { width: min(var(--max-reading), 100% - 2 * clamp(1.25rem, 5vw, 4rem)); margin-inline: auto; }

section { padding-block: clamp(6rem, 12vw, 12rem); position: relative; }
section.tight { padding-block: clamp(4rem, 8vw, 8rem); }

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 6rem); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.5rem, 3vw, 3rem); }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(1.25rem, 2.4vw, 2rem); }
@media (max-width: 900px) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .grid-2.keep-mobile { grid-template-columns: 1fr 1fr; }
}

/* ---------- 6. Nav ---------- */
.nav {
  position: fixed; top: 0; left: 0; right: 0;
  z-index: 100;
  height: var(--nav-height);
  display: flex; align-items: center;
  background: var(--ivory-veil);
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  border-bottom: 1px solid rgba(30, 42, 71, 0.06);
  transition: background var(--dur-standard) var(--ease-inout), transform var(--dur-standard) var(--ease-inout);
}
.nav.is-hidden { transform: translateY(-100%); }
.nav__inner { width: 100%; display: flex; align-items: center; justify-content: space-between; }
.nav__brand {
  font-family: var(--font-wordmark);
  font-weight: 400;
  font-size: 1.5rem;
  letter-spacing: 0.04em;
  color: var(--navy-deep);
  line-height: 1;
  position: relative;
}
.nav__brand::after {
  content: "villamor";
  position: absolute;
  bottom: -10px; left: 0;
  font-family: var(--font-body);
  font-size: 0.55rem;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: var(--rust);
  opacity: 0.8;
}
.nav__links { display: flex; gap: 2.5rem; align-items: center; list-style: none; }
.nav__link {
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--navy);
  position: relative;
  padding-block: 0.5rem;
}
.nav__link::after {
  content: "";
  position: absolute;
  bottom: 0; left: 0;
  width: 100%; height: 1px;
  background: var(--rust);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-standard) var(--ease-inout);
}
.nav__link:hover::after,
.nav__link.is-active::after { transform: scaleX(1); }
.nav__link.is-active { color: var(--rust); }

.nav__cta {
  padding: 0.65rem 1.5rem;
  border: 1px solid var(--navy);
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--navy);
  position: relative; overflow: hidden;
  /* The fill grows from the bottom as a background layer rather than a
     z-index:-1 pseudo-element — that escaped the clip under the nav's
     backdrop-filter and hung below the pill. */
  background-image: linear-gradient(var(--navy), var(--navy));
  background-repeat: no-repeat;
  background-position: 50% 100%;
  background-size: 100% 0%;
  transition:
    background-size var(--dur-standard) var(--ease-out),
    color var(--dur-standard) var(--ease-inout),
    border-color var(--dur-standard) var(--ease-inout);
}
.nav__cta:hover { background-size: 100% 100%; color: var(--ivory); }

.nav__toggle { display: none; width: 40px; height: 40px; position: relative; }
.nav__toggle span { position: absolute; left: 8px; right: 8px; height: 1px; background: var(--navy); transition: transform var(--dur-standard) var(--ease-inout), opacity var(--dur-micro); }
.nav__toggle span:nth-child(1) { top: 15px; }
.nav__toggle span:nth-child(2) { top: 24px; }
.nav.is-open .nav__toggle span:nth-child(1) { top: 20px; transform: rotate(45deg); }
.nav.is-open .nav__toggle span:nth-child(2) { top: 20px; transform: rotate(-45deg); }

@media (max-width: 900px) {
  .nav__toggle { display: block; }
  .nav__links {
    position: fixed;
    inset: var(--nav-height) 0 0 0;
    background: var(--ivory);
    flex-direction: column;
    justify-content: center;
    gap: 2rem;
    transform: translateX(100%);
    transition: transform var(--dur-expressive) var(--ease-out);
    padding-inline: 2rem;
  }
  .nav__links .nav__link { font-size: 1.5rem; font-family: var(--font-display); text-transform: none; letter-spacing: 0; }
  .nav.is-open .nav__links { transform: translateX(0); }
  .nav__cta { align-self: flex-start; }
}

/* ---------- 7. Custom cursor ---------- */
/* Hexagon pointer trail. Sits above the page and below the cursor itself,
   and never eats a click. Hidden on touch and for reduced motion. */
.hex-trail {
  position: fixed; inset: 0;
  /* Above everything the page can put on screen, the message bubble included:
     a pointer that something else covers stops being a pointer. */
  z-index: 2147483004;
  pointer-events: none;
}
@media (hover: none), (pointer: coarse) { .hex-trail { display: none; } }
@media (prefers-reduced-motion: reduce) { .hex-trail { display: none; } }

.cursor-dot, .cursor-ring {
  position: fixed;
  top: 0; left: 0;
  pointer-events: none;
  z-index: 2147483005;          /* the very top — nothing draws over the pointer */
  will-change: transform;
}
/* Hexagonal too — there is no circle anywhere in the pointer now. */
.cursor-dot {
  width: 7px; height: 7px;
  background: var(--rust);
  clip-path: polygon(50% 0%, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%);
  transform: translate(-50%, -50%);
}
/* The hexagon. No border on the box — the shape is the SVG, so the outline
   follows the six sides instead of a square around them. */
.cursor-ring {
  width: 34px; height: 34px;
  transform: translate(-50%, -50%);
  transition: width var(--dur-standard) var(--ease-out),
              height var(--dur-standard) var(--ease-out),
              opacity var(--dur-standard) var(--ease-out);
}
.cursor-ring svg { width: 100%; height: 100%; display: block; overflow: visible; }
.cursor-ring polygon {
  fill: none;
  stroke: var(--rust);
  stroke-width: 1.4;
  vector-effect: non-scaling-stroke;   /* stays hairline as the hex grows */
  opacity: 0.7;
}
.cursor-ring.is-hover { width: 60px; height: 60px; }
.cursor-ring.is-hover polygon { opacity: 1; fill: rgba(168, 75, 28, 0.1); }
.cursor-ring.is-text { width: 16px; height: 34px; }
.cursor-ring.is-text polygon { opacity: 0.45; }
@media (hover: none), (pointer: coarse), (prefers-reduced-motion: reduce) {
  .cursor-dot, .cursor-ring { display: none; }
  * { cursor: auto !important; }
}
/* ============================================================
   MASTHEAD — centred wordmark, nav split either side
   ============================================================ */
.masthead {
  min-height: var(--nav-height);
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  padding: 1.15rem 2.5rem 1.05rem;
  background: rgba(245, 242, 235, 0.86);
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  border-bottom: 1px solid rgba(30, 42, 71, 0.07);
  transition: transform 500ms var(--ease-out), background 400ms var(--ease-out);
}
.masthead.is-hidden { transform: translateY(-100%); }

.masthead__est {
  display: block;
  text-align: center;
  font-family: var(--wa-label), sans-serif;
  font-size: 0.56rem;
  letter-spacing: 0.38em;
  text-transform: uppercase;
  color: var(--navy);
  opacity: 0.55;
  margin-bottom: 0.5rem;
}

.masthead__row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: clamp(1.5rem, 5vw, 4rem);
  max-width: var(--max-outer);
  margin: 0 auto;
}
.masthead__side { display: flex; align-items: center; gap: 0.9rem; }
.masthead__side.left  { justify-content: flex-end; }
.masthead__side.right { justify-content: flex-start; }
.masthead__slash { color: var(--navy); opacity: 0.35; font-size: 0.95rem; }

/* The wordmark sits dead centre */
.masthead__mark { display: block; line-height: 0; }
.masthead__mark img {
  height: clamp(38px, 4.4vw, 58px);
  width: auto;
  display: block;
}
/* On the home page the wordmark is the H1 (15 Sep 2026). A heading brings its
   own margin, size and line height; none of it may move the masthead. */
h1.masthead__h1 { margin: 0; font-size: inherit; line-height: 0; letter-spacing: normal; }
.masthead__home { display: block; line-height: 0; }

/* Nav items — serif small caps, understated until hovered */
.masthead__link {
  position: relative;
  /* Poppins caps want smaller and wider than the serif they replaced —
     at the old 1.2rem/0.10em they read as heavy and cramped. */
  font-family: var(--wa-label), sans-serif;
  font-size: clamp(0.62rem, 0.8vw, 0.76rem);
  font-weight: 400;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--navy);
  padding: 0.2rem 0;
  white-space: nowrap;
  transition: color 300ms var(--ease-out);
}
.masthead__link::after {
  content: "";
  position: absolute;
  left: 0; right: 100%;
  bottom: -2px;
  height: 1px;
  background: var(--rust);
  transition: right 420ms var(--ease-out);
}
.masthead__link:hover { color: var(--rust); }
.masthead__link:hover::after { right: 0; }
.masthead__link.is-active { color: var(--rust); }
.masthead__link.is-active::after { right: 0; background: var(--rust); opacity: 0.5; }

/* Hover caption — the descriptive line that appears under PURPOSE / PASSION */
.masthead__link[data-caption]::before {
  content: attr(data-caption);
  position: absolute;
  top: calc(100% + 0.55rem);
  left: 50%;
  transform: translate(-50%, -4px);
  font-family: var(--wa-serif);
  font-style: italic;
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--rust);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 340ms var(--ease-out), transform 340ms var(--ease-out);
}
.masthead__link[data-caption]:hover::before,
.masthead__link[data-caption]:focus-visible::before {
  opacity: 0.9;
  transform: translate(-50%, 0);
}

.masthead__toggle { display: none; }

@media (max-width: 900px) {
  :root { --nav-height: 132px; }        /* stacks to two rows on narrow screens */
  .masthead { padding: 0.8rem 1.1rem; }
  .masthead__est { font-size: 0.5rem; letter-spacing: 0.28em; margin-bottom: 0.35rem; }
  .masthead__row { grid-template-columns: 1fr; justify-items: center; gap: 0.65rem; }
  .masthead__mark { order: -1; }
  .masthead__mark img { height: 34px; }
  .masthead__side { gap: 0.7rem; }
  .masthead__link { font-size: 0.82rem; letter-spacing: 0.08em; }
  /* Captions would collide at this width */
  .masthead__link[data-caption]::before { display: none; }

  /* ---- one line: HOME / PURPOSE / PASSION / CONTACT (hers, 16 Sep 2026) ----
     "Ampanget ng link, dapat isang linya lang ang Home hanggang Contact." The
     wordmark keeps its own row above; the two halves of the menu now share the
     row beneath it, joined by the same slash that sits inside each half. */
  .masthead__row { grid-template-columns: auto auto; justify-content: center;
    column-gap: 0.7rem; row-gap: 0.65rem; }
  .masthead__mark { grid-column: 1 / -1; justify-self: center; }
  .masthead__side.left  { justify-content: flex-end; }
  .masthead__side.right { justify-content: flex-start; }
  .masthead__side.right::before { content: "/"; color: var(--navy); opacity: 0.35;
    font-size: 0.95rem; margin-right: 0; }
}
/* the narrowest phones: the same line, a touch tighter so it never wraps */
@media (max-width: 380px) {
  .masthead__link { font-size: 0.74rem; letter-spacing: 0.06em; }
  .masthead__side { gap: 0.45rem; }
  .masthead__row { column-gap: 0.45rem; }
}

body.has-cursor, body.has-cursor * { cursor: none; }
/* ...but keep the real arrow over the hero: the pointer drives the portrait,
   so you need to see exactly where it is. */
body.has-cursor .hero-cinema, body.has-cursor .hero-cinema * { cursor: default; }
.hero-cinema .cursor-dot, .hero-cinema .cursor-ring { display: none; }

/* ---------- 8. Preloader ---------- */
/* The arrival. The film frame's four camera marks sit white in the corners
   for a beat, then crawl out and close into one honey hairline while the
   hexagon draws itself in the middle; the dark and the blur then leave
   together, so the page arrives rather than is uncovered.

   It is not an opaque ground. The page is behind it the whole time, held
   dark and out of focus — which is what lets the picture resolve instead of
   being revealed by something sliding away.

   --pre-hold  the beat the marks stay white and still
   --pre-close how long they take to close, and the hexagon to draw
   --pre-clear how long the dark and the blur take to leave
   Together they set how long the arrival lasts; main.js holds the page for
   the same span, so shortening these shortens the wait. */
.preloader {
  --pre-hold: 300ms;
  --pre-close: 850ms;
  --pre-clear: 900ms;
  --pre-inset: clamp(18px, 3.4vmin, 44px);
  --pre-tick: clamp(20px, 3.6vmin, 42px);
  position: fixed; inset: 0;
  z-index: 200;
  pointer-events: none;
  background: rgba(20, 30, 54, 0.92);
  -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px);
  animation: preloader-clear var(--pre-clear) var(--ease-out) forwards;
  animation-delay: calc(var(--pre-hold) + var(--pre-close) * 0.76);
  transition: opacity 500ms var(--ease-out), visibility 0s linear 500ms;
}
.preloader.is-done { opacity: 0; visibility: hidden; }
@keyframes preloader-clear {
  from { background: rgba(20, 30, 54, 0.92);
         -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px); }
  to   { background: rgba(20, 30, 54, 0);
         -webkit-backdrop-filter: blur(0px);  backdrop-filter: blur(0px); }
}

/* the frame, and everything drawn on it, stands down once the page is here */
.preloader__frame {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  animation: preloader-frameout calc(var(--pre-close) * 0.9) var(--ease-out) forwards;
  animation-delay: calc(var(--pre-hold) + var(--pre-close));
}
@keyframes preloader-frameout { to { opacity: 0; } }

/* The four marks. White first — and they have to be SEEN white, so they hold
   still for --pre-hold before anything moves: the easing below covers most of
   its distance almost at once, and without that beat they were honey and
   half-way out before the eye had them at all. */
.preloader__tick {
  position: absolute;
  width: var(--pre-tick); height: var(--pre-tick);
  border: 0 solid rgba(247, 241, 228, 0.9);
  animation: preloader-close var(--pre-close) cubic-bezier(0.16, 1, 0.3, 1) var(--pre-hold) forwards,
             preloader-warm 320ms ease var(--pre-hold) forwards;
}
.preloader__tick--t1 { left: var(--pre-inset);  top: var(--pre-inset);
  border-left-width: 1px;  border-top-width: 1px; }
.preloader__tick--t2 { right: var(--pre-inset); top: var(--pre-inset);
  border-right-width: 1px; border-top-width: 1px; }
.preloader__tick--t3 { left: var(--pre-inset);  bottom: var(--pre-inset);
  border-left-width: 1px;  border-bottom-width: 1px; }
.preloader__tick--t4 { right: var(--pre-inset); bottom: var(--pre-inset);
  border-right-width: 1px; border-bottom-width: 1px; }
@keyframes preloader-close {
  to { width: calc(50% - var(--pre-inset)); height: calc(50% - var(--pre-inset)); }
}
@keyframes preloader-warm { to { border-color: var(--wa-honey, #E4A31A); } }

/* the hexagon, drawing itself in the middle as the marks travel */
.preloader__hex { width: clamp(64px, 9vmin, 132px); aspect-ratio: 1; }
.preloader__hex polygon {
  fill: none; stroke: var(--wa-honey, #E4A31A); stroke-width: 1.2;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: 400; stroke-dashoffset: 400;
  animation: preloader-draw var(--pre-close) cubic-bezier(0.16, 1, 0.3, 1) var(--pre-hold) forwards;
}
@keyframes preloader-draw { to { stroke-dashoffset: 0; } }

/* The pointer draws a hexagon of its own, and until the mouse is first moved
   it sits at the centre of the viewport — exactly where the arrival's hexagon
   draws. Two hexagons on top of one another read as a mistake, so the pointer
   waits for the page it belongs to. body.is-loading is removed with the
   preloader, so this lifts at the same moment. */
body.is-loading .cursor-dot,
body.is-loading .cursor-ring,
body.is-loading .hex-trail { opacity: 0; }
.cursor-dot, .cursor-ring, .hex-trail { transition: opacity 400ms var(--ease-out); }

/* Motion is unwelcome: no marks, no hexagon, no blur — just a ground that
   goes, which main.js clears as soon as the page is ready. */
@media (prefers-reduced-motion: reduce) {
  .preloader { animation: none; background: var(--ivory);
    -webkit-backdrop-filter: none; backdrop-filter: none; }
  .preloader__frame { display: none; }
}

/* ---------- 9. Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 0.75rem;
  padding: 1rem 2rem;
  border-radius: 999px;
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  position: relative; overflow: hidden;
  transition: color var(--dur-standard) var(--ease-inout), border-color var(--dur-standard) var(--ease-inout);
  isolation: isolate;
}
.btn::before {
  content: "";
  position: absolute; inset: 0;
  transform: translateY(101%);
  transition: transform var(--dur-standard) var(--ease-out);
  z-index: -1;
}
.btn:hover::before { transform: translateY(0); }
.btn svg { width: 16px; height: 16px; transition: transform var(--dur-standard) var(--ease-out); }
.btn:hover svg { transform: translateX(4px); }

.btn--primary { background: var(--navy); color: var(--ivory); }
.btn--primary::before { background: var(--rust); }
.btn--ghost { border: 1px solid var(--navy); color: var(--navy); }
.btn--ghost::before { background: var(--navy); }
.btn--ghost:hover { color: var(--ivory); }
.btn--ghost-on-dark { border: 1px solid var(--ivory); color: var(--ivory); }
.btn--ghost-on-dark::before { background: var(--ivory); }
.btn--ghost-on-dark:hover { color: var(--navy); }

.link-underline {
  color: var(--rust);
  font-weight: 500;
  position: relative;
  padding-bottom: 2px;
}
.link-underline::after {
  content: "";
  position: absolute;
  bottom: 0; left: 0;
  height: 1px; width: 100%;
  background: currentColor;
  transform-origin: right center;
  transform: scaleX(1);
  transition: transform var(--dur-standard) var(--ease-inout);
}
.link-underline:hover::after {
  transform-origin: left center;
  transform: scaleX(0);
  animation: link-redraw var(--dur-standard) var(--ease-inout) forwards var(--dur-standard);
}
@keyframes link-redraw { from { transform: scaleX(0); transform-origin: left; } to { transform: scaleX(1); transform-origin: left; } }

/* ---------- 10. Reveal (scroll) ---------- */
[data-reveal] { opacity: 0; transform: translateY(28px); transition: opacity 900ms var(--ease-out), transform 900ms var(--ease-out); }
[data-reveal].is-visible { opacity: 1; transform: translateY(0); }
[data-reveal="mask"] {
  opacity: 1;
  clip-path: inset(0 100% 0 0);
  transform: none;
  transition: clip-path 1200ms var(--ease-out);
}
[data-reveal="mask"].is-visible { clip-path: inset(0 0 0 0); }
[data-reveal="up-slow"] { transition-duration: 1400ms; }
[data-stagger] > * { opacity: 0; transform: translateY(24px); transition: opacity 700ms var(--ease-out), transform 700ms var(--ease-out); }
[data-stagger].is-visible > * { opacity: 1; transform: translateY(0); }

/* Split text hero */
.split-word { display: inline-block; overflow: hidden; vertical-align: baseline; }
.split-word > span { display: inline-block; transform: translateY(105%); transition: transform 1200ms var(--ease-out); }
.split-word.is-visible > span { transform: translateY(0); }

/* ---------- 11a. Hero — Cinematic (Home) ---------- */
.hero-cine {
  position: relative;
  min-height: 100dvh;
  color: var(--ivory);
  overflow: hidden;
  isolation: isolate;
  background:
    radial-gradient(ellipse 900px 700px at 78% 42%, rgba(107, 30, 35, 0.42) 0%, transparent 62%),
    radial-gradient(ellipse 700px 900px at 12% 92%, rgba(168, 75, 28, 0.22) 0%, transparent 58%),
    linear-gradient(180deg, #08101F 0%, #0F1930 45%, #16223D 100%);
}
.hero-cine::before {
  /* film grain */
  content: "";
  position: absolute; inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.55;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='300'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.95  0 0 0 0 0.9  0 0 0 0 0.85  0 0 0 0.06 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}
.hero-cine__stage {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
  perspective: 1400px;
}
.hero-cine__mark {
  font-family: var(--font-wordmark);
  font-weight: 400;
  font-size: clamp(18rem, 38vw, 52rem);
  line-height: 0.72;
  letter-spacing: -0.055em;
  color: transparent;
  -webkit-text-stroke: 1px rgba(245, 239, 228, 0.07);
  white-space: nowrap;
  user-select: none;
  pointer-events: none;
  transform-origin: center center;
  will-change: transform;
  transition: transform 900ms cubic-bezier(0.16, 1, 0.3, 1);
}
.hero-cine__portrait {
  position: absolute;
  right: 6vw;
  top: 50%;
  transform: translateY(-50%) translateZ(0);
  width: min(42vw, 620px);
  aspect-ratio: 3 / 4;
  z-index: 3;
  overflow: hidden;
  border-radius: 2px;
  box-shadow:
    0 60px 120px -30px rgba(0, 0, 0, 0.7),
    0 0 0 1px rgba(245, 239, 228, 0.06);
  will-change: transform;
  transition: transform 600ms cubic-bezier(0.16, 1, 0.3, 1);
  clip-path: inset(0 0 100% 0);
  animation: cine-reveal 1600ms cubic-bezier(0.7, 0, 0.2, 1) 200ms forwards;
}
.hero-cine__portrait img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 12%;
  filter: contrast(1.06) saturate(1.15) brightness(0.95);
  transform: scale(1.08);
  transition: transform 1400ms cubic-bezier(0.16, 1, 0.3, 1);
}
.hero-cine.is-ready .hero-cine__portrait img { transform: scale(1); }
.hero-cine__portrait::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(15, 25, 48, 0.12) 0%, transparent 35%, rgba(15, 25, 48, 0.55) 100%),
    radial-gradient(ellipse at 30% 25%, rgba(201, 120, 71, 0.18) 0%, transparent 55%);
  mix-blend-mode: multiply;
  pointer-events: none;
}
@keyframes cine-reveal {
  0% { clip-path: inset(0 0 100% 0); }
  100% { clip-path: inset(0 0 0 0); }
}

.hero-cine__content {
  position: relative;
  z-index: 4;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-top: var(--nav-height);
  padding-bottom: 15vh;
  width: min(var(--max-outer), 100% - 2 * clamp(1.25rem, 5vw, 4rem));
  margin-inline: auto;
}
.hero-cine__eyebrow {
  color: var(--terracotta);
  margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
}
.hero-cine__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(3rem, 8vw, 8rem);
  line-height: 0.98;
  letter-spacing: -0.025em;
  color: var(--ivory);
  max-width: 14ch;
}
.hero-cine__title em {
  font-style: italic;
  color: var(--terracotta);
  font-weight: 400;
}
.hero-cine__title .line { overflow: hidden; display: block; }
.hero-cine__title .line > span {
  display: block;
  transform: translateY(105%);
  animation: cine-line-in 1100ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.hero-cine__title .line:nth-child(1) > span { animation-delay: 300ms; }
.hero-cine__title .line:nth-child(2) > span { animation-delay: 440ms; }
.hero-cine__title .line:nth-child(3) > span { animation-delay: 580ms; }
@keyframes cine-line-in { to { transform: translateY(0); } }

.hero-cine__lead {
  color: rgba(245, 239, 228, 0.72);
  font-size: clamp(1rem, 1.15vw, 1.15rem);
  line-height: 1.65;
  max-width: 38ch;
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
  opacity: 0;
  animation: cine-fade-in 900ms cubic-bezier(0.16, 1, 0.3, 1) 900ms forwards;
}
.hero-cine__ctas {
  display: flex; gap: 1rem;
  margin-top: clamp(2rem, 4vw, 3rem);
  flex-wrap: wrap;
  opacity: 0;
  animation: cine-fade-in 900ms cubic-bezier(0.16, 1, 0.3, 1) 1050ms forwards;
}
@keyframes cine-fade-in { to { opacity: 1; } }

.hero-cine__btn {
  display: inline-flex; align-items: center; gap: 0.85rem;
  padding: 1.05rem 2rem;
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ivory);
  position: relative;
  border: 1px solid rgba(245, 239, 228, 0.35);
  border-radius: 999px;
  overflow: hidden;
  transition: color 500ms var(--ease-inout), border-color 500ms var(--ease-inout), padding-right 500ms var(--ease-inout);
}
.hero-cine__btn::before {
  content: "";
  position: absolute; inset: 0;
  background: var(--terracotta);
  transform: translateY(101%);
  transition: transform 500ms var(--ease-out);
  z-index: -1;
}
.hero-cine__btn:hover { border-color: var(--terracotta); }
.hero-cine__btn:hover::before { transform: translateY(0); }
.hero-cine__btn svg { width: 14px; height: 14px; transition: transform 500ms var(--ease-out); }
.hero-cine__btn:hover svg { transform: translateX(4px); }
.hero-cine__btn.is-primary { background: var(--ivory); color: var(--navy-deep); border-color: var(--ivory); }
.hero-cine__btn.is-primary::before { background: var(--terracotta); }
.hero-cine__btn.is-primary:hover { color: var(--ivory); }

.hero-cine__foot {
  position: absolute;
  left: 0; right: 0; bottom: 3.5vh;
  z-index: 5;
  padding-inline: clamp(1.25rem, 5vw, 4rem);
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 2rem;
  pointer-events: none;
}
.hero-cine__foot > * { pointer-events: auto; }
.hero-cine__roles {
  display: flex;
  gap: 2.5rem;
  flex-wrap: wrap;
  font-size: 0.68rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(245, 239, 228, 0.58);
  opacity: 0;
  animation: cine-fade-in 900ms cubic-bezier(0.16, 1, 0.3, 1) 1300ms forwards;
}
.hero-cine__roles span { display: flex; align-items: center; gap: 1rem; }
.hero-cine__roles span + span::before {
  content: "";
  display: inline-block;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--terracotta);
  margin-right: 1.5rem;
}
.hero-cine__scroll {
  display: flex; flex-direction: column; align-items: center; gap: 0.75rem;
  font-size: 0.65rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(245, 239, 228, 0.65);
  opacity: 0;
  animation: cine-fade-in 900ms cubic-bezier(0.16, 1, 0.3, 1) 1400ms forwards;
}
.hero-cine__scroll::after {
  content: "";
  width: 1px; height: 40px;
  background: var(--terracotta);
  animation: scroll-line 2s var(--ease-inout) infinite;
  transform-origin: top center;
}

/* Mobile: portrait becomes background wash, content overlays */
@media (max-width: 900px) {
  .hero-cine__portrait {
    position: absolute;
    inset: 0;
    width: 100%;
    aspect-ratio: auto;
    top: 0; right: 0;
    transform: none;
    max-width: none;
    border-radius: 0;
    box-shadow: none;
  }
  .hero-cine__portrait img { object-position: center 20%; filter: contrast(1.05) saturate(1.1) brightness(0.55); }
  .hero-cine__portrait::after {
    background: linear-gradient(180deg, rgba(8, 16, 31, 0.5) 0%, rgba(8, 16, 31, 0.85) 100%);
  }
  .hero-cine__mark {
    font-size: 78vw;
    -webkit-text-stroke: 0.5px rgba(245, 239, 228, 0.09);
  }
  .hero-cine__content { padding-inline: clamp(1.25rem, 5vw, 4rem); width: 100%; }
  .hero-cine__title { max-width: 12ch; }
  .hero-cine__foot { flex-direction: column-reverse; align-items: flex-start; gap: 2rem; }
  .hero-cine__roles { gap: 0.75rem 1.5rem; font-size: 0.62rem; letter-spacing: 0.22em; }
  .hero-cine__roles span + span::before { display: none; }
  .hero-cine__scroll { align-self: flex-end; }
}

/* Dark nav variant when on cinematic hero */
.nav.on-dark { background: transparent; border-bottom-color: rgba(245, 239, 228, 0.08); }
.nav.on-dark .nav__brand { color: var(--ivory); }
.nav.on-dark .nav__brand::after { color: var(--terracotta); }
.nav.on-dark .nav__link { color: rgba(245, 239, 228, 0.85); }
.nav.on-dark .nav__cta {
  border-color: rgba(245, 239, 228, 0.35);
  color: var(--ivory);
  background: transparent;
  transition: background var(--dur-standard) var(--ease-out), border-color var(--dur-standard) var(--ease-out), color var(--dur-standard) var(--ease-out);
}
/* Disable the sliding fill pseudo on the dark variant to avoid pseudo leak. */
.nav.on-dark .nav__cta { background-image: linear-gradient(var(--terracotta), var(--terracotta)); }
.nav.on-dark .nav__cta:hover { border-color: var(--terracotta); color: var(--ivory); }
.nav.on-dark .nav__toggle span { background: var(--ivory); }
.nav.on-dark.is-scrolled { background: rgba(8, 16, 31, 0.75); backdrop-filter: blur(14px) saturate(120%); -webkit-backdrop-filter: blur(14px) saturate(120%); }

/* ============================================================
   HERO — CINEMATIC AI (5-Scene scroll-driven story)
   Scene 1: Silhouette arrival (near-black, head lowered)
   Scene 2: Scroll-scrubbed head lift
   Scene 3: Eye contact + scan line
   Scene 4: HUD lines draw + 4 expertise labels
   Scene 5: Fade-out transition to next section
   ============================================================ */
.hero-cinema {
  position: relative;
  height: 300vh;
  padding: 0;                       /* opt out of the global section rhythm */
  /* The footage is a bright neutral studio (~#E9E9E9) — the stage matches it
     so the frame edges melt into the page instead of forming a hard box. */
  background: linear-gradient(180deg, #F1F1F1 0%, #EAEAEA 60%, #E4E2E1 100%);
  color: var(--navy);
}
.hero-cinema__sticky {
  position: sticky;
  top: 0;
  height: 100dvh;
  overflow: hidden;
  isolation: isolate;
}
.hero-cinema__sticky::before {
  /* film grain */
  content: "";
  position: absolute; inset: 0;
  z-index: 20;
  pointer-events: none;
  opacity: 0.28;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='300'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.95  0 0 0 0 0.95  0 0 0 0 1  0 0 0 0.08 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}
/* Ambient studio light — soft, matching the bright footage */
.hero-cinema__ambient {
  position: absolute; inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(ellipse 55vw 70vh at 50% 42%, rgba(255, 255, 255, 0.6) 0%, transparent 62%),
    linear-gradient(180deg, #F3F3F3 0%, #EAEAEA 55%, #E3E1E0 100%);
}
/* Warm haze — a whisper of rust/burgundy so the stage still belongs to the brand */
.hero-cinema__fog {
  position: absolute; inset: -10%;
  z-index: 2;
  pointer-events: none;
  opacity: 0.5;
  mix-blend-mode: multiply;
  filter: blur(30px);
  background:
    radial-gradient(ellipse 42vw 26vh at 28% 56%, rgba(168, 75, 28, 0.09) 0%, transparent 62%),
    radial-gradient(ellipse 48vw 32vh at 72% 44%, rgba(107, 30, 35, 0.07) 0%, transparent 62%);
  animation: cine-fog-drift 40s var(--ease-inout) infinite alternate;
}
@keyframes cine-fog-drift {
  0%   { transform: translate(0, 0); }
  100% { transform: translate(2%, -1%); }
}

/* -------- Portrait stage — interactive directional watercolour -------- */
.hero-cinema__stage {
  position: absolute; inset: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
/* The source footage is 1280x720 — fill the stage so the composition reads
   full-bleed and cinematic, with only minimal crop on wide viewports. */
.hero-cinema__figure {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  will-change: opacity;

  /* Cursor-tracked mask centres (px, set by JS). Three blobs trailing at
     different rates give the wash an organic, non-circular edge. */
  --wc-x1: 50%; --wc-y1: 50%;
  --wc-x2: 50%; --wc-y2: 50%;
  --wc-x3: 50%; --wc-y3: 50%;
  --wc-r: 210;                       /* bloom radius in px, velocity-driven */
}
/* The canvas is the only visible layer — it composites the aligned base
   clips and masks the colour scenes through the painted trail. */
.hero-cinema__canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  z-index: 2;
  display: block;
  opacity: 0;
  transition: opacity 600ms var(--ease-out);
}
.hero-cinema.canvas-ready .hero-cinema__canvas { opacity: 1; }

/* Source clips: decoded off-screen, never shown directly. Kept in the layout
   (not display:none) so browsers reliably decode frames for canvas drawing. */
.hero-cinema__video {
  position: absolute;
  width: 2px; height: 2px;
  top: 0; left: 0;
  opacity: 0.001;
  pointer-events: none;
  z-index: 1;
}
/* When the real video exists, it drives the animation */
.hero-cinema__video {
  z-index: 2;
  filter: contrast(1.05) saturate(0.98);
}
/* Fallback still (Higgsfield starting frame) — shown until the video's first frame paints */
.hero-cinema__frame {
  z-index: 1;
  opacity: 1;
  transition: opacity 400ms var(--ease-out);
}
/* Once the video reports it can play, hide the still */
.hero-cinema.video-ready .hero-cinema__frame { opacity: 0; }

/* Light edge vignette — just enough to seat the frame, never a visible box */
.hero-cinema__figure::after {
  content: "";
  position: absolute; inset: 0;
  z-index: 4;
  pointer-events: none;
  background:
    radial-gradient(ellipse 102% 112% at 50% 48%, transparent 64%, rgba(122, 112, 108, 0.18) 100%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.10) 0%, transparent 16%, transparent 80%, rgba(96, 86, 84, 0.16) 100%);
}
/* Rim removed — the Higgsfield asset already has real studio lighting */
.hero-cinema__rim { display: none; }

/* -------- Interactive: neon AR shades (cursor proximity) -------- */
.hero-cinema__shades {
  position: absolute;
  z-index: 4;                       /* above the video, below the HUD + labels */
  pointer-events: none;
  overflow: visible;
  opacity: 0;
  /* JS sets left/top/width; this transform is the resting (hidden) pose */
  transform: translate(-50%, -50%) scale(0.82);
  filter: saturate(1.25);
  transition:
    opacity   420ms var(--ease-out),
    transform 620ms cubic-bezier(0.34, 1.4, 0.64, 1);
  will-change: opacity, transform;
}
/* Materialise when the cursor is near her face */
.hero-cinema__shades.is-near { opacity: 1; }

.hero-cinema__shades path { fill: none; vector-effect: non-scaling-stroke; }

.shade-lens {
  fill: url(#lensFill);
  stroke: var(--cine-cyan-hot);
  stroke-width: 1.6;
  stroke-linejoin: round;
}
.shade-bridge,
.shade-arm {
  stroke: var(--cine-cyan-hot);
  stroke-width: 1.6;
  stroke-linecap: round;
}
.shade-scan path {
  stroke: var(--terracotta);
  stroke-width: 0.7;
  opacity: 0.75;
}
/* Lens scanlines drift while the shades are visible */
.hero-cinema__shades.is-near .shade-scan {
  animation: shade-scan-drift 2.6s var(--ease-inout) infinite alternate;
}
@keyframes shade-scan-drift {
  0%   { opacity: 0.35; transform: translateY(-1.5px); }
  100% { opacity: 0.9;  transform: translateY(1.5px); }
}
/* Faint neon breathe on the frame */
.hero-cinema__shades.is-near .shade-lens {
  animation: shade-breathe 3.2s var(--ease-inout) infinite alternate;
}
@keyframes shade-breathe {
  0%   { stroke: var(--cine-cyan); }
  100% { stroke: var(--cine-cyan-hot); }
}

/* Touch devices: no hover, so pulse them gently once revealed */
@media (hover: none), (pointer: coarse) {
  .hero-cinema.is-revealed .hero-cinema__shades {
    opacity: 1;
    animation: shade-touch-pulse 4s var(--ease-inout) infinite alternate;
  }
  @keyframes shade-touch-pulse {
    0%   { opacity: 0.55; transform: translate(-50%, -50%) scale(0.97); }
    100% { opacity: 1;    transform: translate(-50%, -50%) scale(1); }
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero-cinema__shades.is-near .shade-scan,
  .hero-cinema__shades.is-near .shade-lens { animation: none; }
}

/* -------- Scene 3: Scan line (blue thing) -------- */
.hero-cinema__scan {
  position: absolute;
  left: 0; right: 0;
  top: 50%;                                   /* JS positions to actual eye Y */
  height: 2px;
  z-index: 6;
  opacity: 0;
  transform: translateY(-50%) translateX(-40vw);
  pointer-events: none;
  background: linear-gradient(90deg,
    transparent 0%,
    transparent 15%,
    rgba(95, 199, 255, 0.4) 30%,
    var(--cine-cyan-hot) 50%,
    rgba(95, 199, 255, 0.4) 70%,
    transparent 85%,
    transparent 100%);
  box-shadow:
    0 0 12px var(--cine-cyan-glow),
    0 0 32px var(--cine-cyan-glow),
    0 0 64px rgba(95, 199, 255, 0.3);
  will-change: opacity, transform;
}
/* When reveal fires (video hits 5s) the scan sweeps across her eyes */
.hero-cinema.is-revealed .hero-cinema__scan {
  animation: cine-scan-sweep 1100ms cubic-bezier(0.7, 0, 0.3, 1) forwards;
}
@keyframes cine-scan-sweep {
  0%   { opacity: 0; transform: translateY(-50%) translateX(-40vw); }
  15%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { opacity: 0; transform: translateY(-50%) translateX(40vw); }
}
/* HUD lines + eye dots animate on reveal too */
.hero-cinema.is-revealed .hero-cinema__hud path {
  transition: stroke-dashoffset 1400ms cubic-bezier(0.65, 0, 0.35, 1);
  transition-delay: 900ms;                    /* start after the scan finishes */
  stroke-dashoffset: 0;                       /* JS sets initial length; here we drive to 0 */
}
.hero-cinema.is-revealed .hero-cinema__hud circle {
  transition: opacity 400ms ease-out 1000ms;
  opacity: 1;
}
/* Scan line: two thin brackets that ride with the beam */
.hero-cinema__scan::before,
.hero-cinema__scan::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 8px; height: 8px;
  border: 1px solid var(--cine-cyan);
  transform: translateY(-50%);
  opacity: 0.85;
}
.hero-cinema__scan::before { left:  calc(50% - 240px); border-right: 0; border-top: 0; }
.hero-cinema__scan::after  { right: calc(50% - 240px); border-left:  0; border-bottom: 0; }

/* -------- Scene 4: HUD graphics + expertise labels -------- */
.hero-cinema__hud {
  position: absolute; inset: 0;
  z-index: 5;
  pointer-events: none;
  overflow: visible;
}
.hero-cinema__hud path {
  fill: none;
  stroke: var(--terracotta);
  stroke-width: 1;
  stroke-linecap: round;
  stroke-dasharray: 1200;
  stroke-dashoffset: 1200;
  opacity: 0.85;
  filter: drop-shadow(0 0 8px rgba(201, 120, 71, 0.55));
}
.hero-cinema__hud circle {
  fill: var(--terracotta);
  opacity: 0;
  filter: drop-shadow(0 0 8px rgba(201, 120, 71, 0.85));
}
.hero-cinema__labels {
  position: absolute; inset: 0;
  z-index: 5;
  pointer-events: none;                       /* container blocks nothing */
}
.hero-cinema__label {
  position: absolute;
  opacity: 0;
  transform: translateY(12px);
  font-family: var(--font-body);
  color: var(--navy);
  text-decoration: none;
  pointer-events: auto;
  cursor: pointer;
  padding: 0.95rem 1.25rem;
  border-radius: 4px;

  /* Warm glass card behind the navy text — subtle but lifts contrast dramatically */
  background: linear-gradient(135deg,
    rgba(245, 232, 218, 0.94) 0%,
    rgba(238, 220, 200, 0.88) 100%);
  backdrop-filter: blur(20px) saturate(1.4);
  -webkit-backdrop-filter: blur(20px) saturate(1.4);
  border: 1px solid rgba(245, 232, 218, 0.4);
  box-shadow:
    0 16px 48px -12px rgba(15, 5, 10, 0.55),
    inset 0 1px 0 rgba(255, 255, 255, 0.35);
  will-change: opacity, transform;
  transition:
    transform 500ms var(--ease-out),
    filter    500ms var(--ease-out),
    opacity   700ms var(--ease-out),
    background 400ms var(--ease-out),
    border-color 400ms var(--ease-out);
}
.hero-cinema__label small {
  display: block;
  font-size: 0.62rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--rust);
  margin-bottom: 0.45rem;
  font-weight: 600;
  transition: color 300ms var(--ease-out), letter-spacing 400ms var(--ease-out);
}
.hero-cinema__label em {
  font-family: var(--wa-serif);
  font-style: italic;
  font-size: clamp(1.3rem, 2.2vw, 2rem);
  font-weight: 700;
  color: var(--navy-deep);
  line-height: 1.08;
  letter-spacing: -0.005em;
  display: block;
  transition: color 300ms var(--ease-out);
}
.hero-cinema__label .row {
  display: flex; align-items: center; gap: 0.75rem;
}
/* Positioning + transform anchor per corner (so scale grows inward, not off-screen) */
.hero-cinema__label.l-tl { top: 10%; left: 5%;  text-align: left;  transform-origin: top left; }
.hero-cinema__label.l-tr { top: 10%; right: 5%; text-align: right; transform-origin: top right; }
.hero-cinema__label.l-bl { bottom: 14%; left: 5%;  text-align: left;  transform-origin: bottom left; }
.hero-cinema__label.l-br { bottom: 14%; right: 5%; text-align: right; transform-origin: bottom right; }

/* --- Hover: label grows + navy deepens on a warm halo --- */
.hero-cinema__label:hover {
  transform: scale(1.08);
  filter: drop-shadow(0 6px 32px rgba(168, 75, 28, 0.6));
}
.hero-cinema__label:hover em {
  color: var(--navy-deep);
  text-shadow:
    0 0 32px rgba(201, 120, 71, 0.85),
    0 0 12px rgba(245, 232, 218, 0.7),
    0 2px 12px rgba(15, 5, 10, 0.8);
}
.hero-cinema__label:hover small {
  color: var(--navy-deep);
  opacity: 1;
  letter-spacing: 0.42em;
}
.hero-cinema__label:focus-visible {
  outline: 1px solid var(--terracotta);
  outline-offset: 12px;
  border-radius: 2px;
}

/* --- Reveal state (added by JS when video reaches 5s) --- */
.hero-cinema.is-revealed .hero-cinema__label {
  opacity: 1;
  transform: translateY(0);
}
.hero-cinema.is-revealed .hero-cinema__label.l-tl { transition-delay: 100ms; }
.hero-cinema.is-revealed .hero-cinema__label.l-tr { transition-delay: 220ms; }
.hero-cinema.is-revealed .hero-cinema__label.l-bl { transition-delay: 340ms; }
.hero-cinema.is-revealed .hero-cinema__label.l-br { transition-delay: 460ms; }

/* Hover overrides the reveal transform */
.hero-cinema.is-revealed .hero-cinema__label:hover { transform: scale(1.08); }

/* -------- Scene 1 intro overlay -------- */
.hero-cinema__intro {
  position: absolute;
  left: 50%; bottom: 8vh;
  transform: translateX(-50%);
  z-index: 7;
  text-align: center;
  padding-inline: 1.5rem;
  will-change: opacity, transform;
}
.hero-cinema__intro-sub {
  display: block;
  margin-top: 0.5rem;
  font-family: var(--font-body);
  font-size: 0.65rem;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--terracotta);
  opacity: 0.9;
}

/* The invitation rides with the pointer, the way the WORK button does on the
   journal — it trails a little behind and below, and it is only there while
   the pointer is over the hero. Leaving the hero takes it slowly away; coming
   back brings it slowly out again.

   pointer-events must stay off: it sits over the portrait, and the portrait is
   what has to be hovered for the four turns to run at all. */
.hero-cinema__move {
  position: fixed;
  top: 0; left: 0;
  z-index: 9998;          /* beneath the pointer itself, above the page */
  text-align: center;
  pointer-events: none;
  opacity: 0;
  will-change: transform;
  transition: opacity 700ms var(--ease-out);
}
.hero-cinema__move.is-on { opacity: 1; }
.hero-cinema__move-cross {
  display: block;
  width: clamp(28px, 3.2vmin, 40px);
  height: clamp(28px, 3.2vmin, 40px);
  margin: 0 auto 0.55rem;
}
/* Light on purpose. This one rides with the pointer and is read at a glance;
   it is the four points that have to carry across the picture. */
.hero-cinema__move-cross line,
.hero-cinema__move-cross path {
  fill: none; stroke: var(--terracotta); stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.hero-cinema__move-word {
  display: block;
  font-family: var(--font-body);
  font-size: 0.72rem;
  letter-spacing: 0.5em;
  text-indent: 0.5em;
  text-transform: uppercase;
  color: var(--terracotta);
}
/* The four points. They keep company with MOVE — the cross says that she
   turns, these say which ways — so they carry exactly the same timing. DOWN is
   held well clear of the foot so it never sits on the word beneath it. */
.hero-cinema__points {
  position: absolute; inset: 0;
  z-index: 7;
  pointer-events: none;
  opacity: 0;
}
/* These stand alone at the four edges with nothing beside them, so they are
   the ones that have to be seen. Full weight, the darker rust, and a light
   halo so they hold wherever the clip is bright. */
.hero-cinema__point {
  position: absolute;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.58rem;
  letter-spacing: 0.24em;
  text-indent: 0.24em;
  text-transform: uppercase;
  color: var(--rust);
  text-shadow: 0 1px 10px rgba(245, 239, 228, 0.92);
  white-space: nowrap;
}
/* clear of the masthead, which is fixed over the top of the stage and would
   otherwise hide this one word completely */
.hero-cinema__point.up    { left: 50%; top: 16%;    transform: translateX(-50%); }
.hero-cinema__point.down  { left: 50%; bottom: 19%; transform: translateX(-50%); }
.hero-cinema__point.left  { left: 4%;  top: 50%;    transform: translateY(-50%); }
.hero-cinema__point.right { right: 4%; top: 50%;    transform: translateY(-50%); }

/* Before the turn has been asked for, the two invitations trade places on a
   loop — MOVE first, then SCROLL TO BEGIN — because both are now true: moving
   across her opens the hero exactly as scrolling does. One is up while the
   other is down, so they never sit on top of one another.

   The moment either is taken up the hero adds intro-running, this stops, and
   the scroll handler takes the two back. */
.hero-cinema:not(.intro-running):not(.intro-done) .hero-cinema__intro {
  animation: hero-invite 7600ms ease-in-out infinite;
}
/* The points are full-bleed, so they cannot share the keyframes that carry
   the centring transform — they fade on the same clock and nothing more. */
.hero-cinema:not(.intro-running):not(.intro-done) .hero-cinema__points {
  animation: hero-invite-fade 7600ms ease-in-out infinite;
}
@keyframes hero-invite-fade {
  0%,  3%   { opacity: 0; }
  11%, 40%  { opacity: 1; }
  48%, 100% { opacity: 0; }
}
/* half a cycle out of step, so SCROLL TO BEGIN follows the points rather than
   sharing the beat with them */
.hero-cinema:not(.intro-running):not(.intro-done) .hero-cinema__intro {
  animation-delay: -3800ms;
}
@keyframes hero-invite {
  0%,  3%   { opacity: 0; transform: translateX(-50%) translateY(9px); }
  11%, 40%  { opacity: 1; transform: translateX(-50%) translateY(0); }
  48%, 100% { opacity: 0; transform: translateX(-50%) translateY(-7px); }
}

/* No pointer to move, or motion is unwelcome: MOVE has nothing to offer and
   the alternation has nothing to alternate. SCROLL TO BEGIN stands alone. */
@media (hover: none), (pointer: coarse), (prefers-reduced-motion: reduce) {
  .hero-cinema__move, .hero-cinema__points { display: none; }
  .hero-cinema__intro { animation: none !important; opacity: 1; }
}

/* -------- Persistent UI -------- */
.hero-cinema__corners {
  position: absolute; inset: 0;
  z-index: 8;
  pointer-events: none;
}
.hero-cinema__corner {
  position: absolute;
  width: 22px; height: 22px;
  border: 1px solid rgba(30, 42, 71, 0.22);
}
.hero-cinema__corner.tl { top: 24px; left: 24px; border-right: 0; border-bottom: 0; }
.hero-cinema__corner.tr { top: 24px; right: 24px; border-left: 0; border-bottom: 0; }
.hero-cinema__corner.bl { bottom: 24px; left: 24px; border-right: 0; border-top: 0; }
.hero-cinema__corner.br { bottom: 24px; right: 24px; border-left: 0; border-top: 0; }

.hero-cinema__timecode {
  position: absolute;
  top: 24px; left: 50%;
  transform: translateX(-50%);
  z-index: 8;
  font-family: var(--font-body);
  font-variant-numeric: tabular-nums;
  font-size: 0.65rem;
  letter-spacing: 0.32em;
  color: rgba(30, 42, 71, 0.55);
  pointer-events: none;
}
.hero-cinema__progress {
  position: absolute;
  bottom: 0; left: 0;
  height: 1px;
  width: 0%;
  background: linear-gradient(90deg, transparent, var(--rust), var(--terracotta), transparent);
  box-shadow: 0 0 8px rgba(168, 75, 28, 0.55);
  z-index: 9;
  will-change: width;
}

/* -------- Mobile tuning -------- */
@media (max-width: 900px) {
  .hero-cinema { height: 260vh; }
  /* The figure is always full-bleed now — the old portrait-card sizing
     (height: 78vh; max-width: 92vw) squashed the canvas inside the stage. */
  .hero-cinema__label em { font-size: clamp(1.05rem, 4.5vw, 1.4rem); }
  .hero-cinema__label small { font-size: 0.55rem; letter-spacing: 0.28em; }
  .hero-cinema__label.l-tl, .hero-cinema__label.l-tr { top: 8%; }
  .hero-cinema__label.l-bl, .hero-cinema__label.l-br { bottom: 22%; }
}

/* -------- Reduced motion: collapse to a composed static frame -------- */
@media (prefers-reduced-motion: reduce) {
  .hero-cinema { height: 100dvh; }
  .hero-cinema__frame.is-1, .hero-cinema__frame.is-2 { opacity: 0; }
  .hero-cinema__frame.is-3 { opacity: 1; }
  .hero-cinema__hud path { stroke-dashoffset: 0; }
  .hero-cinema__hud circle { opacity: 1; }
  .hero-cinema__label { opacity: 1; transform: none; }
  .hero-cinema__fog { animation: none; }
}

/* ============================================================
   HERO — SCROLL-PINNED CINEMATIC (manayerbamate-inspired)
   ============================================================ */
.hero-scroll {
  position: relative;
  height: 340vh;                       /* extra scroll length drives the timeline */
  background: linear-gradient(180deg, #08101F 0%, #0F1930 60%, #16223D 100%);
  color: var(--ivory);
}
.hero-scroll__sticky {
  position: sticky;
  top: 0;
  height: 100dvh;
  overflow: hidden;
  isolation: isolate;
}

/* Grain */
.hero-scroll__sticky::before {
  content: "";
  position: absolute; inset: 0;
  z-index: 10;
  pointer-events: none;
  opacity: 0.45;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='300'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.95  0 0 0 0 0.9  0 0 0 0 0.85  0 0 0 0.06 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}

/* Ambient glow behind the portrait */
.hero-scroll__glow {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 90vw;
  height: 110vh;
  z-index: 1;
  background:
    radial-gradient(ellipse 55vw 45vh at 50% 45%, rgba(107, 30, 35, 0.32) 0%, transparent 60%),
    radial-gradient(ellipse 40vw 35vh at 50% 55%, rgba(168, 75, 28, 0.22) 0%, transparent 65%);
  pointer-events: none;
  filter: blur(20px);
}

/* Stage holds portrait + lines + labels, all centered */
.hero-scroll__stage {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
}

/* Portrait container. Aspect ratio matches source; anchored center. */
.hero-scroll__portrait {
  position: relative;
  height: min(88vh, 900px);
  aspect-ratio: 3 / 4;
  will-change: transform;
  overflow: hidden;
  border-radius: 3px;
  box-shadow: 0 60px 120px -30px rgba(0, 0, 0, 0.7);
}
.hero-scroll__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 12%;
  will-change: opacity, transform;
  filter: contrast(1.05) saturate(1.08);
}
.hero-scroll__img.is-down {
  z-index: 2;
  opacity: 1;                   /* starts fully visible */
  transform: scale(1.02);
  /* Simulated "looking down" vignette treatment for placeholder */
  filter: contrast(1.08) saturate(0.9) brightness(0.65);
}
.hero-scroll__img.is-down::after {
  /* faux shadow overlay — visualises the down state before the real photo arrives */
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(8, 16, 31, 0.55) 0%, transparent 60%);
}
.hero-scroll__img.is-up {
  z-index: 1;
  opacity: 0;                   /* fades in on scroll */
  transform: scale(1.05);
}
/* Warm color overlay on the whole portrait */
.hero-scroll__portrait::after {
  content: "";
  position: absolute; inset: 0;
  z-index: 3;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(15, 25, 48, 0.1) 0%, transparent 40%, rgba(15, 25, 48, 0.45) 100%),
    radial-gradient(ellipse at 30% 25%, rgba(201, 120, 71, 0.16) 0%, transparent 55%);
  mix-blend-mode: multiply;
}

/* SVG lines drawing from eyes */
.hero-scroll__lines {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: min(140vw, 1800px);   /* wider than portrait so lines can travel outward */
  height: min(140vh, 1400px);
  z-index: 3;
  pointer-events: none;
  overflow: visible;
}
.hero-scroll__lines path {
  fill: none;
  stroke: var(--terracotta);
  stroke-width: 1;
  stroke-linecap: round;
  stroke-dasharray: 1200;
  stroke-dashoffset: 1200;      /* starts hidden — JS animates to 0 */
  opacity: 0.7;
  filter: drop-shadow(0 0 8px rgba(201, 120, 71, 0.6));
}
.hero-scroll__lines circle {
  fill: var(--terracotta);
  opacity: 0;                    /* JS pops these in with the label */
  filter: drop-shadow(0 0 6px rgba(201, 120, 71, 0.8));
}

/* Talent labels sit at the ends of the lines */
.hero-scroll__labels {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
}
.hero-scroll__label {
  position: absolute;
  transform: translateY(20px);
  opacity: 0;
  font-family: var(--wa-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.5rem, 2.6vw, 2.6rem);
  color: var(--ivory);
  line-height: 1.05;
  letter-spacing: -0.005em;
  white-space: nowrap;
  text-shadow: 0 4px 24px rgba(0, 0, 0, 0.6);
}
.hero-scroll__label small {
  display: block;
  font-family: var(--font-body);
  font-style: normal;
  font-size: 0.6rem;
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--terracotta);
  margin-bottom: 0.5rem;
}
/* Label positions (percent of the viewport) */
.hero-scroll__label.l-1 { top: 12%;  left: 6%;  text-align: left; }
.hero-scroll__label.l-2 { top: 62%;  left: 4%;  text-align: left; }
.hero-scroll__label.l-3 { top: 12%;  right: 6%; text-align: right; }
.hero-scroll__label.l-4 { top: 62%;  right: 4%; text-align: right; }

/* Intro text (visible early, fades as portrait takes over) */
.hero-scroll__intro {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  z-index: 5;
  text-align: center;
  padding-inline: 1.5rem;
  will-change: opacity, transform;
}
.hero-scroll__intro-eyebrow {
  color: var(--terracotta);
  justify-content: center;
  margin-bottom: 2rem;
}
.hero-scroll__intro-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2.75rem, 7vw, 6.5rem);
  line-height: 0.98;
  color: var(--ivory);
  max-width: 16ch;
  margin-inline: auto;
  letter-spacing: -0.02em;
}
.hero-scroll__intro-title em { font-style: italic; color: var(--terracotta); font-weight: 400; }

/* Bottom UI: name + scroll cue */
.hero-scroll__ui {
  position: absolute;
  left: 0; right: 0; bottom: 3.5vh;
  z-index: 6;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  padding-inline: clamp(1.25rem, 5vw, 4rem);
  pointer-events: none;
}
.hero-scroll__ui > * { pointer-events: auto; }
.hero-scroll__name {
  font-family: var(--font-wordmark);
  font-size: clamp(1.5rem, 2vw, 2rem);
  letter-spacing: 0.06em;
  color: var(--ivory);
}
.hero-scroll__name small {
  display: block;
  font-family: var(--font-body);
  font-size: 0.55rem;
  letter-spacing: 0.4em;
  color: var(--terracotta);
  text-transform: uppercase;
  margin-top: 4px;
}
.hero-scroll__cue {
  display: flex; align-items: center; gap: 1rem;
  font-size: 0.65rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(245, 239, 228, 0.7);
}
.hero-scroll__cue::after {
  content: "";
  width: 1px; height: 40px;
  background: var(--terracotta);
  animation: scroll-line 2s var(--ease-inout) infinite;
  transform-origin: top center;
}
.hero-scroll__progress {
  position: absolute;
  bottom: 0; left: 0;
  height: 2px;
  width: 0%;                   /* JS drives */
  background: linear-gradient(90deg, var(--rust), var(--terracotta));
  z-index: 7;
  will-change: width;
}

/* ---------- Mobile ---------- */
@media (max-width: 900px) {
  .hero-scroll { height: 320vh; }
  .hero-scroll__portrait { height: 70vh; aspect-ratio: 3 / 4; max-width: 90vw; }
  .hero-scroll__intro-title { font-size: clamp(2.25rem, 10vw, 4rem); }
  .hero-scroll__label { font-size: clamp(1.05rem, 4.5vw, 1.5rem); }
  .hero-scroll__label small { font-size: 0.55rem; letter-spacing: 0.24em; }
  .hero-scroll__label.l-1, .hero-scroll__label.l-3 { top: 8%; }
  .hero-scroll__label.l-2, .hero-scroll__label.l-4 { top: auto; bottom: 18%; }
  .hero-scroll__label.l-1 { left: 5%; right: auto; }
  .hero-scroll__label.l-2 { left: 5%; right: auto; }
  .hero-scroll__label.l-3 { right: 5%; left: auto; }
  .hero-scroll__label.l-4 { right: 5%; left: auto; }
}

/* Reduced motion — collapse to static composed state */
@media (prefers-reduced-motion: reduce) {
  .hero-scroll { height: 100dvh; }
  .hero-scroll__img.is-down { opacity: 0; }
  .hero-scroll__img.is-up { opacity: 1; }
  .hero-scroll__lines path { stroke-dashoffset: 0; }
  .hero-scroll__label { opacity: 1; transform: none; }
  .hero-scroll__intro { opacity: 0; }
}

/* ---------- 11b. Hero — original (kept for other pages / About) ---------- */
.hero {
  padding-top: calc(var(--nav-height) + clamp(2rem, 6vw, 6rem));
  padding-bottom: clamp(4rem, 8vw, 8rem);
  position: relative;
  overflow: hidden;
}
.hero__grid {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}
.hero__meta {
  display: flex; align-items: center; gap: 1rem;
  margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
}
.hero__title { margin-bottom: clamp(1.5rem, 3vw, 2.5rem); }
.hero__signature {
  font-family: var(--font-script);
  font-size: clamp(3rem, 6vw, 5rem);
  color: var(--rust);
  line-height: 1;
  display: inline-block;
  transform: rotate(-4deg);
  margin-left: 0.3em;
}
.hero__lead { margin-bottom: clamp(2rem, 4vw, 3rem); max-width: 46ch; color: var(--navy); }
.hero__ctas { display: flex; gap: 1rem; flex-wrap: wrap; }

.hero__portrait {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border-radius: 6px;
  box-shadow: 0 40px 80px -30px rgba(30, 42, 71, 0.35);
}
.hero__portrait img {
  width: 100%; height: 100%; object-fit: cover; object-position: center 15%;
  will-change: transform;
  transition: transform 1.2s var(--ease-out);
}
.hero__portrait::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 60%, rgba(30, 42, 71, 0.18) 100%);
  pointer-events: none;
}
.hero__badge {
  position: absolute;
  bottom: -18px; left: -18px;
  background: var(--ivory);
  padding: 0.9rem 1.4rem;
  border-radius: 999px;
  box-shadow: 0 10px 24px -12px rgba(30, 42, 71, 0.3);
  font-family: var(--font-body);
  font-size: 0.7rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--navy);
  z-index: 2;
}
.hero__badge strong { color: var(--rust); font-weight: 600; }

.hero__scroll {
  position: absolute;
  bottom: 2rem; left: 50%;
  transform: translateX(-50%);
  font-size: 0.7rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--navy);
  display: flex; align-items: center; gap: 0.75rem;
  opacity: 0.72;
}
.hero__scroll::after {
  content: "";
  width: 1px; height: 40px;
  background: currentColor;
  animation: scroll-line 2s var(--ease-inout) infinite;
  transform-origin: top center;
}
@keyframes scroll-line { 0% { transform: scaleY(0); transform-origin: top; } 50% { transform: scaleY(1); transform-origin: top; } 50.1% { transform-origin: bottom; } 100% { transform: scaleY(0); transform-origin: bottom; } }

/* Botanical accent */
.botanical {
  position: absolute;
  pointer-events: none;
  color: var(--sage-mist);
  opacity: 0.55;
  z-index: 0;
}
.botanical svg { width: 100%; height: 100%; }
.hero .botanical-1 { top: 10%; right: -60px; width: 260px; transform: rotate(15deg); }
.hero .botanical-2 { bottom: 6%; left: -40px; width: 200px; transform: rotate(-25deg); }

@media (max-width: 900px) {
  .hero__grid { grid-template-columns: 1fr; }
  .hero__portrait { max-width: 480px; margin-inline: auto; }
  .hero__scroll { display: none; }
}

/* ---------- 12. Marquee ---------- */
.marquee {
  background: var(--navy);
  color: var(--ivory);
  padding: clamp(1.5rem, 3vw, 2.5rem) 0;
  overflow: hidden;
  position: relative;
}
.marquee__track {
  display: flex; gap: 3rem;
  white-space: nowrap;
  animation: marquee-slide 30s linear infinite;
  will-change: transform;
}
.marquee:hover .marquee__track { animation-play-state: paused; }
.marquee__item {
  font-family: var(--wa-serif);
  font-style: italic;
  font-size: clamp(1.75rem, 3.6vw, 3rem);
  color: var(--ivory);
  display: inline-flex; align-items: center; gap: 3rem;
}
.marquee__dot { color: var(--rust); font-size: 0.5em; transform: translateY(-0.3em); }
@keyframes marquee-slide { to { transform: translateX(-50%); } }

/* ---------- 13. Offer cards (Home) ---------- */
.offers { background: var(--ivory-warm); }
.offer-card {
  padding: clamp(2rem, 3vw, 3rem) clamp(1.5rem, 2.5vw, 2.5rem);
  border: 1px solid rgba(30, 42, 71, 0.1);
  border-radius: 4px;
  position: relative;
  background: var(--ivory);
  transition: transform var(--dur-expressive) var(--ease-out), box-shadow var(--dur-expressive) var(--ease-out), border-color var(--dur-standard) var(--ease-inout);
  overflow: hidden;
}
.offer-card:hover { transform: translateY(-6px); box-shadow: 0 30px 60px -30px rgba(30, 42, 71, 0.25); border-color: var(--rust); }
.offer-card__number {
  font-family: var(--wa-serif);
  font-style: italic;
  font-size: 1.5rem;
  color: var(--rust);
  margin-bottom: 1.5rem;
}
.offer-card__title { font-size: clamp(1.375rem, 2vw, 1.75rem); margin-bottom: 0.75rem; }
.offer-card__desc { color: var(--navy); opacity: 0.75; font-size: 0.95rem; line-height: 1.6; }
.offer-card::after {
  content: "";
  position: absolute;
  bottom: 0; left: 0; right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--rust), var(--terracotta));
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-expressive) var(--ease-out);
}
.offer-card:hover::after { transform: scaleX(1); }

/* ---------- 14. Mission block ---------- */
.mission { background: var(--ivory); }
.mission__quote {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4.2vw, 3.75rem);
  line-height: 1.15;
  font-weight: 400;
  color: var(--navy-deep);
  letter-spacing: -0.01em;
}
.mission__quote em { font-style: italic; color: var(--burgundy); }
.mission__attribution {
  margin-top: 3rem;
  display: flex; align-items: center; gap: 1rem;
  font-size: 0.75rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--navy);
}
.mission__attribution::before { content: ""; width: 40px; height: 1px; background: var(--rust); }

/* ---------- 15. Portfolio preview ---------- */
.portfolio-preview { background: var(--ivory-warm); }
.portfolio-preview__header {
  display: flex; justify-content: space-between; align-items: flex-end;
  margin-bottom: clamp(3rem, 5vw, 5rem);
  gap: 2rem; flex-wrap: wrap;
}
.portfolio-tile {
  position: relative;
  overflow: hidden;
  border-radius: 4px;
  aspect-ratio: 3 / 4;
  background: var(--navy);
}
.portfolio-tile img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 1.2s var(--ease-out), filter var(--dur-expressive) var(--ease-inout);
  filter: brightness(0.92);
}
.portfolio-tile:hover img { transform: scale(1.06); filter: brightness(0.7); }
.portfolio-tile__meta {
  position: absolute;
  left: 1.5rem; right: 1.5rem; bottom: 1.5rem;
  z-index: 2;
  color: var(--ivory);
  transform: translateY(20px);
  opacity: 0;
  transition: transform var(--dur-expressive) var(--ease-out), opacity var(--dur-expressive) var(--ease-inout);
}
.portfolio-tile:hover .portfolio-tile__meta { transform: translateY(0); opacity: 1; }
.portfolio-tile__category { font-size: 0.7rem; letter-spacing: 0.24em; text-transform: uppercase; color: var(--terracotta); margin-bottom: 0.5rem; display: block; }
.portfolio-tile__title { font-family: var(--wa-serif); font-style: italic; font-size: 1.75rem; line-height: 1.1; color: var(--ivory); }
.portfolio-tile__label {
  position: absolute;
  top: 1.5rem; left: 1.5rem;
  font-size: 0.7rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--ivory);
  z-index: 2;
  opacity: 0.85;
}

/* Tall / small variants inside a grid */
.portfolio-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1.5rem;
}
.portfolio-grid .tile-a { grid-column: span 5; aspect-ratio: 3 / 4; }
.portfolio-grid .tile-b { grid-column: span 7; aspect-ratio: 4 / 3; }
.portfolio-grid .tile-c { grid-column: span 4; aspect-ratio: 3 / 4; }
.portfolio-grid .tile-d { grid-column: span 4; aspect-ratio: 3 / 4; }
.portfolio-grid .tile-e { grid-column: span 4; aspect-ratio: 3 / 4; }
.portfolio-grid .tile-f { grid-column: span 7; aspect-ratio: 4 / 3; }
.portfolio-grid .tile-g { grid-column: span 5; aspect-ratio: 3 / 4; }

@media (max-width: 900px) {
  .portfolio-grid { grid-template-columns: 1fr 1fr; }
  .portfolio-grid > * { grid-column: span 1 !important; aspect-ratio: 3 / 4 !important; }
}
@media (max-width: 560px) {
  .portfolio-grid { grid-template-columns: 1fr; }
}

/* Placeholder illustrations for tiles when no photograph is present */
.placeholder-tile {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--ivory);
}
.placeholder-tile.a { background: linear-gradient(135deg, #A84B1C 0%, #6B1E23 100%); }
.placeholder-tile.b { background: linear-gradient(135deg, #1E2A47 0%, #141E36 100%); }
.placeholder-tile.c { background: linear-gradient(135deg, #6D7860 0%, #4E5749 100%); }
.placeholder-tile.d { background: linear-gradient(135deg, #C97847 0%, #A84B1C 100%); }
.placeholder-tile.e { background: linear-gradient(135deg, #6B1E23 0%, #3E1013 100%); }
.placeholder-tile.f { background: linear-gradient(135deg, #1E2A47 0%, #6D7860 100%); }
.placeholder-tile.g { background: linear-gradient(135deg, #A84B1C 0%, #1E2A47 100%); }
.placeholder-tile__mark {
  font-family: var(--font-wordmark);
  font-size: 3rem;
  letter-spacing: 0.1em;
  opacity: 0.35;
}

/* ---------- 16. Testimonial ---------- */
.testimonial {
  background: var(--sage);
  color: var(--ivory);
  position: relative;
  overflow: hidden;
}
.testimonial__inner {
  max-width: 900px;
  margin-inline: auto;
  text-align: center;
}
.testimonial__quote {
  font-family: var(--wa-serif);
  font-size: clamp(1.5rem, 2.8vw, 2.5rem);
  line-height: 1.35;
  font-style: italic;
  color: var(--ivory);
  margin-block: 2rem 3rem;
  position: relative;
}
.testimonial__quote::before, .testimonial__quote::after {
  font-family: var(--font-display);
  font-size: 3em;
  line-height: 0;
  color: var(--terracotta);
  position: relative;
  vertical-align: -0.35em;
  opacity: 0.6;
}
.testimonial__quote::before { content: "\201C"; margin-right: 0.15em; }
.testimonial__quote::after  { content: "\201D"; margin-left: 0.15em; }
.testimonial__author {
  font-size: 0.75rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--ivory);
  opacity: 0.9;
}
.testimonial__author em { font-family: var(--wa-serif); text-transform: none; letter-spacing: 0; font-size: 1rem; color: var(--terracotta); font-style: italic; margin-left: 0.5em; }

/* ---------- 17. CTA band ---------- */
.cta-band {
  background: var(--navy);
  color: var(--ivory);
  position: relative;
  overflow: hidden;
}
.cta-band h2 { color: var(--ivory); }
.cta-band h2 em { color: var(--terracotta); font-style: italic; }
.cta-band__inner { display: grid; grid-template-columns: 1.4fr 1fr; gap: clamp(2rem, 5vw, 5rem); align-items: center; }
.cta-band .lead { color: rgba(245, 239, 228, 0.78); }
@media (max-width: 900px) { .cta-band__inner { grid-template-columns: 1fr; } }
.cta-band .botanical { color: var(--sage-mist); opacity: 0.18; }
.cta-band .botanical-cta { top: 10%; right: -80px; width: 320px; }

/* ---------- 18. Footer ---------- */
.footer { background: var(--navy-deep); color: var(--ivory); padding-top: clamp(3rem, 5vw, 5rem); position: relative; }
.footer__top { display: grid; grid-template-columns: 1.4fr repeat(3, 1fr); gap: 2rem; padding-bottom: 3rem; border-bottom: 1px solid rgba(245, 239, 228, 0.12); }
.footer__brand { font-family: var(--font-wordmark); font-size: 2.5rem; line-height: 1; letter-spacing: 0.04em; margin-bottom: 1rem; }
.footer__tag { font-family: var(--wa-serif); font-style: italic; opacity: 0.8; max-width: 32ch; }
.footer__col h5 { font-family: var(--font-body); font-size: 0.75rem; letter-spacing: 0.24em; text-transform: uppercase; color: var(--terracotta); margin-bottom: 1.25rem; font-weight: 500; }
.footer__col ul { list-style: none; display: flex; flex-direction: column; gap: 0.65rem; }
.footer__col a { color: rgba(245, 239, 228, 0.82); font-size: 0.95rem; transition: color var(--dur-micro); }
.footer__col a:hover { color: var(--terracotta); }
.footer__bottom { padding-block: 2rem; display: flex; justify-content: center; text-align: center; line-height: 2.2; align-items: center; font-size: 0.8rem; letter-spacing: 0.08em; color: rgba(245, 239, 228, 0.6); flex-wrap: wrap; gap: 1rem; }
@media (max-width: 900px) { .footer__top { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .footer__top { grid-template-columns: 1fr; } }

/* ---------- 19. About page ---------- */
.about-hero {
  padding-top: calc(var(--nav-height) + clamp(3rem, 8vw, 7rem));
  padding-bottom: clamp(4rem, 8vw, 8rem);
}
.about-hero__grid { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: clamp(2rem, 5vw, 5rem); align-items: center; }
.about-hero__portrait {
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-radius: 4px;
  position: relative;
  box-shadow: 0 40px 80px -30px rgba(30, 42, 71, 0.4);
}
.about-hero__portrait img { width: 100%; height: 100%; object-fit: cover; object-position: center 12%; }
.about-hero__caption {
  position: absolute; bottom: -20px; left: 20px;
  background: var(--terracotta);
  color: var(--ivory);
  padding: 0.8rem 1.5rem;
  font-family: var(--wa-serif);
  font-style: italic;
  font-size: 1.1rem;
  border-radius: 2px;
}
@media (max-width: 900px) { .about-hero__grid { grid-template-columns: 1fr; } }

.chapter {
  padding-block: clamp(3rem, 6vw, 6rem);
  border-top: 1px solid rgba(30, 42, 71, 0.12);
}
.chapter__grid { display: grid; grid-template-columns: 200px 1fr; gap: clamp(2rem, 5vw, 5rem); align-items: baseline; }
.chapter__number {
  font-family: var(--wa-serif);
  font-size: clamp(3rem, 5vw, 5rem);
  color: var(--rust);
  line-height: 1;
  font-style: italic;
}
.chapter__number span { display: block; font-family: var(--font-body); font-size: 0.7rem; letter-spacing: 0.28em; text-transform: uppercase; color: var(--navy); font-style: normal; margin-top: 0.5rem; }
.chapter__title { font-size: clamp(1.75rem, 3vw, 2.5rem); margin-bottom: 1.5rem; }
.chapter__body { max-width: 60ch; font-size: 1.0625rem; line-height: 1.75; color: var(--navy); }
.chapter__body p + p { margin-top: 1.25em; }
@media (max-width: 700px) { .chapter__grid { grid-template-columns: 1fr; gap: 1.5rem; } }

.values { background: var(--ivory-warm); }
.value-card {
  padding: clamp(2rem, 3vw, 2.5rem) clamp(1.5rem, 2vw, 2rem);
  border-radius: 4px;
  background: var(--ivory);
  border-top: 3px solid var(--rust);
}
.value-card:nth-child(2) { border-top-color: var(--terracotta); }
.value-card:nth-child(3) { border-top-color: var(--sage); }
.value-card:nth-child(4) { border-top-color: var(--burgundy); }
.value-card__title { font-family: var(--wa-serif); font-style: italic; font-size: 1.5rem; color: var(--navy); margin-bottom: 1rem; }

.signature-moment {
  background: var(--navy);
  color: var(--ivory);
  text-align: center;
  padding-block: clamp(5rem, 10vw, 10rem);
}
.signature-moment__quote {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4.5vw, 4rem);
  line-height: 1.15;
  max-width: 22ch;
  margin-inline: auto;
  color: var(--ivory);
}
.signature-moment__quote em { color: var(--terracotta); }
.signature-moment__signature {
  font-family: var(--font-script);
  font-size: 3.5rem;
  color: var(--terracotta);
  display: block;
  margin-top: 2rem;
  transform: rotate(-3deg);
}

/* ---------- 20. Portfolio page ---------- */
.portfolio-hero {
  padding-top: calc(var(--nav-height) + clamp(3rem, 8vw, 7rem));
  padding-bottom: clamp(3rem, 5vw, 5rem);
}
.portfolio-hero__title { max-width: 20ch; margin-bottom: 2rem; }
.portfolio-filters { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 2rem; }
.filter-chip {
  padding: 0.6rem 1.4rem;
  border: 1px solid rgba(30, 42, 71, 0.2);
  border-radius: 999px;
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--navy);
  transition: all var(--dur-standard) var(--ease-inout);
}
.filter-chip:hover { border-color: var(--navy); }
.filter-chip.is-active { background: var(--navy); color: var(--ivory); border-color: var(--navy); }

/* ---------- 21. Journal page ---------- */
.journal-hero {
  padding-top: calc(var(--nav-height) + clamp(3rem, 8vw, 7rem));
  padding-bottom: clamp(3rem, 5vw, 5rem);
}
.featured-essay {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
  padding-block: clamp(3rem, 5vw, 5rem);
  border-top: 1px solid rgba(30, 42, 71, 0.12);
  border-bottom: 1px solid rgba(30, 42, 71, 0.12);
}
.featured-essay__image { aspect-ratio: 4 / 3; overflow: hidden; border-radius: 4px; position: relative; }
.featured-essay__title { font-size: clamp(2rem, 3.5vw, 3rem); line-height: 1.1; margin-block: 1rem; }
.featured-essay__meta { display: flex; gap: 1.5rem; font-size: 0.75rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--navy); opacity: 0.8; margin-top: 1.5rem; }
@media (max-width: 900px) { .featured-essay { grid-template-columns: 1fr; } }

.journal-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(2rem, 3vw, 3rem); }
@media (max-width: 900px) { .journal-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .journal-grid { grid-template-columns: 1fr; } }

.journal-card { display: flex; flex-direction: column; gap: 1.25rem; }
.journal-card__image { aspect-ratio: 4 / 3; overflow: hidden; border-radius: 4px; position: relative; }
.journal-card__image::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 60%, rgba(30, 42, 71, 0.1) 100%);
  pointer-events: none;
}
.journal-card__image .placeholder-tile__mark { font-size: 2rem; }
.journal-card__image img { width: 100%; height: 100%; object-fit: cover; transition: transform 1s var(--ease-out); }
.journal-card:hover .journal-card__image img { transform: scale(1.05); }
.journal-card__category { font-size: 0.7rem; letter-spacing: 0.22em; text-transform: uppercase; color: var(--rust); }
.journal-card__title { font-family: var(--font-display); font-size: 1.35rem; line-height: 1.25; color: var(--navy); transition: color var(--dur-micro); }
.journal-card:hover .journal-card__title { color: var(--rust); }
.journal-card__meta { font-size: 0.8rem; color: var(--navy); opacity: 0.7; margin-top: 0.5rem; }

.newsletter {
  background: var(--sage);
  color: var(--ivory);
  padding-block: clamp(4rem, 7vw, 7rem);
  text-align: center;
}
.newsletter h2 { color: var(--ivory); max-width: 22ch; margin-inline: auto; }
.newsletter h2 em { color: var(--terracotta); }
.newsletter__form { display: flex; max-width: 480px; margin: 2rem auto 0; gap: 0.5rem; }
.newsletter__input {
  flex: 1;
  background: transparent;
  border: 1px solid var(--ivory);
  border-radius: 999px;
  padding: 0.9rem 1.5rem;
  color: var(--ivory);
  font-size: 0.9rem;
}
.newsletter__input::placeholder { color: rgba(245, 239, 228, 0.6); }
.newsletter__input:focus { outline: none; border-color: var(--terracotta); }
.newsletter__submit {
  padding: 0.9rem 1.75rem;
  border-radius: 999px;
  background: var(--ivory);
  color: var(--navy);
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  transition: background var(--dur-standard);
}
.newsletter__submit:hover { background: var(--terracotta); color: var(--ivory); }
@media (max-width: 560px) { .newsletter__form { flex-direction: column; } }

/* ---------- 22. Contact page ---------- 
   Deleted 25 Aug 2026 when contact.html was converted to the wa-*
   system. This held .contact, .contact__grid, .contact__form,
   .contact__info, .field* and the legacy .faq* accordion — 104 lines,
   all of which had exactly one consumer. The replacement is the
   CONTACT block near the end of this file.

   Note for the record: converting contact.html did NOT free
   --terracotta, as PROJECT-MASTER §2 predicted. None of its 38
   usages were in this section — they are in .hero-cine__*, .nav*,
   .newsletter__* and other legacy components that no live page uses.
   Retiring the variable is a separate job. */

/* ---------- 23. Utility ---------- */
.text-center { text-align: center; }
.mx-auto { margin-inline: auto; }
.mt-6 { margin-top: 1.5rem; } .mt-8 { margin-top: 2rem; } .mt-10 { margin-top: 3rem; }
.mb-6 { margin-bottom: 1.5rem; } .mb-8 { margin-bottom: 2rem; }
.hide-on-mobile { display: initial; }
@media (max-width: 700px) { .hide-on-mobile { display: none; } }

/* Prevent horizontal scroll edge cases */
main { overflow: clip; }


/* ============================================================
   WARM AUTUMN — post-hero page sections (2026 re-skin)
   Everything below is namespaced .wa-* so the legacy sections
   used by purpose/passion/contact/journal keep working.
   ============================================================ */

.wa { background: var(--wa-cream); color: var(--wa-ink);
  font-family: var(--wa-body); font-weight: 300; line-height: 1.8; }
.wa img { max-width: 100%; display: block; }
.wa-inner { max-width: 70rem; margin: 0 auto; padding: 0 clamp(1.2rem, 4vw, 3rem); }
.wa-label { font-family: var(--wa-label); font-weight: 400; font-size: 0.58rem;
  letter-spacing: 0.34em; text-transform: uppercase; }
.wa-dsp { color: var(--wa-espresso);
  font-family: var(--wa-display); font-weight: 400; text-transform: uppercase;
  letter-spacing: 0.18em; line-height: 1.24; }
.wa-rule { height: 1px;
  background: linear-gradient(90deg, transparent, var(--wa-rust), var(--wa-honey), transparent);
  opacity: 0.7; }
.wa-vert { writing-mode: vertical-rl; transform: rotate(180deg);
  font-family: var(--wa-label); font-weight: 400; font-size: 0.56rem;
  letter-spacing: 0.34em; text-transform: uppercase; color: var(--wa-ink-soft);
  white-space: nowrap; }

/* ============================================================
   INNER-PAGE COMPONENTS — 17 Aug
   Shared by purpose.html and passion.html so they run on the same palette and
   the same six faces as the home page. These replace the legacy .about-hero /
   .chapter / .values / .portfolio-* / .cta-band blocks, which are still used by
   contact.html and journal.html and so have NOT been deleted yet.
   ============================================================ */

/* --- write-up counts on the map ---
   A badge per country, sized off the plate so it scales with the map like the
   pins do. Only appears where a post is tagged with that country. */
.wa-map__count { position: absolute; transform: translate(-50%, -50%);
  display: grid; place-items: center;
  min-width: 1.55rem; height: 1.55rem; padding: 0 0.35rem;
  border-radius: 999px; background: var(--wa-rust); color: var(--wa-cream);
  border: 1.5px solid var(--wa-cream);
  box-shadow: 0 1px 6px rgba(44, 33, 25, 0.28);
  font-family: "Share Tech Mono", monospace; font-size: 0.66rem; line-height: 1;
  z-index: 4; cursor: pointer;
  transition: transform 260ms var(--ease-out), background 260ms var(--ease-out); }
.wa-map__count:hover { background: var(--wa-brick);
  transform: translate(-50%, -50%) scale(1.12); }
.wa-map__count b { font-weight: 400; }

/* the journal's empty state, until the first post exists */
.wa-blog__empty { max-width: 46ch; margin: 2.5rem auto 0; text-align: center;
  font-family: var(--wa-read); font-size: 0.86rem; line-height: 1.9;
  color: var(--wa-ink-soft); }
.wa-blog__empty code { font-family: "Share Tech Mono", monospace;
  font-size: 0.8rem; color: var(--wa-rust); }

/* --- the second tier of navigation ---
   Sits under the masthead on the pages that hang below it, so Purpose,
   Archive, Résumé, Journal and Volunteerism read as one section rather than
   five unrelated pages. Same type as the masthead links, deliberately. */
.wa-subnav { background: var(--wa-cream);
  /* the masthead is position:fixed, so this is the first thing in normal flow
     and would sit straight underneath it. Every section on these pages clears
     it with its own top padding; the subnav has to do the same. */
  /* +0.5rem because --nav-height is the masthead's MIN height; its padding
     pushes the real box past it, and the bar's text should not touch that edge. */
  margin-top: calc(var(--nav-height) + 0.5rem);
  /* No border-top. The masthead already draws a hairline along its own bottom
     edge, and this bar sits 3px below it — the two rendered as a double line
     above every LIFE/WORK page. The masthead's line is the one that stays,
     because it is the line the pages without a bar have too. */
  border-bottom: 1px solid rgba(46, 74, 62, 0.12); }
/* ---- the section row lives INSIDE the masthead (2 Sep 2026) ----
   Chosen from the A2 comparison in TO TUNE/subnav-options.html: header and
   section row as one block, separated by a soft inset hairline rather than
   the two stacked bars with a 3px gap between their borders.

   The consequence is that the row no longer sits in normal flow, so it is
   no longer what holds the page down below the fixed masthead. main.js
   measures the real header and publishes it as --nav-real; the fallback is
   the tallest the merged header gets, so a no-JS load still clears it. */
.masthead--sec { padding-bottom: 0; }
.masthead--sec .wa-subnav { margin-top: 0; background: none;
  border-top: 1px solid rgba(46, 74, 62, 0.10); border-bottom: 0; }
.masthead--sec .wa-subnav__row {
  padding: clamp(0.7rem, 1.6vw, 1rem) clamp(1rem, 4vw, 3rem)
           clamp(0.85rem, 1.9vw, 1.15rem); }
.masthead--sec ~ main .wa-head {
  padding-top: calc(var(--nav-real, 232px) + clamp(1.2rem, 3vw, 2.2rem)); }
.wa-subnav__row { display: flex; flex-wrap: wrap; justify-content: center;
  align-items: center; gap: clamp(0.6rem, 2vw, 1.3rem);
  padding: clamp(0.9rem, 2.2vw, 1.3rem) clamp(1rem, 4vw, 3rem); }
/* the section name, then the double rule, then its pages */
.wa-subnav__section { font-family: var(--wa-label); font-weight: 700;
  font-size: clamp(0.58rem, 1vw, 0.7rem); letter-spacing: 0.28em;
  text-transform: uppercase; color: var(--wa-espresso); }
.wa-subnav__sep { font-family: var(--wa-label); font-weight: 400;
  font-size: 0.72rem; letter-spacing: 0.08em; color: var(--wa-rust);
  user-select: none; margin: 0 0.2rem; }

.wa-subnav a { font-family: var(--wa-label); font-weight: 400;
  font-size: clamp(0.56rem, 0.95vw, 0.66rem); letter-spacing: 0.3em;
  text-transform: uppercase; color: var(--wa-ink-soft);
  padding-bottom: 0.35rem; border-bottom: 1px solid transparent;
  transition: color 300ms var(--ease-out), border-color 300ms var(--ease-out); }
.wa-subnav a:hover { color: var(--wa-rust); }
.wa-subnav a.is-here { color: var(--wa-rust); border-bottom-color: var(--wa-rust); }
.wa-subnav__slash { color: var(--wa-almond); font-family: var(--wa-label);
  font-size: 0.7rem; user-select: none; }

/* --- page opening --- */
.wa-head { background: var(--wa-cream); text-align: center;
  padding: clamp(4.5rem, 11vw, 8rem) 0 clamp(2.2rem, 5vw, 3.4rem); }
.wa-head__label { display: block; color: var(--wa-rust); margin-bottom: 1.1rem; }
.wa-head__title { font-size: clamp(1.5rem, 5vw, 3.1rem); margin: 0 auto;
  max-width: 18ch; }
.wa-head__lede { font-family: var(--wa-read);
  font-size: clamp(0.88rem, 1.15vw, 1.05rem); line-height: 1.95;
  letter-spacing: 0.03em; color: #3A3229; max-width: 52ch;
  margin: clamp(1.4rem, 3.5vw, 2.2rem) auto 0; }

/* --- the portrait --- */
.wa-portrait { background: var(--wa-cream);
  padding: clamp(1.4rem, 4vw, 2.6rem) 0 clamp(1rem, 3vw, 2rem); }
.wa-portrait figure { max-width: 32rem; margin: 0 auto; position: relative; }
.wa-portrait img { width: 100%; height: auto; }
/* the résumé wants a portrait at document scale, not a hero */
.wa-portrait--sm figure { max-width: 17rem; }

/* --- numbered chapters --- */
.wa-chapters { background: var(--wa-cream);
  padding: clamp(1.5rem, 4vw, 2.6rem) 0 clamp(3rem, 7vw, 5rem); }
.wa-chapter { max-width: 52rem; margin: 0 auto;
  padding: clamp(2rem, 5vw, 3.2rem) 0;
  border-top: 1px solid rgba(46, 74, 62, 0.14); }
.wa-chapter:first-child { border-top: 0; }
.wa-chapter__grid { display: grid; grid-template-columns: 7rem minmax(0, 1fr);
  gap: clamp(1.2rem, 4vw, 2.6rem); align-items: start; }
.wa-chapter__num { font-family: var(--wa-mono, "Share Tech Mono", monospace);
  font-size: 1.5rem; color: var(--wa-rust); line-height: 1; }
.wa-chapter__num span { display: block; margin-top: 0.7rem;
  font-family: var(--wa-label); font-weight: 400; font-size: 0.52rem;
  letter-spacing: 0.26em; text-transform: uppercase; color: var(--wa-ink-soft); }
.wa-chapter__title { font-family: var(--wa-serif); font-weight: 400;
  font-size: clamp(1.15rem, 2.6vw, 1.75rem); line-height: 1.35;
  color: var(--wa-espresso); margin-bottom: 1rem; }
.wa-chapter__title em { font-style: italic; color: var(--wa-rust); }
.wa-chapter__body p { font-family: var(--wa-read);
  font-size: clamp(0.86rem, 1.05vw, 0.98rem); line-height: 1.95;
  letter-spacing: 0.03em; color: #3A3229; max-width: 60ch; }
.wa-chapter__body p + p { margin-top: 1.1rem; }

/* --- four-up cards --- */
.wa-cards { background: var(--wa-cream);
  padding: clamp(2.4rem, 6vw, 4rem) 0 clamp(3rem, 7vw, 5rem); }
.wa-cards__head { text-align: center; margin-bottom: clamp(1.8rem, 4vw, 2.8rem); }
.wa-cards__head .wa-label { display: block; color: var(--wa-rust);
  margin-bottom: 0.9rem; }
.wa-cards__head h2 { font-size: clamp(1.15rem, 3vw, 1.9rem); }
.wa-cards__grid { display: grid; gap: clamp(1rem, 2.5vw, 1.6rem);
  grid-template-columns: repeat(4, minmax(0, 1fr)); }
.wa-card { padding: clamp(1.2rem, 3vw, 1.8rem);
  background: rgba(255, 255, 255, 0.42);
  border-top: 2px solid var(--wa-almond); }
.wa-card:nth-child(2) { border-top-color: var(--wa-rust); }
.wa-card:nth-child(3) { border-top-color: var(--wa-olive); }
.wa-card:nth-child(4) { border-top-color: var(--wa-teal); }
.wa-card__title { font-family: var(--wa-label); font-weight: 500; font-size: 0.6rem;
  letter-spacing: 0.26em; text-transform: uppercase; color: var(--wa-espresso);
  margin-bottom: 0.8rem; }
.wa-card p { font-family: var(--wa-body); font-weight: 300;
  font-size: clamp(0.78rem, 0.95vw, 0.86rem); line-height: 1.85;
  color: var(--wa-ink-soft); }

/* ---------- the four commitments ----------
   These carry class .wa-card, and so does every portfolio cover. The cover's
   rules are written later in this file and were winning: the espresso ground
   meant for a photograph, a 3/4 aspect ratio meant for a portrait, a scrim
   painted over static text, and a title left espresso on espresso — invisible.

   Everything below is scoped to .wa-cards__grid, which outranks the bare
   .wa-card selector, so the two can no longer be confused for one another. */
.wa-cards__grid .wa-card {
  position: static; display: block; overflow: visible;
  aspect-ratio: auto;
  background: none;
  color: var(--wa-espresso);
  padding: 0 clamp(1rem, 2.2vw, 1.8rem);
  border-top: 0;
  border-left: 1px solid var(--wa-almond);
}
.wa-cards__grid .wa-card:first-child { border-left: 0; padding-left: 0; }
/* the scrim belongs to a photograph; there is none here */
.wa-cards__grid .wa-card::before,
.wa-cards__grid .wa-card::after { content: none; }

.wa-cards__grid .wa-card__mark { display: block; }
.wa-cards__grid .wa-card__hex {
  display: block; width: 13px; height: 15px; margin: 0 0 0.9rem;
  background: var(--wa-almond);
  clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
}
.wa-cards__grid .wa-card:nth-child(2) .wa-card__hex { background: var(--wa-rust); }
.wa-cards__grid .wa-card:nth-child(3) .wa-card__hex { background: var(--wa-olive); }
.wa-cards__grid .wa-card:nth-child(4) .wa-card__hex { background: var(--wa-teal); }

.wa-cards__grid .wa-card__title {
  font-family: var(--wa-label); font-weight: 500; font-size: 0.6rem;
  letter-spacing: 0.26em; text-transform: uppercase;
  color: var(--wa-rust); margin: 0 0 0.7rem; text-shadow: none;
}
.wa-cards__grid .wa-card p {
  font-family: var(--wa-body); font-weight: 400;
  font-size: clamp(0.78rem, 0.95vw, 0.86rem); line-height: 1.85;
  color: var(--wa-ink-soft); margin: 0; max-width: 34ch;
}

/* Four columns plus a mark and a numeral is too much for a narrow screen:
   the dividing rules go and the four stack into two, then one. */
@media (max-width: 1000px) {
  .wa-cards__grid { grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(1.4rem, 3vw, 2.2rem); }
  .wa-cards__grid .wa-card { border-left: 0; padding-left: 0; }
}
@media (max-width: 560px) {
  .wa-cards__grid { grid-template-columns: minmax(0, 1fr); }
}

/* --- the pulled quote --- */
.wa-quote { background: var(--wa-linen); text-align: center;
  padding: clamp(3rem, 8vw, 5.5rem) 0; }
.wa-quote blockquote { font-family: var(--wa-serif); font-style: italic;
  font-weight: 400; font-size: clamp(1.1rem, 3vw, 2rem); line-height: 1.5;
  color: var(--wa-espresso); max-width: 24ch; margin: 0 auto; }
.wa-quote blockquote em { font-style: italic; color: var(--wa-rust); }
.wa-quote__sig { display: block; margin-top: 1.6rem;
  font-family: var(--wa-serif); font-style: italic;
  font-size: clamp(1rem, 2.2vw, 1.3rem); color: var(--wa-caramel); }

/* --- closing band, espresso like the WORK wedge --- */
.wa-cta { background: var(--wa-espresso); color: var(--wa-cream);
  padding: clamp(3rem, 8vw, 5.5rem) 0; }
.wa-cta__inner { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.6rem, 5vw, 3.5rem); align-items: center; }
.wa-cta .wa-label { display: block; color: var(--wa-honey);
  margin-bottom: 0.9rem; }
.wa-cta h2 { color: var(--wa-cream);
  font-family: var(--wa-display); font-weight: 400; text-transform: uppercase;
  letter-spacing: 0.16em; line-height: 1.3;
  font-size: clamp(1.1rem, 3vw, 1.9rem); }
.wa-cta p { font-family: var(--wa-read);
  font-size: clamp(0.86rem, 1.05vw, 0.98rem); line-height: 1.9;
  letter-spacing: 0.03em; color: rgba(247, 241, 228, 0.82); max-width: 42ch; }
.wa-cta__link { display: inline-block; margin-top: clamp(1.2rem, 3vw, 1.8rem);
  font-family: var(--wa-label); font-weight: 500; font-size: 0.58rem;
  letter-spacing: 0.28em; text-transform: uppercase;
  color: var(--wa-cream); padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--wa-rust);
  transition: color 300ms var(--ease-out), border-color 300ms var(--ease-out); }
.wa-cta__link:hover { color: var(--wa-honey); border-bottom-color: var(--wa-honey); }

/* --- CliftonStrengths, two takes side by side ---
   Two assessments four years apart, so the interesting thing is what held and
   what moved. Themes present in both carry an olive marker. */
.wa-str { display: grid; gap: clamp(1.6rem, 5vw, 3.5rem);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  max-width: 52rem; margin: 0 auto; }
.wa-str__head { padding-bottom: 0.8rem; margin-bottom: 0.5rem;
  border-bottom: 1px solid rgba(46, 74, 62, 0.16); }
.wa-str__take { font-family: var(--wa-display); font-weight: 400;
  text-transform: uppercase; letter-spacing: 0.18em;
  font-size: clamp(0.8rem, 1.6vw, 1rem); color: var(--wa-espresso); }
.wa-str__meta { margin-top: 0.45rem;
  font-family: "Share Tech Mono", monospace; font-size: 0.66rem;
  letter-spacing: 0.06em; color: var(--wa-ink-soft); }
.wa-str__meta em { font-style: normal; color: var(--wa-rust); }

.wa-str__row { display: grid; grid-template-columns: 2.1rem minmax(0, 1fr) 0.9rem;
  align-items: baseline; gap: 0.5rem; padding: 0.7rem 0;
  border-top: 1px solid rgba(46, 74, 62, 0.08); }
.wa-str__row:first-of-type { border-top: 0; }
.wa-str__n { font-family: "Share Tech Mono", monospace; font-size: 0.72rem;
  color: var(--wa-rust); }
.wa-str__name { font-family: var(--wa-label); font-weight: 500;
  font-size: clamp(0.62rem, 1.1vw, 0.72rem); letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--wa-espresso); }
.wa-str__row.is-kept .wa-str__name { color: var(--wa-olive); }
.wa-str__dot { justify-self: end; width: 0.42rem; height: 0.42rem;
  border-radius: 50%; background: transparent; }
.wa-str__row.is-kept .wa-str__dot { background: var(--wa-olive); }

.wa-str__key { max-width: 52rem; margin: clamp(1.4rem, 3.5vw, 2.2rem) auto 0;
  display: flex; align-items: center; justify-content: center; gap: 0.5rem;
  font-family: var(--wa-label); font-weight: 400; font-size: 0.52rem;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--wa-ink-soft); }
.wa-str__key i { width: 0.42rem; height: 0.42rem; border-radius: 50%;
  background: var(--wa-olive); display: inline-block; }

@media (max-width: 620px) {
  .wa-str { grid-template-columns: minmax(0, 1fr); }
}

/* --- the résumé ---
   Dates in Share Tech Mono like the hero dials, roles in Poppins caps like every
   other label on the site, organisations in Playfair italic, and the bullets in
   Gentium. The ">" markers are the live site's own and are kept. */
.wa-cv { background: var(--wa-cream);
  padding: clamp(1.4rem, 4vw, 2.4rem) 0 clamp(2.6rem, 6vw, 4rem); }
.wa-cv__group { max-width: 54rem; margin: 0 auto; }
.wa-cv__group + .wa-cv__group { margin-top: clamp(2.6rem, 7vw, 4.5rem); }
.wa-cv__title { text-align: center; font-size: clamp(0.95rem, 2.6vw, 1.5rem);
  margin-bottom: 0.9rem; }
.wa-cv__group > .wa-rule { margin-bottom: clamp(1.2rem, 3vw, 2rem); }

.wa-cv__entry { display: grid; grid-template-columns: 11rem minmax(0, 1fr);
  gap: clamp(0.9rem, 3vw, 2.2rem);
  padding: clamp(1.1rem, 3vw, 1.7rem) 0;
  border-top: 1px solid rgba(46, 74, 62, 0.12); }
.wa-cv__entry:first-of-type { border-top: 0; }
.wa-cv__when { font-family: "Share Tech Mono", monospace;
  font-size: 0.72rem; letter-spacing: 0.08em; color: var(--wa-rust);
  text-transform: uppercase; line-height: 1.7; }
.wa-cv__role { font-family: var(--wa-label); font-weight: 500;
  font-size: clamp(0.6rem, 1.1vw, 0.7rem); letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--wa-espresso); line-height: 1.75; }
.wa-cv__org { font-family: var(--wa-serif); font-style: italic;
  font-size: clamp(0.82rem, 1.1vw, 0.95rem); color: var(--wa-caramel);
  margin-top: 0.45rem; }
.wa-cv__org span { color: var(--wa-ink-soft); font-style: italic; }

.wa-cv__points { list-style: none; margin-top: 0.9rem; }
.wa-cv__points li { position: relative; padding-left: 1.1rem;
  font-family: var(--wa-read);
  font-size: clamp(0.8rem, 0.98vw, 0.9rem); line-height: 1.9;
  letter-spacing: 0.03em; color: #3A3229; max-width: 62ch; }
.wa-cv__points li + li { margin-top: 0.5rem; }
.wa-cv__points li::before { content: ">"; position: absolute; left: 0; top: 0;
  font-family: "Share Tech Mono", monospace; color: var(--wa-rust);
  opacity: 0.75; }

/* year-grouped bullets, used by the volunteer entry that has no organisation */
.wa-cv__year { font-family: "Share Tech Mono", monospace;
  font-size: 0.72rem; letter-spacing: 0.08em; color: var(--wa-olive);
  margin-top: 1.1rem; }
.wa-cv__year + .wa-cv__points { margin-top: 0.5rem; }

@media (max-width: 640px) {
  .wa-cv__entry { grid-template-columns: minmax(0, 1fr); gap: 0.5rem; }
}

/* --- the work archive ---
   Photo-backed cards: a kicker, the name, a number, and a rule along the
   bottom, with the blurb and DISCOVER revealed on hover/focus. Covers are
   pre-cropped to 3:4 in assets/img/portfolio/_covers/ so the grid stays light.
   Dutertismo has no recoverable media, so it falls back to a palette ground. */
.wa-work { background: var(--wa-cream);
  padding: clamp(1rem, 3vw, 2rem) 0 clamp(3rem, 7vw, 5rem); }

.wa-filters { display: flex; flex-wrap: wrap; justify-content: center;
  gap: clamp(0.5rem, 1.6vw, 0.9rem);
  margin-bottom: clamp(1.6rem, 4vw, 2.6rem); }
.wa-filter { font-family: var(--wa-label); font-weight: 400; font-size: 0.56rem;
  letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--wa-ink-soft); background: transparent; cursor: pointer;
  border: 1px solid var(--wa-almond); padding: 0.6rem 1.1rem;
  transition: color 280ms var(--ease-out), border-color 280ms var(--ease-out),
              background 280ms var(--ease-out); }
.wa-filter:hover { color: var(--wa-rust); border-color: var(--wa-rust); }
.wa-filter.is-on { background: var(--wa-sage); border-color: var(--wa-sage);
  color: var(--wa-cream); }

.wa-work__grid { display: grid; gap: clamp(0.5rem, 1.4vw, 0.9rem);
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }

.wa-card { position: relative; display: block; overflow: hidden;
  aspect-ratio: 3 / 4; background: var(--wa-espresso); color: var(--wa-cream); }
.wa-card[hidden] { display: none; }
.wa-card__img { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; transform: scale(1.02);
  transition: transform 900ms var(--ease-out); }
.wa-card:hover .wa-card__img,
.wa-card:focus-visible .wa-card__img { transform: scale(1.08); }
/* legibility over any photograph, without flattening it */
.wa-card::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(44,33,25,0.78) 0%, rgba(44,33,25,0.40) 34%,
              rgba(44,33,25,0.28) 55%, rgba(44,33,25,0.55) 78%, rgba(44,33,25,0.86) 100%);
  transition: background 500ms var(--ease-out); }
.wa-card:hover::before,
.wa-card:focus-visible::before {
  background: linear-gradient(180deg, rgba(44,33,25,0.88) 0%, rgba(44,33,25,0.72) 50%,
              rgba(44,33,25,0.92) 100%); }

.wa-card__body { position: relative; height: 100%; display: flex;
  flex-direction: column; padding: clamp(1rem, 2.4vw, 1.5rem); }
.wa-card__kicker { font-family: var(--wa-label); font-weight: 400; font-size: 0.46rem;
  letter-spacing: 0.34em; text-transform: uppercase;
  color: rgba(247, 241, 228, 0.92);
  text-shadow: 0 1px 6px rgba(44, 33, 25, 0.75); }
.wa-card__name { margin-top: 0.5rem;
  font-family: var(--wa-label); font-weight: 700;
  font-size: clamp(1.05rem, 2.6vw, 1.55rem); letter-spacing: 0.01em;
  line-height: 1.1; color: var(--wa-cream);
  text-shadow: 0 2px 12px rgba(44, 33, 25, 0.8), 0 1px 3px rgba(44, 33, 25, 0.6); }
/* the rule that grows out of the name, as in the reference */
.wa-card__name::after { content: ""; display: block; height: 1px; width: 0;
  margin-top: 0.55rem; background: rgba(247, 241, 228, 0.9);
  transition: width 620ms var(--ease-out); }
.wa-card:hover .wa-card__name::after,
.wa-card:focus-visible .wa-card__name::after { width: 2.6rem; }


.wa-card__no { margin-top: auto; text-align: right;
  font-family: "Share Tech Mono", monospace; font-weight: 400;
  font-size: clamp(1.5rem, 3.6vw, 2.3rem); line-height: 1;
  color: var(--wa-cream);
  text-shadow: 0 2px 12px rgba(44, 33, 25, 0.8); }
.wa-card__rule { position: absolute; left: clamp(1rem, 2.4vw, 1.5rem);
  right: clamp(1rem, 2.4vw, 1.5rem); bottom: clamp(0.7rem, 1.6vw, 1rem);
  height: 1px; background: rgba(247, 241, 228, 0.32); }
.wa-card__rule::after { content: ""; position: absolute; inset: 0 auto 0 0;
  width: 0; background: var(--wa-cream);
  transition: width 720ms var(--ease-out); }
.wa-card:hover .wa-card__rule::after,
.wa-card:focus-visible .wa-card__rule::after { width: 100%; }

/* no artwork for this one — keep the format, drop the photograph */
.wa-card--flat { background: var(--wa-brick); }
.wa-card--flat::before { background: linear-gradient(180deg,
  rgba(44,33,25,0.25) 0%, rgba(44,33,25,0.1) 45%, rgba(44,33,25,0.45) 100%); }

@media (hover: none) {
  .wa-card__name::after { width: 2.6rem; }
}

/* --- a piece's own page: photographs and films ---
   Everything here is served from assets/img/portfolio/. The films are YouTube,
   but the poster frames are local too, so a page paints before it ever touches
   youtube.com — the iframe is only built when someone actually presses play. */
.wa-piece { background: var(--wa-cream);
  padding: clamp(1rem, 3vw, 2rem) 0 clamp(3rem, 7vw, 5rem); }
.wa-piece + .wa-piece { padding-top: 0; }
.wa-piece__label { display: block; text-align: center; color: var(--wa-rust);
  margin-bottom: clamp(1.2rem, 3vw, 1.8rem); }

.wa-gal { display: grid; gap: clamp(0.4rem, 1.2vw, 0.7rem);
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }
.wa-gal img { width: 100%; height: 100%; aspect-ratio: 4 / 3;
  object-fit: cover; display: block; background: var(--wa-linen); }

.wa-vids { display: grid; gap: clamp(0.5rem, 1.4vw, 0.9rem);
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); }
/* ---------- the film frame ----------
   Every still that opens a film wears the same frame the WORK panel uses: at
   rest it is simply the picture, and on hover the four camera marks crawl out
   until they close into one honey hairline, a veil comes up, and the hexagon
   play mark arrives in the middle. Nothing is printed on the still until the
   pointer is there.

   The marks, the veil and the play mark are built in main.js — a button that
   carried them in its markup would have to carry them on eleven pages. */
.wa-yt { position: relative; display: block; width: 100%; padding: 0; border: 0;
  background: #000; cursor: pointer; overflow: hidden;
  aspect-ratio: 16 / 9; }
.wa-yt img { width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform 620ms cubic-bezier(.16, 1, .3, 1), opacity 320ms ease; }
.wa-yt:hover img { transform: scale(1.03); opacity: 0.86; }
.wa-yt iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* flat black at 75%, on hover only — the same veil the covers wear */
.wa-film__veil { position: absolute; inset: 0; z-index: 1; pointer-events: none;
  opacity: 0; background: rgb(0 0 0 / var(--film-veil-a, 0.75));
  transition: opacity 420ms ease; }
.wa-yt:hover .wa-film__veil { opacity: 1; }

.wa-film__tick { position: absolute; z-index: 2;
  width: var(--tick, 20px); height: var(--tick, 20px);
  pointer-events: none; border: 0 solid var(--wa-cream); opacity: 0.85;
  transition: width 760ms cubic-bezier(.16, 1, .3, 1),
              height 760ms cubic-bezier(.16, 1, .3, 1),
              border-color 420ms ease, opacity 420ms ease; }
.wa-film__tick--t1 { left: 12px;  top: 12px;    border-left-width: 1px;  border-top-width: 1px; }
.wa-film__tick--t2 { right: 12px; top: 12px;    border-right-width: 1px; border-top-width: 1px; }
.wa-film__tick--t3 { left: 12px;  bottom: 12px; border-left-width: 1px;  border-bottom-width: 1px; }
.wa-film__tick--t4 { right: 12px; bottom: 12px; border-right-width: 1px; border-bottom-width: 1px; }
/* the colour runs with the crawl, not after it */
.wa-yt:hover .wa-film__tick { width: calc(50% - 12px); height: calc(50% - 12px);
  border-color: var(--wa-honey); opacity: 1;
  transition: width 760ms cubic-bezier(.16, 1, .3, 1),
              height 760ms cubic-bezier(.16, 1, .3, 1),
              border-color 300ms ease, opacity 420ms ease; }

.wa-film__play { position: absolute; z-index: 2; left: 50%; top: 50%;
  width: var(--play-size, 52px); height: var(--play-size, 52px);
  transform: translate(-50%, -50%) scale(0.8); opacity: 0;
  background: var(--wa-cream);
  clip-path: polygon(50% 0%, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%);
  display: grid; place-items: center; pointer-events: none;
  transition: opacity 300ms ease, transform 460ms cubic-bezier(.16, 1, .3, 1),
              background 320ms ease; }
.wa-yt:hover .wa-film__play { opacity: 1; transform: translate(-50%, -50%) scale(1);
  background: var(--wa-honey); }
.wa-film__play::after { content: ""; width: 0; height: 0; margin-left: 4px;
  border-left: 14px solid var(--wa-espresso);
  border-top: 9px solid transparent; border-bottom: 9px solid transparent; }

/* The word, in the film frame's own hairline box. It starts in the dead centre
   and steps down into place as the marks close, widening its tracking as it
   goes — the same arrival the WORK panel gives it. Its fade is held back a
   beat so it is invisible while it passes the play mark. */
.wa-film__kind { position: absolute; z-index: 2; left: 50%;
  top: var(--kind-y, 50%); transform: translate(-50%, -50%);
  pointer-events: none; white-space: nowrap;
  font-family: var(--wa-label); font-weight: 500; font-size: 0.5rem;
  letter-spacing: 0.3em; text-transform: uppercase; text-indent: 0.3em;
  color: var(--wa-honey); border: 1px solid var(--wa-honey);
  padding: 0.42rem 0.75rem 0.34rem; opacity: 0;
  transition: top 560ms cubic-bezier(.16, 1, .3, 1),
              letter-spacing 620ms cubic-bezier(.16, 1, .3, 1),
              opacity 320ms ease 140ms; }
.wa-yt:hover .wa-film__kind { top: var(--kind-y-hover, 76%);
  letter-spacing: 0.38em; opacity: 1; }

/* once the film itself is playing the frame has nothing left to say */
.wa-yt.is-live .wa-film__veil,
.wa-yt.is-live .wa-film__tick,
.wa-yt.is-live .wa-film__play,
.wa-yt.is-live .wa-film__kind { display: none; }

/* --- what she actually did, copied from the source pages --- */
.wa-piece__kicker { display: block; text-align: center;
  font-family: var(--wa-label); font-weight: 400; font-size: 0.54rem;
  letter-spacing: 0.26em; text-transform: uppercase; color: var(--wa-ink-soft);
  margin-bottom: clamp(1.4rem, 3.5vw, 2.2rem); }

/* a film with its own caption and role beneath it */
.wa-film { display: block; }
.wa-film__cap { display: block; margin-top: 0.7rem;
  font-family: var(--wa-read); font-size: clamp(0.76rem, 0.95vw, 0.86rem);
  line-height: 1.6; letter-spacing: 0.02em; color: var(--wa-espresso); }
.wa-film__role { display: block; margin-top: 0.28rem;
  font-family: var(--wa-label); font-weight: 400; font-size: 0.5rem;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--wa-rust);
  line-height: 1.7; }

/* the credits block, used when entries cannot be matched one-to-one */
.wa-credits { max-width: 46rem; margin: 0 auto clamp(1.8rem, 4vw, 2.6rem); }
.wa-credits__row { padding: 0.85rem 0;
  border-top: 1px solid rgba(46, 74, 62, 0.14); }
.wa-credits__row:first-child { border-top: 0; }
.wa-credits__what { font-family: var(--wa-read);
  font-size: clamp(0.82rem, 1vw, 0.92rem); line-height: 1.65;
  color: var(--wa-espresso); }
.wa-credits__role { margin-top: 0.3rem;
  font-family: var(--wa-label); font-weight: 400; font-size: 0.52rem;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--wa-rust);
  line-height: 1.7; }

/* --- disciplines, for the work page --- */
.wa-disc { background: var(--wa-cream);
  padding: clamp(1.5rem, 4vw, 2.6rem) 0 clamp(3rem, 7vw, 5rem); }
.wa-disc__list { max-width: 56rem; margin: 0 auto; }
.wa-disc__item { display: grid; grid-template-columns: 4.5rem minmax(0, 1fr);
  gap: clamp(1rem, 3vw, 2.2rem); align-items: baseline;
  padding: clamp(1.4rem, 3.5vw, 2.2rem) 0;
  border-top: 1px solid rgba(46, 74, 62, 0.14); }
.wa-disc__no { font-family: var(--wa-mono, "Share Tech Mono", monospace);
  font-size: 0.8rem; color: var(--wa-rust); letter-spacing: 0.1em; }
.wa-disc__name { font-family: var(--wa-display); font-weight: 400;
  text-transform: uppercase; letter-spacing: 0.16em;
  font-size: clamp(0.92rem, 2.2vw, 1.35rem); color: var(--wa-espresso);
  margin-bottom: 0.7rem; }
.wa-disc__note { font-family: var(--wa-read);
  font-size: clamp(0.84rem, 1vw, 0.95rem); line-height: 1.9;
  letter-spacing: 0.03em; color: #3A3229; max-width: 58ch; }

@media (max-width: 760px) {
  .wa-cards__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .wa-cta__inner { grid-template-columns: minmax(0, 1fr); }
  .wa-chapter__grid { grid-template-columns: minmax(0, 1fr); gap: 0.9rem; }
  .wa-chapter__num { display: flex; align-items: baseline; gap: 0.9rem; }
  .wa-chapter__num span { margin-top: 0; }
}
@media (max-width: 520px) {
  .wa-cards__grid { grid-template-columns: minmax(0, 1fr); }
  .wa-disc__item { grid-template-columns: minmax(0, 1fr); gap: 0.5rem; }
}

/* ---------- 0 · INTRODUCTION ---------- */
.wa-intro { padding: clamp(3rem, 8vw, 6rem) 0 clamp(2rem, 5vw, 3.4rem);
  background: var(--wa-cream); text-align: center; }
/* Five roles then the turn. The credential list and the human line are set
   as two beats rather than one run-on sentence — at this length they would
   otherwise wrap into an undifferentiated block and the turn would be lost
   mid-line. */
.wa-intro__pos {
  font-family: var(--wa-serif); font-style: italic;
  font-size: clamp(1.25rem, 3.2vw, 2.15rem);
  line-height: 1.42; color: var(--wa-espresso);
  /* Wide enough that the turn holds one line on desktop — it is the longer of
     the two beats, so it sets the measure, not the roles. */
  max-width: 46ch; margin: 0 auto;
}
.wa-intro__pos .roles { display: block; }
.wa-intro__pos .turn  { display: block; margin-top: 0.45em; }
.wa-intro__me {
  font-family: var(--wa-read);
  font-size: clamp(0.88rem, 1.1vw, 1.02rem);
  line-height: 1.95; letter-spacing: 0.03em;
  color: #3A3229; max-width: 46ch;
  margin: clamp(1.4rem, 3.5vw, 2.2rem) auto 0;
}
/* Three beats, not one block: the greeting, the paragraph, and the line it
   lands on. Only the middle one is allowed to wrap. */
.wa-intro__me .hi,
.wa-intro__me .mid,
.wa-intro__me .end { display: block; }
.wa-intro__me .mid { margin-top: 0.5em; }
.wa-intro__me .end { margin-top: 0.5em; }

/* ---------- 6b · THE MAP ---------- */
/* No heading of its own since 16 Aug — it reads as the picture the country
   list is talking about, so it sits tight under it. The section keeps its
   aria-label for anyone who cannot see the pins. */
.wa-map { padding: 0 0 clamp(3rem, 7vw, 5rem);
  background: var(--wa-cream); }

.wa-map__legend { display: flex; justify-content: center; flex-wrap: wrap;
  gap: clamp(1rem, 3vw, 2.2rem); margin: 0 0 clamp(1rem, 2.5vw, 1.5rem); }
.wa-map__legend span { display: inline-flex; align-items: center;
  font-family: var(--wa-label); font-weight: 400; font-size: 0.54rem;
  letter-spacing: 0.24em; text-transform: uppercase; color: var(--wa-ink-soft); }
.wa-map__legend span::before {
  content: ""; width: 0.5rem; height: 0.5rem; border-radius: 50%;
  margin-right: 0.5rem;
}
.wa-map__legend .is-been::before { background: var(--wa-olive); border-radius: 1.5px; }
.wa-map__legend .is-want::before { background: var(--wa-rust);
  width: 0.32rem; height: 0.32rem; border-radius: 50%; margin-left: 0.09rem;
  margin-right: 0.59rem; }
.wa-map__legend .is-both::before { border-radius: 1.5px;
  background: radial-gradient(circle at 50% 50%,
              var(--wa-rust) 0 0.1rem, var(--wa-olive) 0.1rem); }

/* Two transparent layers over the section's own ground, so the map reads as
   paper rather than as a pasted-in picture. The plate carries the map's aspect
   ratio itself, because both images are absolutely positioned and so cannot
   set the height. container-type lets the labels below size in cqw. */
.wa-map__plate {
  position: relative; max-width: 62rem; margin: 0 auto;
  aspect-ratio: 1920 / 1152;
  container-type: inline-size;
}
.wa-map__plate img { position: absolute; inset: 0;
  width: 100%; height: 100%; display: block; }
/* Her values, dialled in on map-labels.html: softer fills, firmer outlines. */
.wa-map__fills { opacity: var(--map-fill-alpha, 0.5); }
.wa-map__lines { opacity: var(--map-line-alpha, 0.75); }

/* A place is a zero-size anchor point; the dot, the leader and the tag all hang
   off it, so the % position stays the single source of truth. */
.wa-map__place { position: absolute; width: 0; height: 0; }

/* 0.2rem is hers. Set as the var() fallback rather than as a declaration on
   this element, so the smaller mobile value below still wins by inheritance. */
.wa-map__dot {
  position: absolute; left: 0; top: 0;
  width: var(--map-dot, 0.2rem); height: var(--map-dot, 0.2rem);
  margin: calc(var(--map-dot, 0.2rem) / -2);
  border-radius: 50%; background: var(--wa-rust);
}
/* visited, and going back — the country is already filled, so the dot needs a
   ring to stay legible where it sits on the green */
.wa-map__place.is-both .wa-map__dot {
  box-shadow: 0 0 0 1.5px var(--wa-cream);
}

/* hairline from the dot out to its tag, so the fanned-out European labels
   still say which country they belong to */
.wa-map__lead {
  position: absolute; left: 0; top: 0; height: 0;
  width: calc(hypot(var(--dx), var(--dy)) * 1cqw);
  border-top: 1px solid var(--wa-almond);
  transform: rotate(atan2(var(--dy), var(--dx)));
  transform-origin: 0 0;
}
@supports not (width: calc(hypot(1, 1) * 1cqw)) {
  .wa-map__lead { display: none; }
}

.wa-map__tag {
  position: absolute; left: 0; top: 0;
  transform: translate(calc(var(--dx) * 1cqw), calc(var(--dy) * 1cqw - 50%));
  padding-left: 0.3rem; white-space: nowrap;
  font-family: var(--wa-label); font-weight: 400;
  font-size: clamp(0.4rem, 1.05cqw, 0.54rem);
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--wa-sage);
  /* a halo instead of a chip — keeps it legible over the fills without
     dropping a box onto the paper */
  text-shadow: 0 0 3px var(--wa-cream), 0 0 5px var(--wa-cream),
               0 0 7px var(--wa-cream);
}
/* tags that sit to the left of their dot hang off their own right edge */
.wa-map__place.is-l .wa-map__tag {
  transform: translate(calc(var(--dx) * 1cqw - 100%), calc(var(--dy) * 1cqw - 50%));
  padding-left: 0; padding-right: 0.3rem;
}

/* Too tight for leadered labels — keep the dots, drop the wiring. The full
   list is in the visually-hidden paragraph and in "Places I will travel for". */
@media (max-width: 700px) {
  .wa-map__tag, .wa-map__lead { display: none; }
  /* kept proportionally under the desktop dot, as it was at 0.26 against 0.3 */
  .wa-map__place { --map-dot: 0.17rem; }
}

/* ---------- 6c · THE ADVENTURE LINE ----------
   A statement, not a call to action: no link, no rule under it. It carries no
   padding of its own — the map's bottom padding and Currently's top padding
   already frame it, and adding more opened a hole between the two.
   max-width: none undoes the global `p { max-width: var(--max-prose) }`, which
   would otherwise cap the line at prose width and centre it inside that narrow
   box, so it reads as left-aligned. */
/* Bottom padding matched to the top of "Places" above, so the line gets the
   same amount of air under it that the heading up there gets over it. */
.wa-adventure { background: var(--wa-cream);
  padding: 0 0 clamp(3rem, 7vw, 5.5rem); }
.wa-adventure p { text-align: center; max-width: none;
  font-family: var(--wa-label); font-weight: 500; font-size: 0.56rem;
  letter-spacing: 0.3em; text-transform: uppercase; color: var(--wa-rust); }

/* "Currently" was removed on 16 Aug, and with it .wa-currently. */

/* ---------- 8 · CLOSING ----------
   The "Enter my world" button went on 16 Aug and .wa-closing__cta went with
   it — but a Let's talk / See the work pair was later put back in the markup
   without its rule ever being restored, so it had NO styling at all.

   That is trap 2 in the project master, and it bit exactly as described: the
   global `p { max-width: var(--max-prose) }` boxed the CTA at 72ch, and the
   section's `text-align: center` then centred it inside THAT box rather than
   inside the section. Measured, the links sat 109px left of centre while the
   line above them was centred — which is why it read as misaligned rather
   than as obviously broken. `max-width: none` plus `margin: auto` fixes it. */
.wa-closing { padding: clamp(3rem, 8vw, 5.5rem) 0 clamp(3.5rem, 9vw, 6rem);
  background: var(--wa-linen); text-align: center; }
.wa-closing__cta { max-width: none;
  margin: clamp(1.8rem, 4.5vw, 2.8rem) auto 0;
  display: flex; flex-wrap: wrap; justify-content: center;
  align-items: flex-start; gap: 0 clamp(1.4rem, 4vw, 2.6rem); }

/* Her reference is cream-on-espresso; this section is linen, so the ink goes
   to espresso and the rule stays rust. The arrow is a pseudo-element, not
   typed into the markup, so the link text stays readable to a screen reader.

   These links deliberately no longer carry .masthead__link. That class owns
   an absolutely-positioned ::after — the hover underline that wipes in from
   the left — and putting `content: "→"` on it inherited position:absolute,
   bottom:-2px and left:0, so the arrow rendered as a box UNDER the rule
   instead of after the words. Borrowing the class also dragged in --navy,
   which is not a Warm Autumn colour. The type is restated here instead. */
.wa-closing__cta a {
  display: inline-flex; align-items: baseline;
  gap: clamp(0.7rem, 2vw, 1.1rem);
  /* the same lettering as the section bar: same face, size and tracking */
  font-family: var(--wa-label), sans-serif; font-weight: 400;
  font-size: clamp(0.56rem, 0.95vw, 0.66rem);
  letter-spacing: 0.3em; text-transform: uppercase; white-space: nowrap;
  /* NOT the bar's --wa-ink-soft. That is #5A6B60, and this section sits on
     linen #D9C9AC, where it measures 3.5:1 — under the 4.5 minimum for text
     this small. The palette notes say only Espresso, Teal and Deep Sage hold
     small text on Linen; espresso gives 9.6:1 here. */
  color: var(--wa-espresso);
  padding: 0 clamp(0.2rem, 1vw, 0.5rem) clamp(0.6rem, 1.6vw, 0.85rem);
  border-bottom: 1px solid var(--wa-rust);
  transition: color 300ms var(--ease-out), border-color 300ms var(--ease-out); }
.wa-closing__cta a::after {
  content: "\2192";
  font-family: var(--wa-body); letter-spacing: 0;
  transition: transform 300ms var(--ease-out); }
.wa-closing__cta a:hover,
.wa-closing__cta a:focus-visible { color: var(--wa-rust); }
.wa-closing__cta a:hover::after { transform: translateX(0.22em); }
.wa-closing__slash { font-family: var(--wa-label); font-size: 0.7rem;
  color: var(--wa-almond); user-select: none; align-self: baseline; }

.wa-closing__line { color: var(--wa-espresso);
  font-family: var(--wa-display); font-weight: 400;
  text-transform: uppercase; letter-spacing: 0.18em; line-height: 1.35;
  font-size: clamp(1.1rem, 3.2vw, 2.1rem);
  max-width: 18ch; margin: 0 auto; }

/* The seam under the diagonal.
   The espresso wedge is a clip-path on a section whose OWN background is
   cream, and the section's bottom edge lands on a fractional pixel — 3968.82
   at 1440x900. The last sub-pixel row of the clip is therefore not fully
   painted and the cream ground underneath shows through as a pale hairline,
   which against the sage band below reads as a white line.

   Pulling the band up 1px covers it. Scoped with the sibling selector so it
   only touches this one seam; .wa-band is not given a blanket negative margin.
   Do NOT "fix" this by giving .wa-split an espresso background instead — the
   same sliver exists along its TOP edge, where the wedge is cream, and that
   would simply move a dark hairline up there against the cream intro. */
.wa-split + .wa-band { margin-top: -1px; }

/* ---------- 2 · THE DIAGONAL ----------
   A true corner-to-corner cut. The two triangles are clip-paths on the anchors
   themselves, which means the browser hit-tests the triangle and not its
   bounding box — hover and click land exactly where the paint is, with no JS.
   Gradients are back here on purpose: watercolour is soft colour, so flat mode
   cannot express it. Nothing else on the page was un-flattened. */
.wa-split {
  position: relative;
  min-height: clamp(30rem, 82vh, 48rem);
  overflow: hidden;
  background: var(--wa-cream);
}
.wa-split__half {
  position: absolute; inset: 0;
  display: block;
  overflow: hidden;
}
/* Bottom-left to top-right, so LIFE takes the upper wedge and WORK the lower.
   Written as FOUR points with one deliberately duplicated, even though three
   would draw the same triangle: clip-path only interpolates between polygons
   with matching point counts, and the door animation below opens each triangle
   out into the full rectangle by moving that duplicated point. */
.wa-split__half.is-life { clip-path: polygon(0 0, 100% 0, 0 100%, 0 100%); }
.wa-split__half.is-work { clip-path: polygon(100% 0, 100% 100%, 0 100%, 100% 0); }

.is-life { background: var(--wa-cream); }
.is-work { background: var(--wa-espresso); }

/* the wash — layered blooms, heavily blurred so no edge reads as a shape */
.wa-split__wash {
  position: absolute; inset: -25%;
  pointer-events: none;
  filter: blur(26px);
  transform: scale(1);
  transition: transform 1200ms var(--ease-out), opacity 900ms var(--ease-out);
}
.is-life .wa-split__wash {
  opacity: 0.85;
  background:
    radial-gradient(ellipse 42% 38% at 24% 26%, rgba(168, 75, 28, 0.30) 0%, transparent 62%),
    radial-gradient(ellipse 34% 30% at 52% 10%, rgba(228, 163, 26, 0.24) 0%, transparent 60%),
    radial-gradient(ellipse 30% 38% at 6% 56%, rgba(169, 108, 30, 0.22) 0%, transparent 62%),
    radial-gradient(ellipse 26% 24% at 34% 44%, rgba(163, 52, 26, 0.14) 0%, transparent 64%);
}
.is-work .wa-split__wash {
  opacity: 0.9;
  background:
    radial-gradient(ellipse 42% 38% at 78% 74%, rgba(168, 75, 28, 0.46) 0%, transparent 62%),
    radial-gradient(ellipse 32% 28% at 94% 50%, rgba(191, 116, 21, 0.30) 0%, transparent 60%),
    radial-gradient(ellipse 38% 34% at 58% 96%, rgba(46, 74, 62, 0.42) 0%, transparent 62%),
    radial-gradient(ellipse 24% 22% at 70% 62%, rgba(228, 163, 26, 0.16) 0%, transparent 64%);
}
.wa-split__half:hover .wa-split__wash,
.wa-split__half:focus-visible .wa-split__wash { transform: scale(1.08); opacity: 1; }

/* paper tooth, so the washes sit on a surface rather than float */
.wa-split__grain {
  position: absolute; inset: 0; pointer-events: none;
  background-image: var(--wa-grain);
  opacity: 0.2; mix-blend-mode: multiply;
}
.is-work .wa-split__grain { opacity: 0.28; mix-blend-mode: overlay; }

/* the seam. "to bottom right" puts the colour bands perpendicular to that
   axis — which is exactly the other diagonal, at any aspect ratio. */
.wa-split__seam {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  z-index: 3; pointer-events: none;
  overflow: visible;
}
/* non-scaling-stroke matters here: preserveAspectRatio="none" stretches the
   viewBox unevenly, and without it the stroke would stretch with it. */
.wa-split__seam line { vector-effect: non-scaling-stroke; }
.wa-split__seam .bleed {
  stroke: rgba(168, 75, 28, 0.26); stroke-width: 44;
  filter: blur(22px);
}
.wa-split__seam .edge {
  stroke: rgba(168, 75, 28, 0.6); stroke-width: 2.5;
  filter: blur(2px);
}

/* ---- content ---- */
/* Word and label sit on the vertical centre of their own half; the topics fan
   out around them in an arc. Every position was checked against the cut —
   x = 1 - y is the diagonal at any height, and nothing crosses it. */
.wa-split__body { position: absolute; display: block; z-index: 2;
  text-align: center; white-space: nowrap; }
/* Point-symmetric about the middle of the section: (26,36) and (74,64) sum to
   (100,100), so the two halves are the same composition rotated 180 degrees.
   Moved out from (36,42)/(64,58) on 16 Aug. Those sat hard against the cut: the
   two words nearly touched across it and read as one line, "LIFE WORK", while
   the far corner of each wedge stayed empty. Measured on the rendered ink, the
   words had NEGATIVE clearance — LIFE by 1.9% of the section, WORK by 6.9% —
   so the diagonal was actually clipping them.
   The test is x + y against 100: LIFE lives where x + y <= 100, WORK where
   x + y >= 100, and the worst corner is LIFE's bottom-right and WORK's top-left
   because each big word sits at the narrow end of its own wedge. */
/* LIFE went back to (36,42) on 16 Aug when its topics were arced back out of
   the body. That was the arc-era pairing, and it works again for the same
   reason it did then: with the four topics no longer stacked above the word,
   the body is only the label plus the word, so the word sits much higher in
   the wedge and clears the cut. WORK keeps (74,64) — she asked for it to be
   left alone — so the two are no longer point-symmetric. */
.is-life .wa-split__body { left: 34.5%; top: 36.6%; transform: translate(-50%, -50%); }
.is-work .wa-split__body { left: 74%; top: 64%; transform: translate(-50%, -50%); }

.wa-split__k {
  display: block;
  font-family: var(--wa-label); font-weight: 400; font-size: 0.54rem;
  letter-spacing: 0.28em; text-transform: uppercase; color: var(--wa-rust);
}
/* ---- how the label sits against the word, 2 Sep 2026 ----
   "Masyadong malayo." Measured, and she is right — but the margins were not
   the cause. The word is set at line-height 1, so its box is 1em tall while
   its caps are only ~0.75em, and the caps sit on the baseline near the
   bottom. All the slack is ABOVE the word: measured 0.248em of dead space
   over LIFE and 0.309em over WORK, and effectively none below (the ink
   overshoots the box by 0.057em).

   That is why it read lopsided rather than merely loose — the ink gaps were
   29px over LIFE against 10px under it, and 40px over WORK against 7px.

   So the compensation goes on the WORD, in the word's own em, where it
   scales with `clamp(2.2rem, min(7.5vw, 11vh), 5.6rem)` instead of drifting
   as the window changes. The labels carry no margin at all now; the numbers
   below set the ink gap directly, and it comes out even top and bottom. */
.is-life .wa-split__k   { margin-bottom: 0; }
.is-life .wa-split__sub { margin-top: 0; }
.is-work .wa-split__sub { margin-bottom: 0; }
.is-work .wa-split__k   { margin-top: 0; color: var(--wa-honey); }

/* Two units on purpose. The `em` half cancels the word's dead space and must
   scale with it — the word runs 2.2rem to 5.6rem, a 2.5x range, so a flat px
   trim would over-cut a small word and under-cut a big one. The `rem` half is
   the gap actually wanted, and stays put at every size.

   CORRECTED TWICE. Both earlier attempts overlapped the label into the word,
   and both were measurement bugs, not taste:

   1. Canvas measureText was given el.textContent — "Life", "Work" — but the
      words RENDER through text-transform: uppercase. Mixed-case ascenders are
      taller than caps, so the dead space was under-read.
   2. The baseline was computed with half-leading = (line-height - font-size)/2.
      That is only right when the font fits inside 1em. Poppins needs
      ascent 1.049 + descent 0.346 = 1.395em, and line-height here is 1, so the
      half-leading is NEGATIVE. Using font-size put the baseline 18px too low
      at a 90px word, which over-trimmed by the same 18px — the overlap.

   Correct half-leading is (line-height - (ascent + descent)) / 2. On that
   footing the dead space above the word is 0.202em on LIFE and 0.290em on
   WORK, and below it 0.299em and 0.191em. The asymmetry is real and expected:
   each word has a different neighbour above and below.

   If these are ever re-derived, the check is that the four numbers change when
   the label above and below are swapped — LIFE's top matches WORK's bottom to
   within a hair, because both sit against the same 0.54rem label. */
.is-life .wa-split__t {
  margin-top:    calc(-0.2021em + 0.625rem);
  margin-bottom: calc(-0.2988em + 0.625rem);
}
.is-work .wa-split__t {
  margin-top:    calc(-0.2903em + 0.625rem);
  margin-bottom: calc(-0.1908em + 0.625rem);
}

/* ---- the second half of the label, 2 Sep 2026 ----
   Her arrangement: the label reads across three rows rather than one long
   line. LIFE is `01 — Purpose` / LIFE / `Who I am when the camera is off`;
   WORK is `What I make when it is on` / WORK / `02 — Passion`. Same words as
   before, only the em dash that joined the two halves is gone.

   It also removes the collision that the topic names had with the LIFE block.
   The single line was white-space: nowrap and 332px wide, wider than the word
   itself, and it was that width — not the arc — that left no room beside it.
   Split in two, the longest row is the sub, and the block narrows to it.

   Set a step quieter than the kicker: same face and tracking, no colour, so
   the rust `01 — Purpose` still leads and this reads as the description. */
.wa-split__sub {
  display: block;
  font-family: var(--wa-label); font-weight: 400; font-size: 0.54rem;
  letter-spacing: 0.28em; text-transform: uppercase;
}
.is-life .wa-split__sub { margin-top: 0.55rem; color: #6B6156; }
.is-work .wa-split__sub { margin-bottom: 0.55rem; color: rgba(247, 241, 228, 0.72); }

.wa-split__t {
  /* Poppins bold, not the display serif — this is the one place the section
     wants weight over elegance. 700 rather than 900: black closes the counters
     up at the sizes the diagonal needs. */
  display: block;
  font-family: var(--wa-label); font-weight: 700;
  /* Capped against the viewport HEIGHT as well as its width. Sized on 7.5vw
     alone, a wide-and-short window gave a big word inside a shallow wedge and
     the clearance to the cut collapsed — measured 2px at 1600x560, and 2px at
     1400x620. The 11vh only bites on short windows; at 1440x900 and 820x700 the
     word is untouched. */
  font-size: clamp(2.2rem, min(7.5vw, 11vh), 5.6rem);
  letter-spacing: 0.1em; line-height: 1;
  text-transform: uppercase; color: var(--wa-espresso);
}
.is-work .wa-split__t { color: var(--wa-cream); }

/* ---- topics ----
   The two halves are handled differently on purpose. WORK stacks its topics
   inside the body, below the label: its titles run to 33 characters and an arc
   cannot clear the cut with lines that long. LIFE arcs them around the word —
   restored 16 Aug at her request, to the positions agreed before the stack.
   Its titles are short enough to sit on the oblong without fouling the seam. */
.wa-split__topics { display: block; }
.is-work .wa-split__topics { margin-top: 0.9rem; }
.wa-split__topics span {
  display: block; white-space: nowrap; text-align: center;
  font-family: var(--wa-label); font-weight: 400;
  font-size: clamp(0.5rem, 0.78vw, 0.64rem);
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--wa-espresso);
  padding: 0.22rem 0;
  opacity: 0; transform: translateY(8px);
  transition: opacity 900ms var(--ease-out), transform 900ms var(--ease-out);
}
.is-work .wa-split__topics span { color: rgba(247, 241, 228, 0.9); }

/* LIFE: an arc, laid out against the half rather than the body, which is why
   the markup keeps this span outside .wa-split__body on that side only.
   Reveal order is p1 first — Faith at the bottom, sweeping up to Volunteerism. */
.is-life .wa-split__topics {
  position: absolute; inset: 0; z-index: 2; pointer-events: none; margin: 0;
}
.is-life .wa-split__topics span { position: absolute; }
/* Tuned in TO TUNE/diagonal-life.html, 2 Sep 2026, then evened out numerically.
   Elyne dialled a near-perfect arc by hand (radii 242/241/238/227) but the
   angular gaps came out 29°/28°/41°, so the last step read as a jump — the
   centres were 120/115/163px apart. These keep her start and end angles, 136°
   and 234°, and divide the sweep into three equal 32.7° steps, which puts the
   four centres 166px apart to the pixel.

   Her rules, given 2 Sep: Food & Travel aligned to Faith & Healing's left
   edge; equal vertical steps across all four; Volunteerism continuing that
   step, and sitting as far RIGHT of Food as Lifestyle sits LEFT of it. All
   four hold exactly — the left edges measure Faith 258 / Food 258 (diff 0),
   Lifestyle 38px left, Volunteerism 38px right, and the vertical white gaps
   are 71 / 71 / 71 with zero spread at every window shape.

   KNOWN ISSUE, not yet resolved. These positions bring the names inboard far
   enough to foul the LIFE block. At 1440x900 it is a 39x2px box touch against
   the kicker and the ink does not actually collide, but at 1400x620 and
   1600x560 Food & Travel crosses the word LIFE itself.

   Everything was tried that does not alter her spec: sliding the group left
   (still collides at 1200x860, and runs to 76px off the section edge), and
   moving .wa-split__body through seven positions (freeing Food only makes
   Faith collide instead). The single blocker is .wa-split__k being
   white-space: nowrap, which pins the block at 332px — 41% of the section
   width at the narrow sizes. Letting the kicker wrap at 18ch drops the block
   to 203px and clears every size except 820x700, but it turns that one line
   into four, so it is not being done without her say-so. */

/* Horizontal alignment, her spec of 2 Sep: Faith & Healing centred on Food &
   Travel; Lifestyle starting where the word "Food" ends; Volunteerism starting
   where "Travel" ends. Food & Travel is the anchor and keeps the plain 18.1%.

   The three offsets are in `em`, not px and not %. They have to track the text,
   and the text is `clamp(0.5rem, 0.78vw, 0.64rem)` — so it scales with the
   window between 8px and 10.24px. A px offset would only line up at one size;
   a % offset would only line up at one width. Measured against the type:
     -0.440em   half the width difference between the two labels (106 vs 115px)
     -6.112em   puts the END of "LIFESTYLE" on the F that starts "FOOD"
     10.362em   puts the START of "VOLUNTEERISM" just after the L ending "TRAVEL"

   The three are not symmetrical because they are not the same instruction.
   LIFESTYLE is aligned by its END, to the START of FOOD. VOLUNTEERISM is
   aligned by its START, to the END of TRAVEL. FAITH is aligned by its centre.

   The letter-spacing is 0.22em and CSS applies it AFTER the last glyph too, so
   an element's right edge sits one letter-space past its visible end, while
   its left edge sits flush against the first glyph.

   That asymmetry has to be handled per case. VOLUNTEERISM's V is placed at
   TRAVEL's box right, not at the L's ink end — so the V picks up exactly one
   letter-space after the L, the same rhythm as the gaps inside the words.
   LIFESTYLE's E is meeting a glyph START, which carries no leading space, so
   that offset takes a +1 letter-space correction: -6.112em, not -6.332em. */
.is-life .wa-split__topics .p1 { left: calc(18.1% - 0.440em); top: 50.9%; }   /* Faith & Healing */
.is-life .wa-split__topics .p2 { left: calc(18.1% - 6.112em); top: 37.8%; }   /* Lifestyle       */
.is-life .wa-split__topics .p3 { left: 18.1%;                 top: 24.7%; }   /* Food & Travel   */
.is-life .wa-split__topics .p4 { left: calc(18.1% + 10.362em); top: 11.6%; }  /* Volunteerism    */

.wa-split__half:hover .wa-split__topics span,
.wa-split__half:focus-visible .wa-split__topics span {
  opacity: 1; transform: none;
}
.wa-split__topics .p1 { transition-delay: 60ms; }
.wa-split__topics .p2 { transition-delay: 200ms; }
.wa-split__topics .p3 { transition-delay: 340ms; }
.wa-split__topics .p4 { transition-delay: 480ms; }

/* ---- narrow: a diagonal cannot work, so stack and show everything ---- */
@media (max-width: 760px) {
  .wa-split { min-height: 0; }
  .wa-split__half { position: relative; inset: auto; clip-path: none;
    min-height: 20rem; display: flex; }
  .wa-split__seam { display: none; }
  .wa-split__body { position: relative; left: auto; top: auto; transform: none;
    padding: clamp(1.6rem, 6vw, 2.4rem) clamp(1.6rem, 6vw, 2.4rem) 0;
    align-self: center; white-space: normal; }
  /* The arc has nowhere to go on a phone, so LIFE becomes a plain list like
     WORK. Its selectors have to be repeated at the same weight here: a media
     query adds no specificity, so `.wa-split__topics span` alone would lose to
     the `.is-life .wa-split__topics span` rule above and the topics would stay
     absolutely positioned off in the corner. */
  .is-life .wa-split__topics { position: relative; inset: auto;
    padding: 0 clamp(1.6rem, 6vw, 2.4rem) clamp(1.6rem, 6vw, 2.4rem);
    align-self: center; text-align: center; }
  .wa-split__topics span,
  .is-life .wa-split__topics span {
    position: relative; left: auto; right: auto; top: auto;
    display: block; padding: 0.22rem 0; opacity: 1; transform: none;
    white-space: normal; }
  .wa-split__half { flex-direction: column; justify-content: center; }

  /* ---- hers, 16 Sep 2026, on her phone ----
     "Ung layo ng word na Volunteerism, same sa layo ng passion sa creative
     brand consultant": LIFE had a full padding on both sides of that gap
     (51px) where WORK has only its topics' 0.9rem (15px). Both are 0.9rem now.
     "Hindi pantay": WORK's body kept its top padding with none below, so its
     words sat 68px from the top and 42px from the bottom of the dark block;
     LIFE sat 37/36. Without that top padding both blocks centre their words.
     Letter-spacing also trails every uppercase line by one space, pushing
     centred words a hair left; the matching text-indent puts them on centre.
     "Dapat dikit": no cream band between WORK and the green HERE'S TO THE ONES. */
  .is-life .wa-split__topics { padding-bottom: 0; }
  .is-life .wa-split__body { padding-top: 0.9rem; }
  .is-work .wa-split__body { padding-top: 0; }
  .wa-split { padding-bottom: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .wa-split__wash { transition: none; }
  .wa-split__topics span { transition: opacity 200ms linear; transform: none; }
}

/* ---- the door ----
   Clicking a half opens its wedge out to the full rectangle, then the page
   navigates mid-sweep, and the destination fades in from the same colour — so
   the cut reads as opening INTO purpose.html / passion.html rather than the two
   pages being unrelated. JS adds .is-opening to the section and .is-going to
   the half that was clicked; everything below is CSS. */
.wa-split__half { transition: clip-path 720ms cubic-bezier(0.6, 0.02, 0.2, 1); }
.wa-split.is-opening { pointer-events: none; }
.wa-split.is-opening .wa-split__half.is-going { z-index: 4; }

.wa-split.is-opening .is-going.is-life {
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
.wa-split.is-opening .is-going.is-work {
  clip-path: polygon(100% 0, 100% 100%, 0 100%, 0 0);
}

/* the seam has nothing left to divide once a wedge is opening */
.wa-split.is-opening .wa-split__seam { opacity: 0; transition: opacity 300ms ease; }
/* the half being left behind goes quiet */
.wa-split.is-opening .wa-split__half:not(.is-going) .wa-split__body,
.wa-split.is-opening .wa-split__half:not(.is-going) .wa-split__topics {
  opacity: 0; transition: opacity 240ms ease;
}
/* on the half being entered, the supporting type drops away and the word
   carries the movement on its own */
.wa-split.is-opening .is-going .wa-split__k,
.wa-split.is-opening .is-going .wa-split__topics {
  opacity: 0; transition: opacity 280ms ease;
}
.wa-split.is-opening .is-going .wa-split__t {
  transform: scale(1.05);
  transition: transform 720ms cubic-bezier(0.6, 0.02, 0.2, 1);
}

/* The arrival half of the same gesture: a full-bleed hold in the colour of the
   wedge just opened, fading off as the new page settles. Built in JS so the
   inner pages need no extra markup. */
.wa-veil {
  position: fixed; inset: 0; z-index: 9999; pointer-events: none;
  opacity: 1; transform: scale(1);
  transition: opacity 620ms cubic-bezier(0.4, 0, 0.2, 1),
              transform 900ms cubic-bezier(0.4, 0, 0.2, 1);
}
.wa-veil.is-life { background: var(--wa-cream); }
.wa-veil.is-work { background: var(--wa-espresso); }
.wa-veil.is-gone { opacity: 0; transform: scale(1.04); }

@media (prefers-reduced-motion: reduce) {
  .wa-split__half { transition: none; }
  .wa-veil { display: none; }
}
/* stacked layout — there is no diagonal to open */
@media (max-width: 760px) {
  .wa-split__half { transition: none; }
}

/* ---------- 5 · STATEMENT BAND ---------- */
.wa-band { position: relative; overflow: hidden; text-align: center;
  color: var(--wa-cream); padding: clamp(4.5rem, 13vw, 9rem) 0;
  background:
    radial-gradient(ellipse 70vw 60vh at 50% 44%, rgba(168, 75, 28, 0.34) 0%, transparent 62%),
    radial-gradient(ellipse 46vw 40vh at 16% 84%, rgba(228, 163, 26, 0.16) 0%, transparent 60%),
    linear-gradient(180deg, #22392F 0%, var(--wa-ground) 52%, #16261F 100%); }
.wa-band::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(44, 33, 25, 0.34) 0%, transparent 40%,
    transparent 66%, rgba(44, 33, 25, 0.46) 100%); }
.wa-band .wa-inner { position: relative; z-index: 2; }
/* Sized for a sentence, not a single word. The old 4.2rem / 0.3em was set for
   "REMEMBERED" on its own; an eleven-word line at those values runs off the
   screen, so the measure is capped and the tracking pulled back. */
/* colour stated explicitly: the base `h1,h2,h3,h4` rule sets --navy, and an
   element rule beats inheritance, so the section's own colour never reached it */
.wa-band h2 { color: var(--wa-cream);
  font-family: var(--wa-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(1rem, 3.2vw, 2.1rem); letter-spacing: 0.16em; line-height: 1.28;
  text-indent: 0.16em; max-width: 22ch; margin: 0 auto; }
/* Just the filled block — the thin outer frame was removed 17 Aug. The top
   margin came back down with it, since it had been inflated only to clear the
   old outline-offset. max-width undoes `p { max-width: var(--max-prose) }`. */
.wa-band__note { display: inline-block; max-width: none;
  margin-top: clamp(1.6rem, 4vw, 2.6rem);
  padding: 0.8rem 1.9rem;
  background: var(--wa-rust); color: var(--wa-cream);
  font-family: var(--wa-serif); font-style: italic;
  font-size: clamp(1rem, 2.4vw, 1.3rem); }

/* ---------- 6 · PLACES ---------- */
/* Short bottom padding on purpose: the map is the picture this list is
   describing, so the two are meant to read as one block. */
.wa-places { position: relative;
  padding: clamp(3rem, 7vw, 5.5rem) 0 clamp(1.4rem, 3.5vw, 2.4rem);
  background:
    radial-gradient(ellipse 40vw 34vh at 84% 22%, rgba(15, 81, 88, 0.08) 0%, transparent 62%),
    linear-gradient(180deg, var(--wa-cream) 0%, #FBF7EE 50%, var(--wa-cream) 100%); }
.wa-places__shell { display: grid; grid-template-columns: 2.2rem 1fr;
  gap: clamp(1rem, 3vw, 2.2rem); }
.wa-places__edge { display: flex; flex-direction: column; align-items: center;
  gap: 1.6rem; padding-top: 1rem; }
.wa-places__edge .wa-vert { height: 5.5rem; }
.wa-places__edge b { display: block; width: 1px; height: 2.5rem;
  background: linear-gradient(180deg, var(--wa-rust), transparent); }
.wa-places h2 { text-align: center; font-size: clamp(1.15rem, 3.4vw, 2.1rem);
  letter-spacing: 0.22em; }
.wa-places__intro { text-align: center; max-width: 40rem; margin: 1rem auto 2.2rem;
  font-size: 0.88rem; line-height: 1.9; color: var(--wa-ink-soft); }
.wa-places__lists { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 1.4rem 2.4rem; max-width: 46rem; margin: 0 auto; }
.wa-places__lists ul { list-style: none; }
/* Hers, 16 Sep 2026, on her phone: "PLACES I WILL TRAVEL FOR, masyadong malapit
   sa side. Give bigger space" and "ipasok mo pa ang I do not travel for work, mas
   pasok pa sa Places". Both sat 19px from the edges. The heading now keeps
   2.75rem on each side, and the paragraph sits further in than the heading. */
@media (max-width: 760px) {
  .wa-places h2 { padding-inline: 2.75rem; }
  .wa-places__intro { padding-inline: 4.25rem; }
}
.wa-places__lists li { font-family: var(--wa-label); font-weight: 400; font-size: 0.62rem;
  letter-spacing: 0.22em; text-transform: uppercase; padding: 0.34rem 0;
  border-bottom: 1px solid rgba(46, 74, 62, 0.1); }
/* The adventure line lives between the map and "Currently" — see .wa-adventure
   down in section 6c. It is no longer part of this section. */
@media (max-width: 760px) {
  .wa-places__shell { grid-template-columns: 1fr; }
  .wa-places__edge { display: none; }
}

/* ---------- 7 · FOOTER ---------- */
.wa-foot { position: relative; padding: clamp(2.6rem, 6vw, 4.2rem) 0 2rem;
  background:
    radial-gradient(ellipse 50vw 40vh at 50% 10%, rgba(46, 74, 62, 0.07) 0%, transparent 62%),
    linear-gradient(180deg, #E9E7DC 0%, #DFE0D4 100%);
  color: var(--wa-ink); font-family: var(--wa-body); font-weight: 300; }
.wa-foot__cols { display: grid; grid-template-columns: 1fr auto 1fr;
  gap: clamp(1.2rem, 4vw, 3rem); align-items: center; }
.wa-foot nav { display: flex; flex-direction: column; gap: 0.75rem;
  font-family: var(--wa-label); font-weight: 400; font-size: 0.58rem;
  letter-spacing: 0.3em; text-transform: uppercase; }
.wa-foot nav a { transition: color 300ms var(--ease-out); }
.wa-foot nav a:hover { color: var(--wa-rust); }
.wa-foot nav.r { text-align: right; }
.wa-foot__mid { text-align: center; padding: 0 clamp(1rem, 3vw, 2.4rem);
  border-left: 1px solid rgba(46, 74, 62, 0.18);
  border-right: 1px solid rgba(46, 74, 62, 0.18); }
/* the header's wordmark, repeated */
.wa-foot__logo { display: block; }
.wa-foot__logo img { display: block; margin: 0 auto;
  width: clamp(8.5rem, 15vw, 12.5rem); height: auto; }
/* "Masyadong malayo ang Artist sa elyne." Measured, and the margin was not the
   culprit: the wordmark PNG is 770x222 but its ink is only 705x145, so it
   carries 42px of transparent padding along its bottom — 18.9% of the file.
   At the rendered size that is ~10.9px of invisible space, on top of the
   0.55rem margin, so the gap the eye saw was 19.7px against a 37.7px script:
   more than half the height of the wordmark itself.

   The margin now cancels that padding and then sets the real gap. The image is
   sized by width, so its dead space is a constant 5.45% of the rendered width
   (42/770) — hence the same clamp() the image uses, multiplied out. Change the
   0.375rem alone to open or close the gap; the rest is compensation. */
.wa-foot__tag { font-family: var(--wa-label); font-weight: 400; font-size: 0.5rem;
  letter-spacing: 0.28em; text-transform: uppercase; color: var(--wa-ink-soft);
  margin-top: calc(0.375rem - 0.0545 * clamp(8.5rem, 15vw, 12.5rem)); }
.wa-foot__base { margin-top: 2.2rem; padding-top: 1.4rem; position: relative;
  text-align: center; font-family: var(--wa-body); font-weight: 400; font-size: 0.56rem;
  letter-spacing: 0.26em; text-transform: uppercase; color: var(--wa-ink-soft);
  line-height: 2.2; text-indent: 0.26em; }
.wa-foot__base .wa-rule { position: absolute; top: 0; left: 0; right: 0; }
@media (max-width: 700px) {
  .wa-foot__cols { grid-template-columns: 1fr; text-align: center; }
  .wa-foot nav { align-items: center; }
  .wa-foot nav.r { text-align: center; }
  .wa-foot__mid { border: 0; border-top: 1px solid rgba(46, 74, 62, 0.18);
    border-bottom: 1px solid rgba(46, 74, 62, 0.18); padding: 1.4rem 0; }
}


/* ============================================================
   IDENTITY MANIFEST — hero overlay (12 Aug 2026)
   A drafting sheet, not a HUD. Rust hairlines leave four pins on her
   face — both eyes, the nose, the lips — turn once, terminate in a
   numbered balloon, and a short stub carries each into a title-block
   box. No dimming layer: the watercolour hovers stay live underneath.
   ============================================================ */

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

/* ---------- the drawing ---------- */
.hero-cinema__net {
  position: absolute; inset: 0;
  z-index: 5;
  width: 100%; height: 100%;
  pointer-events: none;
  overflow: visible;
}
.hero-cinema__net .ln {
  fill: none; stroke: var(--wa-rust); stroke-width: 1; opacity: 0.85;
}
.hero-cinema__net .pin { fill: var(--wa-rust); opacity: 0; }
/* ---- the dial: track, sweeping arc, two text states ---- */
.hero-cinema__net .dial {
  fill: none; stroke: rgba(168, 75, 28, 0.26); stroke-width: 1.4; opacity: 0;
}
.hero-cinema__net .prog {
  fill: none; stroke: var(--wa-rust); stroke-width: 2;
  stroke-linecap: round; opacity: 0;
}
.hero-cinema__net .pct,
.hero-cinema__net .num {
  font-family: "Share Tech Mono", monospace;
  fill: var(--wa-rust); opacity: 0;
}

/* faint drafting grid, fades up with the drawing */
/* ---------- layout ---------- */
.hero-cinema__manifest {
  position: absolute; inset: 0;
  z-index: 6;
  pointer-events: none;
}

/* ---------- the title boxes ---------- */
.mf__box {
  position: absolute;
  width: 21%;
  padding: 0.62rem 0.9rem 0.7rem;
  opacity: 0;
  background: rgba(251, 247, 238, 0.96);
  border: 1px solid rgba(168, 75, 28, 0.55);
  box-shadow: 0 6px 18px -12px rgba(44, 33, 25, 0.35);
}
.mf__title {
  font-family: var(--wa-label), sans-serif; font-weight: 400;
  font-size: clamp(0.36rem, 0.8vw, 0.62rem);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--wa-espresso);
  line-height: 1.45;
}
/* vertically centred on their balloons — 21.1% and 73.3% of the stage */
.mf__box.b1 { left: 4%;  top: 21.1%; transform: translateY(-50%); }
.mf__box.b2 { right: 4%; top: 21.1%; transform: translateY(-50%); text-align: right; }
.mf__box.b3 { left: 4%;  top: 73.3%; transform: translateY(-50%); }
.mf__box.b4 { right: 4%; top: 73.3%; transform: translateY(-50%); text-align: right; }

/* ---------- closing line: the patent-figure treatment ---------- */
.mf__final {
  position: absolute; left: 50%; bottom: 6%;
  transform: translateX(-50%) translateY(8px);
  font-family: "Share Tech Mono", monospace;
  font-size: clamp(0.72rem, 1.55vw, 1.15rem);
  letter-spacing: 0.2em;
  text-transform: uppercase; white-space: nowrap;
  color: var(--wa-espresso);
  text-shadow: 0 0 10px rgba(251, 247, 238, 0.95), 0 0 22px rgba(251, 247, 238, 0.85);
  opacity: 0;
}
.mf__plus { color: var(--wa-rust); opacity: 0.9; padding: 0 0.15em; }
.mf__stamp {
  position: absolute; left: 3%; bottom: 5%;
  font-family: "Share Tech Mono", monospace;
  font-size: clamp(0.32rem, 0.6vw, 0.44rem);
  letter-spacing: 0.2em; text-transform: uppercase;
  color: rgba(44, 33, 25, 0.45);
  line-height: 1.9;
  opacity: 0;
}

/* ---------- narrow screens ---------- */
@media (max-width: 880px) {
  .mf__box { width: 30%; padding: 0.4rem 0.5rem 0.45rem; }
  .mf__title { font-size: 0.38rem; letter-spacing: 0.12em; }
  .mf__stamp { display: none; }
}
@media (max-width: 620px) {
  /* the corner geometry stops working — stack, and drop the wiring */
  .hero-cinema__manifest {
    display: flex; flex-direction: column;
    align-items: center; justify-content: flex-start;
    gap: 0.45rem; padding: 0 1rem;
  }
  /* Hers, 16 Sep 2026: "should not be on top of my face. Ibaba mo pa." — she
     chose "Lower, over the chest". Centred, the boxes covered her mouth and
     chin; a spacer now holds them 62% down the stage (a flex basis in this
     column is a share of the stage's height, so it scales with the phone). */
  .hero-cinema__manifest::before { content: ""; flex: 0 0 62%; }
  .mf__box {
    position: static; width: min(17rem, 84%); transform: none; text-align: left;
  }
  .mf__box.b2, .mf__box.b4 { text-align: left; }
  .mf__title { font-size: 0.46rem; letter-spacing: 0.16em; }
  .hero-cinema__net { display: none; }
  .mf__final { position: static; transform: translateY(8px); margin-top: 0.8rem;
    letter-spacing: 0.16em; }
}



/* ============================================================
   CONTACT — 25 Aug 2026
   The last page off the legacy blocks. Everything here is wa-*, so
   .contact / .faq / .field / .display-hero / .botanical /
   .portfolio-preview__header and --terracotta all became dead and
   were deleted with it.

   Two base rules bite on this page, so both are answered explicitly:
   `h1, h2, h3, h4 { color: var(--navy) }` (line 142) means every
   heading on a coloured ground must state its own colour, and
   `p { max-width: var(--max-prose) }` (line 188) means any centred
   line needs its own max-width.
   ============================================================ */

/* .wa-head normally sits below a section bar, and it is the bar that buys
   the clearance from the fixed masthead. Contact carries no bar — LIFE and
   WORK each stay inside their own section — so its head has to buy that
   clearance itself, using the same calc the legacy page heads use.
   Measured: at 375px the masthead is 158px tall while --nav-height is
   132px, so the bare clamp(4.5rem, 11vw, 8rem) resolved to 72px and the
   h1 ran 52px underneath it. */
.wa-head--bare { padding-top: calc(var(--nav-real, var(--nav-height)) + clamp(2.5rem, 8vw, 5rem)); }

.wa-contact { background: var(--wa-cream);
  padding: clamp(1.5rem, 4vw, 2.6rem) 0 clamp(3rem, 7vw, 5rem); }
.wa-contact__grid { display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
  gap: clamp(2rem, 6vw, 4.5rem); align-items: start;
  max-width: 62rem; margin: 0 auto; }
.wa-contact__kicker { display: block; color: var(--wa-rust);
  margin-bottom: clamp(1rem, 2.5vw, 1.5rem); }
/* min-width: 0 because a grid track's default min-content floor would let a
   long unbroken string — hello@elynevillamor.com is one — push the column
   wider than its share and skew the whole grid. */
.wa-contact__main,
.wa-contact__aside { min-width: 0; }

/* the GoHighLevel embed. GHL sets its own type and colour inside the
   frame, so all this owns is the box. */
.wa-contact__embed { display: block; width: 100%; min-height: 42rem;
  border: 0; background: transparent; }

/* shown only while no embed is in place — see the slot in contact.html */
.wa-contact__pending { border: 1px solid rgba(46, 74, 62, 0.18);
  padding: clamp(1.6rem, 4vw, 2.6rem); background: var(--wa-cream); }
.wa-contact__pendingtext { font-family: var(--wa-read);
  font-size: clamp(0.84rem, 1vw, 0.95rem); line-height: 1.9;
  letter-spacing: 0.03em; color: #3A3229; max-width: 44ch; margin: 0; }
.wa-contact__cta { display: inline-block; margin-top: clamp(1.2rem, 3vw, 1.8rem);
  font-family: var(--wa-serif); font-size: clamp(1rem, 2.4vw, 1.35rem);
  color: var(--wa-rust); text-decoration: none;
  border-bottom: 1px solid rgba(168, 75, 28, 0.35);
  padding-bottom: 0.25rem; transition: color 0.3s ease, border-color 0.3s ease; }
.wa-contact__cta:hover,
.wa-contact__cta:focus-visible { color: var(--wa-brick);
  border-bottom-color: var(--wa-brick); }

.wa-contact__dl { margin: 0; }
.wa-contact__dl dt { font-family: var(--wa-label); font-weight: 400;
  font-size: 0.58rem; letter-spacing: 0.34em; text-transform: uppercase;
  color: var(--wa-almond); margin-bottom: 0.45rem; }
.wa-contact__dl dd { margin: 0 0 clamp(1.2rem, 3vw, 1.7rem);
  font-family: var(--wa-read); font-size: clamp(0.84rem, 1vw, 0.95rem);
  line-height: 1.9; letter-spacing: 0.03em; color: #3A3229; }
.wa-contact__dl dd:last-child { margin-bottom: 0; }
.wa-contact__dl a { color: var(--wa-rust); text-decoration: none;
  border-bottom: 1px solid rgba(168, 75, 28, 0.3);
  transition: color 0.3s ease, border-color 0.3s ease; }
.wa-contact__dl a:hover,
.wa-contact__dl a:focus-visible { color: var(--wa-brick);
  border-bottom-color: var(--wa-brick); }

/* --- questions --- */
.wa-faq { background: var(--wa-cream); text-align: center;
  padding: clamp(2rem, 5vw, 3.4rem) 0 clamp(3.5rem, 8vw, 6rem); }
.wa-faq__label { display: block; color: var(--wa-rust); margin-bottom: 1.1rem; }
.wa-faq__title { color: var(--wa-espresso);
  font-size: clamp(1.15rem, 3.4vw, 2rem); max-width: 20ch;
  margin: 0 auto clamp(2rem, 5vw, 3rem); }
.wa-faq__list { max-width: 52rem; margin: 0 auto; text-align: left;
  border-bottom: 1px solid rgba(46, 74, 62, 0.14); }

.wa-faq__item { border-top: 1px solid rgba(46, 74, 62, 0.14); }
.wa-faq__toggle { display: grid;
  grid-template-columns: 3.4rem minmax(0, 1fr) 1.6rem;
  gap: clamp(0.6rem, 2vw, 1.2rem); align-items: baseline;
  width: 100%; padding: clamp(1.2rem, 3vw, 1.7rem) 0;
  background: none; border: 0; text-align: left; cursor: pointer;
  font: inherit; color: inherit; }
.wa-faq__no { font-family: "Share Tech Mono", monospace;
  font-size: 0.8rem; color: var(--wa-rust); letter-spacing: 0.1em; }
.wa-faq__q { font-family: var(--wa-serif); font-weight: 400;
  font-size: clamp(0.94rem, 1.7vw, 1.12rem); line-height: 1.5;
  color: var(--wa-espresso);
  transition: color 0.3s ease; }
.wa-faq__toggle:hover .wa-faq__q,
.wa-faq__toggle:focus-visible .wa-faq__q { color: var(--wa-rust); }

/* plus that becomes a minus. Two bars, the upright one collapses. */
.wa-faq__icon { position: relative; display: block; width: 0.85rem;
  height: 0.85rem; justify-self: end; align-self: center; }
.wa-faq__icon::before,
.wa-faq__icon::after { content: ""; position: absolute; inset: 0; margin: auto;
  background: var(--wa-rust); transition: transform 0.35s ease, opacity 0.35s ease; }
.wa-faq__icon::before { width: 100%; height: 1px; }
.wa-faq__icon::after { width: 1px; height: 100%; }
.wa-faq__item.is-open .wa-faq__icon::after { transform: scaleY(0); opacity: 0; }

/* The cap is written from the panel's own scrollHeight in main.js, not
   from a fixed number: her answers are not written yet, and the legacy
   version's `max-height: 400px` would have quietly clipped a long one.
   Once the panel is open the cap is dropped to `none`, so a reflow or a
   late-arriving webfont cannot cut the text off either.

   An earlier version animated grid-template-rows 0fr -> 1fr instead,
   which needs no JS measuring at all. max-height was kept for its wider
   support — animatable grid-template-rows wants Chrome 107 / Safari 16 /
   Firefox 129. Both work; this one asks less of the browser. */
.wa-faq__panel { overflow: hidden; max-height: 0;
  transition: max-height 0.4s ease; }
.wa-faq__inner p { font-family: var(--wa-read);
  font-size: clamp(0.84rem, 1vw, 0.95rem); line-height: 1.9;
  letter-spacing: 0.03em; color: #3A3229; max-width: 58ch;
  margin: 0 0 clamp(1.2rem, 3vw, 1.7rem); padding-left: calc(3.4rem + 1.2rem); }

/* a pending answer is meant to look unfinished, not neutral, so the page
   cannot ship half-filled without someone noticing. */
.wa-faq__inner p.wa-faq__todo { font-family: var(--wa-serif); font-style: italic;
  color: var(--wa-rust); }

@media (max-width: 860px) {
  .wa-contact__grid { grid-template-columns: minmax(0, 1fr);
    gap: clamp(2.2rem, 7vw, 3rem); }
  /* stacked, the two columns need a line between them or the details read
     as a continuation of the form */
  .wa-contact__aside { border-top: 1px solid rgba(46, 74, 62, 0.14);
    padding-top: clamp(1.6rem, 5vw, 2.2rem); }
}
@media (max-width: 520px) {
  .wa-faq__toggle { grid-template-columns: 2.4rem minmax(0, 1fr) 1.2rem; }
  .wa-faq__inner p { padding-left: calc(2.4rem + 0.6rem); }
}
@media (prefers-reduced-motion: reduce) {
  .wa-faq__panel { transition: none; }
  .wa-faq__icon::before,
  .wa-faq__icon::after { transition: none; }
}


/* ============================================================
   FLAT MODE — 14 Aug 2026
   Every gradient on the site overridden with a flat fill, or removed
   where it was only atmosphere. Kept as one block at the very end so
   it lifts out in a single delete instead of unpicking sixty
   declarations. Selectors match the originals exactly, so plain
   cascade order does the work — no !important anywhere.
   ============================================================ */

/* ---- home page: warm autumn sections ---- */
.wa-places  { background: var(--wa-cream); }
.wa-band    { background: var(--wa-sage); }
.wa-foot    { background: #E9E7DC; }
.wa-band::after     { background: none; }

/* ---- home page: components ---- */
.wa-rule            { background: var(--wa-rust); opacity: 0.45; }
.wa-places__edge b  { background: var(--wa-rust); opacity: 0.6; }

/* photo placeholders — the duotones become single flats */

/* ---- hero: atmosphere layers off, plate goes flat ---- */
.hero-cinema__ambient       { background: #EDEDEB; }
.hero-cinema__fog           { background: none; animation: none; filter: none; }
.hero-cinema__figure::after { background: none; }
.hero-cinema__scan          { background: var(--wa-rust); }
.hero-cinema__progress      { background: var(--wa-rust); }
.hero-cinema__label         { background: var(--wa-cream); }

/* ---- legacy sections, still live on the four inner pages ---- */
.hero-cine                    { background: var(--ivory); }
.hero-cine__portrait::after   { background: none; }
.hero-scroll                  { background: var(--ivory); }
.hero-scroll__glow            { background: none; }
.hero-scroll__portrait::after { background: none; }
.hero-scroll__img.is-down::after { background: none; }
.hero-scroll__progress        { background: var(--rust); }
.hero__portrait::after        { background: none; }
.journal-card__image::after   { background: none; }
.offer-card::after            { background: none; }
.nav__cta,
.nav.on-dark .nav__cta        { background: var(--rust); }
.placeholder-tile.a { background: #A84B1C; }
.placeholder-tile.b { background: #1E2A47; }
.placeholder-tile.c { background: #6D7860; }
.placeholder-tile.d { background: #C97847; }
.placeholder-tile.e { background: #6B1E23; }
.placeholder-tile.f { background: #46524B; }
.placeholder-tile.g { background: #7A4438; }

/* ==========================================================================
   23. Work card — veil and frame
   The original scrim is a five-stop gradient that thins to 28% through the
   middle. That holds over a dark photograph and disappears over a pale one,
   so on the white covers the name, kicker and number were unreadable.
   The veil replaces it with one flat value, and it appears ON HOVER only —
   at rest the photograph is shown clean.
   It is written as five identical stops rather than a flat colour on purpose:
   CSS can only interpolate between two gradients with matching stops, so a
   flat background could not animate.
   Settled 4 September 2026: black at 75% on hover. Final.
   ========================================================================== */
.wa-work__grid { --veil-rgb: 0, 0, 0; --veil-a: 0.75; }

/* At rest the photograph is clean — no scrim at all. This overrides the
   original five-stop espresso gradient, which the stacking fix would otherwise
   have made visible for the first time. Written as five fully transparent
   stops rather than `none` so it can interpolate into the hover veil. */
.wa-work__grid .wa-card::before {
  background: linear-gradient(180deg,
    rgba(var(--veil-rgb), 0) 0%,   rgba(var(--veil-rgb), 0) 34%,
    rgba(var(--veil-rgb), 0) 55%,  rgba(var(--veil-rgb), 0) 78%,
    rgba(var(--veil-rgb), 0) 100%);
  transition: background-image 320ms cubic-bezier(0.4, 0, 0.2, 1); }

.wa-work__grid .wa-card:hover::before,
.wa-work__grid .wa-card:focus-visible::before {
  background: linear-gradient(180deg,
    rgba(var(--veil-rgb), var(--veil-a)) 0%,   rgba(var(--veil-rgb), var(--veil-a)) 34%,
    rgba(var(--veil-rgb), var(--veil-a)) 55%,  rgba(var(--veil-rgb), var(--veil-a)) 78%,
    rgba(var(--veil-rgb), var(--veil-a)) 100%); }

/* Hairline frame inset from the photo edge, set nearer the edge than the text
   so the words keep their margin inside it. */
.wa-work__grid .wa-card::after {
  content: ""; position: absolute; pointer-events: none;
  inset: clamp(0.5rem, 1.2vw, 0.8rem);
  border: 1px solid rgba(247, 241, 228, 0.38);
  opacity: 0;
  transition: opacity 320ms cubic-bezier(0.4, 0, 0.2, 1); }
.wa-work__grid .wa-card:hover::after,
.wa-work__grid .wa-card:focus-visible::after { opacity: 1; }

/* The card already draws a bottom hairline that wipes open on hover. Left
   alone it would run parallel to the frame's bottom edge, so it stands down
   and the frame takes over. */
.wa-work__grid .wa-card__rule {
  transition: opacity 220ms cubic-bezier(0.4, 0, 0.2, 1); }
.wa-work__grid .wa-card:hover .wa-card__rule,
.wa-work__grid .wa-card:focus-visible .wa-card__rule { opacity: 0; }

/* The image and the scrim are both position:absolute with z-index:auto, so
   they paint in DOM order — and the <img> comes after ::before. The photograph
   was covering the veil entirely, which is why the pale covers never had a
   scrim to read against. Give the layers an explicit order:
   photo, then veil, then the words, then the frame. */
.wa-work__grid .wa-card__img   { z-index: 0; }
.wa-work__grid .wa-card::before{ z-index: 1; }
.wa-work__grid .wa-card__body,
.wa-work__grid .wa-card__rule  { z-index: 2; }
.wa-work__grid .wa-card::after { z-index: 3; }

/* ==========================================================================
   Video header — the WORK half of the home diagonal, brought onto this page.
   The three rows reuse .wa-split__k / __t / __sub so the type is the same
   object, not a lookalike; only the order changes, the label now sitting above
   the word and the line beneath it.
   ========================================================================== */
/* --vhead-y is where the crop sits vertically: 0% keeps the top of the frame
   (the head), 100% keeps the bottom. The footage is taller than this band, so
   something is always cut — this decides what. */
.wa-vhead { position:relative; overflow:hidden; isolation:isolate;
  container-type:inline-size;
  /* Settled by Elyne, 4 September 2026. */
  --vhead-scrim:.25; --vhead-tint:var(--wa-espresso);
  --vhead-x:0%; --vhead-y:0%; --vhead-h:50vh;
  --work-size:7.5vw; --work-track:.10em;
  --work-shift-x:0%; --work-shift-y:20%;
  min-height:clamp(20rem, var(--vhead-h), 40rem); display:grid; place-items:center;
  background:var(--wa-espresso); }
.wa-vhead__v { position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:var(--vhead-x) var(--vhead-y); z-index:0; }
/* Deepest at the edges, open through the middle, so the word keeps its
   contrast wherever the footage happens to be bright. */
/* The veil is a quarter strength on both pages, tinted the colour of the
   diagonal's own halves rather than plain black and white: espresso #2C2119
   under WORK, cream #F7F1E4 under LIFE. Elyne, 4 September 2026 — "hindi white
   and black ang color ng opacity." */
.wa-vhead__scrim { position:absolute; inset:0; z-index:1; pointer-events:none;
  opacity:var(--vhead-scrim, 1); background:var(--vhead-tint, #000); }
.wa-vhead__body { position:relative; z-index:2; text-align:center;
  padding:clamp(2.4rem,7vw,4.5rem) clamp(1rem,4vw,3rem);
  /* The shift is a percentage of the text block's own width, which is fine
     until the block is wide: WORK is half again as wide as LIFE, so the same
     75% carried it past the band's edge. Clamped against the space actually
     available — 50cqw is half the band, 50% is half this block — so a shift can
     travel as far as flush-with-the-edge and no further, at any width. */
  --work-x-max:calc(50cqw - 50% - clamp(1rem, 4vw, 3rem));
  transform:translate(
    clamp(calc(-1 * var(--work-x-max)), var(--work-shift-x), var(--work-x-max)),
    var(--work-shift-y)); }
/* The three rows carry their own type rather than borrowing it from
   .wa-split__*, so the component stands alone — the blog's stylesheet has the
   palette but not the diagonal. */
.wa-vhead__k, .wa-vhead__sub {
  display:block; font-family:var(--wa-label); font-weight:400; font-size:.54rem;
  letter-spacing:.28em; text-transform:uppercase; }
.wa-vhead__t { display:block; font-family:var(--wa-label); font-weight:700; }
.wa-vhead__k { color:var(--wa-honey); margin-bottom:.85rem; }
.wa-vhead__t { color:var(--wa-cream); line-height:.92;
  font-size:clamp(2rem, var(--work-size), 20rem);
  letter-spacing:var(--work-track); text-transform:uppercase; }
.wa-vhead__sub { color:rgba(247,241,228,.74); margin-top:1rem; }
@media (prefers-reduced-motion:reduce) { .wa-vhead__v { display:none; } }

/* The two pages lean the word to opposite sides — LIFE left, WORK right.
   The shift is a percentage of the text block's own width, not the band's, so
   the block is measured against the widest line it holds.
   Purpose also carries half the darkening: its footage is a bright mountain
   scene where Passion's is a dark interior. Elyne's values, 4 September 2026. */
.wa-vhead--life { --vhead-tint:var(--wa-cream); --work-shift-x:-100%; }
.wa-vhead--work { --work-shift-x:100%; }

/* Purpose follows the LIFE half of the diagonal: a light veil with dark type,
   against Passion's dark veil with cream. The veil here is flat white at 50%
   rather than the espresso gradient, and the three rows take the diagonal's
   own LIFE colours — rust label, espresso word, #6B6156 line. */
.wa-vhead--life .wa-vhead__k     { color:var(--wa-rust); }
.wa-vhead--life .wa-vhead__t     { color:var(--wa-espresso); }
.wa-vhead--life .wa-vhead__sub   { color:#6B6156; }

/* The band sets its own vertical padding instead of inheriting the generic
   `section { padding-block: clamp(6rem,12vw,12rem) }`. Three reasons:
   the generic value put 168px inside the band AND another 168px above the
   heading below it — 336px of empty cream, which Elyne called OA;
   the blog's stylesheet has no `section` rule at all, so the Journal's band
   came out 440px against the static pages' 637px and the words sat 9px off the
   bottom edge; and a header should not depend on a rule it does not own. */
/* The static pages' bands were built by the generic
   `section { padding-block: clamp(6rem,12vw,12rem) }` and Elyne approved them
   that way. Naming the SAME value here changes nothing on those pages and
   gives the blog — whose stylesheet has no `section` rule — an identical band.
   The original outside is right; the Journal follows it. */
.wa-vhead { padding-block:clamp(6rem, 12vw, 12rem); }
.wa-vhead + section,
.wa-vhead + .wa-head,
.wa-vhead + header { padding-top:clamp(2rem, 4vw, 3.5rem); }

/* The static pages carry a FIXED masthead, so anything at the top of <main>
   slides under it — 161px of the video band was hidden behind the nav. The
   blog's masthead is sticky and sits in flow, so it needs none of this.
   `.wa-head` used to be the first thing under the nav and carried the
   clearance itself; now the video header is first, so the clearance moves to
   the band and the heading below it gets the tight gap instead. The selector
   is deliberately as specific as the rule it replaces. */
.masthead--sec ~ main .wa-vhead + section,
.masthead--sec ~ main .wa-vhead + .wa-head {
  padding-top:clamp(2rem, 4vw, 3.5rem); }

/* ==========================================================================
   The positioning line, rolling — index.html
   Each of the two lines becomes a slot that rolls its own phrases: the one
   leaving climbs out of the top while the next rises into its place, both
   visible for the moment they cross, exactly as the reference does it.
   The mask is the line box itself. It is opened by 0.2em top and bottom, with
   an equal negative margin, so ascenders and descenders are not shaved off —
   overflow:hidden clips the padding box, not the content box.
   The markup keeps Elyne's full sentences: with no JS, or with reduced motion,
   both lines render exactly as they always have.
   ========================================================================== */
/* No padding on the mask. Opening it to protect ascenders also exposed a
   sliver of the phrase stacked above — visible as marks floating over the
   line. A 1.42em line box already contains this face's ascenders and
   descenders, so the mask is exactly one line tall and shows one phrase. */
.wa-roll { display:block; overflow:hidden; height:1.42em; }
.wa-roll__track { display:block;
  transition:transform 620ms cubic-bezier(.16, 1, .3, 1); }
.wa-roll__item { display:block; height:1.42em; white-space:nowrap; }
@media (prefers-reduced-motion:reduce) {
  .wa-roll__track { transition:none; }
}


/* ==========================================================================
   THE WORK CARD — the covers on passion.html, and the same design on
   volunteerism.html. Both pages use .wa-work__grid and identical markup, so
   this lived in passion.html's own <style> until volunteerism needed it too.
   Everything here is scoped to .wa-work__grid: the bare .wa-card selector
   also matches the four commitments on purpose.html.
   ========================================================================== */
/* ---- the words come off the photograph --------------------------------
   Nothing is printed over the picture at rest: the cover is a plain square
   and the year, the discipline and the name sit beneath it on the page's
   own cream, where no cover can make them hard to read. Hover is the one we
   settled — the photograph goes to black, the four camera marks crawl out
   into a single honey hairline — and the sentence and the button open
   inside that frame rather than under the name, so hovering a card never
   pushes the grid about. */
.wa-work__grid .wa-card { aspect-ratio:auto; overflow:visible;
  background:none; color:var(--wa-espresso);
  /* the pattern's first card — the four coloured tiles on the home page —
     carries a padding and a coloured top border. Both were hidden under the
     photograph while the card was the photograph; on a transparent ground
     they came back as a stripe above every cover and a margin round it. */
  padding:0; border-top:0; }
/* the picture keeps its own box: the scale on hover still has something to
   be clipped by, now that the card itself must let the words overflow it */
.wa-work__grid .wa-card__shot { display:block; position:relative;
  aspect-ratio:3/4; overflow:hidden; background:var(--wa-espresso); }
/* the veil belonged to the card, which now includes the words — it moves
   onto the picture. A flat colour, not a gradient: there is no longer any
   type on the photograph for a gradient to protect. */
.wa-work__grid .wa-card::before { display:none; }
.wa-work__grid .wa-card__shot::before { content:""; position:absolute;
  inset:0; z-index:1; pointer-events:none;
  background:rgba(var(--veil-rgb), 0);
  transition:background-color 320ms cubic-bezier(.4, 0, .2, 1); }
.wa-work__grid .wa-card:hover .wa-card__shot::before,
.wa-work__grid .wa-card:focus-visible .wa-card__shot::before,
.wa-work__grid--veil .wa-card__shot::before {
  background:rgba(var(--veil-rgb), var(--veil-a)); }

/* The words under the cover are gone: the grid is photographs, and
   everything the card says is said on the picture while it is hovered.
   They stay in the markup because the hover face is built from them. */
.wa-work__grid .wa-card__body { display:none; }
/* the foot hairline was drawn in cream for a dark card; on the page's own
   ground it has nothing to sit on, and the hover hairline is the event now */
.wa-work__grid .wa-card__rule { display:none; }

/* The camera marks from the panel's film frame, on the cards. At rest four
   corners; on hover each crawls out along both arms until the four close into
   one hairline, honey from the moment it starts moving. */
.wa-work__grid .wa-card__tick { position:absolute; z-index:2; pointer-events:none;
  width:var(--card-tick,18px); height:var(--card-tick,18px);
  border:0 solid rgba(247,241,228,.85);
  transition:width 760ms cubic-bezier(.16,1,.3,1),
             height 760ms cubic-bezier(.16,1,.3,1),
             border-color 300ms ease; }
.wa-work__grid .wa-card__tick--t1 { left:12px;  top:12px;    border-left-width:1px;  border-top-width:1px; }
.wa-work__grid .wa-card__tick--t2 { right:12px; top:12px;    border-right-width:1px; border-top-width:1px; }
.wa-work__grid .wa-card__tick--t3 { left:12px;  bottom:12px; border-left-width:1px;  border-bottom-width:1px; }
.wa-work__grid .wa-card__tick--t4 { right:12px; bottom:12px; border-right-width:1px; border-bottom-width:1px; }
.wa-work__grid .wa-card:hover .wa-card__tick,
.wa-work__grid .wa-card:focus-visible .wa-card__tick {
  width:calc(50% - 12px); height:calc(50% - 12px); border-color:var(--wa-honey); }
/* The card's own hairline frame surrounded the words as well as the
   picture once they moved out; the honey marks are the frame now. */
.wa-work__grid .wa-card::after { display:none; }

/* ---- the hover face ---------------------------------------------------
   While the picture is dark it carries everything the card says: the year
   under the frame's top-left corner, the number at its foot, the name in
   the middle, and the discipline in a honey hairline box below it — the
   same box the film frame's ENGAGEMENT FILM wears. The words beneath the
   picture stand down while this is up, so nothing is said twice. */
.wa-work__grid .wa-card__over { position:absolute; inset:0; z-index:2;
  pointer-events:none; opacity:0;
  transition:opacity 300ms var(--ease-out); }
.wa-work__grid .wa-card:hover .wa-card__over,
.wa-work__grid .wa-card:focus-visible .wa-card__over { opacity:1; }
.wa-work__grid .wa-card__body { transition:opacity 240ms var(--ease-out); }
.wa-work__grid .wa-card:hover .wa-card__body,
.wa-work__grid .wa-card:focus-visible .wa-card__body { opacity:0; }

/* the year and the number, set in from the hairline so the frame is clear */
.wa-work__grid .wa-card__oyr,
.wa-work__grid .wa-card__ono { position:absolute;
  font-family:"Share Tech Mono",monospace; letter-spacing:.12em;
  color:rgba(247,241,228,.92); }
.wa-work__grid .wa-card__oyr { left:26px; top:24px; font-size:.62rem; }
/* the year holds the top left, the number the foot on the opposite side, so
   the two sit on a diagonal rather than stacking down one edge */
.wa-work__grid .wa-card__ono { right:26px; bottom:22px; font-size:1.1rem;
  line-height:1; }

/* The name in white, standing in the faint black the play mark used to sit
   in — a soft round fade, not a plate, so it has no edge of its own. */
.wa-work__grid .wa-card__oname { position:absolute; left:50%; top:46%;
  transform:translate(-50%, -50%); width:80%; text-align:center;
  isolation:isolate; font-family:var(--wa-label); font-weight:700;
  font-size:clamp(1rem, 2.4vw, 1.4rem); line-height:1.15; color:#FFFFFF; }
/* The white warms to honey and cools back — one letter at a time, left to
   right, like a line of bulbs. Each letter runs the same cycle, started a
   beat after the one before it, so the change travels along the word.
   --name-cycle is one full white -> honey -> white; --name-step is the gap
   between neighbouring letters. */
.wa-work__grid .wa-card__oname span { color:#FFFFFF; }
.wa-work__grid .wa-card:hover .wa-card__oname span,
.wa-work__grid .wa-card:focus-visible .wa-card__oname span {
  animation:wa-name-warm var(--name-cycle, 2600ms) ease-in-out infinite;
  animation-delay:calc(var(--i, 0) * var(--name-step, 46ms)); }
@keyframes wa-name-warm {
  0%, 100%  { color:#FFFFFF; }
  40%, 60%  { color:var(--wa-honey); } }

/* The discipline, in the film frame's own hairline box — and it arrives the
   way the film frame's word does: it starts in the dead centre and steps
   down into place, widening its tracking as it goes. Its own fade is held
   back a beat so it is still invisible while it passes the name.
   --card-kind-y is where it starts, --card-kind-y-hover where it lands. */
.wa-work__grid .wa-card__ocat { position:absolute; left:50%;
  top:var(--card-kind-y, 50%);
  transform:translate(-50%, -50%); white-space:nowrap;
  font-family:var(--wa-label); font-weight:500; font-size:.42rem;
  letter-spacing:.26em; text-transform:uppercase; text-indent:.26em;
  color:var(--wa-honey); border:1px solid var(--wa-honey);
  padding:.42rem .72rem .34rem; opacity:0;
  transition:top 560ms cubic-bezier(.16, 1, .3, 1),
             letter-spacing 620ms cubic-bezier(.16, 1, .3, 1),
             opacity 320ms ease; }
.wa-work__grid .wa-card:hover .wa-card__ocat,
.wa-work__grid .wa-card:focus-visible .wa-card__ocat {
  top:var(--card-kind-y-hover, 76%); letter-spacing:.34em; opacity:1; }

.wa-work__grid .wa-card:hover::before,
.wa-work__grid .wa-card:focus-visible::before,
.wa-work__grid--veil .wa-card::before {
  background: linear-gradient(180deg,
    rgba(var(--veil-rgb), var(--veil-a)) 0%,   rgba(var(--veil-rgb), var(--veil-a)) 34%,
    rgba(var(--veil-rgb), var(--veil-a)) 55%,  rgba(var(--veil-rgb), var(--veil-a)) 78%,
    rgba(var(--veil-rgb), var(--veil-a)) 100%); }

/* "Show on every card" holds the hovered state open on the whole grid, so the
   slider can be judged against fourteen photographs at once rather than one */
.wa-work__grid--veil .wa-card::after { opacity: 1; }
.wa-work__grid--veil .wa-card__rule { opacity: 0; }

/* Hairline frame inset from the photo edge, the way the album-cover
   reference sets its type inside a ruled box. It sits nearer the edge than
   the text does, so the words keep their margin inside it. */
.wa-work__grid .wa-card::after {
  content: ""; position: absolute; pointer-events: none;
  inset: clamp(0.5rem, 1.2vw, 0.8rem);
  border: 1px solid rgba(247, 241, 228, 0.38);
  opacity: 0;
  transition: opacity 320ms cubic-bezier(.4, 0, .2, 1); }
.wa-work__grid .wa-card:hover::after,
.wa-work__grid .wa-card:focus-visible::after { opacity: 1; }

/* The resting card already draws a bottom hairline that wipes open on hover.
   Left alone it would run parallel to the frame's bottom edge — the double
   line Elyne rejected on the WORK bar — so the frame takes over and the rule
   stands down while hovered. */
.wa-work__grid .wa-card:hover .wa-card__rule,
.wa-work__grid .wa-card:focus-visible .wa-card__rule { opacity: 0; }
.wa-work__grid .wa-card__rule { transition: opacity 220ms cubic-bezier(.4, 0, .2, 1); }



/* The panel's top rail — every other piece, to move between them without
   closing. Left behind on the first pass because ".ovnav" does not match a
   selector test written for ".ov" followed by punctuation. */


/* ---- jumping to any piece from inside the overlay -------------------
   Two ways, so she can choose. Both reuse something the site already has
   rather than inventing a third kind of control.

   NAMES repeats the section bar: a section word, the rust //, then the
   pages, current one in rust with a rule under it. It is the same object
   as WORK // Résumé / Identity / Portfolio, only longer.

   NUMBERS repeats the card numerals: Share Tech Mono, 01 to 14, which is
   how every count on this site is already written. */
.ovnav { position:absolute; top:0; left:0; right:0; z-index:8;
  display:flex; align-items:center; gap:.7rem; padding:14px clamp(1.2rem,3vw,2rem);
  background:var(--wa-cream); border-bottom:1px solid rgba(46,74,62,.14);
  overflow-x:auto;
  /* Sixteen pieces no longer fit across the panel. The browser's own bar is
     gone and the row dissolves at both ends, so it reads as continuing past
     them — the same treatment the photograph strip already uses. */
  scrollbar-width:none; -ms-overflow-style:none;
  -webkit-mask-image:linear-gradient(90deg, transparent 0, #000 46px,
    #000 calc(100% - 46px), transparent 100%);
  mask-image:linear-gradient(90deg, transparent 0, #000 46px,
    #000 calc(100% - 46px), transparent 100%); }
.ovnav::-webkit-scrollbar { height:0; width:0; display:none; }
/* the row can be pulled along; a press stops the drift, a pull moves it */
.ovnav { cursor:grab; }
.ovnav.is-drag { cursor:grabbing; user-select:none; }
.ovnav button { cursor:pointer; }
.ovnav__s { font-family:var(--wa-label); font-weight:700; font-size:.58rem;
  letter-spacing:.28em; text-transform:uppercase; color:var(--wa-espresso); flex:0 0 auto; }
.ovnav__sep { color:var(--wa-rust); font-family:var(--wa-label); font-size:.7rem; flex:0 0 auto; }
.ovnav button { flex:0 0 auto; background:none; border:0; cursor:pointer;
  font-family:var(--wa-label); font-weight:400; font-size:.56rem; letter-spacing:.24em;
  text-transform:uppercase; color:var(--wa-ink-soft); padding:0 0 6px;
  border-bottom:1px solid transparent; transition:color 300ms ease, border-color 300ms ease; }
.ovnav button:hover { color:var(--wa-rust); }
.ovnav button.on { color:var(--wa-rust); border-bottom-color:var(--wa-rust); }
/* ==========================================================================
   THE WORK PANEL — the sheet that opens over a piece: the rail of sets, the
   fields, the film frame and the photograph stage. It lived inside
   passion.html until volunteerism needed the same thing, and a second copy of
   four hundred lines was not a thing to keep in step by hand.
   ========================================================================== */

/* ---- the mosaic ------------------------------------------------------
   Two columns of tall cells, the way her reference reads: a picture, an
   italic title beside it, the credit groups listed small beneath, and the
   count in the corner. Text-only cells open and close the grid. */
/* a work: picture left, words right */
/* Square, and the picture fills it. The mount is gone: a contained picture
   floating inside a taller box left linen showing on every side, and fourteen
   of those read as holes rather than as a grid.

   This DOES crop, and that is the deliberate split — the index crops to a
   consistent tile so the grid reads as one thing, and the overlay shows the
   work whole. Cropping was the objection on the detail view, not here. */
/* ---- the overlay: Option 03, out of the screen ---------------------- */
.ov { position:fixed; inset:0; z-index:300; background:var(--wa-cream);
  display:grid; grid-template-rows:1fr auto;
  opacity:0; visibility:hidden; transform:scale(.94);
  /* LEAVING. Untouched — this is the direction that already feels right. The
     curve accelerates away, and opacity finishes well before the scale does, so
     the last of the movement happens under a pane that has already gone. */
  transition:opacity 420ms ease, transform 620ms cubic-bezier(.6,.02,.2,1), visibility 0s .5s; }

/* ENTERING. Two things made this stiff.
   The curve: cubic-bezier(.6,.02,.2,1) crawls out of the gate and then rushes,
   which is why it read as a sudden zoom. Run in reverse on the way out it
   becomes fast-then-gentle, which is the smoothness she likes — so entering now
   gets its own decelerating curve rather than the same one played forwards.
   The timing: opacity used to finish at 480ms while the scale ran to 620ms, so
   the pane went fully opaque and you then watched the last 140ms of zoom in
   plain sight. Opacity now runs the full length of the movement. */
.ov.is-on { opacity:1; visibility:visible; transform:none;
  transition:opacity 720ms cubic-bezier(.16,1,.3,1),
             transform 720ms cubic-bezier(.16,1,.3,1),
             visibility 0s; }
/* Close sits in the foot row between the two pieces, not floating over the
   frame. Where it was it landed on the plate beneath the picture — right on
   top of the address — and there is no position over a frame that stays clear
   of every layout. */
.ov__x { background:none; border:0; cursor:pointer;
  font-family:var(--wa-label); font-size:.5rem; letter-spacing:.3em;
  text-transform:uppercase; color:var(--wa-ink-soft);
  border-bottom:1px solid transparent; padding:0 0 .7rem;
  transition:color 280ms ease, border-color 280ms ease; }
.ov__x:hover { color:var(--wa-rust); border-bottom-color:var(--wa-rust); }
/* stage two — now the only stage */
.ov__two { position:absolute; inset:0; background:var(--wa-cream);
  display:grid; grid-template-columns:190px minmax(0,1fr) 62px 1.15fr;
  /* the row is the panel's height, not the tallest thing in it — otherwise a
     capture taller than the panel stretched the row and grew past the frame */
  grid-template-rows:minmax(0,1fr);
  opacity:0; pointer-events:none; transition:opacity 520ms ease; }
.ov.is-deep .ov__two { opacity:1; pointer-events:auto; }
.ov__rail { padding:clamp(1.2rem,2.6vw,1.8rem) 0; overflow-y:auto; }
.ov__it { display:flex; align-items:center; gap:12px; width:100%; background:none;
  border:0; cursor:pointer; padding:10px clamp(.9rem,2vw,1.2rem); text-align:left; }
.ov__it:hover, .ov__it.on { background:rgba(46,74,62,.07); }
/* Circles, at Elyne's request — both levels, so the rail and the strip read as
   the same kind of thing. Film pieces keep their landscape stills: a 16:9 frame
   forced through a circle loses the shot. */
.ov__th { width:var(--dot-rail,50px); height:var(--dot-rail,50px);
  flex:0 0 var(--dot-rail,50px);
  object-fit:var(--dot-fit,cover); object-position:50% var(--dot-pos,0%);
  background:rgba(46,74,62,.06);
  border-radius:50%; filter:grayscale(.4); }
.ov__it.on .ov__th { filter:none; }
.ov__lb { font-family:var(--wa-label); font-size:.52rem; letter-spacing:.22em;
  text-transform:uppercase; color:rgba(247,241,228,.6); }
.ov__it.on .ov__lb { color:var(--wa-espresso); }
/* A group header inside the rail. Both names stay on screen so the work that
   is folded away still announces itself; the open one is marked with the
   site's hexagon rather than a chevron, and carries its count. */
.ov__seg { position:sticky; top:0; z-index:2; display:flex; align-items:center; gap:.6rem;
  width:100%; background:var(--wa-cream); border:0; cursor:pointer; text-align:left;
  padding:.75rem clamp(.9rem,2vw,1.2rem) .55rem;
  border-top:1px solid rgba(46,74,62,.16); }
.ov__seg:first-child { border-top:0; }
.ov__seg span { flex:1 1 auto; font-family:var(--wa-label); font-size:.5rem;
  letter-spacing:.28em; text-transform:uppercase; color:var(--wa-ink-soft); }
.ov__seg b { font-family:var(--wa-mono); font-weight:400; font-size:.58rem;
  color:var(--wa-ink-soft); }
.ov__seg::before { content:''; width:9px; height:10px; flex:0 0 9px;
  background:rgba(46,74,62,.28);
  clip-path:polygon(50% 0,100% 25%,100% 75%,50% 100%,0 75%,0 25%);
  transition:background 220ms ease; }
.ov__seg:hover span, .ov__seg:hover b { color:var(--wa-espresso); }
.ov__seg.is-open span { color:var(--wa-espresso); }
.ov__seg.is-open b { color:var(--wa-rust); }
.ov__seg.is-open::before { background:var(--wa-rust); }
.ov__txt { padding:clamp(1.6rem,3.6vw,2.6rem); overflow-y:auto; }
.ov__dk { font-family:var(--wa-label); font-size:.46rem; letter-spacing:.34em;
  text-transform:uppercase; color:var(--wa-honey); }
.ov__dn { margin:.7rem 0 0; font-family:var(--wa-label); font-weight:700;
  font-size:clamp(1.15rem,2.6vw,1.7rem); color:var(--wa-cream); }
.ov__st { margin:1.6rem 0 .5rem; font-family:var(--wa-serif); font-style:italic;
  font-size:1.05rem; color:var(--wa-honey); }
.ov__ro { font-family:var(--wa-read); font-size:.84rem; line-height:1.95;
  color:rgba(247,241,228,.82); margin:0; max-width:40ch; }
.ov__ct { margin-top:1.6rem; font-family:"Share Tech Mono",monospace; font-size:.82rem;
  letter-spacing:.14em; color:var(--wa-honey); }
.ov__dph { position:relative; border-left:1px solid rgba(247,241,228,.10); }
.ov__dph img { position:absolute; inset:0; width:100%; height:100%; object-fit:contain;
  padding:clamp(1.2rem,2.6vw,2rem); box-sizing:border-box; transition:opacity 400ms ease; }
/* the numbers variant */
.ov[data-jump="numbers"] .ovnav button { font-family:"Share Tech Mono",monospace;
  font-size:.8rem; letter-spacing:.12em; }
.ov[data-jump="numbers"] .ovnav__nm { display:none; }
.ov[data-jump="names"]   .ovnav__no { display:none; }
/* the overlay's own panes start below the bar */
.ov__two { top:52px; }

/* the foot — her third attachment */
/* Three columns rather than space-between: laid out by spacing, CLOSE drifted
   with the length of the two names beside it — 77px off centre on Dutertismo,
   where the piece before it is called Duterte Creatives and there is no piece
   after. The middle column is centred on the panel, whatever flanks it. */
.ov__pn { display:grid; grid-template-columns:1fr auto 1fr; align-items:center;
  padding:16px clamp(1.2rem,3vw,2rem); border-top:1px solid rgba(46,74,62,.16);
  background:var(--wa-cream); position:relative; z-index:7; }
.ov__pn > #ovprev { justify-self:start; }
.ov__pn > #ovx    { justify-self:center; }
.ov__pn > #ovnext { justify-self:end; }
.ov__pn button { display:inline-flex; align-items:baseline; gap:.9rem; background:none;
  border:0; cursor:pointer; font-family:var(--wa-label); font-weight:400;
  font-size:clamp(.56rem,.95vw,.66rem); letter-spacing:.3em; text-transform:uppercase;
  color:var(--wa-espresso); border-bottom:1px solid var(--wa-rust); padding:0 0 .7rem; }
.ov__pn button:hover { color:var(--wa-rust); }
.ov__pn button[disabled] { opacity:.3; cursor:default; border-bottom-color:var(--wa-almond); }



/* ---- films -----------------------------------------------------------
   A film piece shows a player where a photograph piece shows its picture.
   Nothing from YouTube loads until the visitor asks for it: the frame holds
   the still and a hexagon badge, and the iframe is created on the click that
   starts it. That keeps the panel light and keeps YouTube out of the page for
   anyone who only browses. The badge is a hexagon — nothing here is round. */
.ov__film { position:relative; width:100%; aspect-ratio:16/9; overflow:hidden;
  background:#000; cursor:pointer; border:0; padding:0; display:block; }
.ov__film img { width:100%; height:100%; object-fit:cover; display:block;
  transition:transform 620ms cubic-bezier(.16,1,.3,1), opacity 320ms ease; }
.ov__film:hover img { transform:scale(1.03); opacity:.86; }
.ov__film iframe, .ov__film video { position:absolute; inset:0; width:100%; height:100%;
  border:0; background:#000; object-fit:contain; }
/* The play mark sits low and small — the still is the thing to look at, and
   the badge only has to say the frame is a film. */
/* The badge is not there until the pointer is: at rest the frame is a still. */
.ov__play { position:absolute; z-index:2; left:50%; top:50%;
  width:var(--play-size,52px); height:var(--play-size,52px);
  transform:translate(-50%,-50%) scale(.8); opacity:0;
  background:var(--wa-cream);
  clip-path:polygon(50% 0%, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%);
  display:grid; place-items:center; pointer-events:none;
  transition:opacity 300ms ease, transform 460ms cubic-bezier(.16,1,.3,1),
             background 320ms ease; }
.ov__film:hover .ov__play { opacity:1; transform:translate(-50%,-50%) scale(1);
  background:var(--wa-honey); }
.ov__play::after { content:""; width:0; height:0; margin-left:4px;
  border-left:14px solid var(--wa-espresso);
  border-top:9px solid transparent; border-bottom:9px solid transparent; }

/* Corner ticks instead of a border, and the kind of film named on the still.
   The plate beneath carries the couple and the year, the way a print is
   labelled under the mount. */
/* At rest, four camera marks. On hover each one crawls out along both of its
   arms until it meets the next, and the four close into a single hairline. */
.ov__tick { position:absolute; z-index:2; width:var(--tick,20px); height:var(--tick,20px);
  pointer-events:none; border:0 solid var(--wa-cream); opacity:.85;
  transition:width 760ms cubic-bezier(.16,1,.3,1),
             height 760ms cubic-bezier(.16,1,.3,1),
             border-color 420ms ease, opacity 420ms ease; }
.ov__tick--t1 { left:12px; top:12px;    border-left-width:1px;  border-top-width:1px; }
.ov__tick--t2 { right:12px; top:12px;   border-right-width:1px; border-top-width:1px; }
.ov__tick--t3 { left:12px; bottom:12px; border-left-width:1px;  border-bottom-width:1px; }
.ov__tick--t4 { right:12px; bottom:12px;border-right-width:1px; border-bottom-width:1px; }
.ov__film:hover .ov__tick { width:calc(50% - 12px); height:calc(50% - 12px);
  border-color:var(--wa-honey); opacity:1;
  /* the colour runs with the crawl, not after it — the line is already honey
     as it travels, and finishes honey */
  transition:width 760ms cubic-bezier(.16,1,.3,1),
             height 760ms cubic-bezier(.16,1,.3,1),
             border-color 300ms ease, opacity 420ms ease; }

/* Both marks sit in the middle, where these stills carry their own title card.
   A soft veil behind them — centre only, edges untouched — lets the badge and
   the word win without flattening the picture. */
/* The same veil the cards on the grid wear — flat black at 75%, on hover only.
   A real element rather than a pseudo: the frame already spends ::after on the
   play mark's arrow, and a veil that has to cover the whole picture should not
   depend on which rule wins. --film-veil-a is the strength. */
.ov__veil { position:absolute; inset:0; pointer-events:none; z-index:1;
  opacity:0; background:rgb(0 0 0 / var(--film-veil-a, .75));
  transition:opacity 420ms ease; }
.ov__film:hover .ov__veil { opacity:1; }

/* The word sits in the middle, directly under the play mark, and carries its
   own shadow so it holds against a bright still without dimming the picture. */
/* At rest the word holds the middle of the frame. On hover it steps down to
   make room for the badge and comes back up when the pointer leaves.
   --kind-y is where it rests, --kind-y-hover where it goes: 50% is dead
   centre, larger numbers move it toward the foot. */
.ov__filmkind { position:absolute; left:50%; top:var(--kind-y,50%); z-index:2;
  transform:translate(-50%,-50%);
  pointer-events:none; color:var(--wa-cream); white-space:nowrap;
  font-family:var(--wa-label); font-size:.56rem; letter-spacing:.34em;
  text-transform:uppercase; text-indent:.34em;
  /* a hairline around the word rather than a filled plate — the same line the
     camera marks draw, so the two read as one family */
  border:1px solid rgb(247 241 228 / var(--kind-line-a, .75));
  padding:var(--kind-box-pad, .5rem .95rem .42rem);
  opacity:0;   /* like the badge, it belongs to the hover, not to the still */
  transition:top 560ms cubic-bezier(.16,1,.3,1),
             letter-spacing 620ms cubic-bezier(.16,1,.3,1),
             opacity 320ms ease, color 320ms ease, border-color 300ms ease; }
.ov__film:hover .ov__filmkind { top:var(--kind-y-hover,74%); opacity:1;
  letter-spacing:.44em; color:var(--wa-honey); border-color:var(--wa-honey); }

.ov__filmwrap { width:100%; }
.ov__plate { display:flex; justify-content:space-between; align-items:baseline;
  border-top:1px solid rgba(46,74,62,.24); margin-top:.6rem; padding-top:.5rem;
  font-family:var(--wa-label); font-size:.5rem; letter-spacing:.26em;
  text-transform:uppercase; color:var(--wa-ink-soft); }
.ov__plate b, .ov__platelink { font-family:var(--wa-mono); font-weight:400; font-size:.58rem;
  letter-spacing:.06em; color:var(--wa-rust); }
.ov__platelink { text-decoration:none; border-bottom:1px solid transparent;
  transition:color 260ms ease, border-color 260ms ease; }
.ov__platelink:hover { color:var(--wa-espresso); border-bottom-color:var(--wa-espresso); }
/* once it is playing, the still's marks have nothing to mark */
.ov__filmwrap.is-playing .ov__plate { opacity:.55; }

/* ---- a film piece wears landscape covers ------------------------------
   Photograph pieces keep their hexagon crops. Films do not: a 16:9 still
   forced through a hexagon loses the frame, and the reference sets its cards
   out as plain landscape rectangles. The still is whatever cover the video
   carries on YouTube, so the crop has to respect its shape. */
/* The ring that marks the chosen set belonged only to film pieces. Every piece
   has sets, so every piece gets it — a faint edge normally, rust when chosen. */
.ov__th { border:1px solid rgba(46,74,62,.16); }
.ov__it.on .ov__th { border:2px solid var(--wa-rust); filter:none; }
/* the spec list, in the reference's shape — one row per fact */
.ov__spec { margin:1.4rem 0 0; display:grid; gap:.55rem; }
.ov__spec div { display:grid; grid-template-columns:5.6rem 1fr; gap:.9rem;
  align-items:baseline; }
.ov__spec span { font-family:var(--wa-label); font-size:.46rem;
  letter-spacing:.24em; text-transform:uppercase; color:rgba(247,241,228,.5); }
.ov__spec b { font-family:var(--wa-read); font-weight:400; font-size:.86rem;
  color:rgba(247,241,228,.92); }

/* ---- the panel wears the cream palette --------------------------------
   The dark piece page is gone; this one keeps its layout and takes the light
   ground the removed page had. Espresso on cream, rust for the accents, the
   same hairlines at sage rather than cream alpha. */

.ov__it:hover { background:rgba(46,74,62,.05); }
.ov__it.on { background:rgba(46,74,62,.08); }
.ov__th { filter:none; }
.ov__dk { color:var(--wa-rust); }
.ov__dn { color:var(--wa-espresso); }
.ov__st { color:var(--wa-rust); }
.ov__ro { color:#3A3229; }
.ov__ct { color:var(--wa-rust); }
.ov__lb { color:rgba(58,50,41,.72); }
.ov__dph { border-left:1px solid rgba(46,74,62,.14); }
.ov__spec span { color:rgba(58,50,41,.55); }
.ov__spec b { color:var(--wa-espresso); }
/* A photograph fills its column, so it is centred by definition. A film is a
   fixed 16:9 block and was sitting against the top with the rest of the column
   empty beneath it — this drops it to the middle. */
.ov--films .ov__dph, .ov--site .ov__dph { display:grid; place-items:center;
  padding:clamp(1rem, 2.4vw, 2rem); }
.ov--films .ov__dph .ov__filmwrap { width:100%; }
.ov--films .ov__dph .ov__film { width:100%; }
/* A capture is always shown whole. The frame is the picture — it takes no size
   of its own, so at any window the shot shrinks to fit both the width and the
   height it is given and is never cropped. --site-h caps how much of the
   panel's height it may use. */
.ov--site .ov__dph { align-content:center; justify-items:center;
  /* a capture is framed like any other photograph — the same breathing room,
     so it never sits larger in the panel than one of her posters */
  padding:clamp(1.2rem,2.6vw,2rem); box-sizing:border-box; }
/* the wrap hugs the capture, so the plate beneath runs exactly its width and
   its two halves sit at the picture's edges rather than butting together */
.ov--site .ov__dph .ov__filmwrap { width:fit-content; max-width:100%;
  height:100%; min-height:0;
  display:grid; grid-template-rows:minmax(0,1fr) auto; justify-items:stretch; }
/* the capture is as tall as the frame allows and as wide as that makes it —
   whole at any window, never cropped, never larger than a photograph */
.ov__site { height:100%; min-height:0; width:auto; max-width:100%;
  justify-self:center; }
.ov__site img { width:100%; height:100%; object-fit:contain;
  object-position:50% 50%; display:block; }
/* A film is sized by the width it is given, its height following from the
   file. Sizing it by height instead asked a frame that had no shape yet for a
   percentage of nothing, and the recording vanished. */
.ov--site .ov__dph .ov__filmwrap:has(.ov__site--film) { width:100%; }
.ov__site--film { width:100%; height:auto; max-height:100%; }
.ov__site video { width:100%; height:auto; max-height:100%; display:block;
  object-fit:contain; background:#000; }
/* the photograph rule above fits the whole image inside its box, which is right
   for a photograph and wrong for a still — it left the frame ringed in black */
.ov__dph .ov__film img { position:static; inset:auto; padding:0;
  width:100%; height:100%; object-fit:cover; }
/* a whole page captured top to bottom — the frame shows its head, the way a
   browser would */
.ov__site img { object-position:50% 0; }
/* the badge opens the site, so it carries an arrow instead of a play triangle */
.ov__site .ov__play::after { content:"\2197"; border:0; width:auto; height:auto;
  margin:0; font-size:1.15rem; line-height:1; color:var(--wa-espresso); }

/* ---- stepping through a gallery ---------------------------------------
   The arrows sit on the photograph itself, in the same grid cell as the frame
   rather than inside it — paintDeep empties that frame on every change, and
   anything living inside would be thrown away with it.
   Hexagons, like everything else here. */
 /* Placing the arrows explicitly made the browser step the auto-placed frame
    out of their way and onto a second row, where it collapsed to nothing. Once
    one item in a grid is placed by hand the rest have to be too.
    The hexagons sit against the line beside the photograph rather than out at
    the far edge of the panel — the strip belongs to the picture, not the page. */
.ov__rail  { grid-column:1; grid-row:1; }
.ov__txt   { grid-column:2; grid-row:1; }
.ov__strip { grid-column:3; grid-row:1; }
.ov__dph   { grid-column:4; grid-row:1; }
.ov__step { grid-column:4; grid-row:1; align-self:center; z-index:4;
  border:0; padding:0; cursor:pointer;
  /* back to the size it started at, and a hexagon like the play badge */
  width:46px; height:46px;
  background:rgba(44,33,25,.62);
  clip-path:polygon(50% 0%, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%);
  display:grid; place-items:center;
  transition:background 300ms ease, opacity 300ms ease; }
.ov__step:hover { background:var(--wa-honey); }
.ov__step[disabled] { opacity:.22; cursor:default; }
.ov__step[disabled]:hover { background:rgba(44,33,25,.62); }
.ov__step--prev { justify-self:start; margin-left:clamp(.5rem,1.4vw,1.1rem); }
.ov__step--next { justify-self:end;   margin-right:clamp(.5rem,1.4vw,1.1rem); }
.ov__step::after { content:""; width:0; height:0;
  border-top:7px solid transparent; border-bottom:7px solid transparent; }
.ov__step--prev::after { border-right:10px solid var(--wa-cream); margin-right:3px; }
.ov__step--next::after { border-left:10px solid var(--wa-cream);  margin-left:3px; }

/* ---- the inner strip ---------------------------------------------------
   Two levels. The named rail on the left is the main set — the pieces of work
   inside a project. This strip is what is inside the one selected: only the
   photographs, no words, standing against the line beside the frame. */
.ov__strip { overflow-y:auto; overflow-x:hidden; display:flex;
  flex-direction:column; align-items:center; gap:26px;
  padding:34px 0;
  /* the browser's own scrollbar is the wrong object in a panel like this */
  scrollbar-width:none; -ms-overflow-style:none; }
.ov__strip::-webkit-scrollbar { width:0; height:0; }
.ov__strip button { background:none; border:0; padding:0; cursor:pointer;
  flex:0 0 auto; line-height:0; }
/* A strip of one is not a choice — it offers to take you to the only thing
   already on screen. It stays out of the way until there are two. */
.ov__strip:has(> button:only-child) { display:none; }
.ov__sth { width:var(--dot-strip,25px); height:var(--dot-strip,25px); display:block;
  object-fit:var(--dot-fit,cover); object-position:50% var(--dot-pos,0%);
  background:rgba(46,74,62,.06); border-radius:50%;
  filter:grayscale(.45); opacity:.72;
  transition:filter 300ms ease, opacity 300ms ease, transform 300ms ease; }
.ov__strip button:hover .ov__sth { filter:none; opacity:1; }
.ov__strip button.on .ov__sth { filter:none; opacity:1; transform:scale(1.06); }
.ov--films .ov__strip { display:none; }
/* …but a set that holds photographs and its film keeps its strip and its
   arrows while the film is on screen — the film is one stop along it. */
.ov--films.ov--mixed .ov__strip { display:flex; }
.ov--films.ov--mixed .ov__step { display:grid; }
/* the film's place in the strip wears the site's shape, not a circle */
.ov__sfilm .ov__sth { border-radius:0;
  clip-path:polygon(50% 2%, 96% 26%, 96% 74%, 50% 98%, 4% 74%, 4% 26%); }
.ov__sfilm.on::before { background:none; }
.ov__sfilm.on .ov__sth { outline:2px solid var(--wa-rust); outline-offset:3px; }
/* …unless this couple was filmed twice. Then the strip earns its place: the
   two films, each named, so the second circle never appears without saying
   what it is. The column widens just enough to hold the word. */
.ov--films.is-pair .ov__strip { display:flex; justify-content:center; gap:20px;
  mask-image:none; -webkit-mask-image:none;
  /* the letter hangs outside the column, into the empty text column beside it */
  overflow:visible; }
/* The button is exactly the circle, so the circle lands in the middle of the
   column — the same distance from the rule as every other piece's strip. The
   letter is hung off its left instead of sharing the button's width, and the
   gap is measured from the ring, which stands 8px outside the circle. */
.ov--films.is-pair .ov__strip button { position:relative; display:block;
  width:var(--dot-strip,25px); line-height:0; }
.ov__sthl { position:absolute; top:50%; transform:translateY(-50%);
  right:calc(100% + 8px + var(--pair-gap, 12px));
  font-family:var(--wa-label); font-size:.56rem; letter-spacing:.08em; line-height:1;
  text-transform:uppercase; color:var(--wa-ink-soft); white-space:nowrap;
  transition:color 300ms ease; }
.ov--films.is-pair .ov__strip button.on .ov__sthl { color:var(--wa-rust); }
.ov--films.is-pair .ov__strip button:hover .ov__sthl { color:var(--wa-espresso); }
/* The ring belongs to the circle, not to the button — the button is wider than
   the circle because it carries its letter to the left, and insetting from the
   button's edges drew the hexagon around the letter too, stretched and clipped.
   The circle is the button's right-hand end, so the ring is hung off that. */
.ov--films.is-pair .ov__strip button.on::before {
  inset:auto; right:-8px; left:auto; top:50%; transform:translateY(-50%);
  width:calc(var(--dot-strip,25px) + 16px);
  height:calc(var(--dot-strip,25px) + 16px); }
/* The column keeps its width whatever is in it — widening it for the pair
   moved the rule beside the frame, so a film with two circles no longer lined
   up with Mayad WV. The letters fit inside the 62px the strip already had. */
/* A film piece is chosen from the rail at the side, not stepped through — the
   arrows belong to a gallery of photographs, and only to one with more than a
   single photograph in it. */
.ov--films .ov__step { display:none; }
.ov.is-single .ov__step { display:none; }

/* Keyboard focus inside the panel wears the site's own marks — the hexagon on a
   photograph, the rust ring on a rail circle — instead of the rounded box the
   browser draws, which appeared around a circle whenever an arrow key moved
   focus. Focus stays visible; only its shape changes. */
.ov :focus-visible { outline:none; }
.ov__it:focus-visible .ov__th { border:2px solid var(--wa-rust); filter:none; }
/* Keyboard focus in the strip wears a ring on the circle, not a hexagon — the
   hexagon means "this is the photograph on screen", and when focus sat on a
   different circle two hexagons appeared and neither one meant anything. */
.ov__strip button:focus-visible:not(.on) .ov__sth { outline:2px solid var(--wa-rust);
  outline-offset:2px; filter:none; opacity:1; }
.ov__seg:focus-visible span, .ov__seg:focus-visible b { color:var(--wa-rust); }
.ov__step:focus-visible, .ov__film:focus-visible, .ov__x:focus-visible,
.ov__prev:focus-visible, .ov__next:focus-visible {
  outline:1px solid var(--wa-rust); outline-offset:3px; border-radius:0; }

/* the chosen photograph wears a hexagon, drawn as a stroke rather than a clip
   so it reads as a ring around the circle instead of cropping it */
.ov__strip button { position:relative; }
.ov__strip button.on::before { content:""; position:absolute; inset:-8px;
  background:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%3E%3Cpolygon%20points='50,2%2095,26%2095,74%2050,98%205,74%205,26'%20fill='none'%20stroke='%23A84B1C'%20stroke-width='5'/%3E%3C/svg%3E") center/contain no-repeat;
  pointer-events:none; }

/* Elyne chose option 3: no control at all. The strip dissolves at both ends so
   it reads as continuing past them, and the wheel or a drag carries it. */
.ov__strip { mask-image:linear-gradient(180deg, transparent 0, #000 30px,
    #000 calc(100% - 30px), transparent 100%);
  -webkit-mask-image:linear-gradient(180deg, transparent 0, #000 30px,
    #000 calc(100% - 30px), transparent 100%); }

/* a fact not yet written is out of the way until she goes to write it */
.ov__spec div.is-blank { display:none; }
/* Every piece carries the same five rows, and a blank one is hidden from a
   reader. Turning Edit on brings it back so it can be filled in — which the
   renderer always intended, but the rule to do it was never written, and
   ROLE TITLE could not be reached on any piece that had none. */
body.is-editing .ov__spec div.is-blank { display:grid; }
body.is-editing .ov__spec b { min-height:1.1em; min-width:6rem; display:inline-block; }
body.is-editing .ov__spec b:empty::before { content:"\2014"; opacity:.35; }


/* ==========================================================================
   THE STILL — a photograph held in the middle of the page with the words set
   either side of it, the way an editorial spread carries a plate. The rail
   down the left is the hero's own line, turned on its side.
   ========================================================================== */
/* the air above the still is a set distance, not one that grows with the
   window: 60px here plus the heading's own 40px reads as the 100px gap */
.wa-still { background: var(--wa-cream);
  padding: 3.75rem 0 clamp(3.5rem, 9vw, 7rem); }
.wa-still__grid {
  display: grid; align-items: center;
  /* held in from the page's full width: at 1fr either side the two blocks of
     words drifted so far from the plate that they stopped reading as one
     spread. The plate keeps the middle; the words stay within reach of it. */
  max-width: 64rem; margin-inline: auto;
  grid-template-columns: minmax(0, 0.82fr) minmax(0, 1fr) minmax(0, 0.82fr);
  gap: clamp(1.4rem, 3vw, 2.6rem);
}

/* the plate itself */
.wa-still__fig { position: relative; margin: 0 0 0 2.9rem; }
.wa-still__fig img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 2 / 3; object-fit: cover; object-position: 50% 30%;
}

/* The script line sits across the top of the plate and runs a little past it,
   the way a caption written by hand would overhang the print. */
.wa-still__script {
  position: absolute; left: 50%; bottom: calc(100% + 0.5rem);
  transform: translateX(-50%); white-space: nowrap;
  font-family: var(--wa-serif); font-style: italic; font-weight: 400;
  font-size: clamp(1.05rem, 2.4vw, 1.8rem); line-height: 1.3;
  text-align: center; color: var(--wa-espresso);
  pointer-events: none;
}
.wa-still__stamp {
  position: absolute; left: 0; bottom: -1.9rem;
  font-family: "Share Tech Mono", monospace; font-size: 0.6rem;
  letter-spacing: 0.18em; color: var(--wa-rust);
}
/* the hero's line, turned on its side down the outer edge */
.wa-still__rail {
  /* clear of the plate, not across it */
  position: absolute; left: -2.9rem; top: 50%;
  transform: translateY(-50%) rotate(180deg);
  writing-mode: vertical-rl; white-space: nowrap;
  font-family: var(--wa-label); font-size: 0.5rem;
  letter-spacing: 0.34em; text-indent: 0.34em; text-transform: uppercase;
  color: var(--wa-ink-soft); opacity: 0.75;
}

/* set the way the chapters below are set — Gentium, the same size, leading and
   tracking — so the two read as one page rather than two typefaces */
.wa-still__side p {
  font-family: var(--wa-read);
  font-size: clamp(0.86rem, 1.05vw, 0.98rem); line-height: 1.95;
  letter-spacing: 0.03em; color: #3A3229;
  margin: 0 0 1.1rem; max-width: 34ch;
}
.wa-still__side .wa-label { display: block; color: var(--wa-rust);
  margin-bottom: 0.9rem; }
/* a chapter title, in the chapters' own hand */
.wa-still__lead {
  font-family: var(--wa-serif) !important; font-weight: 400; font-style: normal;
  font-size: clamp(1.15rem, 2.6vw, 1.75rem) !important; line-height: 1.35 !important;
  letter-spacing: 0 !important; color: var(--wa-espresso) !important;
  margin-bottom: 1rem !important; max-width: none !important;
}
.wa-still__lead em { font-style: italic; color: var(--wa-rust); }
/* The grid was written for three columns. When a block is dragged in from
   elsewhere the fourth wrapped onto a new row and pushed the right-hand words
   below the fold of the section; it now widens to hold them side by side. */
.wa-still__grid:has(> [data-block]:nth-child(4)) {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.wa-still__grid:has(> [data-block]:nth-child(5)) {
  grid-template-columns: repeat(5, minmax(0, 1fr));
}
/* the marker, standing on its own beside the plate */
.wa-still__grid > .wa-chapter__num { align-self: center; }
.wa-still__grid > .wa-chapter__num span { display: block; margin-top: .7rem;
  text-align: inherit; }
/* and the content, which keeps the chapters' own measure */
.wa-still__grid > [data-block="craft-body"] .wa-chapter__body p { max-width: none; }

/* a chapter that has come to live here loses the rule it wore in Chapters */
.wa-still__grid > .wa-chapter { border-top: 0; padding-top: 0; }
.wa-still__grid > .wa-chapter .wa-chapter__grid { grid-template-columns: minmax(0, 1fr); gap: .6rem; }
.wa-still__grid > .wa-chapter .wa-chapter__num { display: flex; align-items: baseline; gap: .7rem; }
.wa-still__grid > .wa-chapter .wa-chapter__num span { margin-top: 0; }

/* the left column sits low against the plate, the right one high */
.wa-still__side--l { align-self: end; padding-bottom: clamp(1rem, 4vw, 3rem);
  text-align: right; justify-self: end; }
.wa-still__side--l p { margin-left: auto; }
.wa-still__side--r { align-self: start; padding-top: clamp(1rem, 4vw, 3rem); }

/* Below the width where three columns can breathe, the plate leads and the
   two blocks of words fall in under it. The rail has no room and stands down. */
@media (max-width: 900px) {
  .wa-still__grid { grid-template-columns: minmax(0, 1fr); gap: 2rem; }
  .wa-still__fig { order: -1; max-width: 22rem; margin: 0 auto; }
  .wa-still__rail { display: none; }
  .wa-still__script { white-space: normal; width: 118%; }
  .wa-still__side--l, .wa-still__side--r {
    align-self: auto; padding: 0; text-align: left; justify-self: stretch; }
  .wa-still__side--l p { margin-left: 0; }
  .wa-still__side p { max-width: 46ch; }
}


/* ==========================================================================
   A CANVAS SECTION — blocks placed where they are put, rather than flowed.

   Everything is positioned in percentages inside a frame of fixed proportion,
   so the whole arrangement scales together on a narrow screen instead of
   rearranging. That is the price of placing things freely: the section keeps
   its composition at every width, and cannot reflow into a column.
   ========================================================================== */
/* ---- the grid's own furniture -----------------------------------------
   The sort control and the year on each card. These lived inside
   passion.html, which is why volunteerism.html had neither; both pages show
   the same grid, so the grid's clothes belong here where both can wear them. */
.sortbar { display:flex; justify-content:center; align-items:center; gap:.8rem;
  margin:0 0 clamp(1.4rem,3vw,2rem); }
.sortbar span { font-family:var(--wa-label); font-size:.46rem; letter-spacing:.3em;
  text-transform:uppercase; color:var(--wa-ink-soft); }
.sortbar button { font-family:var(--wa-label); font-size:.52rem; letter-spacing:.26em;
  text-transform:uppercase; padding:.5rem .9rem; cursor:pointer;
  background:none; color:var(--wa-espresso); border:1px solid var(--wa-almond); }
.sortbar button.on { background:var(--wa-sage); border-color:var(--wa-sage);
  color:var(--wa-cream); }
.wa-card__yr { position:absolute; top:clamp(.7rem,1.8vw,1rem);
  left:clamp(1rem,2.4vw,1.5rem); z-index:3;
  font-family:"Share Tech Mono",monospace; font-size:.72rem;
  color:rgba(247,241,228,.92); text-shadow:0 1px 4px rgba(44,33,25,.8); }

/* ---- the still, one chapter at a time -----------------------------------
   The number on the left and the words on the right change together, so both
   fade on the same clock. The swap rule is more specific than
   [data-reveal].is-visible on purpose — the reveal owns the opacity until the
   swap borrows it. */
.wa-still__grid > [data-block="craft-mark"],
.wa-still__grid > [data-block="craft-body"] {
  transition: opacity 320ms var(--ease-out); }
.wa-still__grid > [data-block].is-swapping { opacity: 0; }

/* the written line, lying across the picture the way it does on paper — it
   starts outside the photograph and runs onto it, so it is drawn after the
   figure and paints over it */
.wa-still__script-line { font-family: var(--wa-hand, "Birthstone"), "Snell Roundhand", cursive;
  font-weight: 400; color: var(--wa-rust); margin: 0;
  line-height: 1.18; letter-spacing: .01em; pointer-events: none; }
/* it lies over the picture, so it must not swallow clicks — except while you
   are arranging, when it has to be grabbable */
body.arr-on .wa-still__script-line { pointer-events: auto; }
/* the canvas sets every block's size from --fs, and that rule is the more
   specific one — so the written line states its size the same way, keeping the
   arranger's A- / A+ working on it */
[data-canvas] .wa-still__grid > [data-block].wa-still__script-line {
  font-size: calc(var(--size, 20) * 1px * var(--fs, 1)); }

.wa-still__next { display: block; width: 100%; padding: 0; border: 0;
  background: none; color: var(--wa-espresso); cursor: pointer; }
/* inline, so the block's own alignment decides which end of the rule the
   arrow sits at */
.wa-still__next svg { display: inline-block; vertical-align: bottom;
  width: 46px; height: 12px; overflow: visible; }
.wa-still__next svg path { fill: none; stroke: currentColor; stroke-width: 1;
  transition: transform 520ms var(--ease-out); }
.wa-still__next:hover svg path { transform: translateX(7px); }
.wa-still__next-rule { display: block; height: 1px; margin-top: .85rem;
  background: var(--wa-rust); }
.wa-still__next:focus-visible { outline: 1px solid var(--wa-honey);
  outline-offset: 8px; }
@media (prefers-reduced-motion: reduce) {
  .wa-still__grid > [data-block="craft-mark"],
  .wa-still__grid > [data-block="craft-body"],
  .wa-still__next svg path { transition: none; }
}

[data-canvas] .wa-still__grid {
  position: relative; display: block;
  width: 100%; max-width: 72rem; margin-inline: auto;
  aspect-ratio: var(--canvas-ratio, 16 / 9);
}
[data-canvas] .wa-still__grid > [data-block] {
  position: absolute;
  left: var(--x, 0%); top: var(--y, 0%); width: var(--w, 24%);
  margin: 0; padding: 0; align-self: auto; justify-self: auto;
  text-align: var(--align, left); max-width: none;
}
[data-canvas] .wa-still__grid > [data-block] p { max-width: none; margin-left: 0; }
/* the plate fills whatever width it is given, and keeps its own proportion */
[data-canvas] .wa-still__fig img { width: 100%; height: auto; aspect-ratio: 2 / 3; }
[data-canvas] .wa-still__script { position: static; transform: none; white-space: normal;
  display: block; margin-bottom: .4rem; }
[data-canvas] .wa-still__rail { display: none; }

/* The type scale a block carries when it has been pulled larger or smaller.
   em rather than rem, so everything inside a block scales together from one
   number — headings, body, labels and all. */
[data-canvas] [data-block] { font-size: calc(1em * var(--fs, 1)); }

/* any section can be opened as a canvas, not only the still */
section[data-canvas] > .wa-inner { position: relative; }
section[data-canvas] > .wa-inner > [data-block],
section[data-canvas] [data-block] > [data-block] { position: absolute;
  left: var(--x, 0%); top: var(--y, 0%); width: var(--w, 24%); margin: 0; }
section[data-canvas] > .wa-inner { min-height: var(--canvas-h, 60vh); }

/* the handles, only while arranging */
body.arr-on [data-canvas] .wa-still__grid { outline: 1px dashed rgba(168,75,28,.35); }
body.arr-on [data-canvas] .arr-size {
  position: absolute; right: -7px; bottom: -7px; width: 14px; height: 14px;
  background: #A84B1C; cursor: nwse-resize; z-index: 99997;
}

body.arr-on .arr-fs, body.arr-on .arr-free {
  cursor: pointer; font: 500 .5rem/1 Poppins, sans-serif; letter-spacing: .12em;
  text-transform: uppercase; background: #F7F1E4; color: #2C2119;
  border: 1px solid #A84B1C; padding: .35rem .5rem;
}
body.arr-on .arr-free { background: #1E3A2B; color: #F7F1E4; border-color: #1E3A2B; }

/* ==========================================================================
   PHONES — 13 Sep 2026
   Measured at 375px on all 27 pages before a line of this was written:
   · the still on purpose.html kept its desktop canvas, so its blocks crossed
     each other and the words ran one to a line;
   · the work panel kept its four desktop columns and cut the name and the
     facts off at the right;
   · the LIFE / WORK diagonal kept its cut, because `.wa-split__half.is-life`
     outweighs the one-class stacking rule at 760px;
   · the WORK hexagon sat on page titles;
   · most labels rendered at 7–9px and most links were 16–22px tall.
   On the phone each piece keeps the order it reads in on the desktop —
   nothing here re-chooses an arrangement. The desktop is untouched.
   ========================================================================== */
@media (max-width: 760px) {

  /* ---- LIFE / WORK: restated at the desktop rules' own weight ---- */
  .wa-split__half.is-life, .wa-split__half.is-work { clip-path: none; }
  .is-life .wa-split__body, .is-work .wa-split__body {
    left: auto; top: auto; transform: none; }
  .wa-split__k, .wa-split__sub { font-size: 0.7rem; letter-spacing: 0.18em; }
  .wa-split__topics span,
  .is-life .wa-split__topics span { font-size: 0.7rem; letter-spacing: 0.14em; }
  /* centred uppercase with letter-spacing: indent by the same amount (16 Sep 2026) */
  .wa-split__k, .wa-split__sub { text-indent: 0.18em; }
  .wa-split__topics span, .is-life .wa-split__topics span { text-indent: 0.14em; }
  /* the arc offsets are set per name at three classes; on a phone the names are a list */
  .is-life .wa-split__topics .p1, .is-life .wa-split__topics .p2,
  .is-life .wa-split__topics .p3, .is-life .wa-split__topics .p4 { left: auto; top: auto; }

  /* ---- the still: a column, in its reading order ---- */
  [data-canvas] .wa-still__grid { display: flex; flex-direction: column;
    aspect-ratio: auto; gap: 1.5rem; max-width: 34rem; }
  [data-canvas] .wa-still__grid > [data-block] { position: relative;
    left: auto; top: auto; width: 100%; --fs: 1 !important; }
  [data-canvas] .wa-still__grid > [data-block="about-lede"]   { order: 1; }
  [data-canvas] .wa-still__grid > [data-block="still-photo"]  { order: 2;
    width: min(20rem, 82%); margin-inline: auto; }
  /* still lying across the photograph, as it does on the desktop */
  [data-canvas] .wa-still__grid > [data-block="script-line"]  { order: 3;
    width: min(20rem, 88%); margin: -5rem auto 0; z-index: 2; text-align: center; }
  [data-canvas] .wa-still__grid > [data-block="craft-mark"]   { order: 4; margin-top: 0.6rem; }
  [data-canvas] .wa-still__grid > [data-block="craft-body"]   { order: 5; }
  [data-canvas] .wa-still__grid > [data-block="chapter-next"] { order: 6; }
  .wa-chapter__num span { font-size: 0.7rem; }

  /* ---- the work panel: one column that scrolls ---- */
  /* REVERTED 4 Oct 2026. Making the strip take its own space meant restyling
     the panel's wrapper as a flex column, and that emptied the photograph
     column — she opened a work and the panel was blank. The strip goes back to
     sitting over the panel; the slicing is the lesser fault of the two. */
  .ov__two { display: flex; flex-direction: column; overflow-y: auto;
    overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
  .ov__rail { order: 1; flex: 0 0 auto; display: flex; overflow-x: auto; overflow-y: hidden;
    padding: 0.5rem 0.6rem; gap: 0.2rem; border-bottom: 1px solid rgba(46, 74, 62, 0.12);
    scrollbar-width: none; }
  .ov__rail::-webkit-scrollbar { display: none; }
  .ov__it { flex: 0 0 auto; width: 7.2rem; flex-direction: column; align-items: center;
    gap: 0.45rem; padding: 0.6rem 0.4rem; text-align: center; }
  /* A set's name used to run to its full length here — 114 characters on one
     Duterte Creatives film, which took most of the screen (her note, 4 Oct
     2026). A row can now carry its own short `rail` title; this is the net for
     any that still have none: two lines, and never wider than its circle's
     column. */
  .ov__lb { font-size: 0.68rem; letter-spacing: 0.08em; line-height: 1.45;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden; max-width: 11rem; }
  .ov__seg { position: static; flex: 0 0 auto; width: auto; border-top: 0;
    border-left: 1px solid rgba(46, 74, 62, 0.16); padding: 0.6rem 0.8rem; }
  .ov__seg:first-child { border-left: 0; }
  .ov__seg span { font-size: 0.68rem; letter-spacing: 0.16em; white-space: nowrap; }
  .ov__txt { order: 2; flex: 0 0 auto; overflow: visible; padding: 1.4rem 1.25rem 0.4rem; }
  .ov__dk { font-size: 0.68rem; letter-spacing: 0.18em; }
  .ov__spec div { grid-template-columns: 5.4rem minmax(0, 1fr); }
  .ov__spec span { font-size: 0.68rem; letter-spacing: 0.14em; }
  .ov__dph { order: 3; flex: 0 0 auto; height: 68vh; border-left: 0;
    border-top: 1px solid rgba(46, 74, 62, 0.14); }
  .ov--films .ov__dph { display: block; height: auto; padding: 1.2rem 1rem; }
  /* padding inside the width, or the film ran 16px past the right edge */
  .ov__dph { box-sizing: border-box; width: 100%; }
  .ov__strip { order: 4; flex: 0 0 auto; flex-direction: row; overflow-x: auto; overflow-y: hidden;
    padding: 0.9rem 1.25rem 1.2rem; gap: 12px; -webkit-mask-image: none; mask-image: none; }
  .ov__two .ov__step { display: none !important; }
  .ovnav button, .ovnav__s { font-size: 0.7rem; }
  /* On a phone the names sat hard against the top edge of the panel — her note,
     4 Oct 2026, reading passion.html on the phone. More room above the words
     than below, so the underline under the open piece still reads as the lower
     edge of the row. */
  .ovnav { padding-top: 24px; padding-bottom: 10px; }
  .ov__x, .ov__pn button { font-size: 0.7rem; }
  /* clear of the home bar on phones that have one */
  .ov__pn { padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px)); }
  .ov__plate span, .ov__plate b, .ov__platelink { font-size: 0.7rem; }
  /* The name on the frame used to be one unbreakable line with wide tracking,
     so a long one ran straight out of both sides of the box on a phone — her
     note, 4 Oct 2026, on Sorrelle. It now wraps inside the frame and can never
     be wider than it. */
  .ov__filmkind { font-size: 0.62rem; letter-spacing: 0.22em; text-indent: 0.22em;
    white-space: normal; text-align: center; max-width: min(86%, 300px);
    padding: 0.45rem 0.7rem 0.38rem; line-height: 1.5; }
  .ov__film:hover .ov__filmkind { letter-spacing: 0.26em; }

  /* ---- the WORK hexagon: the face alone, smaller ---- */
  body .ew-fab-face { width: 44px; height: 44px; }
  body .ew-fab-word, body .ew-fab-call { display: none; }
  body .ew--work .ew-fab.is-parked { left: 12px; bottom: 14px; }

  /* ---- labels a phone can read, links a thumb can hit ---- */
  .masthead__est { font-size: 0.68rem; letter-spacing: 0.22em; }
  .masthead__link { padding-top: 0.45rem; padding-bottom: 0.45rem;
    margin-top: -0.45rem; margin-bottom: -0.45rem; }
  .wa-subnav__section { font-size: 0.7rem; letter-spacing: 0.2em; }
  .wa-subnav a { font-size: 0.7rem; letter-spacing: 0.1em; padding-top: 0.55rem; margin-top: -0.55rem; }
  /* one line: WORK // RÉSUMÉ / IDENTITY / PORTFOLIO wrapped at 375px */
  .wa-subnav__row { gap: 0.5rem; }
  /* the banner's words sit below the header, however tall the header measures */
  .masthead ~ main .wa-vhead { padding-top: var(--nav-real, 232px); }
  .wa-label { font-size: 0.68rem; letter-spacing: 0.24em; }
  .wa-label > a { display: inline-block; padding-top: 0.6rem; padding-bottom: 0.6rem; }
  .wa-filter { font-size: 0.7rem; letter-spacing: 0.16em; }
  .sortbar span { font-size: 0.68rem; letter-spacing: 0.18em; }
  .sortbar button { font-size: 0.68rem; letter-spacing: 0.14em; }
  body .wa-card__kicker { font-size: 0.68rem; letter-spacing: 0.18em; }
  body .wa-card__title, .wa-cards__grid .wa-card__title { font-size: 0.72rem; }
  body .wa-card__oyr, .wa-work__grid .wa-card__oyr { font-size: 0.72rem; }
  body .wa-card__ocat, .wa-work__grid .wa-card__ocat { font-size: 0.68rem; letter-spacing: 0.12em; }
  .wa-film__kind { font-size: 0.68rem; letter-spacing: 0.18em; }
  .wa-film__role, .wa-credits__role { font-size: 0.68rem; letter-spacing: 0.08em; }
  .wa-piece__kicker { font-size: 0.7rem; letter-spacing: 0.18em; }
  .wa-cv__role { font-size: 0.7rem; letter-spacing: 0.14em; }
  .wa-str__name { font-size: 0.72rem; }
  .wa-str__key { font-size: 0.7rem; }
  .wa-contact__dl dt { font-size: 0.7rem; letter-spacing: 0.24em; }
  /* a thumb-sized place to tap, without moving the underline */
  .wa-contact__dl a { position: relative; }
  .wa-contact__dl a::before { content: ""; position: absolute; inset: -0.6rem -0.25rem; }
  .wa-map__legend span { font-size: 0.7rem; }
  .wa-adventure p { font-size: 0.7rem; letter-spacing: 0.18em; }
  .wa-cta__link, .wa-closing__cta a { font-size: 0.7rem; padding-top: 0.55rem; padding-bottom: 0.55rem; }
  .wa-foot nav { font-size: 0.72rem; letter-spacing: 0.2em; gap: 0.15rem; }
  /* On a phone a short link like "AI" was a 15px-wide target. The padding widens
     what a thumb can hit; the equal negative margin keeps every word exactly
     where it was (15 Sep 2026, mobile check). */
  .wa-foot nav a { display: inline-block; padding: 0.5rem 0.75rem; margin: 0 -0.75rem; }
  .wa-foot__tag { font-size: 0.68rem; }
  .wa-foot__base { font-size: 0.68rem; letter-spacing: 0.16em; }
  body:has(.ew-fab) .wa-foot { padding-bottom: 5.5rem; }
}
/* the hero's manifest boxes only stack below 620px, so their words follow them */
@media (max-width: 620px) {
  .mf__title { font-size: 0.68rem; letter-spacing: 0.1em; }
}

/* ==========================================================================
   PHONES — Purpose and Passion, from Elyne's phone, 16 Sep 2026
   Every rule here is phone-only (max-width 760px); the desktop keeps her
   settled values.
   ========================================================================== */
@media (max-width: 760px) {
  /* 1 · "Ung video sa PURPOSE and PASSION sa header, wala sa gitna on mobile."
     Her desktop framing is 0% 0% — the left edge of a 16:9 film. A phone band
     is nearly square, so that kept only the left third: the runner and the
     face were cut at the right. Centred, both films keep their subject. */
  .wa-vhead { --vhead-x: 50%; }

  /* 1b · The band keeps the look it has — hers, 4 Oct 2026: "ifollow mo ung
     last revision". Only its size is set for a phone. It was carrying the
     desktop's 96px of padding top AND bottom inside a 422px band, so nearly
     half the height was empty and the film was squeezed into what was left.
     The band is now a little taller, the padding a third of what it was, and
     svh is used so the browser's own bar appearing does not resize it. */
  /* "I want the whole video to fit in here" — 4 Oct 2026, with the band at this
     size. Both films are 9:16 portrait; the band is about 390x540, so fitting
     the film whole gives roughly 304x540 — nearly the full width, nothing cut.
     The narrow margin either side takes the band's own colour. */

  /* 2 · "WHO I AM sa header, unreadable" — her choice: a cream box behind the
     words. Only on Purpose; Passion's cream words on its dark film read well. */
  /* The cream box behind Purpose's words was added when the film was cropped
     to a bright sliver and "WHO I AM" was unreadable over it. Hers, 4 Oct 2026:
     "kung ano sa passion, dapat ganun sa purpose" — so it goes, and the two
     headers are the same again. The film is shown whole now, and the veil over
     it is what carries the words. */
  .wa-vhead--life .wa-vhead__body { background: none; padding: 0; }

  /* 3 · "Masyadong malayo ang My work lives sa A Creative And Marketing Junkie":
     95px, the heading's bottom padding plus the still's full top padding. */
  section[data-block="about"] { padding-bottom: 1rem; }
  section[data-block="still"] { padding-top: 0.75rem; }

  /* 3 · "Continue to learn nasa taas ng photo ... nakapatong sa photo just like
     on desktop." In the phone column the line followed the photograph and only
     its top edge touched it. The column becomes a grid so the line can share
     the photograph's row, lying across the lower part of the picture, while
     everything after still starts below the photograph whatever its height. */
  /* The desktop's `.wa-still__grid:has(> [data-block]:nth-child(5))` asks for
     five columns and outranks a plain override, which squeezed every block to
     one word a line — so this states one column at a higher weight. */
  [data-canvas] .wa-still__grid.wa-still__grid:has(> [data-block]) {
    display: grid; grid-template-columns: minmax(0, 1fr); }
  [data-canvas] .wa-still__grid > [data-block] { grid-column: 1 / -1; }
  /* the written line is pulled up above the photograph's top edge, so the
     paragraph over it needs room or the two touch. */
  [data-canvas] .wa-still__grid > [data-block="about-lede"]   { grid-row: 1;
    margin-bottom: 2.2rem; }
  [data-canvas] .wa-still__grid > [data-block="still-photo"]  { grid-row: 2; }
  /* 4 Oct 2026: "Mali itong nasa ibaba ang Continue to learn. Dapat nasa taas."
     It was pinned to the bottom of the photograph's row, where it lay across
     the grass. It now sits at the top of the same row, still over the picture. */
  /* 4 Oct 2026: "Ung placement sana, same na same sa desktop, nasa upper left
     banda."  So this is the desktop placement scaled to the phone, not a new
     one. Measured from the live desktop (photo 400x600 at x513,y1078; the
     written line 344 wide at x477, y1018, 30px):

       line width   = 0.86 x the photograph's width
       starts       = 0.09 x that width OUTSIDE its left edge
       sits         = 0.15 x that width ABOVE its top edge
       size         = 0.075 x that width

     Everything is tied to the photograph, so the line keeps the same hand and
     the same two-line break at every phone width. The photograph itself is
     min(20rem, 82%) — hence --ph. */
  [data-canvas] .wa-still__grid > [data-block="script-line"].wa-still__script-line {
    --ph: min(20rem, 82%);
    grid-row: 2; align-self: start; justify-self: start;
    text-align: left; z-index: 2;
    width: calc(var(--ph) * 0.86);
    /* straddles the photograph's top edge the way the desktop does — measured
       there as half the written block above the edge, half on the picture.
       0.02 lands it at 50%; -0.15 put the whole line above the photograph,
       where it collided with the paragraph over it. */
    margin: calc(var(--ph) * 0.02) 0 0
            calc((100% - var(--ph)) / 2 - var(--ph) * 0.09);
    font-size: min(24px, calc((100vw - 64px) * 0.0615)); }
  [data-canvas] .wa-still__grid > [data-block="craft-mark"]   { grid-row: 3; }
  [data-canvas] .wa-still__grid > [data-block="craft-body"]   { grid-row: 4; }
  [data-canvas] .wa-still__grid > [data-block="chapter-next"] { grid-row: 5; }

  /* 4 · "The 4 commitments ... igitna mo silang lahat just like the title Four
     Quiet Commitments. Pati ang hexagon igitna." */
  .wa-cards__grid .wa-card,
  .wa-cards__grid .wa-card:first-child { text-align: center; padding-left: 0; padding-right: 0; border-left: 0; }
  .wa-cards__grid .wa-card__hex { margin: 0 auto 0.9rem; }
  .wa-cards__grid .wa-card p { margin-left: auto; margin-right: auto; }

  /* 5 · "Lahat ng Pages, lagyan mo ng 25px or 50px man lang." Every section's
     content sits in .wa-inner, which gave 19px at the sides on a phone. */
  .wa-inner { padding-left: 2rem; padding-right: 2rem; }
}

/* ---- the work panel's foot, Passion and Volunteerism (hers, 16 Sep 2026) ----
   "Ang pangit nung sa ilalim, nagpapatong patong na sila. Liitan mo na lang ang
   text." On a phone the 11px, widely tracked names had ~150px each and broke
   onto two or three lines (DUTERTE / CREATIVES →). Smaller and tighter, the
   longest names (Sorrelle Affiliate, 18 letters) fit on one line; the caption
   under the picture likewise holds its longest title (40 letters) on one line.
   Should a name ever outgrow its column it ends in "…" rather than stacking. */
@media (max-width: 760px) {
  .ov__pn { column-gap: 0.5rem; }
  .ov__x, .ov__pn button { font-size: 0.55rem; letter-spacing: 0.1em; gap: 0.45rem;
    white-space: nowrap; min-width: 0; max-width: 100%; }
  .ov__pn button span { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
  .ov__plate { gap: 0.6rem; }
  .ov__plate span { font-size: 0.56rem; letter-spacing: 0.1em; white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis; min-width: 0; }
  .ov__plate b, .ov__platelink { font-size: 0.58rem; white-space: nowrap; flex: none; }
}

/* ==========================================================================
   TABLETS — iPad and the Pad 5, 23 Sep 2026
   Her question: "is the website also optimized for iPad or Pad 5?"
   Measured at 768, 800, 820 and 1024: the layout holds, nothing scrolls
   sideways and the menu stays on one line. What did not reach a tablet were
   the thumb-sized targets: every phone fix stops at 760px, and an iPad in
   portrait is 768–834px, a Pad 5 is 800px. So the links there were still
   16–23px tall — a mouse size, on a screen with no mouse.
   The band is 761–900px AND a touch screen, so a desktop window narrowed to
   850px keeps its desktop sizes. Padding only: the equal negative margin
   leaves every word exactly where she placed it.
   ========================================================================== */
@media (min-width: 761px) and (max-width: 900px) and (pointer: coarse) {
  .masthead__link { padding-top: 0.5rem; padding-bottom: 0.5rem;
    margin-top: -0.5rem; margin-bottom: -0.5rem; }
  .wa-subnav a { display: inline-block; padding-top: 0.55rem; padding-bottom: 0.55rem;
    margin-top: -0.55rem; margin-bottom: -0.55rem; }
  .wa-label > a { display: inline-block; padding-top: 0.6rem; padding-bottom: 0.6rem;
    margin-top: -0.6rem; margin-bottom: -0.6rem; }
  .wa-foot nav a { display: inline-block; padding: 0.5rem 0.75rem; margin: 0 -0.75rem; }
  .wa-cta__link, .wa-closing__cta a { display: inline-block;
    padding-top: 0.55rem; padding-bottom: 0.55rem; margin-top: -0.55rem; margin-bottom: -0.55rem; }
  /* the underline stays exactly where it is; only what a finger can hit grows */
  .wa-contact__dl a { position: relative; }
  .wa-contact__dl a::before { content: ""; position: absolute; inset: -0.6rem -0.25rem; }
}

/* A funnel that is not published yet wears the same frame as the published
   ones — the corner marks, the name, the plate — but there is nothing to open,
   so it is not a link and the badge that opens a site stays away.
   (23 Sep 2026, hers: "make sure parehas ang pagshow sa work") */
.ov__site--unpublished { cursor: default; }
.ov__site--unpublished .ov__play { display: none; }

/* ---------------- THE HEADER FILM ON PHONES AND TABLETS ----------------
   Hers, 4 Oct 2026: "wala na lang text if mobile, pero wala rin ung dark areas
   sa ilalim ng video. Sa pad, wala na rin. Focus on a good looking header."

   Both films are 16:9 LANDSCAPE — 1920x1080 and 1280x720, read from the posters.
   (`mdls` reports the mp4s as portrait; that is the rotation metadata, not the
   picture, and two earlier rounds of fixes were built on that wrong number.)

   The band used to be 540px tall while the film fitted whole is about 220px —
   that gap is where the dark strip under the video came from. The band now
   takes the film's own shape, so the picture fills it exactly: nothing cropped,
   nothing left over. The words are off, and so is the veil that carried them. */
@media (max-width: 1024px) {
  /* The masthead is FIXED and carries a near-solid cream bar 158px tall. With
     the band starting at y=0 that bar was sitting on top of the film — on a
     phone it covered 158px of a 211px picture. The band now BEGINS under the
     nav (margin, not padding: padding would be inside the band, and the video
     is inset:0, so it would go on being covered). Nothing is over the film and
     nothing is under it. */
  .masthead ~ main .wa-vhead,
  .wa-vhead {
    aspect-ratio: 16 / 9;
    min-height: 0;
    max-height: none;
    padding-block: 0;
    margin-top: var(--nav-real, 158px);
  }
  .wa-vhead__v { object-fit: cover; object-position: 50% 50%; }
  .wa-vhead__body,
  .wa-vhead__scrim { display: none; }
  /* The band is the picture now, so the section after it needs its own air. */
  .wa-vhead + section,
  .wa-vhead + .wa-head,
  .wa-vhead + header { padding-top: 2.2rem; }
}
