/* ============================================================================
   TRT Atelier — Option 1 (dark, serif) per Bart's "web tryouts" concept,
   V2 pass 2026-08-13: visible hero (clean left crop of Bart's own photo),
   text right per the mock, engine depth, proof frame, beams + lifts.
   V3.1 pass 2026-08-18: Kristine's seven pages. The one-page furniture she
   dropped (method split, governance path, hero kicker) is gone with it; the
   interior-page head, the six principles and the case rail are new, in the
   same idiom. Tokens: StudioBarda Rev-03 as shipped on trt-website; Sage Blue
   pinned from the tryouts PDF swatch. VARIANCE 5 · MOTION 5 · DENSITY 4.
   ========================================================================== */

/* ---- fonts (files copied from trt-website, Bart's shipped set) ---- */
@font-face {
  font-family: "Editor";
  src: url("/fonts/Editor-Regular.woff2") format("woff2"),
       url("/fonts/Editor-Regular.woff") format("woff");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Editor";
  src: url("/fonts/Editor-Light.woff2") format("woff2");
  font-weight: 300; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Editor";
  src: url("/fonts/Editor-Italic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
}
@font-face {
  font-family: "Avenir Next";
  src: url("/fonts/AvenirNext-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Avenir Next";
  src: url("/fonts/AvenirNext-Medium.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Avenir Next";
  src: url("/fonts/AvenirNext-DemiBold.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}

/* ---- tokens ---- */
:root {
  /* palette (canon) */
  --sacred-stone: #F6F2EC;
  --linen: #DCCFB9;
  --olive-wash: #8A957A;
  --terracotta: #A86A4D;
  --oxblood: #5B1F28;
  --midnight-ink: #0F1B2A;
  --sage-blue: #8CA3A5;      /* pinned from Bart's tryouts swatch, 2026-08-13 */
  --soft-gold: #B3944A;      /* reserved — R1; declared, unused */

  /* roles */
  --bg: var(--midnight-ink);
  --fg: var(--sacred-stone);
  --fg-muted: rgba(246, 242, 236, 0.72);
  --fg-faint: rgba(246, 242, 236, 0.55);
  --accent-serif: var(--linen);            /* the italic accent thread */
  --rule: rgba(246, 242, 236, 0.16);
  --band-light-bg: var(--sacred-stone);
  --band-light-fg: var(--midnight-ink);
  --band-light-muted: rgba(15, 27, 42, 0.72);
  --band-light-rule: rgba(15, 27, 42, 0.18);
  --band-sage-bg: var(--sage-blue);
  --band-sage-fg: var(--midnight-ink);

  /* type */
  --serif: "Editor", "Iowan Old Style", Georgia, serif;
  --sans: "Avenir Next", "Avenir", "Helvetica Neue", Arial, sans-serif;

  /* scale + rhythm */
  --measure: 34em;
  --section-pad: clamp(6rem, 12vw, 10rem);
  --gutter: clamp(1.25rem, 5vw, 4rem);
  --ease: cubic-bezier(0.22, 1, 0.36, 1); /* house outExpo (frontend-taste) */
}

/* ---- reset-lite ---- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .hero-beams { display: none; }
}
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  font-weight: 400;
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img { max-width: 100%; display: block; }
.svg-defs { display: none; } /* symbol sheet only — CSP forbids inline style attributes */
a { color: inherit; }

h1, h2 {
  font-family: var(--serif);
  font-weight: 400;
  line-height: 1.08;
  margin: 0;
  text-wrap: balance;
}
h3 { font-family: var(--serif); font-weight: 400; margin: 0; }
p { margin: 0; }

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

/* ---- motion (js-motion set only when JS runs AND reduced-motion is off;
        without it every element is simply visible — no hidden content) ---- */
.js-motion .reveal {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.55s var(--ease), transform 0.55s var(--ease);
}
/* page entrances are felt, scroll reveals stay quick (Stephen 8/20): what greets you on
   arrival — the hero, every page head, the founder page — rises slower and from deeper */
.js-motion .hero .reveal,
.js-motion .page-head .reveal,
.js-motion .fpage .reveal,
.js-motion .write .wcopy .reveal {
  transform: translateY(18px);
  transition-duration: 1.15s;
}
/* a section heading opens a section, so it rises from deeper and takes longer than the
   generic scroll reveal (Stephen 8/22 — the foundation page reads as motionless) */
.js-motion .section-h2.reveal {
  transform: translateY(16px);
  transition-duration: 0.85s;
}
.js-motion .reveal.in {
  opacity: 1;
  transform: translateY(0);
}
/* hairline draw on method principles */
.js-motion .principle { border-top-color: transparent; position: relative; }
.js-motion .principle::before {
  content: "";
  position: absolute;
  top: -1px; left: 0;
  width: 100%; height: 1px;
  background: var(--rule);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.9s var(--ease) 0.15s;
}
.js-motion .principle.in::before { transform: scaleX(1); }
.js-motion .principle:last-child { border-bottom-color: transparent; }
.js-motion .principle:last-child::after {
  content: "";
  position: absolute;
  bottom: -1px; left: 0;
  width: 100%; height: 1px;
  background: var(--rule);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.9s var(--ease) 0.3s;
}
.js-motion .principle.in:last-child::after { transform: scaleX(1); }

/* ---- header ---- */
.site-header {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem 2.5rem;
  flex-wrap: wrap;
  padding: 1.6rem var(--gutter);
}
.lockup {
  display: inline-flex;
  align-items: center;
  min-height: 44px;              /* touch floor: it is the link home from every page */
  gap: 0.75rem;
  text-decoration: none;
}
.lockup-rose { width: 30px; height: 30px; fill: var(--fg); flex: none; }
.lockup-name {
  font-family: var(--serif);
  font-size: 1.05rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
}
.lockup-rule { width: 44px; height: 1px; background: var(--rule); }
.lockup-arm {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.38em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.site-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 2rem;
}
.site-nav a {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--fg-muted);
  padding: 0.5rem 0;
  transition: color 180ms var(--ease);
}
.site-nav a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0.15rem;
  width: 100%; height: 1px;
  background: var(--fg);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 260ms var(--ease);
}
.site-nav a:hover { color: var(--fg); }
.site-nav a:hover::after { transform: scaleX(1); }
/* the page you are on: the rule the hover draws is simply already drawn */
.site-nav a[aria-current="page"] { color: var(--fg); }
.site-nav a[aria-current="page"]::after { transform: scaleX(1); }

/* ---- mobile navigation: a word and a drawer (below 700px) ----
   Matches the TRT website's SiteNav pattern. Everything here is scoped under html.nav-js,
   which only nav.js sets, so with JS off the nav stays the plain inline list above.
   The toggle and drawer are display:none above the breakpoint. */
.nav-toggle { display: none; }
.nav-frost { display: none; }

.nav-js .nav-toggle {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  /* Full Sacred Stone, not the row's 72%. The header sits over the hero photograph, where
     a muted value is at the mercy of the pixels behind it — the same shape as the TRT
     site's open "mobile menu under 2:1" finding. Deliberately not inherited. */
  color: var(--fg);
  background: none;
  border: 0;
  padding: 0 0.15rem;
  min-height: 44px;              /* touch floor, as the 700px block sets for .site-nav a */
  cursor: pointer;
  z-index: 60;                   /* above the frost and the drawer */
  position: relative;
}
.nav-js .nav-toggle:focus-visible {
  outline: 1px solid var(--linen);
  outline-offset: 3px;
}

@media (max-width: 700px) {
  .nav-js .nav-toggle { display: inline-flex; align-items: center; }

  /* The frost is its own layer with nothing animating inside it, and it is always present
     at opacity 0 — so its blur is rasterized well before the drawer opens and the ground
     never arrives late. */
  .nav-js .nav-frost {
    display: block;
    position: fixed;
    inset: 0;
    min-height: 100dvh;            /* belt and braces, as the drawer below sets it */
    z-index: 30;
    background: rgba(15, 27, 42, 0.94);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 260ms var(--ease);
  }
  body.nav-open .nav-frost { opacity: 1; }

  /* Open, the header goes fixed: absolute would carry the row off-screen on a page already
     scrolled down, so the lockup and the toggle would vanish with it. */
  body.nav-open .site-header { position: fixed; z-index: 60; }
  body.nav-open { overflow: hidden; }

  .nav-js .site-nav {
    position: fixed;
    inset: 0;
    /* Belt and braces (2026-08-22). The drawer and the frost are inside <header> in the DOM,
       so anything that makes the header a containing block for fixed children — a transform,
       a backdrop-filter — turns "inset: 0" into the header's own 82px row instead of the
       screen. The header-follows block at the foot of this file no longer does either; these
       two lines mean that even if something does, the drawer is still the size of the screen
       and the column still runs down it rather than wrapping sideways over the hero. A floor,
       not a height: on a page whose layout viewport is taller than the screen, "inset: 0" is
       the larger of the two and must keep winning. */
    min-height: 100dvh;
    z-index: 40;
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: flex-start;
    gap: 1.6rem;
    padding: 7.5rem var(--gutter) 4rem;
    overflow-y: auto;
    overscroll-behavior: contain;
    /* Closed it is genuinely gone — not transparent-but-tappable over the hero. */
    visibility: hidden;
    opacity: 0;
    transition: opacity 220ms var(--ease), visibility 220ms var(--ease);
  }
  body.nav-open .site-nav { visibility: visible; opacity: 1; }

  /* Serif and large, as the TRT drawer sets them — a room, not a list of tabs. */
  .nav-js .site-nav a {
    font-family: var(--serif);
    font-size: clamp(1.6rem, 7vw, 2.1rem);
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    color: var(--fg);
    padding: 0.15rem 0;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  .nav-js .site-nav a::after { display: none; }   /* the hover rule belongs to the desktop row */
  /* No hairline in the drawer, so the current page is marked in the accent thread instead. */
  .nav-js .site-nav a[aria-current="page"] { color: var(--accent-serif); }
  .nav-js .site-nav a:focus-visible {
    outline: 1px solid var(--linen);
    outline-offset: 4px;
  }
  .nav-js .nav-foot {
    margin: 1.4rem 0 0;
    padding-top: 1.6rem;
    border-top: 1px solid var(--rule);
    align-self: stretch;
    font-family: var(--sans);
    font-size: 0.62rem;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: var(--fg-faint);
  }

  /* The links rise on the house curve at the quick tempo. The global reduced-motion block
     already flattens animation to none, so this needs no guard of its own. */
  body.nav-open .site-nav > * { animation: nav-rise 0.7s var(--ease) both; }
  body.nav-open .site-nav > *:nth-child(1) { animation-delay: 0.08s; }
  body.nav-open .site-nav > *:nth-child(2) { animation-delay: 0.14s; }
  body.nav-open .site-nav > *:nth-child(3) { animation-delay: 0.20s; }
  body.nav-open .site-nav > *:nth-child(4) { animation-delay: 0.26s; }
  body.nav-open .site-nav > *:nth-child(5) { animation-delay: 0.32s; }
  body.nav-open .site-nav > *:nth-child(6) { animation-delay: 0.38s; }
  body.nav-open .site-nav > *:nth-child(7) { animation-delay: 0.44s; }
  body.nav-open .site-nav > *:nth-child(8) { animation-delay: 0.50s; }
}
@keyframes nav-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Above the breakpoint the drawer furniture is simply absent. */
.nav-foot { display: none; }
@media (max-width: 700px) { .nav-js .nav-foot { display: block; } }

/* ---- shared section furniture ---- */
.section-inner {
  max-width: 74rem;
  margin: 0 auto;
  padding: var(--section-pad) var(--gutter);
}
.eyebrow {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.38em;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin-bottom: 2.25rem;
}
/* The hit area is 44px at every width, not only on a phone: the type stays at 0.76rem and
   the height comes from padding, with the label sitting on the rule at the bottom of the
   box. A hairline link is the site's only call to action, so it cannot be the one control
   that is hard to hit. */
.cta {
  display: inline-flex;
  align-items: flex-end;
  min-height: 44px;
  margin-top: 3rem;
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.76rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--fg);
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--fg-muted);
  transition: border-color 180ms var(--ease);
}
.cta:hover {
  border-color: var(--fg);
  border-bottom-width: 2px;
  padding-bottom: calc(0.6rem - 1px);
  color: var(--accent-serif);
}

/* Hit area, not size. These links are set small on purpose — a nav row in 0.72rem caps, a
   mail address in the footer — so the target grows without the type, the rule beneath it or
   the rhythm moving a pixel. 44px, centred on the link. */
.site-nav a,
.footer-contact a { position: relative; }
.footer-contact a { display: inline-block; }
.site-nav a::before,
.footer-contact a::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: 44px;
  transform: translateY(-50%);
}

/* ---- hero: image lives left, copy lives right (Bart's composition) ---- */
.hero {
  position: relative;
  min-height: 100dvh;
  display: flex;
  align-items: stretch;
}
.hero-media {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none; /* decorative — must never eat clicks */
}
.hero-media img {
  position: absolute;
  left: 0; top: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
  /* no zoom drift — the image holds still and full (Stephen's call, 8/13 late) */
}
/* faint engineering grid drifting over everything — the "techy" layer */
.hero-media::before {
  content: "";
  position: absolute;
  inset: -120px;
  z-index: 1;
  background:
    repeating-linear-gradient(90deg, rgba(246,242,236,0.11) 0 1px, transparent 1px 96px),
    repeating-linear-gradient(0deg, rgba(246,242,236,0.085) 0 1px, transparent 1px 96px);
  animation: grid-drift 26s linear infinite alternate;
}
@keyframes grid-drift { to { transform: translate3d(96px, 96px, 0); } }
/* the blend: image stays readable on the left, ink takes over where copy sits */
.hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  background:
    linear-gradient(90deg, rgba(15,27,42,0.10) 0%, rgba(15,27,42,0.22) 38%,
                    rgba(15,27,42,0.5) 55%, rgba(15,27,42,0.42) 78%, rgba(15,27,42,0.3) 100%),
    linear-gradient(180deg, rgba(15,27,42,0.4) 0%, rgba(15,27,42,0) 22%,
                    rgba(15,27,42,0) 74%, rgba(15,27,42,0.32) 100%);
}
/* light layer: streaks, a slow sheen, and a breathing city glow.
   transform/opacity only; the photograph itself never moves or scales. */
.hero-beams {
  position: absolute;
  inset: 0;
  z-index: 2;
  overflow: hidden;
}
.hero-beams span {
  position: absolute;
  left: -45%;
  width: 62%;
  height: 3px;
  /* dimmed 2026-08-17 with the sheen: 0.85/0.6 read as bright lines on the plate */
  background: linear-gradient(90deg,
    transparent,
    rgba(140, 163, 165, 0.42),
    rgba(246, 242, 236, 0.28),
    transparent);
  filter: blur(2.5px);
  animation: beam-run 21s linear infinite;
}
.hero-beams span:nth-child(2) {
  top: 52%;
  width: 46%;
  height: 2px;
  background: linear-gradient(90deg, transparent, rgba(220, 207, 185, 0.34), transparent);
  animation-duration: 29s;
  animation-delay: 4s;
}
.hero-beams span:nth-child(1) { top: 27%; }
.hero-beams span:nth-child(3) {
  top: 73%;
  width: 72%;
  animation-duration: 37s;
  animation-delay: 9s;
}
@keyframes beam-run {
  0%   { transform: rotate(-13deg) translate3d(0, 0, 0); opacity: 0; }
  14%  { opacity: 0.3; }
  82%  { opacity: 0.24; }
  100% { transform: rotate(-13deg) translate3d(215%, 0, 0); opacity: 0; }
}
/* Ambient light, not a passing beam (Stephen, 2026-08-17: 'less obvious', and 'maybe it
   shouldn't be one vertical strip').

   This was a 38%-wide near-vertical band travelling 330% across the frame every 13s at full
   opacity — a strip crossing the city, and the eye followed it. Two broad blooms now sit in
   the frame instead and simply drift and breathe: no edges, no direction of travel, nothing
   to track. The light in the room changes rather than a light going past.

   Slow on purpose — 34s, roughly three times the old cycle — because the register is
   unhurried and because motion you cannot time is motion you stop noticing. Peak values are
   down too: 0.20 and 0.12 against the old 0.34 and 0.22.
   transform/opacity only, as the layer above states; the photograph never moves. */
.hero-beams::before {
  content: "";
  position: absolute;
  inset: -18%;
  background:
    radial-gradient(44% 34% at 24% 32%, rgba(140, 163, 165, 0.20), transparent 70%),
    radial-gradient(36% 30% at 66% 64%, rgba(246, 242, 236, 0.12), transparent 72%);
  filter: blur(34px);
  animation: hero-light 34s ease-in-out infinite;
}
@keyframes hero-light {
  0%, 100% { transform: translate3d(-1.5%, 0.8%, 0); opacity: 0.5; }
  50%      { transform: translate3d(2.5%, -1.2%, 0); opacity: 1; }
}
/* the city itself breathes, warm and slow */
.hero-beams::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(58% 42% at 26% 46%, rgba(168, 106, 77, 0.18), transparent 72%);
  /* was 9s swinging 0.3 -> 1, which read as a pulse. Slower and narrower now: a breath. */
  animation: city-breathe 17s ease-in-out infinite;
}
@keyframes city-breathe {
  0%, 100% { opacity: 0.55; }
  50%      { opacity: 0.9; }
}
.hero-inner {
  position: relative;
  z-index: 3; /* above the media's grid/tint/beams — never under the wash again */
  width: 100%;
  max-width: 74rem;
  margin: 0 auto;
  padding: 9rem var(--gutter) clamp(6rem, 13vh, 9rem);
  display: grid;
  grid-template-columns: minmax(0, 42fr) minmax(0, 58fr);
  align-items: end;
}
.hero-copy { grid-column: 2; }
.hero-inner .eyebrow { color: var(--fg-muted); }
.hero h1 {
  font-size: clamp(3.1rem, 8vw, 6rem);
  letter-spacing: 0.005em;
}
.hero-sub {
  max-width: var(--measure);
  margin-top: 2.5rem;
  font-size: 1.125rem;
  color: var(--fg-muted);
}

/* ---- interior pages (v3.1, seven pages) ----
   Home clears the absolute header with the hero's own 9rem of top padding; every other page
   needs the same room, so its head owns it. One idea per screen, so a head is a headline, at
   most one line under it, and the reading column — nothing else. */
/* A watermark hangs off its section's corner by design (.wm-br sits at right: -140px), so the
   section it lives in has to clip it — the same two lines .compl, .foundation, .sysmap,
   .built-sec and .fpage-txt each carry. The atelier's rose lives in the page head and this
   rule was missing, so that page scrolled sideways by ~150px at every width. */
.page-head { position: relative; overflow: hidden; }
.page-head .section-inner { padding-top: clamp(9.5rem, 20vh, 13rem); }
/* Two stacked sections would otherwise put --section-pad twice into one gap — 20rem of
   nothing between a page's head and its body. The head gives up most of its bottom padding
   when something follows it; alone on a page (the founder) it keeps the full measure. */
.page-head:not(:last-child) .section-inner { padding-bottom: clamp(3rem, 6vw, 5rem); }
.page-head h1 {
  font-size: clamp(2.4rem, 5.4vw, 4.2rem);
  max-width: 16em;
}
.page-lede {
  margin-top: 2.5rem;
  max-width: var(--measure);
  font-size: 1.125rem;
  color: var(--fg-muted);
}
.page-body {
  margin-top: 2rem;
  max-width: var(--measure);
  color: var(--fg-muted);
}
/* the one earned line a page is allowed */
.page-line {
  margin-top: 2.6rem;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.15rem, 1.9vw, 1.45rem);
  color: var(--accent-serif);
  max-width: 30em;
}
/* a step down from an h1: a heading that is a sentence, not a display line */
.section-h2 {
  font-size: clamp(1.55rem, 2.6vw, 2.15rem);
  max-width: 26em;
}

/* ---- the hairline-ruled label-and-line rhythm (atelier disciplines, case sections) ---- */
.principles { margin: 0; padding-top: 0.6rem; }
.principle {
  padding: 2.2rem 0;
  border-top: 1px solid var(--rule);
}
.principle:last-child { border-bottom: 1px solid var(--rule); }
.principle dt {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin-bottom: 0.9rem;
}
.principle dd {
  margin: 0;
  max-width: var(--measure);
  color: var(--fg-muted);
}
/* No hover state here, or on the six principles, or on the product cards. Nothing in any of
   them opens, and a wash under the cursor sends a reader hunting for the link that is not
   there. Hover belongs to the things that do something. */
/* the five disciplines follow the page lede rather than opening a section */
.disciplines { margin-top: 3.4rem; }
/* the case's "what was built" hangs off a single rail, as the engines' spec list does on the
   light band — the same gesture in the dark palette */
.case-band { border-color: var(--rule); }

/* ---- page 2: the six principles ----
   Her design note, followed: "each principle as a large Georgia numeral, a two-word title in
   Helvetica bold, one line beneath. A grid of six, three by two." The numeral is set in
   Editor, whose fallback stack is Georgia's, and the title in Avenir Next DemiBold — the
   site's serif and sans roles, rather than a second type system imported to satisfy a name.
   Ruled on all four sides, unlike the system grid: six principles are six things you can
   hold us to, and the closed frame says a set rather than a structure with fields. */
/* Her heading says the six principles "follow", so they have to sit close enough to read as
   the same page — not a second one under 250px of nothing. */
.foundation {
  background: var(--band-light-bg);
  color: var(--band-light-fg);
  position: relative;
  overflow: hidden;
}
.foundation .section-inner { padding-top: clamp(4rem, 8vw, 6rem); position: relative; }
.foundation :focus-visible { outline-color: var(--band-light-fg); }
.foundation .cta { color: var(--band-light-fg); border-bottom-color: rgba(15, 27, 42, 0.4); }
.foundation .cta:hover { border-color: var(--band-light-fg); color: var(--oxblood); }
.foundation .section-h2 { color: var(--band-light-fg); }
.principles-six {
  list-style: none;
  margin: 3.4rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--band-light-rule);
  border-left: 1px solid var(--band-light-rule);
}
.principle-card {
  border-right: 1px solid var(--band-light-rule);
  border-bottom: 1px solid var(--band-light-rule);
  padding: 2.1rem 1.9rem 2.5rem;
  display: flex;
  flex-direction: column;
  min-height: 15rem;
  background: var(--band-light-bg);
  transition: background 300ms var(--ease), transform 320ms var(--ease), box-shadow 320ms var(--ease);
}
/* the cell comes toward you (Stephen 8/20) — lift + a breath of scale, compositor only */
@media (hover: hover) {
  .principle-card:hover {
    background: #EDE6DB;
    transform: translate3d(0, -6px, 0) scale(1.015);
    box-shadow: 0 26px 44px -26px rgba(15, 27, 42, 0.5);
    position: relative;
    z-index: 1;
  }
}
.pc-n {
  display: block;
  font-family: var(--serif);
  font-size: clamp(1.9rem, 3vw, 2.4rem);
  line-height: 1;
  color: var(--terracotta);
  margin-bottom: auto;
  font-weight: 300;
}
/* Titles set in the serif per the approved design-pass mock (v2.2). Her v3.1 written note
   said a sans bold title; the mock she reviewed carries the serif — flagged in the packet,
   hers to overrule. */
.pc-title {
  display: block;
  font-family: var(--serif);
  font-size: clamp(1.4rem, 2.4vw, 1.85rem);
  line-height: 1.15;
  margin: 2.2rem 0 0.7rem;
  min-height: 2.3em;
  display: flex;
  align-items: flex-end;
}
.pc-line {
  display: block;
  color: var(--band-light-muted);
  font-size: 0.97rem;
  max-width: 30ch;
}

/* ---- the still-life band (the case) ----
   A 6:1 strip could only ever show a texture; at roughly 2.6:1 the photograph reads as a
   photograph — the linen, the candle, the stone, the written page (Bart's note, 8/22). */
.gov-band {
  height: clamp(240px, 38vw, 660px);
  overflow: hidden;
  border-top: 1px solid rgba(15, 27, 42, 0.25);
  border-bottom: 1px solid rgba(15, 27, 42, 0.25);
}
.gov-band img {
  width: 100%;
  height: 132%;
  object-fit: cover;
  animation: gov-pan 44s ease-in-out infinite alternate;
}
@keyframes gov-pan { from { transform: translateY(-14%); } to { transform: translateY(0); } }

/* ---- the people the disciplines are held by (page 3) ----
   PLATES HELD 2026-08-18. The row and its stylesheet block (.technologists, .tech-wrap,
   .tech-four, .plate and every .p-* rule) came out with the markup rather than being left
   here dead: they return together, from git, when each person's own portrait, each person's
   own words and Kristine's person→discipline mapping exist. expand.js is unreferenced
   until then.
   Reviews: the-rose-tablet/product/atelier-site/2026-08-18-rhaenyra-v3-1-review.md. */


/* ---- inquiry form ---- */
.inquire {
  margin: 3.5rem auto 0;
  max-width: 40rem;
  text-align: left;
}
.inquire-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 2rem;
}
.inquire-field {
  display: block;
  margin-bottom: 1.9rem;
}
.inquire-field span {
  display: block;
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.7rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin-bottom: 0.7rem;
}
.inquire-field span em { font-style: normal; letter-spacing: 0.14em; opacity: 0.8; }
/* A field is a component boundary, so its edge owes 3:1 (WCAG 1.4.11) — and it owes it
   against a moving photograph, not a flat ground. The old 0.16 rule measured 1.6:1 and the
   fields dissolved into the skyline.
   0.42 was the review's number and it measured 2.74:1 in the render, because a 1px border on
   a fractional box edge is split across two device rows and neither row gets the full value.
   0.55 measures 5.5:1 on a whole row and 3.7:1 on the worst split, so it holds either way,
   and it still sits a step under the button's 0.72 — the action stays the brightest edge on
   the page. The field is near-solid ink as well, so the photograph behind it stops counting. */
.inquire-field input,
.inquire-field textarea {
  width: 100%;
  background: rgba(15, 27, 42, 0.9);
  border: 1px solid rgba(246, 242, 236, 0.55);
  border-radius: 2px;
  padding: 0.85rem 1rem;
  color: var(--fg);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.5;
  transition: border-color 180ms var(--ease), background-color 180ms var(--ease);
}
.inquire-field textarea { resize: vertical; min-height: 8.5rem; }
.inquire-field input:hover,
.inquire-field textarea:hover { border-color: rgba(246, 242, 236, 0.78); }
/* The old rule set `outline: none` and lifted the border a shade instead, which left the
   focused field indistinguishable at arm's length. The site's own 2px ring does the work
   now — it was always in the stylesheet, the form was the one place that removed it. */
.inquire-field input:focus-visible,
.inquire-field textarea:focus-visible {
  outline: 2px solid var(--fg);
  outline-offset: 2px;
  border-color: var(--fg);
  background: rgba(15, 27, 42, 0.85);
}
.inquire-trap {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}
.inquire-send {
  /* .cta bottom-aligns its label against a hairline; a bordered button centres its own. */
  align-items: center;
  justify-content: center;
  border: 1px solid var(--fg-muted);
  border-radius: 2px;
  background: transparent;
  padding: 1rem 2.2rem 0.95rem;
  margin-top: 0.4rem;
  cursor: pointer;
  transition: border-color 180ms var(--ease), background-color 180ms var(--ease), color 180ms var(--ease);
}
.inquire-send:hover {
  border-color: var(--fg);
  background: rgba(246, 242, 236, 0.08);
  /* keep .cta's hover math out of the button: it thickens a bottom border and takes a pixel
     off the padding to compensate, which on a bordered button is a 1px jitter under the
     cursor. The button already has a border on all four sides; it does not need the tell. */
  padding-bottom: 0.95rem;
  border-bottom-width: 1px;
}
.inquire-send:disabled { opacity: 0.6; cursor: default; }
.inquire-status {
  min-height: 1.6em;
  margin-top: 1.4rem;
  font-size: 0.98rem;
  color: var(--fg);
}
/* ---- footer ---- */
.site-footer {
  border-top: 1px solid var(--rule);
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 3rem var(--gutter);
  align-items: end;
  max-width: 74rem;
  margin: 0 auto;
  padding: 4.5rem var(--gutter) 5.5rem;
}
.footer-lockup { display: flex; align-items: center; gap: 1.1rem; }
.footer-rose { width: 40px; height: 40px; fill: var(--fg); flex: none; }
.footer-name {
  font-family: var(--serif);
  font-size: 1rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  line-height: 1.35;
}
.footer-rule { width: 1px; height: 42px; background: var(--rule); }
.footer-arm {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.7rem;
  letter-spacing: 0.38em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.footer-lines p {
  max-width: 26em;
  font-size: 0.95rem;
  color: var(--fg-muted);
}
.footer-contact { text-align: right; font-size: 0.95rem; }
.footer-contact p { color: var(--fg-muted); }
.footer-contact a {
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 0.15rem;
  transition: border-color 180ms var(--ease);
}
.footer-contact a:hover { border-color: var(--fg); }

/* ---- responsive ---- */
@media (max-width: 900px) {
  .principles-six { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hero-inner { grid-template-columns: minmax(0, 1fr); }
  .hero-copy { grid-column: 1; }
  .hero-media img { width: 100%; opacity: 0.55; }
  .hero-media::after {
    background:
      linear-gradient(180deg, rgba(15,27,42,0.55) 0%, rgba(15,27,42,0.35) 35%,
                      rgba(15,27,42,0.82) 78%, rgba(15,27,42,0.95) 100%);
  }
  .inquire-row { grid-template-columns: minmax(0, 1fr); }
  .site-footer {
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    padding-bottom: 6.5rem;
  }
  .footer-contact { text-align: left; }
}
@media (max-width: 700px) {
  .principles-six { grid-template-columns: minmax(0, 1fr); }
  .principle-card { padding: 1.9rem 1.4rem 2.2rem; }
  /* One column, so the cross becomes a single stack of rules. The nth-child rules above are
     DOM order, not visual position: unchanged here they left the odd cards flush and the even
     ones indented, and kept a right border on cards that no longer have a neighbour. Every
     card aligns to the headline, and only the divisions BETWEEN them are drawn. */
  .site-header { padding: 1.2rem var(--gutter); }
  .lockup-rule { display: none; }
  .hero-inner { padding-top: 11rem; }
  .hero-beams { display: none; }
  .site-nav a { padding: 0.72rem 0; }
}
/* On a 390px phone the lockup and the word "Menu" no longer fit one row, and the header wrapped
   to two — the arm dropping under the name, the toggle under that, and the top of every page
   pushed down. The lockup gives back the letterspacing rather than the site giving up the arm.
   Caught by the 390-wide capture (Rhaenyra, finding 11: breakpoints not shot this pass). */
@media (max-width: 480px) {
  .site-header { gap: 0.75rem 1rem; flex-wrap: nowrap; }
  .lockup { gap: 0.55rem; min-width: 0; }
  .lockup-name { font-size: 0.92rem; letter-spacing: 0.09em; }
  .lockup-arm { font-size: 0.6rem; letter-spacing: 0.24em; }
}

/* ============================================================================
   DESIGN PASS 2026-08-19 (approved mock v2.2, artifact fb62f004) — the pages
   after the hero get pace, light beats, made graphics and her five rulings:
   merit-led parallels, the "no longer the edge" line with no-orphan setting,
   the timeline with cut-out plates, roles without people, sentence-case titles.
   Classes only — the CSP forbids inline style attributes.
   ========================================================================== */

/* ---- shared: small caps key label (sage on ink, sage-dark on stone) ---- */
.klabel {
  display: block;
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--sage-blue);
  margin-bottom: 1.4rem;
}
.band-light .klabel, .foundation .klabel { color: #5C7577; }

/* ---- shared: display roles (the mock's scale) ---- */
.disp-2 {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(2.2rem, 4.6vw, 3.6rem);
  line-height: 1.08;
  letter-spacing: -0.01em;
  text-wrap: balance;
  max-width: 21em;
}
.disp-3 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.7rem, 3.2vw, 2.5rem);
  line-height: 1.16;
  letter-spacing: -0.008em;
  text-wrap: balance;
}
.disp-4 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.4rem, 2.5vw, 1.85rem);
  line-height: 1.24;
  text-wrap: balance;
}
.line-it { font-style: italic; color: var(--accent-serif); }
.band-light .line-it, .foundation .line-it { color: var(--terracotta); }

/* no-orphan setting (her rule, 8/22: the comma ends line one and no word ever sits alone on
   a line). Two mechanics, both in the markup so they hold at every width rather than at the
   widths we happened to test:
     1. the break is written — a <br> after the comma, so line one always ends there;
     2. the last two words of every line are joined with &nbsp;, so the shortest a line can
        ever be is two words. That includes inside .hold, which gives up its nowrap on a
        phone.
   Not text-wrap: pretty — it only reduces the odds of an orphan, it does not forbid one. */
.hold { white-space: nowrap; }
@media (max-width: 480px) { .hold { white-space: normal; } }

/* ---- the rose as a quiet watermark ---- */
.wm {
  position: absolute;
  pointer-events: none;
  opacity: 0.07;
  fill: currentColor;
}
.wm-br { right: -140px; bottom: -180px; width: 620px; height: 620px; }
.wm-tl { left: -120px; top: -160px; width: 560px; height: 560px; }
.wm-spin { animation: wm-turn 120s linear infinite; transform-origin: 50% 50%; }
@keyframes wm-turn { to { transform: rotate(360deg); } }

/* ---- page 1: the situation — one line, then the timeline ---- */
.situation { border-top: 1px solid var(--rule); position: relative; overflow: hidden; }
.beats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0 2rem;
  margin-top: 5.5rem;
  position: relative;
  padding-top: 2.5rem;
}
.beats::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 1px;
  background: linear-gradient(90deg, var(--linen) 0%, rgba(220, 207, 185, 0.45) 62%, transparent 100%);
}
.beat { position: relative; padding-top: 9rem; min-height: 19rem; }
.beat::before {
  content: "";
  position: absolute;
  left: 0; top: -2.75rem;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--linen);
}
.beat-art {
  position: absolute;
  left: 0; top: -0.5rem;
  width: 230px; height: 170px;
  max-width: 100%;
  pointer-events: none;
}
.beat-n {
  display: block;
  font-family: var(--serif);
  font-weight: 300;
  font-size: 2.6rem;
  line-height: 1;
  color: var(--accent-serif);
  opacity: 0.85;
  margin-bottom: 1rem;
  position: relative;
}
.beat p {
  font-family: var(--serif);
  font-size: clamp(1.15rem, 2vw, 1.5rem);
  line-height: 1.3;
  max-width: 26ch;
  position: relative;
}

/* ---- page 1: the parallel — the merit leads (her ruling #5) ---- */
.parallel {
  display: grid;
  grid-template-columns: 7fr 5fr;
  gap: 0 4.5rem;
  margin-top: 6rem;
  align-items: start;
}
.par { padding-top: 1.75rem; position: relative; }
.par .klabel { margin-bottom: 1.25rem; }
.par-merit { border-top: 2px solid var(--linen); }
.par-merit .klabel { color: var(--linen); }
.par-merit p {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(1.7rem, 3.2vw, 2.5rem);
  line-height: 1.2;
}
.par-merit em { font-style: italic; color: var(--accent-serif); }
.par-dim { border-top: 1px solid var(--rule); margin-top: 3.5rem; }
.par-dim .klabel { color: var(--fg-faint); }
.par-dim p {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(1.15rem, 2vw, 1.5rem);
  line-height: 1.35;
  color: var(--fg-faint);
}

/* ---- page 1: the complication band (light), the line held to her setting ---- */
.compl {
  background: var(--band-light-bg);
  color: var(--band-light-fg);
  position: relative;
  overflow: hidden;
}
.compl :focus-visible { outline-color: var(--band-light-fg); }
.compl-p {
  font-size: clamp(1.1rem, 1.8vw, 1.3125rem);
  line-height: 1.55;
  max-width: 44ch;
  color: var(--band-light-fg);
}
.compl-line {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(1.9rem, 5.5vw, 4.4rem);
  line-height: 1.1;
  letter-spacing: -0.012em;
  margin-top: 4.5rem;
  position: relative;
}
.compl-line em { font-style: italic; color: var(--terracotta); }

/* ---- page 1: question and answer, facing ---- */
.qa-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3rem 5rem;
}
.qa-col p {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.7rem, 3.2vw, 2.5rem);
  line-height: 1.16;
  letter-spacing: -0.008em;
  text-wrap: balance;
}
.qa-col .line-it { font-weight: 400; }

/* ---- page 1: the proof, beside her ---- */
.proof .section-inner { border-top: 1px solid var(--rule); }
.proof-split {
  display: grid;
  grid-template-columns: 5fr 7fr;
  gap: 0 5rem;
  align-items: center;
}
.proof-plate { position: relative; overflow: hidden; aspect-ratio: 4 / 5; }
.proof-plate img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 18%;
  filter: saturate(0.9);
}
.proof-plate::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(15, 27, 42, 0) 60%, rgba(15, 27, 42, 0.5));
}
.proof-h {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.4rem, 2.5vw, 1.85rem);
}
.proof-p {
  margin-top: 1.6rem;
  font-size: clamp(1.1rem, 1.8vw, 1.3125rem);
  line-height: 1.55;
  max-width: 52ch;
  color: var(--fg-muted);
}

/* ---- the closing band: the line over the city, breathing ---- */
.close-band {
  position: relative;
  text-align: center;
  overflow: hidden;
  border-top: 1px solid var(--rule);
}
.close-band-media { position: absolute; inset: 0; pointer-events: none; }
.close-band-media img {
  position: absolute;
  left: 0; top: -10%;
  width: 100%; height: 120%;
  object-fit: cover;
  opacity: 0.28;
  filter: saturate(0.6);
  animation: pan-slow 40s ease-in-out infinite alternate;
}
@keyframes pan-slow { from { transform: translate3d(0, -3%, 0); } to { transform: translate3d(0, 3%, 0); } }
.close-band-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(60% 60% at 50% 50%, rgba(15, 27, 42, 0.35), rgba(15, 27, 42, 0.92));
}
.close-band .section-inner { position: relative; }
.close-band .close-line { margin: 0 auto; }
/* a band may carry a second statement — the case closes on its outcome, then hands off to
   the invitation (Stephen 8/22). The gap has to read as two statements, not one paragraph. */
.close-band .close-line + .close-line { margin-top: clamp(2rem, 4vw, 3.2rem); }
.close-line {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(1.5rem, 3.4vw, 2.6rem);
  line-height: 1.18;
  color: var(--accent-serif);
}

/* ---- page 2: the written page (the sheet) ---- */
.head-grid {
  display: grid;
  grid-template-columns: 7fr 5fr;
  gap: 3rem 5rem;
  align-items: end;
}
.sheet {
  background: var(--sacred-stone);
  color: var(--midnight-ink);
  padding: 2.4rem 2.4rem 2.9rem;
  position: relative;
  box-shadow: 0 30px 60px -30px rgba(0, 0, 0, 0.55);
  background-image: repeating-linear-gradient(180deg, transparent 0 37px, rgba(15, 27, 42, 0.12) 37px 38px);
  background-position: 0 18px;
}
/* the sheet sits straight — Kristine's ruling 8/23 ("just do straight for now, cute na siya
   na notepad"). It still arrives as one object; its markings land on it afterwards. */
.js-motion .sheet.reveal { transform: translateY(22px); }
.js-motion .sheet.reveal.in { transform: translateY(0); }
/* inside the sheet the rise is shorter and quicker than the page entrance, so the card
   reads as already settled while its ink appears on it */
.js-motion .sheet .reveal { transform: translateY(12px); transition-duration: 0.8s; }
.js-motion .sheet .reveal.in { transform: translateY(0); }
.sheet-label {
  display: block;
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.66rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: #5C7577;
  margin-bottom: 0.9rem;
}
.sheet-line {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.3rem, 2.3vw, 1.75rem);
  line-height: 38px;
  max-width: 24ch;
}
.sheet-rose {
  position: absolute;
  right: 2rem; bottom: 1.6rem;
  width: 28px; height: 28px;
  fill: rgba(15, 27, 42, 0.35);
}
/* On this head the line reads as display, not as the italic accent line — the approved
   mock (v2.2) sets it roman; the italic thread on this page belongs to the side quote. */
.head-grid .page-line { font-style: normal; color: var(--fg); }

.body-grid {
  display: grid;
  grid-template-columns: 7fr 5fr;
  gap: 3rem 5rem;
  margin-top: clamp(3rem, 7vw, 6rem);
  align-items: start;
}
.body-grid .page-body { margin-top: 0; }
.side-quote {
  border-left: 1px solid var(--rule);
  padding-left: 2.5rem;
}
/* the quote's rule draws itself down the margin as the quote arrives — the same hand as
   the hairline on .principle and the crossing rule on the map (2026-08-22) */
.js-motion .side-quote { border-left-color: transparent; position: relative; }
.js-motion .side-quote::before {
  content: "";
  position: absolute;
  top: 0; left: -1px;
  width: 1px; height: 100%;
  background: var(--rule);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 1s var(--ease) 0.25s;
}
.js-motion .side-quote.in::before { transform: scaleY(1); }
.side-quote p {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.3rem, 2.3vw, 1.75rem);
  line-height: 1.3;
  color: var(--accent-serif);
}

/* ---- page 3: the disciplines as a masthead ledger (roles, not people) ---- */
.ledger { margin-top: 3.4rem; border-top: 1px solid var(--rule); padding-top: 0; }
.ledger .principle {
  display: grid;
  grid-template-columns: 4fr 8fr;
  gap: 0 3rem;
  padding: 2.4rem 0;
  align-items: start;
  /* transform, never padding: padding animates layout and stutters; transform stays on the
     compositor (Stephen 8/20 — the artifact's motion was the standard) */
  transition: transform 320ms var(--ease);
}
.ledger .principle dt {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(1.6rem, 3vw, 2.4rem);
  line-height: 1.08;
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--fg);
  transition: color 300ms var(--ease);
  margin: 0;
}
.ledger .principle dd { margin: 0; color: var(--fg-muted); max-width: 52ch; }
.ledger .principle dt::after {
  content: "";
  display: block;
  width: 100%;
  height: 1px;
  margin-top: 0.55rem;
  background: var(--accent-serif);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 480ms var(--ease);
}
@media (hover: hover) {
  .ledger .principle:hover { transform: translateX(0.9rem); }
  .ledger .principle:hover dt { color: var(--accent-serif); }
  .ledger .principle:hover dt::after { transform: scaleX(1); }
}

/* ---- page 4: the system, as one drawing (light band) ---- */
.sysmap {
  background: var(--band-light-bg);
  color: var(--band-light-fg);
  position: relative;
  overflow: hidden;
}
.sysmap :focus-visible { outline-color: var(--band-light-fg); }
.map {
  margin-top: 3rem;
  display: grid;
  grid-template-columns: minmax(9rem, 10.5rem) 1fr minmax(9rem, 10.5rem);
  gap: 0 1.25rem;
  align-items: stretch;
}
.map-pole {
  border: 1px solid var(--band-light-rule);
  padding: 1.3rem 1.1rem;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 14.5rem;
  background: #EDE6DB;
}
/* inside the tiles the labels give up size and tracking so they never cross the frame
   (Stephen 8/20 — PRODUCTION was touching the rule at map width) */
.map-pole .klabel, .map-e .klabel {
  margin-bottom: 0.8rem;
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  overflow-wrap: break-word;
}
.map-pole-in {
  background-color: #EDE6DB;
  background-image: repeating-linear-gradient(180deg, transparent 0 23px, rgba(15, 27, 42, 0.1) 23px 24px);
  background-position: 0 12px;
}
.map-pole-t { font-family: var(--serif); font-size: 1.3rem; line-height: 1.12; }
.map-engines {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  position: relative;
}
.map-engines::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: 1px;
  background: var(--band-light-rule);
}
/* the drawing draws itself (Stephen 8/20 — more motion): the crossing rule sweeps left to
   right as the map enters; the container itself never hides, only its tiles stagger */
.js-motion .map-engines.reveal { opacity: 1; transform: none; }
.js-motion .map-engines::before {
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 1.4s var(--ease) 0.25s;
}
.js-motion .map-engines.in::before { transform: scaleX(1); }
.js-motion .map-e.reveal { transform: translateY(20px) scale(0.985); }
.js-motion .map-e.reveal.in { transform: none; }
.map-e .klabel { transition: color 250ms var(--ease); }
.map-e {
  position: relative;
  border: 1px solid var(--band-light-rule);
  background: var(--sacred-stone);
  margin: 0 0.4rem;
  padding: 1.2rem 1rem;
  min-height: 14.5rem;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  transition: transform 400ms var(--ease), box-shadow 400ms var(--ease);
}
@media (hover: hover) {
  .map-e:hover {
    transform: translate3d(0, -6px, 0);
    box-shadow: 0 24px 40px -24px rgba(15, 27, 42, 0.5);
  }
  .map-e:hover .klabel { color: var(--terracotta); }
}
.map-e-t { font-family: var(--serif); font-size: 1.25rem; line-height: 1.12; margin: 0.8rem 0 0.6rem; }
.map-e-s { font-size: 0.78rem; line-height: 1.4; color: var(--band-light-muted); }
.map-base {
  grid-column: 1 / -1;
  margin-top: 0.6rem;
  border: 1px solid var(--band-light-rule);
  padding: 1rem 1.4rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem 2rem;
  flex-wrap: wrap;
  font-size: 0.875rem;
  color: var(--band-light-muted);
}
.map-base b { font-family: var(--serif); font-weight: 400; font-size: 1.1rem; color: var(--band-light-fg); }

/* ---- page 4: the engines, read (dark, two columns) ---- */
/* the engines read as plates that mirror the map above (Stephen 8/20): the same axis
   label, framed, lifting like the tiles — the drawing and the reading are one system */
.engine-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.engine-list li {
  border: 1px solid var(--rule);
  padding: 2.2rem 2.2rem 2.6rem;
  transition: transform 320ms var(--ease), box-shadow 320ms var(--ease), border-color 320ms var(--ease);
}
@media (hover: hover) {
  .engine-list li:hover {
    transform: translate3d(0, -6px, 0);
    border-color: rgba(220, 207, 185, 0.4);
    box-shadow: 0 28px 48px -30px rgba(0, 0, 0, 0.7);
  }
}
.engine-list li:last-child { grid-column: 1 / -1; }
.engine-list .klabel { margin-bottom: 1.1rem; }
.engine-list h3 {
  font-size: clamp(1.4rem, 2.5vw, 1.85rem);
  letter-spacing: -0.008em;
  margin-bottom: 0.9rem;
}
.engine-list p { color: var(--fg-muted); max-width: var(--measure); }
.held-panel {
  margin-top: clamp(3.5rem, 8vw, 6rem);
  border: 1px solid var(--rule);
  padding: clamp(1.8rem, 4vw, 3.5rem);
  display: grid;
  grid-template-columns: 4fr 8fr;
  gap: 2rem 4rem;
  align-items: start;
  position: relative;
  overflow: hidden;
}
.held-panel h3 {
  font-weight: 300;
  font-size: clamp(1.7rem, 3.2vw, 2.4rem);
  line-height: 1.08;
}
.held-panel p { color: var(--fg-muted); max-width: 56ch; }
.held-panel .wm { opacity: 0.05; }
/* the panel that holds it all comes last and quietest, and the closing line inks in once
   the frame has settled (2026-08-22 — Stephen asked this page for motion). The italic is
   inline, so it fades only: transform does nothing to a non-replaced inline box. */
.js-motion .held-panel.reveal { transform: translateY(18px); transition-duration: 0.95s; }
.js-motion .held-panel.reveal.in { transform: translateY(0); }
.js-motion .held-panel .line-it { opacity: 0; transition: opacity 0.7s var(--ease) 0.75s; }
.js-motion .held-panel.in .line-it { opacity: 1; }

/* ---- page 5: the case — the head sheet, the season row, the built grid ----
   The head is the written page of page 2, carrying the case (Stephen 8/22): the sheet holds
   the label, the title and the five parts; the lede reads beside it, bottom-aligned to the
   sheet as the foundation's head-grid aligns its own pair. Everything the sheet needs —
   paper, tilt, seal, reveal choreography — comes from the .sheet block above; only what a
   title page changes is written here. */
.case-head .head-grid { align-items: end; }
.case-sheet { padding-bottom: 3.4rem; }
.case-sheet h1 {
  font-size: clamp(1.7rem, 3.1vw, 2.9rem);
  max-width: none;
  margin-top: 0.3rem;
}
/* the lede is a column of the grid now, and the grid's own row gap spaces it when the two
   stack on a phone */
.case-head .head-grid .page-lede { margin-top: 0; }

.season {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0 1rem;
  margin-top: 4.5rem;
}
.season-i { border-top: 1px solid var(--rule); padding-top: 1.1rem; }
.season-n {
  display: block;
  font-family: var(--serif);
  font-weight: 300;
  font-size: 2.4rem;
  line-height: 1;
  color: var(--accent-serif);
  margin-bottom: 0.6rem;
}
.season-w {
  display: block;
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg-faint);
}
/* On the sheet the same five marks are read down the page as its contents, not across it as
   a row of scores. They carry no rules of their own: the sheet's own ruling draws the lines,
   so each part takes exactly one ruled line of it. */
.case-sheet .season {
  grid-template-columns: 1fr;
  gap: 0;
  margin-top: 1.8rem;
}
.case-sheet .season-i {
  display: grid;
  grid-template-columns: 2.6rem 1fr;
  align-items: baseline;
  border-top: 0;
  padding-top: 0;
  line-height: 38px;
}
.case-sheet .season-n {
  font-size: 1.3rem;
  line-height: inherit;
  color: rgba(15, 27, 42, 0.5);
  margin-bottom: 0;
}
.case-sheet .season-w {
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  line-height: inherit;
  color: var(--band-light-muted);
}
/* readable over the photograph (Stephen, 8/20): larger, stone, on a quiet scrim */
.band-cap {
  position: absolute;
  left: var(--gutter); bottom: 1.8rem;
  z-index: 1;
  color: var(--sacred-stone);
  font-size: 0.95rem;
  letter-spacing: 0.3em;
  text-shadow: 0 1px 14px rgba(15, 27, 42, 0.9), 0 0 2px rgba(15, 27, 42, 0.8);
}
.gov-band::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(15, 27, 42, 0) 45%, rgba(15, 27, 42, 0.55) 100%);
}
.gov-band img { position: relative; }
.gov-band { position: relative; }
.built-sec {
  background: var(--band-light-bg);
  color: var(--band-light-fg);
  position: relative;
  overflow: hidden;
}
.built-sec :focus-visible { outline-color: var(--band-light-fg); }
.built-sec .section-h2 { color: var(--band-light-fg); }
.built {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid var(--band-light-rule);
  border-left: 1px solid var(--band-light-rule);
  margin-top: 3rem;
  list-style: none;
  padding: 0;
}
.built li {
  border-right: 1px solid var(--band-light-rule);
  border-bottom: 1px solid var(--band-light-rule);
  padding: 2rem 2rem 2.5rem;
  background: var(--band-light-bg);
  transition: background 300ms var(--ease), transform 320ms var(--ease), box-shadow 320ms var(--ease);
}
@media (hover: hover) {
  .built li:hover {
    background: #EDE6DB;
    transform: translate3d(0, -6px, 0) scale(1.015);
    box-shadow: 0 26px 44px -26px rgba(15, 27, 42, 0.5);
    position: relative;
    z-index: 1;
  }
}
.built h4 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.25rem, 2.2vw, 1.6rem);
  line-height: 1.15;
  margin: 0 0 0.6rem;
}
.built p { font-size: 0.97rem; color: var(--band-light-muted); }
.brief {
  display: grid;
  grid-template-columns: 4fr 8fr;
  gap: 1.5rem 4rem;
  padding: 3.4rem 0;
  border-top: 1px solid var(--rule);
}
.brief-k {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(1.5rem, 2.8vw, 2.1rem);
  line-height: 1.1;
}
.brief p { color: var(--fg-muted); max-width: 56ch; }

/* ---- page 6: the founder, at full height ---- */
.fpage {
  display: grid;
  /* the photograph capped, not proportional (her note 3, 8/20) — and the copy column
     capped at its own measure and the pair centred as one composition (Stephen 8/20:
     the wide column left a dead third of navy right of the text) */
  grid-template-columns: minmax(0, 29rem) minmax(0, 46rem); /* a touch wider (Stephen 8/20) */
  justify-content: center;
  column-gap: clamp(2.5rem, 5vw, 5rem);
  min-height: min(52rem, 92vh);
  /* the header is absolute on every page; this page has no .page-head to clear it, so the
     grid itself starts below it — the photograph hangs from the header band, as in the mock */
  margin-top: 7.2rem;
  border-top: 1px solid var(--rule);
}
.fpage-pic { position: relative; overflow: hidden; min-height: 24rem; }
.fpage-pic img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 20%;
  filter: saturate(0.92);
}
.fpage-txt {
  padding: clamp(4rem, 9vh, 6rem) 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  position: relative;
  overflow: hidden;
}
.fpage-txt h1 {
  font-weight: 300;
  font-size: clamp(2.6rem, 5.4vw, 4.4rem);
  letter-spacing: -0.01em;
}
.fpage-bio { margin-top: 1.8rem; max-width: 58ch; color: var(--fg-muted); font-size: 0.97rem; }
.fpage-bio + .fpage-bio { margin-top: 1.1rem; }
.fpage-pull {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.3rem, 2.4vw, 1.7rem);
  line-height: 1.3;
  color: var(--accent-serif);
  max-width: 26ch;
  margin-top: 2.2rem;
  position: relative;
}
.fpage-locus {
  display: block;
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--fg-faint);
  margin-top: 2.2rem;
}
.fpage-txt .cta { align-self: flex-start; }

/* ---- page 7: write to us — the form on its own panel ---- */
.write .section-inner { padding-top: clamp(9.5rem, 20vh, 13rem); }
.wsplit {
  display: grid;
  grid-template-columns: 5fr 7fr;
  gap: 3.5rem 6rem;
  align-items: start;
}
.wcopy h1 {
  font-weight: 300;
  font-size: clamp(2.6rem, 5.4vw, 4.4rem);
  letter-spacing: -0.01em;
}
.wcopy .page-lede .line-it { color: var(--accent-serif); }
.wcopy-locus { margin-top: 2.6rem; color: var(--fg-muted); font-size: 0.95rem; }
.form-panel {
  background: var(--sacred-stone);
  color: var(--midnight-ink);
  padding: clamp(1.8rem, 4vw, 3rem);
  box-shadow: 0 40px 80px -40px rgba(0, 0, 0, 0.6);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  margin-top: 0;
  max-width: none;
}
.form-panel .inquire-row { display: contents; }
.form-panel .inquire-field { margin: 0; }
.form-panel .inquire-field-wide { grid-column: 1 / -1; }
.form-panel .inquire-field span {
  color: #5C7577;
  font-size: 0.66rem;
  letter-spacing: 0.18em;
}
.form-panel .inquire-field input,
.form-panel .inquire-field textarea {
  background: #FFFFFF;
  border: 1px solid rgba(15, 27, 42, 0.45);
  color: var(--midnight-ink);
  transition: border-color 180ms var(--ease), box-shadow 180ms var(--ease);
}
.form-panel .inquire-field input:hover,
.form-panel .inquire-field textarea:hover { border-color: var(--midnight-ink); }
.form-panel .inquire-field input:focus-visible,
.form-panel .inquire-field textarea:focus-visible {
  outline: 2px solid var(--midnight-ink);
  outline-offset: 2px;
  border-color: var(--midnight-ink);
  box-shadow: 0 0 0 3px rgba(140, 163, 165, 0.35);
}
.form-panel .inquire-send {
  grid-column: 1 / -1;
  justify-self: start;
  background: var(--midnight-ink);
  color: var(--sacred-stone);
  border: none;
  border-bottom: none;
  padding: 1.1rem 1.8rem;
  min-height: 44px;
  margin-top: 0.4rem;
  cursor: pointer;
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.76rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  transition: background 180ms var(--ease);
}
.form-panel .inquire-status:empty { display: none; }
.form-panel .inquire-send:hover { background: var(--oxblood); color: var(--sacred-stone); }
.form-panel .inquire-send:focus-visible { outline: 2px solid var(--midnight-ink); outline-offset: 3px; }
.form-panel .inquire-status { grid-column: 1 / -1; color: var(--band-light-muted); }

/* ---- design-pass responsive ---- */
@media (max-width: 900px) {
  .beats { grid-template-columns: 1fr; gap: 3.5rem 0; padding-top: 2rem; }
  .beat { padding-top: 8.5rem; min-height: 0; }
  .beat::before { top: auto; display: none; }
  .parallel { grid-template-columns: 1fr; gap: 2.5rem 0; }
  .par-dim { margin-top: 0; }
  .qa-grid { grid-template-columns: 1fr; }
  .proof-split { grid-template-columns: 1fr; gap: 2.5rem 0; }
  .head-grid, .body-grid { grid-template-columns: 1fr; }
  .side-quote { border-left: none; padding-left: 0; border-top: 1px solid var(--rule); padding-top: 1.6rem; }
  /* the rule moves to the top here, so it draws across instead of down */
  .js-motion .side-quote { border-top-color: transparent; }
  .js-motion .side-quote::before {
    top: -1px; left: 0;
    width: 100%; height: 1px;
    transform: scaleX(0);
    transform-origin: left;
  }
  .js-motion .side-quote.in::before { transform: scaleX(1); }
  .ledger .principle { grid-template-columns: 1fr; gap: 0.8rem 0; }
  .map { grid-template-columns: 1fr; gap: 1rem 0; }
  .map-engines { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.8rem; }
  .map-engines::before { display: none; }
  .map-e { margin: 0; min-height: 0; }
  .map-pole { min-height: 0; }
  .engine-list { grid-template-columns: 1fr; }
  .held-panel { grid-template-columns: 1fr; }
  /* the season row's phone breakpoints went with the row itself (2026-08-22): the five
     parts are a contents list on the sheet now, one column at every width */
  .built { grid-template-columns: 1fr; }
  .brief { grid-template-columns: 1fr; }
  .fpage { grid-template-columns: 1fr; min-height: 0; }
  .fpage-pic { aspect-ratio: 4 / 5; min-height: 0; }
  .fpage-pic img { position: static; height: 100%; }
  /* Stacked, the copy loses its margin. The two-column grid is centred rather than padded,
     so on a wide screen the gutter is what is left over beside the pair; collapse it to one
     column and there is nothing left over — every line ran to both edges of the phone (found
     on the live site 2026-08-22). Put the site's own gutter back on the text column. The
     photograph keeps the full width, as it nearly does on desktop, where it sits at the
     grid's left edge. */
  .fpage-txt { padding-left: var(--gutter); padding-right: var(--gutter); }
  .wsplit { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .form-panel { grid-template-columns: 1fr; }
  .map-engines { grid-template-columns: 1fr; }
}

/* ---- the header follows (header.js; 2026-08-20) ----
   The mobile drawer lives inside this header in the DOM, and a transform or a backdrop-filter
   on an element makes it the containing block for its fixed children. Shipped on it, both did:
   the drawer's "inset: 0" measured the header's 82px row, so the seven links wrapped sideways
   over the hero instead of filling the screen (found on the live site 2026-08-22).
   So the glass is painted on a pseudo-element — a child, which contains nothing — and the
   header itself carries a transform only while it is actually away. */
.hdr-js .site-header {
  position: fixed;
  transition: transform 520ms var(--ease);
}
.hdr-js .site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;                   /* behind the lockup and the nav, over the page it covers */
  pointer-events: none;
  transition: background 320ms var(--ease), box-shadow 320ms var(--ease);
}
.hdr-js .site-header.hdr-glass::before {
  background: rgba(15, 27, 42, 0.88);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 1px 0 rgba(246, 242, 236, 0.1);
}
.hdr-js .site-header.hdr-away { transform: translateY(-110%); }
/* header.js already keeps the header home while the menu is open, but the return from away
   takes 520ms — open the drawer mid-slide and the header would still be carrying a transform.
   Cut it dead. Closing restores no transform, which is the resting state either way, so the
   drawer's 220ms fade out has nothing to snap into. */
@media (max-width: 700px) {
  .hdr-js body.nav-open .site-header { transform: none; transition: none; }
}
