/* ============================================================
   Discern Like A Rebel - site.css
   Faithful port of the emely-wensky source aesthetic:
   cream name-card · Pinyon Script (blue) · Georgia serif ·
   outline pill nav · grayscale→colour photo grid · black footer.
   Extended with accordion / tabs / quiz components for DLAR.
   ============================================================ */

/* Pinyon Script, self-hosted (was a render-blocking Google Fonts @import).
   latin covers English; latin-ext covers Slovak diacritics. */
@font-face {
  font-family: 'Pinyon Script';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../assets/fonts/pinyon-script-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Pinyon Script';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../assets/fonts/pinyon-script-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Homepage hero lockup display + script (index.html .lockup only). */
@font-face {
  font-family: 'Cubic Ranger';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../assets/fonts/cubic-ranger.woff2') format('woff2');
}
@font-face {
  font-family: 'Jane Eyre';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../assets/fonts/jane-eyre.woff2') format('woff2');
}

/* Homepage hero lockup faces. No size-adjust: the hero is finalised
   and must not grow. */
@font-face {
  font-family: 'CA Texteron SmallCaps';
  font-style: normal; font-weight: 400; font-display: swap;
  src: url('../assets/fonts/ca-texteron-smallcaps.woff2') format('woff2');
}
@font-face {
  font-family: 'Billa Mount';
  font-style: normal; font-weight: 400; font-display: swap;
  src: url('../assets/fonts/billa-mount.woff2') format('woff2');
}

/* CA Texteron body family. Homepage + nav bar only.
   size-adjust renders every glyph 5% larger, which restores Georgia's
   optical size AND density, so the ORIGINAL tracking values still fit.
   This is why you must NOT hand-tighten letter-spacing anywhere. */
@font-face {
  font-family: 'CA Texteron';
  font-style: normal; font-weight: 400; font-display: swap; size-adjust: 105%;
  src: url('../assets/fonts/ca-texteron-regular.woff2') format('woff2');
}
@font-face {
  font-family: 'CA Texteron';
  font-style: italic; font-weight: 400; font-display: swap; size-adjust: 105%;
  src: url('../assets/fonts/ca-texteron-italic.woff2') format('woff2');
}
@font-face {
  font-family: 'CA Texteron';
  font-style: normal; font-weight: 700; font-display: swap; size-adjust: 105%;
  src: url('../assets/fonts/ca-texteron-bold.woff2') format('woff2');
}
@font-face {
  font-family: 'CA Texteron';
  font-style: italic; font-weight: 700; font-display: swap; size-adjust: 105%;
  src: url('../assets/fonts/ca-texteron-bolditalic.woff2') format('woff2');
}
/* The wordmark must stay pixel-identical, so it uses an unscaled cut. */
@font-face {
  font-family: 'CA Texteron Logo';
  font-style: normal; font-weight: 400; font-display: swap;
  src: url('../assets/fonts/ca-texteron-regular.woff2') format('woff2');
}

:root {
  --ink:    #0c0c0c;          /* source near-black */
  --blue:   #2f3e8f;          /* the handwritten name + category links */
  --blue-deep: #232f6e;
  --cream:  #f7f4e9;          /* the centered name card */
  --cream-2:#efe9d8;
  --paper:  #ffffff;
  --rule:   #e4ded0;          /* warm hairline on cream */
  --muted:  #6b6b6b;          /* 4.8:1 on white (WCAG AA) */
  --maxw:   1200px;
  --serif:  Georgia, "Times New Roman", "Times", serif;
  --script: "Pinyon Script", cursive;
  --wash:   rgba(47,62,143,.06);   /* faint accent tint, repainted per area */
}

/* Homepage ink override - #6F2136 oxblood in place of the blue */
body.home {
  --blue:      #6F2136;
  --blue-deep: #571a2a;
  --serif: 'CA Texteron', Georgia, "Times New Roman", "Times", serif;
  line-height: 1.4;
  letter-spacing: -.015em;
  word-spacing: -.06em;
}

/* The nav links never say font-family: var(--serif), they inherit from body,
   so setting the variable alone would do nothing here. */
.sitenav {
  --serif: 'CA Texteron', Georgia, "Times New Roman", "Times", serif;
  font-family: var(--serif);
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
html, body { overflow-x: hidden; }   /* guard against any decorative bleed */
@media (prefers-reduced-motion: reduce){ html{ scroll-behavior:auto; } *{ animation:none!important; transition:none!important; } }

body {
  font-family: var(--serif);
  color: var(--ink);
  background: #fff;
  line-height: 1.5;
}
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }

/* text wrapping: balanced headings, no orphaned last words in copy */
h1, h2, h3, h4 { text-wrap: balance; }
p, li, blockquote, figcaption { text-wrap: pretty; }

/* ---------------- shared page header (sticky pill nav) ---------------- */
.sitenav {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 18px 24px;
  background: rgba(255,255,255,0.86);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
}
.sitenav .logo { line-height: 1; }
.sitenav .logo .small {
  display: block; font-family: 'CA Texteron Logo', var(--serif);
  font-size: 10px; letter-spacing: .40em; text-transform: uppercase;
  color: var(--muted);
}
.sitenav .logo .script {
  font-family: var(--script); color: var(--blue);
  font-size: 30px; line-height: .9;
}
.sitenav .links { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; align-items: center; }
.sitenav .links a {
  font-size: 16px; letter-spacing: .04em;
  background: #fff; color: #000;
  border: 1px solid #111; border-radius: 999px;
  padding: 7px 20px; line-height: 1.2;
  transition: background-color .2s, color .2s, scale .15s ease-out;
  white-space: nowrap;
}
@media (hover: hover) and (pointer: fine) and (min-width: 861px) {
  .sitenav .links > a:active { scale: .96; }
}
.sitenav .links a:hover { background: #000; color: #fff; }
.sitenav .links a.active { background: var(--blue); border-color: var(--blue); color: #fff; }
.sitenav .links a.cta { background: var(--blue); border-color: var(--blue); color: #fff; }
.sitenav .links a.cta:hover { background: var(--blue-deep); }
.nav-toggle { display: none; position: relative; background: none; border: 1px solid #111; border-radius: 999px; padding: 7px 16px; font-family: var(--serif); font-size: 15px; }
/* extend the tap target to 44px tall without growing the visible pill */
.nav-toggle::after { content: ""; position: absolute; left: -4px; right: -4px; top: 50%; transform: translateY(-50%); height: 44px; }
@media (max-width: 860px) {
  .sitenav .links { position: absolute; top: 100%; right: 0; left: 0;
    flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 0;
    background: #fff; border-bottom: 1px solid var(--rule);
    max-height: 0; overflow: hidden; transition: max-height .35s ease; padding: 0 16px; }
  .sitenav.open .links { max-height: 70vh; padding: 8px 16px 16px; }
  .sitenav .links a { border: 0; border-bottom: 1px solid var(--rule); border-radius: 0; padding: 14px 6px; text-align: left; background: none; }
  .sitenav .links a.cta, .sitenav .links a.active { background: none; color: var(--blue); }
  .nav-toggle { display: inline-block; }
}

/* ---------------- language switch (EN / SK), injected into every header ---------------- */
.lang-switch {
  display: inline-flex; align-items: center; gap: 2px;
  border: 1px solid #111; border-radius: 999px;
  padding: 4px 7px; margin-left: 2px; line-height: 1;
}
.lang-switch button {
  position: relative;
  font-family: var(--serif); font-size: 13px; letter-spacing: .08em;
  background: none; border: 0; color: #000; cursor: pointer;
  padding: 3px 7px; border-radius: 999px; transition: background-color .2s, color .2s;
}
/* taller tap target (vertical only: EN / SK sit side by side) */
.lang-switch button::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%); height: 40px; }
.lang-switch button:hover { color: var(--blue); }
.lang-switch button.active { background: var(--blue); color: #fff; }
.lang-switch button.active:hover { color: #fff; }
.lang-switch .lang-sep { color: var(--muted); font-size: 12px; }
@media (max-width: 860px) {
  /* in the mobile dropdown the switch sits as its own left-aligned row */
  .lang-switch { align-self: flex-start; margin: 12px 6px 6px; }
}

/* ---------------- Areas menu (cascade flyout → mobile accordion) ---------------- */
.nav-areas { position: relative; }
.sitenav .areas-trigger { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; }
.areas-trigger .caret { font-size: 11px; line-height: 1; transition: transform .2s ease; }
.nav-areas:hover .areas-trigger .caret,
.nav-areas.open .areas-trigger .caret { transform: rotate(180deg); }

/* the dropdown panel: vertical list of areas */
.areas-menu {
  position: absolute; top: calc(100% + 9px); left: 0;
  min-width: 234px;
  background: var(--paper);
  border-radius: 14px;
  /* hairline ring lives in the shadow stack, so it adapts to any backdrop */
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.07), 0 22px 48px -22px rgba(20, 16, 40, .42);
  padding: 8px;
  opacity: 0; visibility: hidden; transform: translateY(-7px);
  transition: opacity .18s ease, transform .18s ease, visibility .18s;
  z-index: 60;
}
.nav-areas:hover .areas-menu,
.nav-areas:focus-within .areas-menu { opacity: 1; visibility: visible; transform: translateY(0); }

/* a row + its name (override the pill base styling for in-menu anchors;
   .links in the selector so it actually outranks the `.sitenav .links a` pill) */
.area-row { position: relative; }
.area-row + .area-row { margin-top: 2px; }
.sitenav .links .area-name {
  display: flex; align-items: center; gap: 10px;
  font-family: var(--serif); font-size: 16px; letter-spacing: .02em;
  background: transparent; border: 0; border-radius: 6px;   /* concentric: 14 outer - 8 padding */
  padding: 10px 13px; white-space: nowrap; color: var(--ink);
}
.area-row.is-live > .area-name { cursor: pointer; }
.area-row.is-live > .area-name::after {
  content: "\203A"; margin-left: 2px; font-size: 18px; color: var(--blue);
  opacity: .5; transition: transform .18s ease, opacity .18s ease;
}
.sitenav .area-row.is-live:hover > .area-name { background: var(--cream); color: var(--blue); }
.area-row.is-live:hover > .area-name::after { transform: translateX(3px); opacity: 1; }
.area-name.is-disabled { color: var(--muted); cursor: default; }

/* flag pills (Live / Soon), pushed to the right edge of the row */
.area-flag {
  margin-left: auto; font-family: var(--serif); font-size: 10px;
  letter-spacing: .14em; text-transform: uppercase;
  padding: 2px 9px; border-radius: 999px; color: #fff; background: var(--blue);
}
.area-flag.soon { background: transparent; color: var(--muted); border: 1px solid var(--rule); }

/* second-level flyout: Principles + Swaps */
.area-sub {
  position: absolute; top: -8px; left: 100%;
  min-width: 158px;
  background: var(--paper);
  border-radius: 12px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.07), 0 22px 48px -22px rgba(20, 16, 40, .42);
  padding: 6px; margin-left: 8px;
  opacity: 0; visibility: hidden; transform: translateX(-7px);
  transition: opacity .16s ease, transform .16s ease, visibility .16s;
}
.area-sub::before {          /* invisible hover bridge across the gap */
  content: ""; position: absolute; top: 0; left: -14px; width: 14px; height: 100%;
}
.area-row.is-live:hover > .area-sub,
.area-row.is-live:focus-within > .area-sub { opacity: 1; visibility: visible; transform: translateX(0); }
.sitenav .area-sub a {
  display: block; background: transparent; border: 0; border-radius: 6px;   /* concentric: 12 outer - 6 padding */
  padding: 9px 14px; font-size: 15px; letter-spacing: .03em; white-space: nowrap; color: var(--ink);
}
.sitenav .area-sub a:hover { background: var(--blue); color: #fff; }

@media (max-width: 860px) {
  /* accordion: panels collapse inline inside the hamburger */
  .nav-areas { width: 100%; }
  .sitenav .areas-trigger { justify-content: space-between; }
  .areas-menu {
    position: static; min-width: 0; padding: 0; margin: 0;
    border: 0; border-radius: 0; box-shadow: none;
    opacity: 1; visibility: visible; transform: none;
    max-height: 0; overflow: hidden; transition: max-height .32s ease;
  }
  .nav-areas.open .areas-menu { max-height: 1200px; }
  .sitenav .area-name { padding: 13px 6px 13px 22px; border-bottom: 1px solid var(--rule); }
  .area-row.is-live > .area-name::after { margin-left: 10px; transition: transform .2s ease; }
  .area-row.open > .area-name::after { transform: rotate(90deg); }
  .area-sub {
    position: static; min-width: 0; margin: 0; padding: 0;
    border: 0; border-radius: 0; box-shadow: none;
    opacity: 1; visibility: visible; transform: none;
    max-height: 0; overflow: hidden; transition: max-height .3s ease;
  }
  .area-sub::before { display: none; }
  .area-row.open > .area-sub { max-height: 320px; }
  .sitenav .area-sub a { padding: 12px 6px 12px 40px; border-bottom: 1px solid var(--rule); }
}

/* ---------------- The House menu (flat dropdown → mobile accordion) ----------------
   Reuses the .areas-menu panel (position / paper / shadow / hover-reveal); only the
   inner flat anchors need their own look, overriding the .sitenav .links a pill. */
.sitenav .links .house-menu a {
  display: flex; align-items: center;
  font-family: var(--serif); font-size: 16px; letter-spacing: .02em;
  background: transparent; border: 0; border-radius: 6px;   /* concentric: 14 outer - 8 padding */
  padding: 10px 13px; white-space: nowrap; color: var(--ink);
}
.house-menu a + a { margin-top: 2px; }
.sitenav .links .house-menu a:hover { background: var(--cream); color: var(--blue); }
@media (max-width: 860px) {
  /* accordion rows inside the hamburger, matching the Areas sub-links */
  .sitenav .links .house-menu a {
    padding: 13px 6px 13px 22px; border-bottom: 1px solid var(--rule); border-radius: 0;
  }
}

/* ---------------- HERO (full-screen, source name-card) ---------------- */
.hero {
  position: relative;
  min-height: calc(100vh - 67px);
  display: flex; align-items: center; justify-content: center;
  overflow: visible; padding: 40px 20px;   /* let the figures rise in front of the nav */
}
.hero::before {
  content: ""; position: absolute; inset: 0;
  background: var(--hero-img, none) center / cover no-repeat;
  filter: grayscale(100%) contrast(1.02);
  z-index: 0;
}
.hero::after {           /* very gentle wash so the card always reads */
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(120% 90% at 50% 45%, rgba(255,255,255,0), rgba(255,255,255,.18));
  z-index: 0;
}
.hero .deco {
  position: absolute; z-index: 60; opacity: 1; pointer-events: none;
  filter: grayscale(100%) contrast(1.02);
}
/* full-size figures that rise in FRONT of the nav (z-index 60 > nav 50,
   hero overflow visible so their tops aren't clipped). */
.hero .deco--left  { left: 0;  bottom: 0;  width: min(34.56vw, 518px); }
.hero .deco--right { right: 0; bottom: -2%; width: min(28.79vw, 422px); }
/* Two stacked copies of the right hand let it yield to the nav only on demand.
   The base copy sits just below the sticky nav (z 50). A pixel-aligned twin
   (.deco--ghost) floats ABOVE the nav and is fully opaque by default - so the
   hand reads as the topmost layer everywhere, including over the nav strip.
   While the visitor is actually using the nav (hover / keyboard focus), the twin
   fades to 20%, letting the Areas/House flyouts - and the pills the fingers reach
   toward - read cleanly through it; the base copy keeps the hand solid over the
   hero meanwhile. It reverts to fully solid the moment they leave the nav.
   NOTE: .hero is nested in <main>, so it is NOT a sibling of .sitenav - the fade
   must be driven via :has() on a common ancestor, not a `~` sibling selector
   (the old `.sitenav:hover ~ .hero` never matched, so the hand stayed solid). */
.hero .deco--right { z-index: 40; }
.hero .deco--right.deco--ghost { z-index: 70; opacity: 1; transition: opacity .25s ease; }
body:has(.sitenav:hover) .hero .deco--right.deco--ghost,
body:has(.sitenav:focus-within) .hero .deco--right.deco--ghost { opacity: .2; }

/* ===== living-hero videos (hero-alive-video.js) =====
   Each clip is placed by JS to sit exactly over its drawing. The source is a
   white-on-black negative; invert(1) + multiply turn it into a black-on-cream
   engraving whose background drops into the page, so it fades up "out of" the
   still and back into it. opacity is the only thing that animates here. */
/* Absolute in PAGE coordinates, so the clip scrolls with the document: no
   rAF, no scroll listener (the girl's clip loops forever, and a permanent
   rAF would break the performance contract). Placed by JS on load + resize. */
.alive-vid {
  position: absolute; pointer-events: none; opacity: 0;
  object-fit: fill;
  transition: opacity .6s ease;
  will-change: opacity;
}
.alive-vid.is-playing { opacity: 1; }

/* The hero clips carry their own alpha: they ARE the engraving, transparent
   between the hatching exactly like the .deco stills. No filter, no blend,
   no paper plate underneath. The girl's clip is still a negative, so she
   alone keeps the invert + multiply that turns her black-on-cream. */
.alive-vid--girl { filter: invert(1) contrast(1.85); mix-blend-mode: multiply; }
/* Narrow/mobile only: the girl's clip is re-parented INTO its .consult-fig box
   (hero-alive-video.js) and placed by these percentages, the CSS twin of the
   fx/fy/fw/fh page-coord placement. The box is position:sticky there, so the clip
   holds on screen and keeps looping while the copy scrolls past it. On wide the
   clip rides the document in page coords instead and this class is absent. */
.alive-vid--girl.alive-vid--pinned {
  left: -1.85%;
  top: -18.86%;
  width: 105.47%;
  height: 127.42%;
}

/* the still hands over to its clip while it plays; a play-once clip hands the
   drawing back when it ends (see below). It also returns if the clip never plays */
.alive-still-out { opacity: 0 !important; transition: opacity .6s ease; }

/* THE DRAWING COMES BACK. The hero clips are 720px sources (that is what the
   footage was generated at) stretched over stills that land ~1:1 on a retina
   screen, so a held last frame reads ~1.3x upscaled next to the engraving it
   replaced. The clips end ON the drawing, so at 'ended' we cross-fade back to
   the still: motion covers the softness while the clip plays, and the hero
   RESTS pin-sharp. The still carries the same idle keyframes in phase, so the
   swap back is a straight dissolve with nothing to re-align.

   The fade needs its own class because the .6s transition lives on
   .alive-still-out: removing that class alone would snap the drawing back with
   no fade (the base .deco has no opacity transition of its own), and the hand's
   ghost twin would fade on its 0.25s nav transition instead, so the two
   pixel-locked copies would visibly drift apart. This rule must therefore also
   outrank `.hero .deco--right.deco--ghost` (it does: equal specificity, later
   in the sheet), and hero-alive-video.js strips it once the fade is done so the
   ghost gets its 0.25s nav-hover fade back. */
.hero .deco.alive-still-back,
.consult-fig.alive-still-back { transition: opacity .6s ease; }

/* The woman and her dog have no still at all: this empty box only holds her
   place (aspect of the drawing, so the grid and the phone float never shift)
   and the looping clip is laid on it. If motion is off, or the machine is
   weak, the drawing is painted in so the section is never an empty gap. */
.consult-live { aspect-ratio: 1180 / 1819; }
@media (prefers-reduced-motion: reduce) {
  .consult-live {
    background: url("../assets/new%20girl%20dog.webp") center / contain no-repeat;
    mix-blend-mode: multiply;
  }
}
html.dlar-lowpower .consult-live {
  background: url("../assets/new%20girl%20dog.webp") center / contain no-repeat;
  mix-blend-mode: multiply;
}

/* the clips keep the drawings breathing once they settle, exactly as the
   stills did, so the hero never goes dead-static after the play-once */
@media (min-width: 861px) {
  .alive-vid--diana { transform-origin: 50% 96%; animation: alive-statue 11s ease-in-out infinite; }
  .alive-vid--hand  { transform-origin: 82% 100%; animation: alive-hand 8.5s ease-in-out infinite; }
}
html.dlar-lowpower .alive-vid { animation: none !important; }

/* the hand clip plays above the nav flyouts (like the ghost twin), so it
   steps aside the same way while the menus are open */
body:has(.sitenav:hover) .alive-vid--hand.is-playing,
body:has(.sitenav:focus-within) .alive-vid--hand.is-playing { opacity: .2; }

@media (prefers-reduced-motion: reduce) { .alive-vid { display: none !important; } }

.card {
  position: relative; z-index: 3;
  background: var(--cream);
  width: min(64vw, 840px);
  padding: 40px 48px 30px;
  box-shadow: 0 30px 60px rgba(0,0,0,.18);
  text-align: center;
}
.card .eyebrow {
  font-family: var(--serif); color: var(--blue);
  font-size: 12px; letter-spacing: .22em; text-transform: uppercase;
  margin-bottom: 14px;
}
.card .lockup { display: block; color: #6F2136; }
.card .lockup .d, .card .lockup .r {
  display: block; font-family: 'CA Texteron SmallCaps', var(--serif); font-weight: 400;
  letter-spacing: .08em;
  font-size: clamp(37px, 6.54vw, 83px); line-height: .96;
}
.card .lockup .mid {
  display: block; font-family: 'Billa Mount', var(--script);
  font-size: clamp(32px, 5.56vw, 71px); line-height: .96; margin: 0;
  transform: translateY(-5px);
}
.card .tagline {
  color: #3a3a3a; font-style: italic;
  font-size: clamp(14px, 1.6vw, 18px);
  max-width: 46ch; margin: 22px auto 0;
}
.card .cats {
  display: flex; justify-content: center; gap: 22px; flex-wrap: wrap;
  margin-top: 26px;
}
.card .cats a {
  position: relative;
  color: var(--blue); font-size: 12px;
  letter-spacing: .14em; text-transform: uppercase;
  border-bottom: 1px solid transparent; padding-bottom: 3px;
}
/* 40px-tall tap targets for the small uppercase links (vertical only:
   neighbours sit beside them, so widening would collide) */
.card .cats a::after, .foot .links a::after, .social a::after {
  content: ""; position: absolute; left: 0; right: 0; top: 50%;
  transform: translateY(-50%); height: 40px;
}
.card .cats a:hover { border-color: var(--blue); }
.scrollcue { position: absolute; z-index: 3; bottom: 18px; left: 50%; transform: translateX(-50%);
  font-size: 11px; letter-spacing: .22em; text-transform: uppercase; color: #555; }
@media (max-width: 700px) {
  /* Mobile hero: the statue floats to the RIGHT and the wordmark text wraps
     tight around its silhouette (shape-outside reads the engraving's alpha).
     One cohesive cream panel; image sits a touch above/below the text and the
     text contours its shape. Desktop/tablet untouched. */
  .home .hero {
    display: block;
    min-height: auto;
    padding: 18px 16px 14px;
    overflow: hidden;
  }
  .home .hero .deco--right,
  .home .hero .deco--right.deco--ghost { display: none; }
  .home .hero .deco--left {
    position: relative; z-index: 4; float: right;
    left: auto; right: auto; bottom: auto; top: auto;
    width: 70.2%; max-width: 356px;
    margin: -8px -8px -4px 0;
    opacity: 1;
    /* the statue's left profile as a fixed polygon (extracted from the
       image alpha): available before the image loads, so the hero text
       never re-wraps mid-load (that re-wrap was a 0.29 CLS hit) */
    shape-outside: polygon(100% 0%, 99.9% 0%, 53.8% 7.2%, 55.7% 14.3%, 54.5% 21.4%, 46.6% 28.6%, 37.1% 35.7%, 28.7% 42.9%, 19.6% 50%, 14% 57.1%, 19.5% 64.3%, 14.4% 71.4%, 30.3% 78.6%, 23.3% 85.7%, 10.4% 92.8%, 99.9% 99.9%, 100% 100%);
    shape-margin: 2px;
  }
  .home .hero .card {
    position: relative;
    width: auto; max-width: none; margin: 0;
    padding: 16px 14px 20px 16px;
    text-align: left;
    background: var(--cream);
    box-shadow: none;
  }
  .home .hero .card .eyebrow { margin-bottom: 9px; font-size: 10.5px; letter-spacing: .14em; }
  .home .hero .card .lockup .d,
  .home .hero .card .lockup .r { font-size: clamp(24px, 8.07vw, 48px); letter-spacing: .08em; }
  .home .hero .card .lockup .mid { font-size: clamp(21px, 6.87vw, 40px); }
  .home .hero .card .tagline { margin: 12px 0 0; max-width: none; font-size: 13.5px; }
  .home .hero .card .cats { justify-content: flex-start; gap: 14px; margin-top: 16px; }
  .scrollcue { display: none; }
}

/* ---------------- inner page hero (smaller) ---------------- */
.page-hero { max-width: var(--maxw); margin: 0 auto; padding: 80px 24px 24px; text-align: center; }
.page-hero .badge { font-size: 12px; letter-spacing: .22em; text-transform: uppercase; color: var(--blue); }
.page-hero h1 { font-family: var(--script); color: var(--blue); font-weight: 400;
  font-size: clamp(46px, 8vw, 92px); line-height: .95; margin: 10px 0 14px; }
.page-hero p { font-size: 18px; max-width: 60ch; margin: 0 auto; color: #333; }

/* ---------------- generic section scaffolding ---------------- */
.section-label {
  max-width: var(--maxw); margin: 0 auto; padding: 72px 24px 0;
  font-size: 13px; letter-spacing: .22em; text-transform: uppercase; color: var(--muted);
}
.wrap { max-width: var(--maxw); margin: 0 auto; padding: 24px; }
.wrap--narrow { max-width: 820px; }
.lead-serif { font-size: clamp(22px, 3vw, 34px); line-height: 1.3; }
.script-h { font-family: var(--script); color: var(--blue); font-weight: 400; font-size: clamp(36px,6vw,72px); line-height: .95; }
.italic { font-style: italic; }
.center { text-align: center; }

/* grids */
.grid { display: grid; gap: 30px; grid-template-columns: repeat(3, 1fr); }
.grid-2 { display: grid; gap: 30px; grid-template-columns: repeat(2, 1fr); }
@media (max-width: 900px) { .grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 760px) { .grid-2 { grid-template-columns: 1fr; } }
@media (max-width: 600px) { .grid { grid-template-columns: 1fr; } }

/* Private Consulting (home): the copy and the living drawing read as ONE
   centred plate. The drawing stands on the right, tall (it runs past the fold
   on purpose, you scroll to meet it), anchored to the wrap's right edge. The
   paragraph runs wide and its last words slip UNDER the drawing's blank left
   margin, which is transparent through the clip's multiply blend, so copy and
   figure overlap into a single image. Flex + a negative left margin on the
   figure is what pulls them together; --fig-w drives the width and the overlap. */
.consult-grid {
  --fig-w: clamp(360px, 44vw, 560px);
  --overlap: calc(var(--fig-w) * 0.30);   /* how far the figure sits over the copy's tail (blank left margin) */
  display: flex;
  align-items: center;   /* the drawing is the taller item, so the copy drops to its vertical centre */
  gap: 0;
  position: relative;
}
.consult-grid > .consult-copy { order: 1; flex: 1 1 auto; min-width: 0; }
/* the eyebrow is now the copy's first line, not a standalone section header:
   drop the header's 72px top gap and 24px indent so it sits flush-left with the
   heading, tight above it */
.consult-grid .section-label { padding: 0; margin: 0 0 12px; max-width: none; }
.consult-grid .lead-serif { max-width: 22ch; }   /* headline stays a tight 2 lines; the paragraph runs wide */
/* the paragraph may run under the figure's blank upper-left margin (the merge),
   but the season note sits lower, where the drawing's ink is, so it must stop
   before the figure: cap it just short of the figure's left edge */
.consult-grid .consult-note { max-width: calc(100% - var(--overlap) - 30px); }
.consult-grid > .consult-fig {
  order: 2;
  flex: 0 0 auto;
  width: var(--fig-w);
  max-width: none;
  /* top: lift the drawing ~10% of its height so the copy reads lower against it
     (the clip follows: hero-alive-video.js places it from the box's offsetTop,
     which includes this margin). left: the overlap merge. */
  margin: calc(var(--fig-w) * -0.26) 0 0 calc(-1 * var(--overlap));
  position: relative;
  z-index: 2;                                     /* figure (and the reduced-motion still) rides over the copy */
}

/* Narrow + mobile: SAME logic as wide, just a smaller drawing. Two columns
   (copy left, drawing right), the copy's tail slips under the drawing's blank
   left margin (the merge), and the drawing sits vertically centred against the
   taller copy (align-items:center, inherited). The clip rides the document in
   page coords exactly as on wide, so there is no sticky, no stacking context and
   no white plate. The drawing is sized to stay moderate and keep the copy a
   readable column (>= ~150px). */
@media (max-width: 820px) {
  .consult-grid { --fig-w: min(60vw, calc(100% - 150px)); }
  .consult-grid .lead-serif { max-width: none; }
}

/* the season note, melted into the page: no paper card, just the italic voice */
.consult-note { font-style: italic; color: #333; }

/* directory / project cards w/ grayscale→colour hover (source mechanic) */
.card-link .thumb { aspect-ratio: 3 / 4; overflow: hidden; background: #f0ece0; position: relative; }
.card-link .thumb img { width:100%; height:100%; object-fit: contain; filter: grayscale(100%) opacity(.85); transition: filter .4s, transform .6s; padding: 12%; }
.card-link:hover .thumb img { filter: grayscale(0%) opacity(1); transform: scale(1.04); }
/* per-card image enlargement (base scale; hover values = base * 1.04) */
.card-link .thumb img.enlarge-wave { transform: scale(1.35); }
.card-link:hover .thumb img.enlarge-wave { transform: scale(1.404); }
.card-link .thumb img.enlarge-clothes { transform: scale(1.15); }
.card-link:hover .thumb img.enlarge-clothes { transform: scale(1.196); }
.card-link .meta { padding: 14px 2px 0; }
.card-link .num { color: var(--muted); font-size: 12px; }
.card-link h3 { font-size: 18px; letter-spacing: .03em; text-transform: uppercase; margin: 2px 0 5px; font-weight: 400; }
.card-link .tags { font-size: 12px; color: var(--muted); font-style: italic; }
.status-pill { display:inline-block; font-size:10px; letter-spacing:.12em; text-transform:uppercase; padding:3px 10px; border-radius:999px; border:1px solid var(--blue); color:var(--blue); margin-top:8px; }
.status-pill.soon { border-color:#b9b2a0; color:#6e6857; }

/* ---- The Directory: all six areas on one row; smaller cards that grow on wide screens ---- */
/* Let the directory breathe wider than the 1200px default on large screens. */
@media (min-width: 1440px) { .wrap--dir { max-width: 1440px; } }

.dir-grid { grid-template-columns: repeat(6, 1fr); gap: 20px; }
.dir-grid .card-link h3   { font-size: 15px; margin: 2px 0 4px; }
.dir-grid .card-link .tags { font-size: 11px; }
.dir-grid .card-link .num  { font-size: 11px; }
.dir-grid .status-pill     { font-size: 9px; padding: 3px 8px; letter-spacing: .1em; }
.dir-grid > [data-reveal]:nth-child(6) { transition-delay: .5s; }

@media (min-width: 1440px) {
  .dir-grid { gap: 26px; }
  .dir-grid .card-link h3    { font-size: 17px; }
  .dir-grid .card-link .tags { font-size: 12px; }
}
/* Tablet: even three-up rather than a cramped single row. */
@media (max-width: 1000px) { .dir-grid { grid-template-columns: repeat(3, 1fr); } }
/* Mobile: two columns. */
@media (max-width: 620px)  { .dir-grid { grid-template-columns: repeat(2, 1fr); gap: 18px 14px; } }

/* ============================================================
   manifesto - "The Unruly Way"
   gutter dagger scroll-marker · ink trail · magnetic parallax
   ============================================================ */
.manifesto { position: relative; max-width: var(--maxw); margin: 0 auto; padding: 8px 24px; }
.manifesto-list { position: relative; max-width: none; margin: 0; padding: 0; }

/* --rip = how torn THIS sheet is (0..1); --rip-above = how torn the sheet above
   is (drives this sheet's torn TOP). Registered so they animate smoothly - the
   tear deepens over time even on a fast scroll flick. */
@property --rip       { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --rip-above { syntax: "<number>"; inherits: true; initial-value: 0; }

/* Each credo is a THIN sheet of paper abutting into a seamless pad. At rest NO
   tear shows - it's a plain rectangle. As a sheet scrolls up it tears off: the
   sheet's OWN top + bottom edges are CUT into a real fibrous torn line (masks cut
   from the tear-b photo) that slides in as --rip / --rip-above rise. Because it is
   the sheet's own paper being clipped, the torn edge is the exact same colour with
   NO gap. The sheet leans + skews as ONE piece (paper AND text), pivots on its
   right so the LEFT lifts up + up, and fades off the top. Shallow cut = thin sheets. */
.manifesto-item {
  position: relative;
  display: grid; grid-template-columns: 64px 1fr; gap: 20px;
  padding: 34px 30px;              /* thin sheet; a little room for the shallow cut */
  margin-bottom: -1px;             /* kill a sub-pixel maroon seam between sheets at rest */
  --mx: 0px; --my: 0px;            /* magnetic offset, set by JS */
  --rip: 0; --rip-above: 0;        /* tear progress, set by JS from scroll */
  background-color: var(--cream);
  background-image: url("../assets/paper-sheet.webp");
  background-size: cover;
  background-position: center;
  background-blend-mode: multiply;
  opacity: calc(1 - (var(--rip) * var(--rip)));
  transform-origin: 100% 50%;
  transform:
    translateY(calc(var(--rip) * -70px))
    rotate(calc(var(--rip) * 6deg))
    skewX(calc(var(--rip) * -5deg))
    skewY(calc(var(--rip) * 2deg));
  transition: --rip .55s ease, --rip-above .55s ease, mask-position .55s ease, -webkit-mask-position .55s ease;
  /* soft shadow only while tearing, so the torn edge reads as real paper depth */
  filter: drop-shadow(1px 3px 2px rgba(46, 12, 18, calc(var(--rip) * 0.35)));
  z-index: calc(1 + var(--rip) * 9);   /* a tearing sheet lifts above the ones below it */
  /* CUT the sheet's own edges into the torn line; the masks slide in with the rip
     and combine with intersect so only the two torn slivers get removed. Static
     longhands only: at rest each torn line is parked just off the sheet (-30px)
     and app.js slides mask-position directly as the rip deepens. No var() in any
     mask value, Firefox does not re-resolve a mask that rides on an animated
     custom property (sheets moved but never tore there). */
  -webkit-mask-image: url("../assets/tear-clip-bot.webp"), url("../assets/tear-clip-top.webp");
  -webkit-mask-size: 100% 560px, 100% 560px;
  -webkit-mask-repeat: no-repeat, no-repeat;
  -webkit-mask-position: left 0px bottom -30px, left 0px top -30px;
  -webkit-mask-composite: source-in, source-over;
  mask-image: url("../assets/tear-clip-bot.webp"), url("../assets/tear-clip-top.webp");
  mask-size: 100% 560px, 100% 560px;
  mask-repeat: no-repeat, no-repeat;
  mask-position: left 0px bottom -30px, left 0px top -30px;
  /* the FIRST layer's operator combines it with the layers below, so intersect must
     sit on layer 1 - with `add` there the two masks unioned and nothing ever got cut.
     Standard mask-composite stays AFTER the webkit line so it wins where both parse. */
  mask-composite: intersect, add;
}
/* first sheet has nothing above it: its top never tears (--rip-above stays 0) */
.manifesto-item:last-child  { margin-bottom: 0; }
/* one texture file, shown at a different crop per sheet: no two sheets repeat the same grain */
.manifesto-item:nth-child(2) { background-position: 18% 72%; }
.manifesto-item:nth-child(3) { background-position: 74% 26%; }
.manifesto-item:nth-child(4) { background-position: 42% 88%; }
.manifesto-item:nth-child(5) { background-position: 88% 60%; }
.manifesto-item:nth-child(6) { background-position: 8% 34%; }
.manifesto-item:nth-child(7) { background-position: 60% 12%; }
.manifesto-item:nth-child(8) { background-position: 30% 50%; }

.manifesto-item .n {
  font-family: var(--script); color: var(--blue); font-size: 44px; line-height: .8;
  transition: transform .5s cubic-bezier(.22,1,.36,1), color .4s, opacity .6s;
  transform: translate(calc(var(--mx) * .5), calc(var(--my) * .5));
  will-change: transform;
}
.manifesto-item .m-body { transition: transform .5s cubic-bezier(.22,1,.36,1); transform: translate(var(--mx), var(--my)); will-change: transform; }
.manifesto-item h3 {
  font-size: 22px; font-weight: 400; letter-spacing: .02em; margin-bottom: 8px;
  transition: color .4s, letter-spacing .5s cubic-bezier(.22,1,.36,1);
}
.manifesto-item p { color: #444; max-width: 64ch; transition: color .4s; }

/* the active principle (nearest viewport centre / dagger target) */
.manifesto-item.is-active .n { color: var(--blue-deep); }
.manifesto-item.is-active h3 { letter-spacing: .055em; }
.manifesto-item.is-active p { color: #2c2c2c; }

/* ---- gutter rail + dagger marker (desktop only) ---- */
.manifesto-rail { display: none; }

@media (min-width: 880px) and (pointer: fine) {
  .manifesto { padding-left: 168px; }   /* nudged right (was 132) */
  .manifesto-rail {
    display: block; position: absolute; left: 60px; top: 0; bottom: 0; width: 96px;  /* nudged right (was 24) */
    pointer-events: none;
    z-index: 6;   /* above the paper sheets (z-index 4) so the blade tip lies ON the page */
  }
  /* etched vertical track the blade rides */
  .manifesto-track {
    position: absolute; top: 30px; bottom: 30px; left: 50%; width: 1px;
    transform: translateX(-.5px);
    background: repeating-linear-gradient(to bottom,
      color-mix(in srgb, var(--blue) 32%, transparent) 0 6px,
      transparent 6px 12px);
    opacity: .55;
  }
  /* fading ink/blood streak between old + new position (JS-driven) */
  .manifesto-trail {
    position: absolute; left: 50%; width: 3px; top: 0; height: 0;
    transform: translateX(-50%); border-radius: 3px; opacity: 0;
    background: linear-gradient(to bottom,
      transparent, color-mix(in srgb, var(--blue) 80%, #000 6%), transparent);
    filter: blur(2.4px);
  }
  /* the dagger - already points right in the asset; transparent PNG, no blend needed */
  .manifesto-dagger {
    position: absolute; left: 50%; top: 0; width: 248px; max-width: none; height: auto;
    transform: translate(calc(-50% - 46.8px), var(--dy, 0px));
    transform-origin: center;
    filter: drop-shadow(0 6px 10px rgba(40,18,24,.18));
    transition: transform .62s cubic-bezier(.34,1.2,.4,1);
    opacity: 0; will-change: transform;
  }
  .manifesto.armed .manifesto-dagger { opacity: 1; }
  /* a faint breathing sway so the blade feels alive while resting */
  .manifesto.armed .manifesto-dagger { animation: dagger-breathe 5.5s ease-in-out infinite; }
}

@keyframes dagger-breathe {
  0%, 100% { filter: drop-shadow(0 6px 10px rgba(40,18,24,.18)); }
  50%       { filter: drop-shadow(0 9px 14px rgba(40,18,24,.26)); }
}

@media (max-width:600px){
  .manifesto-item{ grid-template-columns: 44px 1fr; gap:14px; }
  .manifesto-item .n{ font-size:32px; }
}
@media (prefers-reduced-motion: reduce){
  .manifesto-dagger{ animation: none !important; }
  .manifesto-item .n, .manifesto-item .m-body { transform: none !important; }
}

/* Oxblood contrast band behind the whole Unruly Way section (label + intro +
   manifesto). Deep footer oxblood, so the paper sheets and the dagger read as
   printed ON a coloured page. Paper + dagger assets are untouched; only the
   dark label/heading type is lifted to cream so it stays legible. */
.unruly-band { background: #4A0E13; }
/* label sits on the dark band: lift it off body.alive's oxblood ink to cream
   (higher specificity than body.alive .section-label so it actually wins) */
body.alive .unruly-band .section-label { color: rgba(247,244,233,.72); }
.unruly-band .lead-serif { color: var(--cream); }

/* steps */
.steps { display: grid; gap: 26px; grid-template-columns: repeat(3,1fr); }
@media (max-width:760px){ .steps{ grid-template-columns:1fr; } }
.step { border: 1px solid var(--rule); background: var(--cream); padding: 28px; }
.step .rn { font-family: var(--script); color: var(--blue); font-size: 38px; line-height:.8;
  display: flex; align-items: center; gap: 14px; }
/* the numeral hands off to a hairline that runs to the card's edge */
.step .rn::after { content: ""; flex: 1; height: 1px; background: var(--rule); }
@media (hover: hover) and (pointer: fine) {
  .step { transition: translate .22s ease, border-color .22s ease; }
  .step:hover { translate: 0 -2px; border-color: #cfc7b6; }
}
.step h3, .step h4 { font-size: 19px; font-weight: 400; margin: 10px 0 8px; }
.step p { color:#444; }

/* generic buttons */
.btn { display:inline-block; font-family: var(--serif); font-size:15px; letter-spacing:.04em;
  border:1px solid #111; border-radius:999px; padding:11px 26px; background:#fff; color:#000;
  transition: background-color .2s,color .2s,border-color .2s,scale .15s ease-out; cursor:pointer; }
.btn:hover { background:#000; color:#fff; }
.btn:active { scale: .96; }
.btn--blue { background: var(--blue); border-color: var(--blue); color:#fff; }
.btn--blue:hover { background: var(--blue-deep); }
.btnrow { display:flex; gap:14px; flex-wrap:wrap; }
.btnrow.center { justify-content:center; }

/* callout / pull quote */
.callout { background: var(--cream); border-left: 3px solid var(--blue); padding: 22px 26px; font-style: italic; color:#333; }
.callout--paper { background: url('../assets/paper 01.webp') center/cover no-repeat, var(--cream); }
.pull { font-family: var(--script); color: var(--blue); font-size: clamp(26px,4vw,46px); line-height:1.05; }

/* cross-link */
.xlink { color: var(--blue); font-size: 13px; letter-spacing:.04em; border-bottom:1px solid var(--blue); padding-bottom:2px; }

/* ---------------- accordion (Principles) ---------------- */
.acc { max-width: 920px; margin: 0 auto; padding: 0 24px; }
.epigraph + .acc { margin-top: 44px; }
.acc__item { border-top: 1px solid var(--rule); }
.acc__item:last-child { border-bottom: 1px solid var(--rule); }
.acc__q { width:100%; text-align:left; background:none; border:0; cursor:pointer;
  display:flex; align-items:baseline; gap:18px; padding: 26px 0; font-family: var(--serif); }
.acc__q .qn { font-family: var(--script); color: var(--blue); font-size: 34px; line-height:.7; flex:none; width:46px;
  transition: transform .5s cubic-bezier(.34,1.45,.44,1), opacity .3s ease; opacity: .82; }
.acc__q .qt { font-size: 22px; flex:1; transition: color .25s ease; }
/* the row acknowledges the reader: title inks on hover, and the script
   numeral leans in while its principle is open */
@media (hover: hover) and (pointer: fine) {
  .acc__q:hover .qt { color: var(--blue); }
}
.acc__item.open .acc__q .qn { transform: translateX(3px) scale(1.08); opacity: 1; }
.acc__item.open .acc__q .qt { color: var(--blue); }
.acc__q .ic { font-size: 26px; color: var(--blue); transition: transform .3s; }
.acc__item.open .acc__q .ic { transform: rotate(45deg); }
.acc__a { overflow: hidden; max-height: 0; transition: max-height .45s ease; }
.acc__a > div { padding: 0 0 28px 64px; color:#3a3a3a; }
.acc__a p { margin-bottom: 12px; max-width: 70ch; }
.acc__a ul { margin: 10px 0 14px 20px; }
.acc__a strong { color: var(--ink); }
@media (max-width:600px){ .acc__a > div{ padding-left:0; } .acc__q .qt{ font-size:18px; } }

/* ---------------- tabs (Swaps) ---------------- */
.tabs { max-width: var(--maxw); margin: 0 auto; padding: 8px 24px 0; }
/* tabbed directory (Swaps + future areas): roomy symmetric gutters on wide
   screens so the floating scroll hint clears the tables; tighter on small,
   with a slim right reserve kept for the hint. */
@media (min-width:1200px){ .tabs { max-width: min(1180px, calc(100vw - 380px)); } }
@media (min-width:560px) and (max-width:1199.98px){ .tabs { padding-left:16px; padding-right:16px; } }
@media (max-width:559.98px){ .tabs { padding-left:14px; padding-right:14px; } }
.tabbar { display:flex; flex-wrap:wrap; gap:10px; border-bottom:1px solid var(--rule); padding-bottom:18px; margin-bottom:8px; }
.tabbar button { font-family: var(--serif); font-size:15px; letter-spacing:.04em;
  background:#fff; border:1px solid #111; border-radius:999px; padding:8px 20px; cursor:pointer;
  transition: background-color .2s,color .2s,scale .15s ease-out; }
.tabbar button:hover { background:#eee; }
.tabbar button:active { scale: .96; }
.tabbar button.active { background: var(--blue); border-color: var(--blue); color:#fff; }
.tabpanel { display:none; padding: 26px 0 8px; }
.tabpanel.active { display:block; }
.tabpanel .tp-label { font-size:12px; letter-spacing:.22em; text-transform:uppercase; color:var(--blue); }
.tabpanel .tp-title { font-family: var(--script); color: var(--blue); font-weight:400; font-size: clamp(32px,5vw,58px); line-height:.95; margin: 6px 0 10px; }
.tabpanel .tp-intro { color:#333; max-width:70ch; margin-bottom: 22px; font-size:17px; }

/* tables ~10% more compact than before, for a calmer, less crowded read */
table.dlar { width:100%; border-collapse: collapse; font-size: 13.5px; }
/* Priced tables get a min-width so the .table-scroll wrapper scrolls sideways on narrow screens instead of crushing columns */
table.dlar.priced { min-width: 760px; }
table.dlar th, table.dlar td { text-align:left; padding: 11px 12px; border-bottom:1px solid var(--rule); vertical-align: top; }
/* Price column: keep the € rating on a single line and give it a little breathing room */
table.dlar th.price, table.dlar td.price { white-space: nowrap; padding-right: 18px; }
table.dlar th { font-weight:400; text-transform:uppercase; letter-spacing:.08em; font-size:10px; color:var(--muted); }
table.dlar tr:hover td { background: var(--cream); }
table.dlar a { color: var(--blue); border-bottom:1px solid var(--blue); }
/* "Visit ↗" link: the URL stays hidden behind it, opens in a new tab */
table.dlar a.visit { display:inline-flex; align-items:center; gap:4px; border-bottom:0;
  text-decoration: underline; text-underline-offset:3px; text-decoration-thickness:1px;
  font-size:13px; letter-spacing:.03em; white-space:nowrap; }
table.dlar a.visit .va { font-size:12px; transition: transform .2s ease; }
table.dlar a.visit:hover { border-bottom:0; }
table.dlar a.visit:hover .va { transform: translate(2px,-2px); }
.table-scroll { overflow-x:auto; }
.legend { display:flex; gap:16px; flex-wrap:wrap; font-size:12px; color:#555; margin: 6px 0 16px; }
.legend b { color: var(--blue); }
.minicards { display:grid; gap:14px; grid-template-columns: repeat(2,1fr); margin-bottom: 24px; }
@media (max-width:680px){ .minicards{ grid-template-columns:1fr; } }
.minicard { border:1px solid var(--rule); background:var(--cream); padding:14px 16px; }
.minicard h5, .minicard .mc-h { font-weight:400; font-size:15px; margin-bottom:5px; }
.minicard p { font-size:13px; color:#444; }
.rank { font-family: var(--script); color: var(--blue); font-size: 23px; }

/* scroll hint on the tabbed directory: Georgia italic in blue, stays up until
   you near the bottom. Wide screens: sits in the right gutter, no plate.
   Smaller screens: overlaps the table on a soft cream plate, with ~25% kept
   in the reserved gutter. Hidden on true phones. */
.scroll-hint { position: fixed; right: 24px; bottom: 24px; z-index: 20;
  display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;
  max-width: 150px; pointer-events: none;
  opacity: .92; transition: opacity .55s ease, transform .55s ease; }
.scroll-hint.is-hidden { opacity: 0; transform: translateY(10px); }
.scroll-hint .sh-text { font-family: var(--serif); font-style: italic; color: var(--blue);
  font-size: 22px; line-height: 1.3; }
.scroll-hint .sh-arrow { color: var(--blue); animation: shBob 1.9s ease-in-out infinite; }
@keyframes shBob { 0%,100%{ transform: translateY(0); } 50%{ transform: translateY(6px); } }
/* smaller windows: text only, no plate; allowed to overlap the table */
@media (min-width:560px) and (max-width:1199.98px){ .scroll-hint { right: 14px; max-width: 140px; } }
@media (max-width: 559.98px){ .scroll-hint { display:none; } }
@media (prefers-reduced-motion: reduce){ .scroll-hint .sh-arrow { animation: none; } }

/* Swaps hint (principles page): a floating shortcut straight to the Swaps page,
   shown whenever the on-page "See the Swaps" button is scrolled out of view.
   Same italic-blue-serif treatment as .scroll-hint, laid out horizontally. */
.swaps-hint { position: fixed; right: 24px; bottom: 24px; z-index: 20;
  display: inline-flex; align-items: center; gap: 10px; text-decoration: none;
  font-family: var(--serif); font-style: italic; color: var(--blue);
  font-size: 22px; line-height: 1.2;
  opacity: .92; transition: opacity .55s ease, transform .55s ease; }
.swaps-hint:hover { opacity: 1; }
.swaps-hint.is-hidden { opacity: 0; transform: translateY(10px); pointer-events: none; }
.swaps-hint .sh-arrow { color: var(--blue); display: inline-flex; animation: shBobX 1.9s ease-in-out infinite; }
@keyframes shBobX { 0%,100%{ transform: translateX(0); } 50%{ transform: translateX(6px); } }
@media (max-width: 559.98px){ .swaps-hint { display:none; } }
@media (prefers-reduced-motion: reduce){ .swaps-hint .sh-arrow { animation: none; } }

/* ---------------- quiz ---------------- */
.quiz { max-width: 820px; margin: 0 auto; padding: 8px 24px; }
.quiz__head { text-align:center; margin-bottom: 28px; }
.quiz__q { border-top:1px solid var(--rule); padding: 22px 0; }
.quiz__q .ql { font-family: var(--script); color: var(--blue); font-size: 26px; margin-right: 8px; }
.quiz__q p.qtext { font-size: 18px; margin-bottom: 14px; display:inline; }
.quiz__opts { display:grid; gap:10px; margin-top: 12px; }
.quiz__opts label { display:flex; gap:12px; align-items:flex-start; cursor:pointer; padding:10px 14px; border:1px solid var(--rule); background:#fff; transition: background-color .15s, border-color .15s; }
.quiz__opts label:hover { background: var(--cream); }
.quiz__opts input { margin-top:5px; accent-color: var(--blue); }
.quiz__opts input:checked + span { color: var(--blue); }
.quiz__actions { text-align:center; margin: 26px 0; }
.quiz__result { display:none; background: var(--cream); border:1px solid var(--rule); padding: 30px; text-align:center; }
.quiz__result.show { display:block; }
.quiz__result .level { font-size:12px; letter-spacing:.18em; text-transform:uppercase; color: var(--blue); }
.quiz__result h3 { font-family: var(--script); color: var(--blue); font-weight:400; font-size: clamp(30px,5vw,52px); margin:6px 0 12px; }
.quiz__result p { max-width:60ch; margin:0 auto 18px; color:#333; }
.quiz__score { font-style:italic; color:#666; font-size:14px; margin-top:14px; font-variant-numeric: tabular-nums; }

/* offer cards (Work) */
.offer { border:1px solid var(--rule); background:var(--cream); padding: 30px; }
.offer .tag { font-size:11px; letter-spacing:.18em; text-transform:uppercase; color:var(--blue); }
.offer h3 { font-size:24px; font-weight:400; margin:8px 0 12px; }
.offer ul { list-style:none; margin:16px 0; }
.offer li { padding:9px 0 9px 22px; position:relative; border-bottom:1px solid var(--rule); font-size:15px; }
.offer li::before { content:"✶"; color:var(--blue); position:absolute; left:0; }

/* ----------------------------------------------------------
   Work: Individual / Organisation toggle (single column,
   no card / no beige - sits on the page with hairline rules)
   ---------------------------------------------------------- */
.offer-switch { display:flex; justify-content:center; margin:0 0 44px; }
.offer-switch__rail { position:relative; display:inline-grid; grid-auto-flow:column;
  grid-auto-columns:1fr; gap:4px; padding:5px; border:1px solid var(--blue);
  border-radius:999px; background:var(--paper); }
.offer-switch__btn { appearance:none; -webkit-appearance:none; border:0; background:transparent;
  color:var(--blue); font-family:var(--serif); font-size:14.5px; letter-spacing:.05em;
  padding:11px 30px; border-radius:999px; cursor:pointer; position:relative; z-index:1;
  transition:background-color .22s ease, color .22s ease, scale .15s ease-out; }
.offer-switch__btn:active { scale: .96; }
.offer-switch__btn:not(.active):hover { background:rgba(47,62,143,.07); }
.offer-switch__btn.active { background:var(--blue); color:#fff; }
/* the ink slides between the two labels instead of teleporting: an absolutely
   positioned thumb glides under the active button (equal 1fr columns make the
   travel exact). Browsers without :has() keep the classic per-button fill. */
@supports selector(:has(*)) {
  .offer-switch__rail::before { content:""; position:absolute; top:5px; bottom:5px; left:5px;
    width:calc(50% - 7px); border-radius:999px; background:var(--blue);
    transition: transform .42s cubic-bezier(.3,1.2,.35,1); }
  .offer-switch__rail:has(.offer-switch__btn:last-child.active)::before { transform: translateX(calc(100% + 4px)); }
  .offer-switch__btn.active { background:transparent; }
}

.offer-panel { display:none; }
/* the chosen offer settles in as a cascade: kicker, title, lead, list, note,
   buttons - each a beat behind the last (backwards-fill keeps them hidden
   until their turn) */
.offer-panel.active { display:block; }
.offer-panel.active > * { animation: offerFade .4s ease backwards; }
.offer-panel.active > *:nth-child(2) { animation-delay: .05s; }
.offer-panel.active > *:nth-child(3) { animation-delay: .1s; }
.offer-panel.active > *:nth-child(4) { animation-delay: .15s; }
.offer-panel.active > *:nth-child(5) { animation-delay: .2s; }
.offer-panel.active > *:nth-child(6) { animation-delay: .25s; }
@keyframes offerFade { from { opacity:0; transform:translateY(7px); } to { opacity:1; transform:none; } }
.offer-kicker { font-size:11px; letter-spacing:.18em; text-transform:uppercase; color:var(--blue); }
.offer-title { font-size:30px; font-weight:400; margin:7px 0 18px; line-height:1.15; }
.offer-lead { color:#444; font-size:17px; line-height:1.72; max-width:62ch; }
.offer-list { list-style:none; margin:28px 0 32px; padding:0; border-top:1px solid var(--rule); }
.offer-list li { padding:15px 0 15px 28px; position:relative; border-bottom:1px solid var(--rule);
  font-size:15.5px; line-height:1.55; color:#333; }
.offer-list li::before { content:"✶"; color:var(--blue); opacity:.8; font-size:13px; position:absolute; left:0; top:17px; }
@media (max-width:560px){
  .offer-switch__btn { padding:11px 20px; font-size:13.5px; }
  .offer-title { font-size:26px; }
  .offer-lead { font-size:16px; }
}

/* scarcity microcopy that sits above a CTA pair (The List / The Notes) */
.cta-note { font-size:13.5px; line-height:1.6; font-style:italic; color:#6a6a6a;
  max-width:54ch; margin:2px 0 16px; }
.cta-note .em { font-style:normal; color:var(--blue); }

/* value items */
.values { display:grid; gap:20px; grid-template-columns: repeat(2,1fr); }
@media (max-width:680px){ .values{ grid-template-columns:1fr; } }
.value { border-top:2px solid var(--blue); padding-top:14px; }
.value h3, .value h4 { font-weight:400; font-size:18px; margin-bottom:6px; }
.value p { color:#444; font-size:15px; }

/* social */
.social { display:flex; gap:22px; flex-wrap:wrap; justify-content:center; }
.social a { position:relative; font-size:14px; letter-spacing:.1em; text-transform:uppercase; border-bottom:1px solid transparent; padding-bottom:3px; color:var(--blue); }
.social a:hover { border-color:var(--blue); }

/* ---------------- footer (oxblood, big script) ---------------- */
footer.site { background:#4A0E13; color:#fff; margin-top: 80px; }
.foot { max-width: var(--maxw); margin: 0 auto; padding: 80px 24px; text-align:center; }
.foot .seal { width:120px; height:auto; margin: 0 auto 22px; opacity:.7; filter: invert(1) grayscale(1); }
.foot h2 { font-family: var(--script); font-size: clamp(20px,3.5vw,44px); line-height:0.78; font-weight:400; color:#fff; }
.foot .tagline { color:#bbb; font-style:italic; margin-top:10px; }
.foot .links { display:flex; gap:26px; justify-content:center; flex-wrap:wrap; margin-top:26px; }
.foot .links a { position:relative; font-size:14px; letter-spacing:.1em; text-transform:uppercase; padding-bottom:3px; border-bottom:1px solid transparent; }
.foot .links a:hover { border-color:#fff; }
.foot .legal { margin-top:34px; color:#9a9a9a; font-size:11px; letter-spacing:.05em; line-height:1.8; }
.foot .legal a { color:#a8a8a8; border-bottom:1px solid #444; }

/* reveal: subtle rise + focus-in (12px, blurred enter per the enter-animation
   recipe). Decorative imgs with inline filters keep their own filter (inline
   wins), and .faq-card opts out below (blur would flatten its 3D flip). */
[data-reveal]{ opacity:0; transform: translateY(12px); filter: blur(4px); transition: opacity .6s ease, transform .6s ease, filter .6s ease; }
[data-reveal].in{ opacity:1; transform:none; filter:none; }
/* sibling cards revealed together get a ~100ms stagger instead of one block */
.grid > [data-reveal]:nth-child(2), .grid-2 > [data-reveal]:nth-child(2),
.steps > [data-reveal]:nth-child(2), .values > [data-reveal]:nth-child(2) { transition-delay: .1s; }
.grid > [data-reveal]:nth-child(3),
.steps > [data-reveal]:nth-child(3), .values > [data-reveal]:nth-child(3) { transition-delay: .2s; }
.grid > [data-reveal]:nth-child(4), .values > [data-reveal]:nth-child(4) { transition-delay: .3s; }
.grid > [data-reveal]:nth-child(5) { transition-delay: .4s; }

/* ============================================================
   SUPPLEMENTS AREA  ·  "The Spelled Hand"
   Botanical-green accent override (mirrors body.home oxblood).
   Every component that reads var(--blue) repaints green for free.
   ============================================================ */
body.supplements {
  --blue:      #355E3B;   /* deep botanical / hunter green replaces the blue accent */
  --blue-deep: #28482d;
  --nogo:      #6F2136;   /* oxblood for "hard no" verdicts */
  --wash:      rgba(53,94,59,.08);
}
body.supplements footer.site { background:#16301c; }   /* deep forest sign-off */

/* ----- decorative engraved hands: sit ABOVE every layer (nav z50, flyout z60),
   purely visual (click-through), hidden on phones. Anchored to the viewport
   edges so they bleed off-screen exactly like the reference. ----- */
body.supplements .sup-fig { position: absolute; z-index: 80; pointer-events: none;
  user-select: none; height: auto; }
/* hero: anchored to the (transformed) .page-hero box so it tracks the text and
   drapes over the right ends of the title + subtitle + epigraph */
body.supplements .sup-fig--hero { top: -11px; right: -28px; width: clamp(280px, 27vw, 320px); }
/* decoder: .decoder is the positioned anchor; calc() pins the left-edge bleed
   to a constant distance off the viewport's left edge at every width */
body.supplements .decoder { position: relative; }
body.supplements .sup-fig--decoder { top: -64px;
  left: min(calc((900px - 100vw) / 2 - 70px), -70px); width: clamp(240px, 40vw, 600px); }
@media (max-width: 700px){ body.supplements .sup-fig { display: none; } }

/* ----- Living Water (principles) decorative engravings: same top-layer,
   click-through treatment as the supplement hands. Fine black line art kept
   as-is (no filter). hand.png bleeds off the hero's right edge; oyster shell
   sits over quiz Q1. Hidden on phones. ----- */
body.principles .lw-fig { position: absolute; z-index: 80; pointer-events: none;
  user-select: none; height: auto; }
/* hero hand: anchored to the initial containing block (viewport); wrist meets the
   title, ripples fall over accordion rows 01-02, right edge a hair off the page.
   Left and bottom edges fade in over the outer 10% so the artwork meets the
   shifted text and the accordion as a gradient, not a hard seam. The 6.5%
   interpolation hint (default would be 5%) biases each ramp toward transparency,
   so the edge reads ~15% more see-through without moving where the fade starts.
   Two gradients intersected so a pixel shows only where BOTH are opaque; top and
   right edges stay full. */
body.principles .lw-fig--hero { top: 150px; right: 10px; width: clamp(240px, 29vw, 420px);
  -webkit-mask-image: linear-gradient(to right, transparent 0%, 6.5%, #000 10%, #000 100%),
                      linear-gradient(to top, transparent 0%, 6.5%, #000 10%, #000 100%);
  -webkit-mask-composite: source-in;
          mask-image: linear-gradient(to right, transparent 0%, 6.5%, #000 10%, #000 100%),
                      linear-gradient(to top, transparent 0%, 6.5%, #000 10%, #000 100%);
          mask-composite: intersect; }
/* oyster: .quiz is the positioned anchor (820px centered box); sits over Q1,
   pearl right-of-centre, tip near the subhead, plank to the Q1/Q2 boundary */
body.principles .quiz { position: relative; }
body.principles .lw-fig--oyster { top: 180px; left: 61%; width: clamp(280px, 29vw, 400px); }
@media (max-width: 700px){ body.principles .lw-fig { display: none; } }

/* Optical balance: nudge only the content (eyebrow, headline, intro, accordion)
   ~7% to the left. The absolutely-positioned .lw-fig hand is anchored to the
   viewport (not a transformed ancestor), so it stays put; the CTA buttons live
   in a later .wrap and are untouched. Reset on phones (image hidden, text
   returns to centre). */
body.principles .page-hero .badge,
body.principles .page-hero h1,
body.principles .page-hero p,
body.principles .acc { transform: translateX(clamp(-84px, -5.5vw, -44px)); }
@media (max-width: 700px){
  body.principles .page-hero .badge,
  body.principles .page-hero h1,
  body.principles .page-hero p,
  body.principles .acc { transform: none; }
}

/* ----- Work With Me (work) decorative engraving: same top-layer, click-through,
   native-tone treatment as the principles/supplement figures (no filter, so the
   fine pencil line art keeps its true tones). glasses.png is anchored to the
   right, slightly overhanging the content's right edge; the whole hero block is
   shifted into the open space to its left so it clears the artwork. Hidden on
   phones. ----- */
body.work .wk-fig { position: absolute; z-index: 80; pointer-events: none;
  user-select: none; height: auto; filter: none; }
/* anchored to the (transformed) .page-hero box, so it tracks the text at every
   width and drapes over the right ends of the title + subtitle */
body.work .wk-fig--hero {
  top: 10px;
  right: -16px;
  width: clamp(300px, 32vw, 480px);
}
/* hero text relocated left of the glasses: full-width box with a right reserve
   tracking the image footprint, so the centered badge + title + subtitle clear it */
/* keep the centred hero, nudged just slightly left of page centre; the title is
   enlarged and the subtitle widened so their right ends run up under the glasses
   (which sit on top), making the artwork appear to almost cover the text */
body.work .page-hero { max-width: var(--maxw); margin: 0 auto; transform: translateX(-44px); }
body.work .page-hero h1 { font-size: clamp(54px, 9.2vw, 122px); }
body.work .page-hero p { max-width: 820px; }
@media (max-width: 700px){
  /* Mobile Work hero: glasses engraving floats right; the badge, title and
     paragraph wrap its silhouette (shape-outside). Bigger image, text hugs it. */
  body.work .wk-fig { display: block; position: static; }
  body.work .wk-fig--hero {
    float: right;
    top: auto; right: auto;
    width: 44%; max-width: 220px;
    margin: 0 -2px 2px 12px;
    shape-outside: url("../assets/glasses.webp");
    shape-image-threshold: 0.12;
    shape-margin: 7px;
  }
  body.work .page-hero {
    max-width: var(--maxw);
    padding: 50px 22px 24px;
    margin: 0 auto;
    transform: none;
    text-align: left;
    overflow: hidden;
  }
  body.work .page-hero .badge { text-align: left; }
  body.work .page-hero h1 { font-size: clamp(34px, 9.5vw, 56px); text-align: left; }
  body.work .page-hero p { max-width: none; text-align: left; }
}

/* Decoder headline/subhead: fluid narrowing so the centered text clears the
   sand hand on narrow screens. (Unchanged.) */
/* Decoder content hugs the sand hand: push the whole block's content rightward
   so its LEFT edge sits ~8px from the hair, and left-align everything. Padding
   doesn't move the hand (it anchors to the unchanged border box). */
body.supplements .decoder {
  text-align: left;
  padding-left: max(0px, calc(0.9713 * clamp(240px,40vw,600px) - 62px - max(50vw - 450px, 0px)));
}
body.supplements .decoder__head { text-align: left; margin-bottom: 22px; }
body.supplements .decoder__eyebrow {
  font-size: 13px; letter-spacing: .22em; text-transform: uppercase; color: var(--muted);
  margin-bottom: 6px; }
body.supplements .decoder__head h2 { max-width: none; margin-left: 0; margin-right: 0; }
body.supplements .decoder__head p { max-width: 60ch; margin-left: 0; margin-right: 0; }
body.supplements .decoder__search,
body.supplements .decoder__verdict { margin-left: 0; margin-right: auto; }

/* Supplements hero: same treatment as the Work page. Keep the centred hero +
   epigraph nudged slightly left of page centre, enlarge the title and widen the
   subtitle/quote so their right ends run up under the blueberry hand (which sits
   on top and, via the page-hero transform, now tracks the text at every width). */
body.supplements .page-hero { max-width: var(--maxw); margin: 0 auto; transform: translateX(-44px); }
body.supplements .page-hero h1 { font-size: clamp(54px, 9.2vw, 122px); }
body.supplements .page-hero p { max-width: 820px; }
body.supplements .epigraph { max-width: 780px; margin: 22px auto 0; transform: translateX(-44px); }

@media (max-width: 700px){
  /* phones: hands are hidden, so restore the normal centered layout */
  body.supplements .page-hero { max-width: var(--maxw); padding: 80px 24px 24px; margin: 0 auto; transform: none; }
  body.supplements .page-hero h1 { font-size: clamp(46px, 8vw, 92px); }
  body.supplements .epigraph { max-width: 760px; padding: 0 24px; margin: 22px auto 0; transform: none; }
  body.supplements .page-hero p { max-width: 60ch; }
  body.supplements .decoder { padding-left: 24px; text-align: center; }
  body.supplements .decoder__head { text-align: center; }
  body.supplements .decoder__eyebrow { margin-bottom: 4px; }
  body.supplements .decoder__head h2 { max-width: none; }
  body.supplements .decoder__head p { max-width: 60ch; margin-left: auto; margin-right: auto; }
  body.supplements .decoder__search, body.supplements .decoder__verdict { margin-left: auto; }
}

/* hero epigraph (the line that names "The Spelled Hand") */
.epigraph { position: relative; max-width: 760px; margin: 22px auto 0; text-align:center; padding: 0 24px; }
/* an engraved ghost of the opening mark floats behind the line, the way a
   printer's flourish sits behind an epigraph on a title page */
.epigraph::before {
  content: "\201C"; position: absolute; left: 50%; top: -0.28em;
  transform: translateX(-50%);
  font-family: var(--serif); font-size: clamp(90px, 12vw, 130px); line-height: 1;
  color: var(--blue); opacity: .07; pointer-events: none;
}
.epigraph blockquote {
  position: relative;
  font-family: var(--serif); font-style: italic; font-size: clamp(19px,2.4vw,25px);
  line-height: 1.5; color: #2c2c2c;
  hanging-punctuation: first last;   /* true hang where supported (Safari) */
}
.epigraph .src { display:block; margin-top:16px; font-style:normal; font-size:12px;
  letter-spacing:.18em; text-transform:uppercase; color: var(--blue); }

/* Hearth: nudge the epigraph (quote + signature) 8% left so it reads more in
   line with the hero art. Reset on phones where the layout is plain centered. */
body.hearth .epigraph { transform: translateX(-8%); }
@media (max-width: 700px){ body.hearth .epigraph { transform: none; } }

/* a thin botanical rule used between sections */
.leaf-rule { display:flex; align-items:center; justify-content:center; gap:14px;
  max-width: 540px; margin: 46px auto; color: var(--blue); }
.leaf-rule::before, .leaf-rule::after { content:""; height:1px; flex:1; background: var(--rule); }
.leaf-rule span { font-size:15px; letter-spacing:.3em; }

/* ---------------- The Filler Decoder ---------------- */
.decoder { max-width: 900px; margin: 0 auto; padding: 8px 24px; }
.decoder__head { text-align:center; margin-bottom: 26px; }
.decoder__head p { max-width: 60ch; margin: 12px auto 0; color:#555; }
.decoder__search { display:flex; gap:10px; max-width:560px; margin: 0 auto; }
.decoder__search input {
  flex:1; font-family:var(--serif); font-size:16px; padding:13px 16px;
  border:1px solid var(--rule); background:#fff; color:var(--ink);
}
.decoder__search input:focus { outline:none; border-color:var(--blue); }
.decoder__verdict { max-width:560px; margin: 16px auto 0; }
.verdict { border:1px solid var(--rule); border-left-width:4px; background:#fff; padding:18px 20px;
  animation: verdictIn .35s ease; }
@keyframes verdictIn { from{ opacity:0; transform: translateY(6px);} to{ opacity:1; transform:none;} }
.verdict__tag { font-size:11px; letter-spacing:.18em; text-transform:uppercase; font-weight:700; }
.verdict h4 { font-family:var(--serif); font-weight:400; font-size:21px; margin:7px 0 7px; text-transform:capitalize; color:var(--ink); }
.verdict p { color:#444; margin:0; max-width:60ch; font-size:15.5px; }
.verdict--nogo { border-left-color: var(--nogo); }
.verdict--nogo .verdict__tag { color: var(--nogo); }
.verdict--okay { border-left-color: var(--blue); }
.verdict--okay .verdict__tag { color: var(--blue); }
.verdict--none { border-left-color: var(--muted); }
.verdict--none .verdict__tag { color: var(--muted); }

.decoder__lists { display:grid; grid-template-columns:1fr 1fr; gap:34px; margin-top:36px; }
@media (max-width:600px){ .decoder__lists { grid-template-columns:1fr; gap:26px; } }
.decoder__label { font-size:12px; letter-spacing:.18em; text-transform:uppercase;
  margin-bottom:15px; padding-bottom:9px; border-bottom:1px solid var(--rule); }
.decoder__label.is-nogo { color:var(--nogo); }
.decoder__label.is-okay { color:var(--blue); }
.chips { display:flex; flex-wrap:wrap; gap:9px; }
.chip { position:relative; font-family:var(--serif); font-size:13.5px; cursor:pointer; background:#fff;
  padding:7px 14px; border:1px solid var(--rule); border-radius:999px;
  transition:background-color .15s, border-color .15s, color .15s, opacity .15s, scale .15s ease-out;
  color:#3a3a3a; text-transform:capitalize; }
/* extend each chip's tap target ~4px per side (chip gap is 9px, so no overlap) */
.chip::after { content:""; position:absolute; inset:-4px; border-radius:inherit; }
.chip:active { scale: .96; }
.chip[data-verdict="nogo"]:hover, .chip[data-verdict="nogo"].is-active {
  border-color:var(--nogo); color:var(--nogo); background:rgba(111,33,54,.06); }
.chip[data-verdict="okay"]:hover, .chip[data-verdict="okay"].is-active {
  border-color:var(--blue); color:var(--blue); background:rgba(53,94,59,.07); }
.chip.is-dim { opacity:.22; }

/* closing "what I actually use" teaser */
.usenote { max-width: 720px; margin: 0 auto; text-align:center; }
.usenote .soon { display:inline-block; margin-top:18px; font-style:italic; color:#777; font-size:15px; }

/* ============================================================
   THE INDEPENDENCE CREDO  ·  rippling text-line + closing note
   States, plainly, that the swap directory is unaffiliated: no
   sponsorships, no paid placements, nothing bought. A trust signal
   framed as a standard, not a disclaimer. Accent follows var(--blue)
   so it reads in each area's own colour. The line is a hairline with
   the credo centred in it; js/credo-rule.js makes it ripple like the
   homepage water-line (cursor-pluck on desktop, gentle wave on
   mobile), the text riding the wave. Swap directories only.
   ============================================================ */
.credo-rule {
  position: relative; width: calc(100% - 48px); max-width: var(--maxw);
  /* tighter top gap so the line sits closer under the hero paragraph; the
     hero already carries 24px of its own bottom padding above this */
  margin: 12px auto 44px; height: 56px;
  display: flex; align-items: center; justify-content: center;
}
.credo-rule__line { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.credo-rule__line path {
  fill: none; stroke: color-mix(in srgb, var(--blue) 40%, transparent); stroke-width: 1;
}
.credo-rule__txt {
  position: relative; z-index: 1; font-family: var(--serif); font-size: 15px;
  letter-spacing: .02em; color: var(--blue); white-space: nowrap; padding: 0 6px;
  will-change: transform;
}
/* progressive enhancement: until JS marks it live, a plain centred hairline */
.credo-rule:not(.is-live)::before {
  content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px;
  background: color-mix(in srgb, var(--blue) 40%, transparent);
}
.credo-rule:not(.is-live) .credo-rule__txt { background: var(--paper); padding: 0 16px; }
@media (max-width: 560px) { .credo-rule__txt { font-size: 13px; } }
@media (prefers-reduced-motion: reduce) { .credo-rule__txt { transform: none !important; } }

/* the fuller "word on trust" note, in the closing section */
.credo-note { max-width: 60ch; margin: 30px auto 0; text-align: center; }
.credo-note__eyebrow {
  font-size: 12px; letter-spacing: .22em; text-transform: uppercase;
  color: var(--blue); margin-bottom: 10px;
}
.credo-note__p { font-size: 16px; line-height: 1.65; color: #444; margin: 0; }

/* ============================================================
   NEWSLETTER POPUP  ·  "The List"
   A DLAR-native modal that wraps the MailerLite capture form.
   Inherits the page accent via var(--blue), so it reads oxblood
   on the home page and brand-blue elsewhere, like everything else.
   ============================================================ */
.nl-modal { position: fixed; inset: 0; z-index: 200; display: none;
  align-items: center; justify-content: center; padding: 24px; }
.nl-modal.is-open { display: flex; }
.nl-backdrop { position: absolute; inset: 0; background: rgba(12,12,12,.62);
  backdrop-filter: blur(4px); animation: nlFade .35s ease; }
@keyframes nlFade { from { opacity: 0; } to { opacity: 1; } }

.nl-card { position: relative; z-index: 1; width: 100%; max-width: 440px;
  max-height: calc(100vh - 48px); overflow-y: auto;
  background: url('../assets/paper 01.webp') center/cover no-repeat, var(--cream);
  border: 0; border-top: 3px solid var(--blue);
  border-radius: 6px;
  /* hairline ring folded into the shadow stack (reads on the dark backdrop) */
  box-shadow: 0 0 0 1px rgba(0,0,0,.08), 0 24px 60px rgba(12,12,12,.34);
  padding: 40px 36px 30px; text-align: center;
  animation: nlRise .4s cubic-bezier(.2,.7,.3,1); }
@keyframes nlRise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }

/* exit: softer + quicker than the enter, a small fixed lift instead of drama */
.nl-modal.is-closing { pointer-events: none; }
.nl-modal.is-closing .nl-card { animation: nlExit .15s ease-in forwards; }
.nl-modal.is-closing .nl-backdrop { animation: nlFadeOut .15s ease-in forwards; }
@keyframes nlExit { to { opacity: 0; transform: translateY(-12px); } }
@keyframes nlFadeOut { to { opacity: 0; } }

.nl-close { position: absolute; top: 9px; right: 11px; width: 40px; height: 40px;
  border: none; background: none; cursor: pointer; color: var(--muted);
  font-family: var(--serif); font-size: 30px; line-height: 1; padding: 0;
  transition: color .2s, scale .15s ease-out; }
.nl-close:active { scale: .96; }
.nl-close:hover { color: var(--ink); }

.nl-flourish { font-family: var(--script); color: var(--blue); line-height: .9;
  font-size: clamp(40px, 9vw, 58px); margin-bottom: 4px; }
.nl-eyebrow { font-size: 11px; letter-spacing: .24em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 14px; }
.nl-title { font-family: var(--serif); font-weight: 400; color: var(--ink);
  font-size: clamp(24px, 4.4vw, 30px); line-height: 1.12; margin: 0 0 10px; }
.nl-sub { color: #4a4a4a; font-size: 15px; line-height: 1.55; margin: 0 auto 22px;
  max-width: 34ch; }

.nl-form { display: flex; flex-direction: column; gap: 11px; text-align: left; }
.nl-form input[type="text"], .nl-form input[type="email"] {
  width: 100%; font-family: var(--serif); font-size: 16px; color: var(--ink);
  background: #fff; border: 1px solid var(--rule); border-radius: 4px;
  padding: 13px 15px; transition: border-color .2s; }
.nl-form input::placeholder { color: #9a958a; }
.nl-form input:focus { outline: none; border-color: var(--blue); }
.nl-form input.nl-invalid { border-color: var(--nogo, #b23a48); }

.nl-error { display: none; color: var(--nogo, #b23a48); font-size: 13px; margin: -3px 2px 0; }
.nl-error.is-shown { display: block; }

.nl-submit { margin-top: 6px; width: 100%; cursor: pointer;
  font-family: var(--serif); font-size: 16px; letter-spacing: .04em; font-weight: 700;
  color: #fff; background: var(--blue); border: 1px solid var(--blue);
  border-radius: 4px; padding: 14px; transition: background-color .2s, scale .15s ease-out; }
.nl-submit:hover { background: var(--blue-deep); }
.nl-submit:not(:disabled):active { scale: .96; }
.nl-submit:disabled { opacity: .65; cursor: default; }
.nl-submit .nl-spin { display: none; width: 16px; height: 16px; vertical-align: -2px;
  border: 2px solid rgba(255,255,255,.5); border-top-color: #fff; border-radius: 50%;
  animation: nlSpin .8s linear infinite; }
.nl-modal.is-sending .nl-submit .nl-label { display: none; }
.nl-modal.is-sending .nl-submit .nl-spin { display: inline-block; }
@keyframes nlSpin { to { transform: rotate(360deg); } }

.nl-fine { font-size: 12px; color: #8a857b; line-height: 1.5; margin: 16px auto 0;
  max-width: 36ch; }
.nl-fine a { color: #6a655c; text-decoration: underline; }

/* success state (shown after submit) */
.nl-success { display: none; }
.nl-modal.is-done .nl-form-view { display: none; }
.nl-modal.is-done .nl-success { display: block; }
.nl-success .nl-title { margin-bottom: 12px; }
.nl-success .nl-sub { margin-bottom: 24px; }
.nl-success .nl-submit { max-width: 200px; margin: 0 auto; display: block; }

.nl-sink { position: absolute; width: 0; height: 0; border: 0; opacity: 0;
  pointer-events: none; }

@media (max-width: 460px) {
  .nl-modal { padding: 0; align-items: flex-end; }
  .nl-card { max-width: none; max-height: 92vh; border-radius: 14px 14px 0 0;
    padding: 34px 24px 26px; }
}

/* ============================================================
   LIST FORM POPUP  ·  "The List" application questionnaire
   Reuses the .nl-* popup shell above (backdrop, card, title,
   submit, success), so it inherits the per-page accent. This
   block adds only what the longer form needs: a wider card,
   stacked field labels, and select / textarea styling that
   matches the .nl-form inputs.
   ============================================================ */
.nl-modal--list .nl-card { max-width: 540px; }

.lf-form { gap: 14px; }

.lf-field { display: flex; flex-direction: column; gap: 5px; }
.lf-label { font-family: var(--serif); font-size: 12.5px; letter-spacing: .02em;
  color: var(--muted); }

/* selects + textareas match the .nl-form text inputs */
.lf-form select.lf-select,
.lf-form textarea {
  width: 100%; font-family: var(--serif); font-size: 16px; color: var(--ink);
  background: #fff; border: 1px solid var(--rule); border-radius: 4px;
  padding: 13px 15px; transition: border-color .2s; }
.lf-form textarea { resize: vertical; min-height: 64px; line-height: 1.5; }
.lf-form textarea::placeholder { color: #9a958a; }
.lf-form select.lf-select { cursor: pointer; appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%239a958a' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center;
  padding-right: 36px; }
.lf-form select.lf-select:focus,
.lf-form textarea:focus { outline: none; border-color: var(--blue); }
.lf-form textarea.nl-invalid,
.lf-form select.nl-invalid { border-color: var(--nogo, #b23a48); }

/* two closed-set questions sit side by side on a roomy card */
.lf-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 480px) { .lf-row { grid-template-columns: 1fr; } }

/* spam honeypot: never shown, never reached by tab or screen readers */
.lf-hp { position: absolute; left: -9999px; width: 1px; height: 1px;
  opacity: 0; pointer-events: none; }

/* ============================================================
   FAQ PAGE - "The Range": oxblood target cards you shoot to
   flip open. Homepage oxblood ink. Desktop gets a reticle
   cursor + recoil + ceramic shards (wired in js/faq.js); touch
   and reduced-motion degrade to a calm tap-to-flip card grid.
   ============================================================ */
body.faq {
  --blue:      #6F2136;   /* match the homepage oxblood ink */
  --blue-deep: #571a2a;
  --ox:        #6F2136;
  --ox-deep:   #571a2a;
  --ox-lt:     #8d2f47;
}

/* a quieter hero standfirst + the desktop-only "take aim" line */
body.faq .page-hero { padding-bottom: 8px; }
.faq-aim {
  margin: 18px auto 0; max-width: 46ch;
  font-style: italic; font-size: 14px; letter-spacing: .02em; color: var(--ox-lt);
  opacity: .9;
}
.faq-aim span { color: var(--muted); font-style: normal; }
/* the aim prompt only makes sense where you can actually aim (desktop) */
@media (hover: none), (pointer: coarse) { .faq-aim { display: none; } }
@media (max-width: 900px) { .faq-aim { display: none; } }

/* ---- the range ---- */
.faq-range {
  position: relative; max-width: 1180px; margin: 0 auto; padding: 30px 24px 12px;
  overflow: visible;
}
.faq-ornament {
  position: absolute; left: 50%; top: 46%; width: min(72vw, 760px);
  transform: translate(-50%, -50%); opacity: .05; pointer-events: none;
  z-index: 0; will-change: transform; filter: grayscale(100%);
}

.faq-grid {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: 1fr 1fr; gap: 26px 30px;
  align-items: start;
  perspective: 1700px;          /* shared camera so cards tip back in 3D */
  perspective-origin: 50% 38%;
}
/* the scattered "targets" feel: a gentle alternating vertical drop only.
   The decorative lean must NOT live on the flipping element, or it turns the
   clean 180 flip into a degenerate, uneven rotation (looks like "red, pause,
   text"). So the scatter is vertical offset alone. */
.faq-card:nth-child(even) { margin-top: 34px; }

/* ---- the card / flip mechanism ---- */
/* the card itself takes the knock-back (rotateX from its base); the inner
   does the fall-and-spring face flip, also on the X axis - so the whole thing
   reads as "shot, falls onto its back, springs up with the answer" */
.faq-card { transform-style: preserve-3d; transform-origin: center bottom; }
.faq-card__inner {
  position: relative; display: block; width: 100%;
  text-align: left; cursor: pointer; background: none; border: 0; padding: 0;
  font-family: var(--serif);
  transform-style: preserve-3d;   /* flip pivots from centre = stays in place */
  transition: transform .78s cubic-bezier(.34,1.42,.5,1), filter .3s ease;
  will-change: transform;
}
/* canonical flip-card structure for a TRUE 3D turn: the answer face sits in
   normal flow (so it sets the card height, no JS), the question face is
   absolutely overlaid on top. backface-visibility then genuinely hides each
   side as it turns away - the front rotates edge-on, the back swings in. */
.faq-card__face {
  -webkit-backface-visibility: hidden; backface-visibility: hidden;
  display: flex; flex-direction: column;
  min-height: 188px; padding: 30px 30px 28px; border-radius: 6px;
  border: 1px solid rgba(87,26,42,.22);
}
.faq-card__face--q { position: absolute; inset: 0; }   /* front, overlay */
.faq-card__face--a { position: relative; }             /* back, defines height */

/* QUESTION face: oxblood tile, cream type - the target. Three faint etched
   rings in the lower-right corner make it read as a range target plate, not
   an app card (static backgrounds, never filters - see the 3D note below). */
.faq-card__face--q {
  background:
    radial-gradient(circle at 85% 84%, transparent 25px, rgba(247,244,233,.11) 25.5px 26.5px, transparent 27px),
    radial-gradient(circle at 85% 84%, transparent 43px, rgba(247,244,233,.08) 43.5px 44.5px, transparent 45px),
    radial-gradient(circle at 85% 84%, transparent 61px, rgba(247,244,233,.06) 61.5px 62.5px, transparent 63px),
    radial-gradient(120% 140% at 18% 12%, #7c2740 0%, var(--ox) 46%, var(--ox-deep) 100%);
  color: var(--cream);
  box-shadow: 0 12px 26px rgba(40,12,20,.28), 0 2px 6px rgba(40,12,20,.20), inset 0 0 0 1px rgba(255,255,255,.07);
  justify-content: space-between;
}
.faq-card__n {
  font-family: var(--script); font-size: 40px; line-height: .7; color: var(--cream);
  opacity: .62;
}
.faq-card__q {
  display: block; margin-top: 14px;
  font-size: clamp(20px, 2vw, 25px); line-height: 1.22; letter-spacing: .005em;
  text-wrap: balance;
}
.faq-card__cue {
  margin-top: 18px; font-size: 10px; letter-spacing: .26em; text-transform: uppercase;
  color: rgba(247,244,233,.62); display: inline-flex; align-items: center; gap: 8px;
  transition: color .2s ease;
}
.faq-card__cue::before {
  content: ""; width: 13px; height: 13px; border-radius: 50%;
  border: 1px solid currentColor; box-shadow: 0 0 0 3px rgba(247,244,233,.10);
}

/* ANSWER face: cream paper, ink type - the reward */
.faq-card__face--a {
  background:
    linear-gradient(180deg, #fbf9f1 0%, var(--cream) 100%);
  color: #33302a;
  transform: rotateX(180deg);
  box-shadow: 0 12px 26px rgba(40,12,20,.16), 0 2px 6px rgba(40,12,20,.10), inset 0 0 0 1px rgba(255,255,255,.5);
  border-color: rgba(111,33,54,.18);
  border-left: 3px solid var(--ox);
  justify-content: center;
}
.faq-card__a { font-size: 16.5px; line-height: 1.62; }

/* hover micro-interaction (desktop pointer).
   CRITICAL: never use filter / opacity / mix-blend on .faq-card__inner or the
   faces - those force a FLAT 3D context, which collapses the flip and snaps an
   open card back to the question on hover. Only shadow / border / colour here. */
@media (hover: hover) and (pointer: fine) {
  .faq-card:hover .faq-card__face--q {
    box-shadow: 0 16px 34px rgba(40,12,20,.38), 0 3px 8px rgba(40,12,20,.24), inset 0 0 0 1px rgba(247,244,233,.20);
    border-color: rgba(247,244,233,.42);
  }
  .faq-card:hover .faq-card__n { opacity: .82; }
  .faq-card:hover .faq-card__cue { color: rgba(247,244,233,.95); }
  .faq-card:hover .faq-card__cue::before {
    background: rgba(247,244,233,.16);
    box-shadow: 0 0 0 4px rgba(247,244,233,.16);
  }
}

/* OPEN: a clean, uniform 180 turn on the horizontal bar to the answer side */
.faq-card.is-open .faq-card__inner { transform: rotateX(180deg); }

/* reveal-on-scroll (shares the global [data-reveal] -> .in observer).
   filter:none opts out of the global blurred enter - any filter here would
   force a flat 3D context and collapse the card flip. */
.faq-card[data-reveal] { opacity: 0; transform: translateY(20px); filter: none; transition: opacity .7s ease, transform .7s ease; }
.faq-card[data-reveal].in { opacity: 1; transform: translateY(0); }
/* keep the alternating drop after reveal settles */
.faq-card:nth-child(even)[data-reveal].in { transform: translateY(0); }

/* ---- the oxblood reticle cursor (desktop, injected by faq.js) ---- */
.faq-reticle {
  position: fixed; left: 0; top: 0; z-index: 1000; pointer-events: none;
  opacity: 0; transform: translate(-100px,-100px); transition: opacity .25s ease;
  width: 64px; height: 64px;
}
.faq-reticle svg { width: 100%; height: 100%; display: block;
  transition: transform .18s cubic-bezier(.2,.8,.3,1.2); transform: scale(1); }
.faq-reticle.lock svg { transform: scale(.82) rotate(45deg); }
.faq-reticle.fire svg { transform: scale(1.18); transition: transform .08s ease; }
/* hide the native cursor only when the reticle is live */
body.faq.faq-armed, body.faq.faq-armed * { cursor: none !important; }

/* the shard / dust canvas sits above cards, below the reticle */
.faq-canvas { position: fixed; inset: 0; z-index: 980; pointer-events: none; }

/* the subtle "Handled." flourish, fired once when the last card opens */
.faq-handled {
  position: fixed; left: 50%; top: 50%; z-index: 1001; pointer-events: none;
  transform: translate(-50%,-44%); opacity: 0;
  font-family: var(--script); color: var(--ox); font-size: clamp(64px, 10vw, 128px);
  line-height: 1; text-shadow: 0 4px 30px rgba(40,12,20,.18);
}
.faq-handled.show { animation: faqHandled 2s ease both; }
@keyframes faqHandled {
  0%   { opacity: 0; transform: translate(-50%,-40%) scale(.92); }
  18%  { opacity: 1; transform: translate(-50%,-50%) scale(1); }
  72%  { opacity: 1; transform: translate(-50%,-50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%,-56%) scale(1.03); }
}

/* closing line */
.faq-close { font-size: 19px; line-height: 1.5; color: #3a352f; max-width: 52ch; margin: 0 auto; font-style: italic; }

/* ---- responsive ---- */
@media (max-width: 900px) {
  .faq-grid { grid-template-columns: 1fr; gap: 18px; }
  .faq-card:nth-child(even) { margin-top: 0; }
  .faq-card__face { min-height: 0; padding: 26px 24px; }
  .faq-card__q { font-size: 21px; }
}

/* reduced motion: no 3D spin, just a clean cross-fade reveal */
@media (prefers-reduced-motion: reduce) {
  .faq-card__inner { transform: none !important; }
  .faq-card.is-open .faq-card__inner { transform: none !important; }
  .faq-card__face { backface-visibility: visible; }
  .faq-card__face--a {
    transform: none; opacity: 0; visibility: hidden;
    transition: opacity .2s ease;
  }
  .faq-card.is-open .faq-card__face--q { opacity: 0; visibility: hidden; }
  .faq-card.is-open .faq-card__face--a { opacity: 1; visibility: visible; }
  .faq-card[data-reveal] { opacity: 1; transform: none; }
}

/* ============================================================
   HOME CURSOR THEATRE  ·  quill-and-ink cursor (js/ink-cursor.js)
   An oxblood ink dot with a lagging hairline ring, a fading
   calligraphic trail on a canvas, script labels over the
   directory cards, and pluckable hairline rules between
   sections. Desktop fine-pointer only; the JS gates itself on
   pointer, width and reduced motion, and stands down while the
   intro game or a popup owns the screen.
   ============================================================ */
/* native cursor steps aside only while the ink cursor is armed */
@media (hover: hover) and (pointer: fine) and (min-width: 880px) {
  body.home.ink-on, body.home.ink-on * { cursor: none !important; }
}

/* ============================================================
   HOME CURSOR  ·  the burgundy cross
   Two delicate oxblood lines crossing, on a soft cream backing
   so they read over both the pale paper and the dark hero art.
   Hotspot sits dead centre of the 32px art, at 16 16. Applied
   over the whole page, links and buttons included, so the cross
   never breaks character. Mouse-driven pointers only; touch and
   coarse pointers never see a cursor.
   ============================================================ */
@media (hover: hover) and (pointer: fine) {
  body.home, body.home * {
    cursor: url('../assets/home-cursor-target.png') 16 16, crosshair !important;
    cursor: image-set(
      url('../assets/home-cursor-target.png') 1x,
      url('../assets/home-cursor-target@2x.png') 2x
    ) 16 16, crosshair !important;
  }
}

.ink-dot, .ink-ring {
  position: fixed; left: 0; top: 0; pointer-events: none;
  will-change: transform;
}
.ink-dot {
  z-index: 2002; width: 7px; height: 7px; border-radius: 50%;
  background: var(--blue); mix-blend-mode: multiply;
  transition: opacity .25s ease, scale .25s ease, background-color .25s ease;
}
.ink-ring {
  z-index: 2001; width: 34px; height: 34px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--blue) 55%, transparent);
  mix-blend-mode: multiply;
  display: flex; align-items: center; justify-content: center;
  transition: width .28s cubic-bezier(.2,.7,.3,1), height .28s cubic-bezier(.2,.7,.3,1),
              background-color .28s ease, border-color .28s ease, opacity .25s ease;
}
.ink-ring.is-hover { width: 48px; height: 48px;
  border-color: color-mix(in srgb, var(--blue) 85%, transparent); }
/* over a directory card the ring becomes a small oxblood plaque
   with a script word; the dot tucks away beneath it */
.ink-ring.is-label { width: 96px; height: 42px;
  background: var(--blue); border-color: transparent; mix-blend-mode: normal; }
.ink-dot.is-label { opacity: 0; }
.ink-ring__label {
  font-family: var(--script); font-size: 22px; line-height: 1; color: var(--cream);
  opacity: 0; transition: opacity .18s ease .08s; white-space: nowrap;
}
.ink-ring.is-label .ink-ring__label { opacity: 1; }
/* the dark footer flips the ink to cream so it stays visible */
.ink-dot.is-bright { background: var(--cream); mix-blend-mode: normal; }
.ink-ring.is-bright { border-color: rgba(247,244,233,.75); mix-blend-mode: normal; }
.ink-dot.is-off, .ink-ring.is-off { opacity: 0; }

.ink-canvas {
  position: fixed; inset: 0; z-index: 1995; pointer-events: none;
  width: 100vw; height: 100vh;
}

/* hairline dividers between home sections; static 1px rules that the
   JS upgrades into pluckable sprung lines (svg path) on desktop */
.home-rule { max-width: var(--maxw); margin: 56px auto 0; padding: 0 24px; height: 56px; }
.home-rule::before { content: ""; display: block; height: 1px; margin-top: 27px;
  background: color-mix(in srgb, var(--blue) 28%, transparent); }
.home-rule.is-live::before { display: none; }
.home-rule svg { display: block; width: 100%; height: 100%; overflow: visible; }
.home-rule path { fill: none; stroke: color-mix(in srgb, var(--blue) 40%, transparent);
  stroke-width: 1; }

@media (max-width: 879.98px), (hover: none), (pointer: coarse) {
  .ink-dot, .ink-ring, .ink-canvas { display: none !important; }
}
@media (prefers-reduced-motion: reduce) {
  .ink-dot, .ink-ring, .ink-canvas { display: none !important; }
}

/* ============================================================
   THE LEDGER (proof.html) - aged gold-ink theme, one repeating
   entry rhythm, evidence band, gallery + lightbox.
   ============================================================ */
body.ledger {
  --blue:      #6e5418;   /* aged ledger-ink gold */
  --blue-deep: #57420f;
}

/* --- section kicker with index numeral (a quiet WELL-style rail) --- */
.led-kicker { display: flex; align-items: baseline; gap: 14px; margin-bottom: 4px; }
.led-kicker .idx { font-family: var(--script); color: var(--blue); font-size: 30px; line-height: 1; }
.led-kicker .lbl { font-size: 13px; letter-spacing: .22em; text-transform: uppercase; color: var(--muted); }
.led-kicker::after { content: ""; flex: 1 1 auto; align-self: center; height: 1px; background: linear-gradient(90deg, var(--rule), transparent); margin-left: 6px; }

/* --- market: what the great houses know --- */
.market-lede  { font-size: clamp(22px, 3vw, 32px); line-height: 1.28; max-width: 22ch; margin: 18px 0 0; }
.market-intro { color: #444; margin-top: 16px; max-width: 62ch; font-size: 16.5px; line-height: 1.55; }

.stat-band {
  display: grid; grid-template-columns: repeat(3, 1fr);
  border: 1px solid var(--rule); background: var(--cream); margin-top: 32px;
}
.stat-band .stat { padding: 26px 28px; border-left: 1px solid var(--rule); }
.stat-band .stat:first-child { border-left: 0; }
.stat-band .stat .fig { font-size: clamp(26px, 3.4vw, 38px); color: var(--blue); font-variant-numeric: tabular-nums; line-height: 1; }
.stat-band .stat .cap { font-size: 13px; color: var(--muted); margin-top: 11px; line-height: 1.45; }
@media (max-width: 760px) {
  .stat-band { grid-template-columns: 1fr; }
  .stat-band .stat { border-left: 0; border-top: 1px solid var(--rule); }
  .stat-band .stat:first-child { border-top: 0; }
}

.ledger-claims {
  display: grid; grid-template-columns: repeat(2, 1fr); margin-top: 32px;
  border-top: 1px solid var(--rule); border-left: 1px solid var(--rule);
}
.ledger-claim { border-right: 1px solid var(--rule); border-bottom: 1px solid var(--rule); padding: 22px 26px; }
.ledger-claim h3, .ledger-claim h4 { font-weight: 400; font-size: 12px; letter-spacing: .18em; text-transform: uppercase; color: var(--blue); margin: 0 0 9px; }
.ledger-claim p { font-size: 15px; color: #444; line-height: 1.5; margin: 0; }
@media (max-width: 600px) { .ledger-claims { grid-template-columns: 1fr; } }

/* --- the entry: one shape, repeated --- */
.ledger-entry {
  position: relative;
  border: 1px solid var(--rule); background: var(--cream);
  padding: clamp(24px, 3vw, 40px); margin-top: 22px;
}
.ledger-entry:first-of-type { margin-top: 6px; }
/* fine-press fillet: a faint inner rule, the way a mounted print is double-framed */
.ledger-entry::after { content: ""; position: absolute; inset: 7px; border: 1px solid var(--rule); opacity: .5; pointer-events: none; }
.ledger-entry__head {
  display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap;
  border-bottom: 1px solid var(--rule); padding-bottom: 18px; margin-bottom: 26px;
}
.ledger-entry__no { font-family: var(--script); color: var(--blue); font-size: 42px; line-height: .7; }
.ledger-entry__name { font-size: clamp(20px, 2.4vw, 26px); font-weight: 400; letter-spacing: .01em; margin: 0; }
.ledger-entry__place { color: var(--muted); font-style: italic; font-size: 15px; }
.ledger-chips { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; align-self: center; }
.chip {
  font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
  padding: 5px 13px; border-radius: 999px; border: 1px solid var(--rule);
  color: #555; background: #fff; white-space: nowrap;
}
.chip--awarded { background: var(--blue); border-color: var(--blue); color: #fff; }
.chip--soon    { background: transparent; color: var(--blue); border-color: var(--blue); }

.ledger-entry__main { display: grid; grid-template-columns: auto 1fr; gap: clamp(28px, 4vw, 56px); align-items: start; }
@media (max-width: 820px) { .ledger-entry__main { grid-template-columns: 1fr; gap: 28px; } }

/* --- matted archival plate (shared: feature media + gallery thumbs) --- */
.plate-mat {
  display: inline-block; position: relative; background: #fff; padding: 9px;
  border: 1px solid var(--rule); box-shadow: 0 1px 0 rgba(40, 32, 12, .03);
  transition: transform .55s cubic-bezier(.2, .7, .2, 1), box-shadow .55s ease;
}
.plate-mat .shot { display: block; overflow: hidden; border: 1px solid rgba(110, 84, 24, .24); background: #faf8f1; }
.plate-mat .shot img, .plate-mat .shot video { display: block; }
/* engraved viewfinder corners, revealed on interaction */
.plate-mat::before, .plate-mat::after {
  content: ""; position: absolute; width: 11px; height: 11px;
  opacity: 0; transition: opacity .35s ease; pointer-events: none;
}
.plate-mat::after  { top: 5px; right: 5px; border-top: 1px solid var(--blue); border-right: 1px solid var(--blue); }
.plate-mat::before { bottom: 5px; left: 5px; border-bottom: 1px solid var(--blue); border-left: 1px solid var(--blue); }

/* feature media: a single contained plate, modest (no crop) */
.ledger-media { margin: 0; }
.ledger-media .plate-mat { max-width: 100%; }
.ledger-media .shot img, .ledger-media .shot video { width: auto; max-width: 100%; height: 250px; margin: 0 auto; }
@media (max-width: 820px) { .ledger-media .shot img, .ledger-media .shot video { height: auto; max-height: 280px; width: 100%; object-fit: contain; } }
.ledger-media figcaption { font-size: 12.5px; color: var(--muted); font-style: italic; margin-top: 10px; max-width: 30ch; line-height: 1.45; }

.ledger-lede { color: #444; font-size: 16.5px; line-height: 1.55; margin: 0; }
.ledger-list { list-style: none; margin: 18px 0 0; padding: 0; }
.ledger-list li {
  display: flex; justify-content: space-between; gap: 18px;
  padding: 10px 0; border-bottom: 1px dashed var(--rule); font-size: 15px; color: #333;
}
.ledger-list li .cost { white-space: nowrap; color: var(--blue); font-variant-numeric: tabular-nums; }
.ledger-total {
  display: flex; justify-content: space-between; gap: 18px;
  padding: 14px 0 0; font-size: 16px; letter-spacing: .02em;
}
.ledger-total .cost { color: var(--blue); font-weight: 600; font-variant-numeric: tabular-nums; }
.ledger-note { font-size: 13.5px; color: var(--muted); font-style: italic; margin-top: 16px; max-width: 56ch; }

/* --- gallery: a matted contact sheet; each plate lifts to a lightbox --- */
.ledger-gallery {
  margin-top: clamp(26px, 3vw, 38px);
  display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 16px;
}
.ledger-gallery__head {
  grid-column: 1 / -1; display: flex; justify-content: space-between; align-items: baseline;
  font-size: 11.5px; letter-spacing: .2em; text-transform: uppercase; color: var(--muted);
  border-top: 1px solid var(--rule); padding-top: 18px; margin-bottom: 2px;
}
.ledger-gallery__head .led-ornament { color: var(--blue); }
.lg-item { display: block; cursor: pointer; outline: none; }
.lg-item .plate-mat { display: block; padding: 7px; }
.lg-item .shot img { width: 100%; height: 104px; object-fit: cover; transition: transform .9s cubic-bezier(.2, .7, .2, 1); }
.lg-item:hover .plate-mat, .lg-item:focus-visible .plate-mat {
  transform: translateY(-4px); box-shadow: 0 14px 28px -16px rgba(40, 32, 12, .5);
}
.lg-item:hover .plate-mat::before, .lg-item:hover .plate-mat::after,
.lg-item:focus-visible .plate-mat::before, .lg-item:focus-visible .plate-mat::after { opacity: .85; }
.lg-item:hover .shot img, .lg-item:focus-visible .shot img { transform: scale(1.04); }

/* --- reserved entries: same shell, an awaiting plate where the ledger goes --- */
.ledger-entry--reserved .ledger-entry__main { grid-template-columns: 1fr; }
.ledger-await {
  margin-top: 20px; border-left: 3px solid var(--blue); background: var(--cream-2);
  padding: 15px 20px; color: var(--blue-deep); font-style: italic; font-size: 14.5px;
  letter-spacing: .02em;
}

.led-callout { margin-top: 34px; }
.led-pull { font-size: clamp(22px, 3vw, 28px); line-height: 1.25; display: block; }

/* awards strip (still used on about.html) */
.awards-strip {
  display: flex; align-items: center; justify-content: center; gap: 60px; flex-wrap: wrap;
  border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
  padding: 36px 20px; margin-top: 14px;
}
.award { display: flex; align-items: center; gap: 20px; }
.award img { width: 88px; height: 88px; border-radius: 50%; display: block; }
.award-name { font-size: 16px; letter-spacing: .03em; color: #2a2a2a; }
.award-sub { font-size: 11.5px; color: var(--muted); letter-spacing: .22em; text-transform: uppercase; margin-top: 5px; }

/* --- lightbox: a plate lifted under glass (built by js/ledger.js) --- */
.lightbox {
  position: fixed; inset: 0; z-index: 1000; display: flex;
  align-items: center; justify-content: center; padding: 6vh 6vw;
  background: radial-gradient(125% 125% at 50% 28%, rgba(34, 27, 11, .9), rgba(11, 8, 3, .96));
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .45s ease, visibility .45s ease;
}
.lightbox.open { opacity: 1; visibility: visible; pointer-events: auto; }
.lightbox__stage {
  margin: 0; max-width: 720px; max-height: 86vh; display: flex; flex-direction: column; align-items: center;
  transform: scale(.965); transition: transform .55s cubic-bezier(.2, .7, .2, 1);
}
.lightbox.open .lightbox__stage { transform: none; }
.lightbox__img {
  max-width: 100%; max-height: 72vh; object-fit: contain; background: #0b0803;
  padding: 10px; border: 1px solid rgba(233, 226, 207, .22);
  box-shadow: 0 30px 70px -30px rgba(0, 0, 0, .8);
}
.lightbox__cap { color: #e9e2cf; font-style: italic; font-size: 14.5px; margin-top: 20px; text-align: center; max-width: 56ch; line-height: 1.5; }
.lightbox__cap::before { content: ""; display: block; width: 32px; height: 1px; background: rgba(233, 226, 207, .42); margin: 0 auto 14px; }
.lightbox__count { color: #b9ad8c; font-size: 11px; letter-spacing: .3em; text-transform: uppercase; margin-top: 12px; text-align: center; }
.lightbox__count:empty { display: none; }
.lightbox__count::before { content: "Plate "; }
.lightbox__btn {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 64px; height: 64px; border: 0; background: none; color: #cdbf9c;
  font-size: 38px; line-height: 1; cursor: pointer; display: grid; place-items: center;
  transition: color .3s ease, transform .3s cubic-bezier(.2, .7, .2, 1);
}
.lightbox__btn:hover { color: #fff; }
.lightbox__prev { left: max(8px, 2vw); }
.lightbox__next { right: max(8px, 2vw); }
.lightbox__prev:hover { transform: translateY(-50%) translateX(-4px); }
.lightbox__next:hover { transform: translateY(-50%) translateX(4px); }
.lightbox__close {
  position: absolute; top: max(16px, 3vh); right: max(16px, 3vw);
  width: 46px; height: 46px; border: 0; background: none; color: #b9ad8c;
  font-size: 30px; line-height: 1; cursor: pointer; transition: color .3s ease, transform .3s ease;
}
.lightbox__close:hover { color: #fff; transform: rotate(90deg); }
@media (max-width: 600px) { .lightbox__btn { width: 48px; height: 48px; font-size: 30px; } }

/* About: portrait plate + pinch animation */
.ab-plate {
  display: inline-block; background: #fff;
  border: 1px solid var(--blue); padding: 16px;
  width: 360px; max-width: 100%; margin: 0 auto;
}
.ab-plate img {
  display: block; width: 100%;
  border: 1px solid rgba(47, 62, 143, .28);
}
.ab-pinch { display: block; width: 100%; max-width: 380px; margin: 0 auto; }

/* ============================================================================
   THE LEDGER - card-canvas (proof.html)
   An infinite drag-to-explore field of cards over window.png. The motion lives
   in js/proof.js; this is the look (matted gold plates, 3D flip) and the
   no-JS / touch / reduced-motion fallback to a plain readable grid.
   ============================================================================ */

/* keep-scrolling hint under the hero numbers */
.proof-lead { text-align: center; margin-top: 30px; }
.proof-scrollhint {
  display: inline-flex; flex-direction: column; align-items: center; gap: 9px;
  font-size: 12.5px; letter-spacing: .2em; text-transform: uppercase; color: var(--muted);
}
.proof-scrollhint .ph-arrow {
  width: 22px; height: 22px; border-right: 1px solid var(--blue); border-bottom: 1px solid var(--blue);
  transform: rotate(45deg); animation: phBob 2.4s ease-in-out infinite;
}
@keyframes phBob { 0%,100% { transform: rotate(45deg) translate(0,0); opacity:.5 } 50% { transform: rotate(45deg) translate(3px,3px); opacity:1 } }

/* ---- the stage ---- */
.proof-canvas {
  position: relative; margin-top: clamp(28px, 4vw, 52px);
  border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
  background: var(--cream);
  isolation: isolate;
}
.proof-bg {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: url('../assets/window.webp') center/cover no-repeat;
  opacity: .16;
}
.proof-bg::after {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(120% 80% at 50% 38%, rgba(247,244,233,0) 40%, rgba(247,244,233,.9) 100%),
    linear-gradient(var(--cream), transparent 18%, transparent 82%, var(--cream));
}

/* ---- default (no JS / touch / reduced-motion): a quiet readable grid ---- */
.proof-plane {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(248px, 1fr));
  gap: clamp(20px, 2.4vw, 34px);
  max-width: var(--maxw); margin: 0 auto;
  padding: clamp(34px, 5vw, 72px) clamp(18px, 4vw, 40px);
}

/* ---- canvas mode (desktop): full-viewport draggable field ---- */
.proof-canvas.is-canvas { height: 100vh; min-height: 620px; overflow: hidden; cursor: grab; touch-action: none; -webkit-user-select: none; user-select: none; }
.proof-canvas.is-canvas .pcard__shot img, .proof-canvas.is-canvas .pcard__shot video { -webkit-user-drag: none; user-drag: none; pointer-events: none; }
.proof-canvas.is-canvas.is-grabbing { cursor: grabbing; }
.proof-canvas.is-canvas .proof-plane {
  position: absolute; inset: 0; display: block; max-width: none; margin: 0; padding: 0;
}
.proof-canvas.is-canvas .pcard { margin: 0; }

/* ---- the card ---- */
.pcard {
  position: relative; width: 100%; height: 392px; perspective: 1400px;
  background: none; border: 0; outline: none;
}
.proof-canvas.is-canvas .pcard { width: 290px; height: 392px; }

.pcard__inner {
  position: relative; width: 100%; height: 100%;
  transform-style: preserve-3d;
  transition: transform .62s cubic-bezier(.2,.7,.2,1);
}
.pcard__face {
  position: absolute; inset: 0; -webkit-backface-visibility: hidden; backface-visibility: hidden;
  display: flex; flex-direction: column; overflow: hidden;
  background: #fffdf7;
  border: 1px solid var(--rule);
  box-shadow: 0 1px 0 rgba(40,32,12,.04), 0 18px 34px -28px rgba(40,32,12,.5);
  transition: box-shadow .5s ease;
}
/* fine-press double frame: a faint inner gold fillet */
.pcard__face::before {
  content: ""; position: absolute; inset: 7px; border: 1px solid rgba(110,84,24,.30);
  pointer-events: none; z-index: 2;
}
/* engraved viewfinder corners, revealed when the card lifts */
.pcard__face::after {
  content: ""; position: absolute; top: 11px; right: 11px; width: 12px; height: 12px;
  border-top: 1px solid var(--blue); border-right: 1px solid var(--blue);
  opacity: 0; transition: opacity .4s ease; z-index: 2;
}
.pcard__back { transform: rotateY(180deg); }

/* flip: hover in grid fallback, .is-flipped in canvas mode.
   :focus-visible is kept in its OWN rule so that, on engines that don't know the
   pseudo-class, it can't invalidate the whole selector list and kill the flip. */
.proof-canvas:not(.is-canvas) .pcard:hover .pcard__inner,
.pcard.is-flipped .pcard__inner { transform: rotateY(180deg); }
.pcard:focus-visible .pcard__inner { transform: rotateY(180deg); }
.pcard.is-flipped .pcard__face,
.proof-canvas:not(.is-canvas) .pcard:hover .pcard__face {
  box-shadow: 0 1px 0 rgba(40,32,12,.04), 0 40px 60px -34px rgba(40,32,12,.62);
}
.pcard.is-flipped .pcard__face::after { opacity: 1; }

/* ---- FRONT: image card (SET A) ---- */
.pcard__shot {
  position: relative; flex: 1 1 auto; margin: 9px 9px 0; overflow: hidden;
  border: 1px solid rgba(110,84,24,.22); background: #f3efe4;
}
.pcard__shot img, .pcard__shot video {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.pcard__shot--placeholder {
  display: flex; align-items: center; justify-content: center; text-align: center;
  background:
    repeating-linear-gradient(45deg, rgba(110,84,24,.05) 0 9px, transparent 9px 18px),
    #f3efe4;
}
.pcard__shot--placeholder span {
  font-style: italic; color: var(--blue); font-size: 13px; letter-spacing: .04em; padding: 0 18px; line-height: 1.5;
}
.pcard__cap { padding: 13px 16px 16px; }

/* gold-leaf glint: a narrow sheen crosses the photograph when the plate is
   handled. Transform/opacity only, on a pseudo INSIDE the face (never a
   filter on the face itself - that would flatten the 3D flip), clipped by
   the shot's own overflow. */
.pcard__shot::after {
  content: ""; position: absolute; top: -20%; bottom: -20%; left: 0; width: 42%;
  background: linear-gradient(105deg, transparent 0%,
    rgba(212,175,55,.14) 42%, rgba(255,246,220,.30) 50%, rgba(212,175,55,.14) 58%, transparent 100%);
  transform: translateX(-130%); opacity: 0; pointer-events: none; z-index: 1;
  transition: transform .9s cubic-bezier(.3,.6,.3,1), opacity .35s ease;
}
@media (hover: hover) and (pointer: fine) {
  .pcard:hover .pcard__shot::after { transform: translateX(290%); opacity: 1; }
}

/* ---- FRONT: text card (SET B / SET C) - type IS the image ---- */
.pcard--text .pcard__front { justify-content: center; padding: 26px 22px; text-align: center; }
.pcard__display {
  font-family: var(--serif); color: var(--blue);
  font-size: clamp(38px, 4.4vw, 56px); line-height: .98; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
}
.pcard__display.is-name { font-size: clamp(26px, 2.8vw, 34px); line-height: 1.08; letter-spacing: .005em; }
.pcard__unit { display: block; margin-top: 12px; font-size: 12px; letter-spacing: .2em; text-transform: uppercase; color: var(--muted); }

/* shared front bits */
.pcard__kicker {
  font-size: 10.5px; letter-spacing: .2em; text-transform: uppercase; color: var(--muted);
  display: block; margin-bottom: 7px;
}
.pcard--text .pcard__kicker { position: absolute; top: 18px; left: 0; right: 0; text-align: center; }
.pcard__star { color: var(--blue); }
.pcard__title { font-family: var(--serif); font-weight: 400; font-size: 19px; line-height: 1.18; margin: 0; color: var(--ink); }
.pcard__hook { margin: 9px 0 0; font-size: 13px; line-height: 1.5; color: #555; }
.pcard--text .pcard__hook { margin-top: 16px; max-width: 30ch; margin-left: auto; margin-right: auto; }

/* ---- BACK ---- */
.pcard__back { background: var(--cream); }
.pcard__backscroll {
  position: absolute; inset: 9px; padding: 16px 16px 14px; overflow: auto;
  display: flex; flex-direction: column; gap: 9px;
}
.pcard__backscroll::-webkit-scrollbar { width: 5px; }
.pcard__backscroll::-webkit-scrollbar-thumb { background: rgba(110,84,24,.35); border-radius: 4px; }
.pcard__btitle { font-family: var(--serif); font-weight: 400; font-size: 15.5px; margin: 0 0 2px; color: var(--blue); letter-spacing: .02em; }
.pcard__body { font-size: 12.5px; line-height: 1.5; color: #3a3a3a; margin: 0; }
.pcard__split { margin: 2px 0 0; display: flex; flex-direction: column; gap: 7px; }
.pcard__split > div { }
.pcard__split dt { font-size: 9.5px; letter-spacing: .18em; text-transform: uppercase; color: var(--blue); margin-bottom: 2px; }
.pcard__split dd { margin: 0; font-size: 12px; line-height: 1.45; color: #3a3a3a; }
.pcard__foot { margin-top: auto; padding-top: 9px; border-top: 1px solid var(--rule); display: flex; flex-direction: column; gap: 5px; }
.pcard__cost { font-size: 12.5px; color: var(--blue); font-variant-numeric: tabular-nums; }
.pcard__src { font-size: 10.5px; font-style: italic; color: var(--muted); line-height: 1.4; }

/* ---- drag hint ---- */
.proof-hint {
  position: absolute; left: 50%; bottom: 26px; transform: translateX(-50%); z-index: 5;
  display: none; align-items: center; gap: 11px; pointer-events: none;
  font-size: 11.5px; letter-spacing: .24em; text-transform: uppercase; color: var(--blue);
  background: rgba(255,253,247,.78); border: 1px solid var(--rule); padding: 9px 18px; border-radius: 999px;
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  transition: opacity .6s ease;
}
.proof-canvas.is-canvas .proof-hint { display: inline-flex; }
.proof-canvas.explored .proof-hint { opacity: 0; }
.proof-hint .ph-hand { font-size: 14px; letter-spacing: 0; }

@media (prefers-reduced-motion: reduce) {
  .pcard__inner { transition: none; }
  .proof-scrollhint .ph-arrow { animation: none; }
}

/* ============================================================================
   THE LEDGER card-field - WebGL (proof.js) + dark theme + click-through detail
   Overrides the earlier light card-canvas block. The cards you SEE in WebGL are
   drawn in proof.js; the .pcard DOM stays for SEO + the detail panel + fallback.
   ============================================================================ */
.proof-canvas { background: var(--cream); border-color: transparent; }

/* the GL canvas */
.proof-gl { position: absolute; inset: 0; width: 100% !important; height: 100% !important; display: block; z-index: 0; touch-action: none; }
.proof-canvas.has-webgl { height: 100vh; min-height: 600px; overflow: hidden; cursor: url('../assets/proof-cursor-open.png') 11 33, grab; -webkit-user-select: none; user-select: none; }
.proof-canvas.has-webgl.is-grabbing { cursor: url('../assets/proof-cursor-grab.png') 14 33, grabbing; }
/* during the load (armed, engine booting but not yet revealed) keep a normal cursor -
   the engraved glove only belongs to the live, draggable world */
html.proof-armed .proof-canvas:not(.proof-ready) { cursor: default; }
.proof-canvas.has-webgl .proof-plane { position: absolute; inset: 0; display: block; opacity: 0; pointer-events: none; }
.proof-canvas.has-webgl .proof-bg { display: none; }
/* (the old cream top-fade lived here; in the full-bleed layout the world now
   reaches the top edge and the legibility veil moved onto the fixed nav below) */

/* drag hint over the beige field */
.proof-canvas.has-webgl .proof-hint {
  display: inline-flex; z-index: 5; color: var(--blue);
  background: rgba(255,253,247,.82); border-color: rgba(110,84,24,.26);
}
.proof-canvas.explored .proof-hint { opacity: 0; }
/* the drag hint steps aside while a card is held in spatial focus */
.proof-canvas.is-focused .proof-hint { opacity: 0; }

/* ---- static fallback (no WebGL / reduced-motion / mobile): light cards ---- */
.proof-canvas:not(.has-webgl) .proof-bg {
  background: url('../assets/globe.webp') center/contain no-repeat; opacity: .22;
}

/* ============================================================================
   Proof: SINGLE-SCREEN spherical world. nav + "Proof / The Ledger" + the canvas,
   no footer, no page scroll. The world fills everything under the title.
   ============================================================================ */
body.proof-page { background: var(--cream); }

/* the only words on the page */
.proof-title { text-align: center; padding: clamp(12px,2.2vw,24px) 24px clamp(6px,1.2vw,12px); }
.proof-badge { display: block; font-size: 12px; letter-spacing: .24em; text-transform: uppercase; color: var(--blue); margin-bottom: 3px; }
.proof-h1 { font-family: var(--script); color: var(--blue); font-weight: 400; font-size: clamp(40px,6vw,84px); line-height: .86; margin: 0; }

/* PROOF PAGE: the stage is the immersion. In the fallback (no WebGL / reduced
   motion) the nav stays a quiet cream bar above the scrolling grid; the corner
   logo carries the only words: "The Proof / The Ledger". */
.proof-page .sitenav {
  background: var(--cream);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  border-bottom: 0;
}
.proof-page .sitenav .logo .small { color: var(--blue); }
.proof-page .proof-canvas { border-top: 0; border-bottom: 0; }

/* ============================================================================
   FULL-BLEED IMMERSION (WebGL live). The whole viewport is one continuous
   spatial environment: the canvas fills 100% w/h and travels behind the nav.
   The nav is a fixed, transparent interface layer floating over the world.
   Gated on .has-webgl so the no-WebGL fallback keeps a normal scrolling
   document with a readable in-flow nav.
   ============================================================================ */
html:has(.proof-canvas.has-webgl) { height: 100%; }
body.proof-page:has(.proof-canvas.has-webgl) {
  height: 100vh; height: 100dvh; overflow: hidden;
}

/* 1 · the canvas IS the viewport - fixed, full-bleed, behind everything */
body.proof-page:has(.proof-canvas.has-webgl) .proof-canvas.has-webgl {
  position: fixed; inset: 0; z-index: 0;
  width: 100vw; height: 100vh; height: 100dvh;
  min-height: 0; margin: 0;
}

/* 2 · the nav floats as a fixed, transparent layer over the world */
body.proof-page:has(.proof-canvas.has-webgl) .sitenav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  background: transparent;
  padding-top: clamp(18px, 2.4vw, 28px);
}
/* soft top veil: cards still travel visibly behind the nav, but they fade a
   full step under it so the wordmark + links always win. Strengthened from the
   original (.80 peak) after Natalie's note that the nav "disappeared" once the
   sphere loaded: near-solid at the very top, dissolving to nothing by ~170px. */
body.proof-page:has(.proof-canvas.has-webgl) .sitenav::before {
  content: ""; position: absolute; inset: 0 0 auto 0;
  height: clamp(120px, 17vh, 176px);
  background: linear-gradient(to bottom,
    rgba(247,244,233,.95) 0%,
    rgba(247,244,233,.84) 32%,
    rgba(247,244,233,.46) 64%,
    rgba(247,244,233,0) 100%);
  pointer-events: none; z-index: -1;
}
/* kill the hairline divider: on mobile the COLLAPSED .links menu (max-height:0)
   still paints its border-bottom as a 1px rule across the full width under the
   transparent nav. On the full-bleed proof page the chrome must dissolve into
   the world with no dividing line, so drop that border (open + closed). */
body.proof-page:has(.proof-canvas.has-webgl) .sitenav .links { border-bottom: 0; }

/* 3 · lighten the chrome into a floating interface (desktop): text links,
   not heavy pills; only the primary action keeps a solid plate. Mobile keeps
   its own white dropdown panel + tap targets, so this is desktop-only. */
@media (min-width: 861px) {
  body.proof-page:has(.proof-canvas.has-webgl) .sitenav .links a {
    background: none; border-color: transparent; color: var(--ink);
    padding: 7px 13px;
  }
  body.proof-page:has(.proof-canvas.has-webgl) .sitenav .links a:hover {
    background: none; color: var(--blue);
  }
  body.proof-page:has(.proof-canvas.has-webgl) .sitenav .links a.cta {
    background: var(--blue); border: 1px solid var(--blue); color: #fff;
    border-radius: 999px; padding: 7px 18px;
  }
  body.proof-page:has(.proof-canvas.has-webgl) .sitenav .links a.cta:hover {
    background: var(--blue-deep); color: #fff;
  }
}
/* language switch + mobile toggle: a faint gold hairline, not a hard pill */
body.proof-page:has(.proof-canvas.has-webgl) .lang-switch,
body.proof-page:has(.proof-canvas.has-webgl) .nav-toggle {
  border-color: rgba(110,84,24,.30);
}

/* ============================================================================
   PRE-BOOT (WebGL armed). A synchronous <head> check adds html.proof-armed the
   instant the page parses, BEFORE proof.js has fetched + booted. This holds the
   warm cream stage full-bleed from the first paint - so the readable fallback
   grid never flashes, and there's no layout jump when the canvas takes over
   (the canvas inherits the exact same fixed full-bleed box). The .pcard grid
   stays in the DOM at opacity 0 so proof.js can still read it into textures.
   If the engine fails, proof.js removes .proof-armed and the grid reveals.
   ============================================================================ */
html.proof-armed, html.proof-armed body.proof-page { height: 100%; }
html.proof-armed body.proof-page { height: 100dvh; overflow: hidden; }
html.proof-armed .proof-canvas {
  position: fixed; inset: 0; z-index: 0;
  width: 100vw; height: 100vh; height: 100dvh;
  min-height: 0; margin: 0; border: 0; overflow: hidden;
  /* warm paper: a soft vignette that lifts the orb off the page, matching the GL
     backdrop's paper vignette so the hand-off is seamless. (Cheap gradient only - a
     full-viewport SVG grain filter here was repainting every frame and wrecked LCP/SI.) */
  background:
    radial-gradient(130% 100% at 50% 44%, rgba(110,84,24,0) 50%, rgba(110,84,24,.06) 100%),
    var(--cream);
}
/* The readable grid is the static globe's understudy: when the WebGL world is armed
   it is never shown (the globe replaces it), but it must stay in the DOM for SEO and
   so the engine can read each card into a texture. content-visibility:hidden keeps it
   in the DOM yet skips its render + layout entirely, so 21 perspective cards (each with
   3D faces, shadows and a lazy image) never cost the initial paint. */
html.proof-armed .proof-plane { position: absolute; inset: 0; display: block; opacity: 0; pointer-events: none; content-visibility: hidden; }
html.proof-armed .proof-bg { display: none; }
html.proof-armed .sitenav { position: fixed; top: 0; left: 0; right: 0; z-index: 50; background: transparent; }

/* Instant placeholder: the same globe art, painted from the already-preloaded
   globe2.avif (~64KB) the moment the page parses - so the hero is never a blank
   cream panel during the ~200KB WebGL boot. A pseudo-element paints UNDER the
   canvas (which proof.js inserts as the first child); the live GL world fades in
   over it and, once opaque, fully covers it. Fades out on .proof-ready as a clean
   cross-fade into the real globe. */
html.proof-armed .proof-canvas::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  /* The warm globe, pre-BAKED onto cream (globe2 x cream paper, baked once with sharp):
     the white field melts into the page and the lines read as warm ink - engraving on
     paper, not clip-art on white. A plain image (NO runtime mix-blend-mode: a live blend
     here got re-computed over the whole viewport on every animation frame and wrecked the
     score). A radial cream wash dissolves the square edges into a soft floating orb. */
  background:
    radial-gradient(circle at 50% 47%, rgba(247,244,233,0) 30%, var(--cream) 64%),
    url('../assets/globe2-warm.avif') center / auto min(76vh, 740px) no-repeat;
  opacity: .92;
  transition: opacity .6s ease;
}
html.proof-armed .proof-canvas.proof-ready::before { opacity: 0; }

/* The loading cue: a single soft gold gleam that slowly orbits the orb's rim, like a
   point of light travelling a meridian - bespoke + on-brand, and CHEAP (only a ~12px
   element composites; the orbit is one rotate transform around the globe centre, so
   nothing large repaints). Shown the whole armed-but-not-yet-live window, fading out as
   the live globe paints. */
html.proof-armed .proof-canvas::after {
  content: ""; position: absolute; left: 50%; top: 50%; z-index: 2; pointer-events: none;
  width: 12px; height: 12px; margin: -6px 0 0 -6px; border-radius: 50%;
  background: radial-gradient(circle, var(--blue) 0%, rgba(110,84,24,.55) 35%, rgba(110,84,24,0) 72%);
  opacity: 0; will-change: transform; transform: translateZ(0);
  animation: proofOrbit 3.8s linear infinite, proofOrbitIn 1s ease .3s forwards;
}
html.proof-armed .proof-canvas.proof-ready::after { animation: none; opacity: 0; transition: opacity .5s ease; }
/* Pure GPU-compositable orbit: ONLY rotate animates; the radius is a constant
   translate (no calc()/min(), which kept the browser from compositing this and pinned
   it to the main thread - so every boot/bake task froze the point). Now nothing on the
   main thread can stutter it. -37vh ~ the globe rim on a typical desktop. */
@keyframes proofOrbit {
  from { transform: rotate(0deg)   translateY(-37vh); }
  to   { transform: rotate(360deg) translateY(-37vh); }
}
@keyframes proofOrbitIn { to { opacity: .92; } }

/* Show the editorial drag invitation during the pre-boot window too (it is normally
   gated to the live canvas), so the load state reads as a composed hero, not a bare orb. */
html.proof-armed .proof-canvas .proof-hint { display: inline-flex; }

@media (prefers-reduced-motion: reduce) {
  html.proof-armed .proof-canvas::after { animation: none; opacity: 0; }
}

/* The world fades up over the cream stage on its first painted frame, so the
   cards arrive softly instead of popping in. proof.js adds .proof-ready after
   the first render. (Cream-on-cream means there's no visible seam either way.) */
.proof-gl { opacity: 0; transition: opacity .55s ease; }
.proof-canvas.proof-ready .proof-gl { opacity: 1; }

/* ---- click-through detail panel (the card "back" content) ---- */
.pcard-detail { position: fixed; inset: 0; z-index: 1200; display: none; }
.pcard-detail.is-open { display: block; }
.pcard-detail__scrim { position: absolute; inset: 0; background: rgba(6,6,9,.80); -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px); animation: pdFade .4s ease; }
.pcard-detail__card {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
  width: min(560px, 92vw); max-height: 84vh; overflow: auto;
  background: #0e0e13; border: 1px solid #2a2a33; padding: 36px 38px 30px;
  box-shadow: 0 50px 120px -44px #000; animation: pdRise .5s cubic-bezier(.2,.7,.2,1);
}
.pcard-detail__card::before { content: ""; position: absolute; inset: 8px; border: 1px solid rgba(205,168,90,.26); pointer-events: none; }
.pcard-detail__card .pcard__btitle { font-family: var(--serif); font-weight: 400; color: #cda85a; font-size: 23px; margin: 0 0 14px; letter-spacing: .01em; }
.pcard-detail__card .pcard__body { font-family: var(--serif); color: #d9d3c5; font-size: 16px; line-height: 1.62; margin: 0; }
.pcard-detail__card .pcard__foot { margin-top: 20px; padding-top: 14px; border-top: 1px solid #2a2a33; display: flex; flex-direction: column; gap: 6px; }
.pcard-detail__card .pcard__cost { color: #cda85a; font-size: 14px; font-variant-numeric: tabular-nums; }
.pcard-detail__card .pcard__src { color: #8c8576; font-size: 12px; font-style: italic; }
.pcard-detail__close {
  position: absolute; top: 12px; right: 16px; width: 40px; height: 40px; border: 0; background: none;
  color: #8c8576; font-size: 26px; line-height: 1; cursor: pointer; transition: color .3s ease, transform .3s ease; z-index: 2;
}
.pcard-detail__close:hover { color: #efe7d2; transform: rotate(90deg); }
@keyframes pdFade { from { opacity: 0 } to { opacity: 1 } }
@keyframes pdRise { from { opacity: 0; transform: translate(-50%,-46%) scale(.97) } to { opacity: 1; transform: translate(-50%,-50%) scale(1) } }

/* ============================================================
   Terms of Engagement - editorial "car" section (work.html)
   Full-bleed: the four principles on the left, the supplied
   car-and-street drawing printed into the right of the page.
   Medallion cards with no boxes; beige dissolves into the page.
   ============================================================ */
.terms { position: relative; overflow: hidden; padding: 76px 0 92px; }

/* the supplied illustration, faded into the page like a printed drawing */
.terms__art { position: absolute; top: 0; right: 0; bottom: 0; width: 46vw; z-index: 1; pointer-events: none; }
.terms__art img {
  position: absolute; right: 0; top: 76px; bottom: auto;
  width: 43.68vw; height: auto; max-width: none;
  filter: grayscale(1) contrast(.8) brightness(1.07);
  opacity: .5;
  -webkit-mask-image:
    linear-gradient(to left, #000 50%, transparent 100%),
    linear-gradient(to bottom, transparent 0%, #000 14%, #000 86%, transparent 100%);
  -webkit-mask-composite: source-in;
          mask-image:
    linear-gradient(to left, #000 50%, transparent 100%),
    linear-gradient(to bottom, transparent 0%, #000 14%, #000 86%, transparent 100%);
          mask-composite: intersect;
}

.terms__bd { position: relative; z-index: 2; max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }
.terms__col { max-width: 714px; margin-left: 0; }
.terms__label {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(22px, 3vw, 30px); letter-spacing: .2em;
  text-transform: uppercase; color: #2a2a2a;
}
.terms__rule { height: 1px; background: var(--rule); margin: 20px 0 36px; }

.terms__grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 30px 40px; }
.terms__card {
  position: relative; text-align: center; padding: 30px 24px 26px;
  background: radial-gradient(125% 105% at 50% 38%,
    rgba(239,233,216,.62) 0%, rgba(239,233,216,.34) 46%, rgba(239,233,216,0) 80%);
}
.terms__seal {
  position: relative; width: 62px; height: 62px; margin: 0 auto 16px;
  display: grid; place-items: center; border-radius: 50%;
  border: 1px solid var(--rule); background: rgba(247,244,233,.55);
}
.terms__seal::before { content: ""; position: absolute; inset: 5px; border-radius: 50%; border: 1px solid var(--rule); }
.terms__seal span { font-family: var(--script); color: var(--blue); font-size: 26px; line-height: 1; }
.terms__card h3 { font-size: 22px; font-weight: 400; margin: 0 0 12px; }
.terms__card p { color: #444; font-size: 15.5px; line-height: 1.6; }

/* stagger the reveal in step with the rest of the site */
.terms__grid > [data-reveal]:nth-child(2) { transition-delay: .08s; }
.terms__grid > [data-reveal]:nth-child(3) { transition-delay: .16s; }
.terms__grid > [data-reveal]:nth-child(4) { transition-delay: .24s; }

/* the seal's inner ring presses in a beat after its card lands, like a
   stamp meeting paper (rides the same [data-reveal] -> .in observer) */
.terms__card .terms__seal::before {
  transition: transform .7s cubic-bezier(.34,1.45,.44,1) .28s, opacity .45s ease .28s;
}
.terms__card[data-reveal]:not(.in) .terms__seal::before { transform: scale(.55); opacity: 0; }

/* the closing pull-quote hangs its opening quotation mark into the margin */
body.work .callout .pull { text-indent: -.45ch; }

/* tablet: ease the drawing back so the text keeps its air */
@media (max-width: 1100px) {
  .terms__art { width: 52vw; }
  .terms__art img { opacity: .42; }
  .terms__col { max-width: 630px; margin-left: 0; }
}
/* phones: the drawing stays, faded behind the stacked cards */
@media (max-width: 760px) {
  .terms { padding: 56px 0 64px; }
  .terms__art { width: 100%; left: 0; right: 0; }
  .terms__art img { height: auto; width: 150%; right: -22%; top: auto; bottom: 0; opacity: .13; }
  .terms__col { max-width: none; margin-left: 0; }
  .terms__grid { grid-template-columns: 1fr; gap: 6px; }
  .terms__card { padding: 22px 16px 18px; }
}

/* ============================================================
   FOOD AREA  ·  "Forbidden Fruit"
   Deep plum / mulberry accent override (mirrors body.supplements).
   Every component that reads var(--blue) repaints plum for free.
   ============================================================ */
body.forbidden {
  --blue:      #6B2A4F;   /* deep plum / mulberry replaces the blue accent */
  --blue-deep: #511f3b;
  --nogo:      #7C243E;   /* warm oxblood for cautions */
  --wash:      rgba(107,42,79,.08);
}
body.forbidden footer.site { background:#2a1020; }   /* dark mulberry sign-off */

/* ----- Forbidden Fruit (food principles) hero engraving: the cherry-pie plate
   drapes over the LEFT of the title, mirroring the Spelled Hand hero on the
   opposite side. Same top-layer, click-through, phone-hidden treatment. The
   .page-hero transform nudges the text AND becomes the figure's positioning
   context. Scoped with :not(.directory) so the food-swaps hero is untouched. ----- */
/* Shift the whole unit (title + plate) left so the hero reads centered: the
   plate bleeds off the right, so the pair needs a leftward nudge. Bounded +
   width-scaled so it is gentle on tablets and stronger on wide desktops. */
body.forbidden:not(.directory) .page-hero { position: relative; transform: translateX(clamp(-150px, calc(170px - 24vw), -26px)); max-width: var(--maxw); margin: 0 auto; }
body.forbidden:not(.directory) .page-hero h1 { font-size: clamp(50px, 8.6vw, 112px); }
body.forbidden .ff-fig { position: absolute; z-index: 80; pointer-events: none; user-select: none; height: auto; }
body.forbidden .ff-fig--hero { top: 40px; right: -34px; width: clamp(260px, 27vw, 360px);
  /* Soften the side edges into the page: fade the left 10% (the side facing the
     text) and the right 5%, for a smoother text-to-image connection. */
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 15%, #000 95%, transparent 100%);
          mask-image: linear-gradient(to right, transparent 0%, #000 15%, #000 95%, transparent 100%); }
@media (max-width: 820px){
  body.forbidden:not(.directory) .page-hero { transform: none; }
  body.forbidden .ff-fig { display: none; }
}

/* ============================================================
   VANITY AREA  ·  "The Vanity"
   Dusty rose / blush-clay accent override (mirrors body.forbidden).
   Every component that reads var(--blue) repaints rose for free.
   ============================================================ */
body.vanity {
  --blue:      #964B58;   /* deep dusty rose / blush clay replaces the blue accent */
  --blue-deep: #7a3b47;
  --nogo:      #7C243E;   /* warm oxblood for cautions */
  --wash:      rgba(150,75,88,.08);
}
body.vanity footer.site { background:#2e1218; }   /* deep rosewood sign-off */

/* ----- The Vanity (principles) hero engraving: the bathroom-counter line
   drawing drapes over the RIGHT of the title, mirroring the Spelled Hand /
   glasses treatment. Same top-layer, click-through, phone-hidden. The
   .page-hero transform nudges the text left AND becomes the figure's
   positioning context. Scoped :not(.directory) so the swaps hero is clean. ----- */
body.vanity:not(.directory) .page-hero { position: relative; transform: translateX(clamp(-120px, calc(120px - 17vw), -20px)); max-width: var(--maxw); margin: 0 auto; }
body.vanity:not(.directory) .page-hero h1 { font-size: clamp(50px, 8.6vw, 112px); }
body.vanity .vn-fig { position: absolute; z-index: 80; pointer-events: none; user-select: none; height: auto; }
body.vanity .vn-fig--hero { top: 18px; right: -34px; width: clamp(280px, 30vw, 404px);
  /* fade the left edge (the side facing the text) so the counter dissolves into the page */
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 20%, #000 96%, transparent 100%);
          mask-image: linear-gradient(to right, transparent 0%, #000 20%, #000 96%, transparent 100%); }
@media (max-width: 820px){
  body.vanity:not(.directory) .page-hero { transform: none; }
  body.vanity .vn-fig { display: none; }
}

/* ----- The Second Skin (clothing): a faded indigo / raw-denim accent,
   kept far from the other five areas' colours. Warm oxblood stays for
   cautions to match the site. ----- */
body.clothing {
  --blue:      #3E5C76;
  --blue-deep: #2f475d;
  --nogo:      #7C243E;
  --wash:      rgba(62,92,118,.08);
}
body.clothing footer.site { background:#14202e; }   /* deep indigo sign-off */

/* The line drawing of legs on a train seat drapes over the RIGHT of the
   principles title, mirroring the Vanity / glasses treatment: top-layer,
   click-through, edge-faded into the page, hidden on phones. */
body.clothing:not(.directory) main { position: relative; }
body.clothing:not(.directory) .page-hero { max-width: var(--maxw); margin: 0 auto; }
body.clothing:not(.directory) .page-hero h1 { font-size: clamp(50px, 8.6vw, 112px); }
/* Nudge the text block gently left (~10%) so the pair reads centered: the
   enlarged drawing bleeds off the right, so the copy needs a subtle leftward
   shift. Bounded + width-scaled so it stays gentle on tablets. We shift the
   text ELEMENTS (eyebrow, headline, paragraph, and the epigraph quote +
   signature), NOT the .page-hero box: transforming .page-hero would make it
   the figure's containing block and drag the drawing left with the text.
   The figure stays anchored to <main>, so only the copy moves. */
body.clothing:not(.directory) .page-hero .badge,
body.clothing:not(.directory) .page-hero h1,
body.clothing:not(.directory) .page-hero p,
body.clothing:not(.directory) .epigraph { transform: translateX(clamp(-104px, calc(120px - 15vw), -34px)); }
/* The drawing hangs in the LOWER-RIGHT of the hero and hugs the page edge.
   It is anchored to full-width <main> (not the centred hero), so it stays near
   the right on any screen width; dropped below the title, and faded on its left
   edge so it dissolves into the page. Desktop only.
   Enlarged ~22% and scaled from its TOP-RIGHT anchor: top + right stay fixed,
   so the extra width/height grows toward the centre and toward the bottom,
   letting the artwork carry more visual weight without adding whitespace. */
body.clothing .cl-fig { position: absolute; z-index: 80; pointer-events: none; user-select: none; height: auto; }
body.clothing .cl-fig--hero { top: 49px; right: 8px; width: clamp(342px, 32vw, 488px);
  /* fade the left ~9% into the page (matches the food principles hero) */
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 9%, #000 99%, transparent 100%);
          mask-image: linear-gradient(to right, transparent 0%, #000 9%, #000 99%, transparent 100%); }
@media (max-width: 1024px){
  body.clothing .cl-fig { display: none; }
  /* figure gone: re-center the copy */
  body.clothing:not(.directory) .page-hero .badge,
  body.clothing:not(.directory) .page-hero h1,
  body.clothing:not(.directory) .page-hero p,
  body.clothing:not(.directory) .epigraph { transform: none; }
}

/* ============================================================
   HOME AREA  ·  "The Hearth"
   Warm ember / hearth accent override (mirrors body.vanity).
   Every component that reads var(--blue) repaints ember for free.
   ============================================================ */
body.hearth {
  --blue:      #9A5B2D;   /* deep ember amber replaces the blue accent */
  --blue-deep: #7d4722;
  --nogo:      #7C243E;   /* the site's warm oxblood stays for cautions */
  --wash:      rgba(154,91,45,.08);
}
body.hearth footer.site { background:#2b1a0e; }   /* deep ember-brown sign-off */

/* ----- The Hearth (principles) hero engraving: the four flip phones drape
   over the RIGHT of the title, mirroring the Vanity treatment. Top-layer,
   click-through, native line-art tones (no filter). The .page-hero transform
   nudges hero text + image left as ONE element toward the optical centre and
   becomes the figure's positioning context, keeping the pair close together.
   Scoped :not(.directory) so the swaps hero stays clean. ----- */
body.hearth:not(.directory) .page-hero { position: relative; transform: translateX(clamp(-120px, calc(120px - 17vw), -20px)); max-width: var(--maxw); margin: 0 auto; }
body.hearth:not(.directory) .page-hero h1 { font-size: clamp(50px, 8.6vw, 112px); }
/* keep the subtitle's right edge inside the figure's faded zone, so the pair
   sits close without solid line art crossing the body text */
body.hearth:not(.directory) .page-hero p { max-width: 560px; }
body.hearth .hh-fig { position: absolute; z-index: 80; pointer-events: none; user-select: none; height: auto; }
body.hearth .hh-fig--hero { top: 6px; right: -30px; width: clamp(280px, 30vw, 420px);
  /* fade the left ~10% (the side meeting the text) until fully transparent,
     so the phones dissolve into the page instead of ending on a hard seam;
     the bottom edge fades too where the keypads meet the epigraph (two
     gradients intersected, as on the Living Water hero hand) */
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 10%, #000 97%, transparent 100%),
                      linear-gradient(to top, transparent 0%, #000 12%, #000 100%);
  -webkit-mask-composite: source-in;
          mask-image: linear-gradient(to right, transparent 0%, #000 10%, #000 97%, transparent 100%),
                      linear-gradient(to top, transparent 0%, #000 12%, #000 100%);
          mask-composite: intersect; }
@media (max-width: 820px){
  body.hearth:not(.directory) .page-hero { transform: none; }
  body.hearth .hh-fig { display: none; }
}

/* ============================================================
   THE SWAP DIRECTORY  (supplements-swaps · food-swaps)
   Filter chips + search + EU/US toggle + expandable editorial cards.
   Scoped to .dir / body.directory so nothing else is touched. The
   accent follows var(--blue): green on Supplements, plum on Food.
   ============================================================ */
/* the directory pages have no decorative hero figure, so undo the
   supplement hero's left-shift and shrink the oversized title a touch */
body.directory .page-hero { transform: none; max-width: var(--maxw); }
body.directory .page-hero h1 { font-size: clamp(44px, 7vw, 82px); }
@media (max-width: 700px){ body.directory .page-hero h1 { font-size: clamp(40px, 8vw, 64px); } }

.dir { max-width: 940px; margin: 0 auto; padding: 4px 24px 8px; }

/* ---- "The standard" collapsible (supplements only) ---- */
.dstandard { border: 1px solid var(--rule); background: var(--cream); margin-bottom: 30px; }
.dstandard > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 12px;
  padding: 16px 20px; font-size: 19px; font-family: var(--serif);
}
.dstandard > summary::-webkit-details-marker { display: none; }
.dstandard__eyebrow { font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: var(--blue); }
.dstandard__ic { margin-left: auto; font-size: 24px; color: var(--blue); transition: transform .3s; }
.dstandard[open] .dstandard__ic { transform: rotate(45deg); }
.dstandard__body { padding: 4px 20px 22px; border-top: 1px solid var(--rule); }
.dstandard__tiers { list-style: none; margin: 16px 0 0; display: grid; gap: 9px; }
.dstandard__tiers b { color: var(--blue); }
.dstandard__tiers li { font-size: 14.5px; color: #3a3a3a; }
.dstandard__line { font-style: italic; color: #555; margin: 16px 0 4px; max-width: 70ch; }
.dstandard__cols { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; margin-top: 18px; }
@media (max-width: 600px){ .dstandard__cols { grid-template-columns: 1fr; gap: 20px; } }
.dstandard__col h4 { font-size: 11px; letter-spacing: .18em; text-transform: uppercase;
  font-weight: 400; margin-bottom: 11px; padding-bottom: 8px; border-bottom: 1px solid var(--rule); }
.dstandard__col h4.is-nogo { color: var(--nogo); }
.dstandard__col h4.is-okay { color: var(--blue); }
.dstandard__col ul { list-style: none; display: grid; gap: 7px; }
.dstandard__col li { font-size: 13.5px; color: #444; padding-left: 16px; position: relative; }
.dstandard__col li::before { content: "·"; position: absolute; left: 4px; color: var(--blue); }

/* ---- control bar: search + region toggle ---- */
.dir__bar { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.dir__search { position: relative; flex: 1; min-width: 220px; }
.dir__search input {
  width: 100%; font-family: var(--serif); font-size: 16px; padding: 13px 44px 13px 16px;
  border: 1px solid var(--rule); background: #fff; color: var(--ink);
}
.dir__search input:focus { outline: none; border-color: var(--blue); }
.dir__search-ic { position: absolute; right: 15px; top: 50%; transform: translateY(-50%);
  font-size: 20px; color: var(--muted); pointer-events: none; }
.dir__region { display: inline-flex; border: 1px solid var(--rule); border-radius: 999px; padding: 3px; background: #fff; }
.dir__region button {
  font-family: var(--serif); font-size: 14px; letter-spacing: .06em; cursor: pointer;
  background: transparent; border: 0; border-radius: 999px; padding: 8px 20px; color: var(--ink);
  transition: background-color .2s, color .2s, scale .15s ease-out;
}
.dir__region button:active { scale: .96; }
.dir__region button.is-active { background: var(--blue); color: #fff; }

/* ---- category chips ---- */
.dir__chips { display: flex; flex-wrap: wrap; gap: 9px; margin: 18px 0 4px; }
.dchip {
  font-family: var(--serif); font-size: 13.5px; letter-spacing: .02em; cursor: pointer;
  background: #fff; border: 1px solid var(--rule); border-radius: 999px; padding: 7px 15px; color: #3a3a3a;
  transition: background-color .15s, border-color .15s, color .15s, scale .15s ease-out;
}
.dchip:hover { border-color: var(--blue); color: var(--blue); }
.dchip:active { scale: .96; }
.dchip.is-active { background: var(--blue); border-color: var(--blue); color: #fff; }

.dir__meta { font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin: 14px 0 12px; }
.dir__empty { text-align: center; color: var(--muted); font-style: italic; padding: 40px 0; }

/* ---- cards ---- */
.dir__list { display: grid; gap: 10px; }
.dcard { border: 1px solid var(--rule); background: #fff; transition: border-color .2s, box-shadow .2s; }
.dcard:hover { border-color: #cfc7b6; }
.dcard.open { border-color: var(--blue); box-shadow: 0 0 0 1px var(--blue); }
.dcard__head {
  width: 100%; text-align: left; cursor: pointer; background: none; border: 0;
  display: flex; align-items: center; gap: 16px; padding: 18px 20px; font-family: var(--serif);
}
.dcard__txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.dcard__group { font-size: 10.5px; letter-spacing: .18em; text-transform: uppercase; color: var(--blue); }
.dcard__name { font-size: 20px; color: var(--ink); }
.dcard__teaser { font-size: 14px; color: #6b6b6b; line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.dcard.open .dcard__teaser { display: none; }
.dcard__count { flex: none; font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--blue); background: var(--wash); padding: 5px 11px; border-radius: 999px; white-space: nowrap; }
.dcard__ic { flex: none; font-size: 24px; line-height: 1; color: var(--blue); transition: transform .3s; }
.dcard.open .dcard__ic { transform: rotate(45deg); }

.dcard__body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .4s ease; }
.dcard.open .dcard__body { grid-template-rows: 1fr; }
.dcard__inner { overflow: hidden; }
.dcard.open .dcard__inner { padding: 0 20px 22px; }
@media (prefers-reduced-motion: reduce){ .dcard__body { transition: none; } }

/* ---- editorial blocks: a clear hierarchy instead of stacked plain text ---- */
.dblock { margin-top: 20px; }
.dblock h4 { font-size: 11px; letter-spacing: .16em; text-transform: uppercase; font-weight: 400;
  color: var(--blue); margin-bottom: 8px; display: flex; align-items: center; gap: 9px; }
.dblock h4::before { content: ""; width: 16px; height: 1px; background: currentColor; opacity: .55; flex: none; }
.dblock p { font-size: 15px; line-height: 1.62; color: #3a3a3a; max-width: 68ch; margin-bottom: 8px; }
.dblock p:last-child { margin-bottom: 0; }

/* Food directory: a short orienting lead (full philosophy lives on food.html)
   and a quiet link back to the principles. */
.dlead { font-size: 15px; line-height: 1.62; color: #3a3a3a; max-width: 68ch; margin: 4px 0 10px; }
.dlead + .dlead { margin-top: 0; }
.dmore { margin-top: 18px; }

/* "Why it fails" - secondary; sits quietly under the name, doesn't dominate */
.dblock--fail h4 { color: var(--nogo); }
.dblock--fail p { font-size: 14px; color: #6e6e6e; }

/* Tier 1 - the food-first answer; tinted panel, the visual hero of the card */
.dblock--ideal { background: var(--wash); border-left: 3px solid var(--blue); padding: 16px 20px; }
.dblock--ideal h4 { color: var(--blue); }
.dblock--ideal p { color: #2f2f2f; }

/* Tier 2 - acceptable; quieter label */
.dblock--ok h4 { color: var(--muted); }

/* Tested products - a distinct "shop" panel with a scannable grid of picks */
.dblock--picks { margin-top: 24px; background: var(--cream); padding: 18px 18px 20px; }
.dblock--picks h4 { color: var(--blue); margin-bottom: 14px; }
.dpicks { list-style: none; display: grid; gap: 8px;
  grid-template-columns: repeat(auto-fill, minmax(244px, 1fr)); }
.dpicks li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 7px;
  background: var(--paper); border: 1px solid var(--rule); padding: 11px 13px;
  transition: border-color .15s, box-shadow .15s; }
.dpicks li:hover { border-color: var(--blue); box-shadow: inset 0 0 0 1px var(--blue); }
.dpicks a.visit { color: var(--blue); text-decoration: none; font-size: 14.5px; letter-spacing: .01em;
  border-bottom: 1px solid transparent; padding-bottom: 1px; }
.dpicks a.visit:hover { border-bottom-color: var(--blue); }
.dpicks a.visit .va { font-size: 12px; margin-left: 2px; transition: transform .2s ease; display: inline-block; }
.dpicks a.visit:hover .va { transform: translate(2px,-2px); }
.dpick-name { font-size: 14.5px; color: var(--ink); }
.dnote { width: 100%; font-size: 11.5px; font-style: italic; color: var(--muted); }
/* per-pick price tag (Home directory): quiet serif, rides the same line as the link */
.dpick-price { font-family: var(--serif); font-size: 12.5px; color: var(--ink);
  opacity: .78; font-variant-numeric: tabular-nums; white-space: nowrap; }
.dpicks-none { font-size: 14px; font-style: italic; color: var(--muted); grid-column: 1 / -1; }
/* region show/hide */
.dir[data-region="eu"] .dpicks-wrap[data-region-list="us"],
.dir[data-region="us"] .dpicks-wrap[data-region-list="eu"] { display: none; }

/* caution - a quiet warning footer */
.dcaution { margin-top: 18px; font-size: 13.5px; line-height: 1.55; color: #555;
  border-left: 3px solid var(--nogo); padding: 4px 0 4px 16px; }
.dcaution span { color: var(--nogo); font-weight: 700; margin-right: 4px; }

/* ---- per-product cards (Vanity): a price chip in the head + a single Visit
   link in the body. Each card is one product, so the group name is the
   eyebrow and the lead sits under it. ---- */
.dcard__price { flex: none; max-width: 44%; text-align: right; font-family: var(--serif);
  font-size: 12.5px; letter-spacing: .01em; line-height: 1.35; color: var(--blue);
  background: var(--wash); padding: 6px 12px; border-radius: 999px; }
.dcard--product .dcard__inner .dlead:first-child { margin-top: 4px; }
.dvisit { margin-top: 22px; display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 14px; }
.dvisit .visit { color: var(--blue); text-decoration: none; font-size: 15px; letter-spacing: .01em;
  border-bottom: 1px solid transparent; padding-bottom: 1px; }
.dvisit .visit:hover { border-bottom-color: var(--blue); }
.dvisit .visit .va { font-size: 12px; margin-left: 2px; display: inline-block; transition: transform .2s ease; }
.dvisit .visit:hover .va { transform: translate(2px,-2px); }
.dvia { font-size: 12px; font-style: italic; color: var(--muted); }
@media (max-width: 560px){
  .dcard__price { max-width: 40%; font-size: 11.5px; padding: 5px 9px; }
}

@media (max-width: 560px){
  .dcard__head { gap: 10px; padding: 16px 15px; }
  .dcard__name { font-size: 18px; }
  .dcard.open .dcard__inner { padding: 0 15px 20px; }
  .dir { padding-left: 16px; padding-right: 16px; }
}

/* ============================================================
   SEAMLESS PAGE FLOW - cross-document view transitions
   Same-origin navigations cross-fade instead of flashing white,
   and the header stays visually continuous across pages (it has
   its own transition group, so it does not fade with the root).
   Pure progressive enhancement: browsers without support, and
   visitors with reduced motion, get the classic instant swap.
   Pairs with the speculation-rules prerender in each page head,
   which makes the incoming page ready before the fade begins.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  .sitenav { view-transition-name: dlar-nav; }
  ::view-transition-old(root) { animation-duration: .22s; }
  ::view-transition-new(root) { animation-duration: .22s; }
  ::view-transition-old(dlar-nav) { animation: none; }
  ::view-transition-new(dlar-nav) { animation: none; }
}

/* ============================================================
   RENDER VIRTUALIZATION - the "never freezes, however much
   content" layer. content-visibility:auto lets the browser skip
   layout + paint for everything off screen, so a directory with
   500 cards costs the same to render as one with 20, and long
   text pages scale for free. contain-intrinsic-size "auto N"
   reserves an estimated height first, then remembers the real
   one, keeping the scrollbar honest. Cards and the footer are
   self-contained boxes (no decorations painting outside them),
   which is the safety condition for paint containment.
   ============================================================ */
.dcard { content-visibility: auto; contain-intrinsic-size: auto 96px; }
footer.site { content-visibility: auto; contain-intrinsic-size: auto 560px; }

/* ============================================================
   CRAFT LAYER (v120) - the sitewide micro-interaction and
   print-feel pass. One physics for the whole house: underlines
   draw in like ink, chips pool their fill, accordions settle
   with a spring, the hero card reads as a printed plate, and
   the hero engravings breathe with the scroll (JS scrubs
   --hero-drift in app.js; desktop, fine pointers only).
   Transform + opacity only. Reduced motion is covered by the
   global guard at the top of this file; low-power overrides
   live at the bottom and win the cascade.
   ============================================================ */

/* ---- selection reads as pressed ink in the page accent ---- */
::selection { background: var(--blue); color: var(--cream); }

/* ---- whisper links: the hairline draws in from the left.
   ::after on these is the 40px tap target, so the line is ::before. ---- */
.card .cats a::before, .foot .links a::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: currentColor;
  transform: scaleX(0); transform-origin: left center;
  transition: transform .34s cubic-bezier(.25,.6,.25,1);
}
.card .cats a:hover::before, .foot .links a:hover::before { transform: scaleX(1); }
.card .cats a:hover, .foot .links a:hover { border-color: transparent; }

/* the standing xlink underline stays; a second, full-strength line
   draws over it on hover so the link reads as inked-in, not swapped */
.xlink { position: relative; }
.xlink::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: currentColor;
  transform: scaleX(0); transform-origin: left center;
  transition: transform .3s cubic-bezier(.25,.6,.25,1);
}
.xlink:hover::before { transform: scaleX(1); }

/* ---- accordions: the + turns with a small spring, and the opened
   answer settles into place instead of merely appearing ---- */
.acc__q .ic, .dcard__ic, .dstandard__ic {
  transition: transform .5s cubic-bezier(.34,1.45,.44,1);
}
.acc__a > div {
  opacity: 0; transform: translateY(7px);
  transition: opacity .4s ease, transform .4s ease;
}
.acc__item.open .acc__a > div { opacity: 1; transform: none; transition-delay: .06s; }

/* ---- chips + region toggle: the fill pools from the centre ---- */
.dchip, .dir__region button {
  position: relative; isolation: isolate; overflow: hidden;
}
.dchip::before, .dir__region button::before {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
  background: var(--blue);
  transform: scale(.55); opacity: 0;
  transition: transform .32s cubic-bezier(.3,.9,.4,1), opacity .22s ease;
}
.dchip.is-active, .dir__region button.is-active { background: transparent; }
.dchip.is-active::before, .dir__region button.is-active::before {
  transform: scale(1.02); opacity: 1;
}

/* ---- buttons: a quiet lift on fine pointers (press stays .96) ---- */
.btn { transition: background-color .2s, color .2s, scale .15s ease-out, translate .18s ease-out; }
@media (hover: hover) and (pointer: fine) {
  .btn:hover { translate: 0 -1px; }
}

/* ---- mobile drawer rows acknowledge the finger ---- */
@media (max-width: 860px) {
  .sitenav .links a:active { background: var(--wash); }
}

/* ---- area cards: the title inks when the plate colours ---- */
.card-link h3 { transition: color .25s ease; }
.card-link:hover h3 { color: var(--blue); }

/* ---- homepage hero card: a printed plate, not a flat rectangle.
   Grain is a static feTurbulence tile at 4%; the frame is a single
   hairline kept off the tight mobile layout. Both are ::pseudos in
   the card's own stacking context (z:-1 sits above the cream, below
   the type). ---- */
.home .hero .card::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: .04;
}
@media (min-width: 701px) {
  .home .hero .card::after {
    content: ""; position: absolute; inset: 8px; pointer-events: none;
    border: 1px solid color-mix(in srgb, var(--blue) 16%, transparent);
  }
}

/* ---- hero engravings: scroll-scrubbed drift (depth, not motion).
   app.js writes --hero-drift (0..1) on .hero during scroll; both
   copies of the right hand share the class, so the ghost stays
   pixel-aligned. Mobile keeps the composition still. ---- */
@media (min-width: 861px) {
  .hero .deco--left  { transform: translateY(calc(var(--hero-drift, 0) * 52px)); }
  .hero .deco--right { transform: translateY(calc(var(--hero-drift, 0) * 84px)); }
}

/* ---- the scroll cue breathes three times, then rests ---- */
@keyframes cue-pulse { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
.scrollcue { animation: cue-pulse 2.8s ease-in-out .9s 3 both; }

/* ---- numbers set as columns wherever money or counts align ---- */
.dcard__price, .dcard__count { font-variant-numeric: tabular-nums; }

/* ---- About: the journey draws its own ink line down the margin as the
   story is read. app.js scrubs --journey-draw (0..1) during scroll, the
   same pattern as the manifesto dagger; no scroll = no work. Desktop only
   (the narrow column owns the margin there). ---- */
@media (min-width: 700px) {
  .journey { position: relative; }
  .journey::before {
    content: ""; position: absolute; left: -26px; top: 14px; bottom: 14px;
    width: 1px; background: var(--blue); opacity: .38;
    transform: scaleY(var(--journey-draw, 0)); transform-origin: top center;
  }
}

/* ---- Contact: the correspondence desk. The candlelit window plate rests
   over the hero's right shoulder, its edges dissolved into the paper by a
   soft mask so it reads as printed into the page, not pasted on it. Same
   top-layer, click-through treatment as the other engraved figures.
   Hidden on phones, like its siblings. ---- */
body.contact .ct-fig { position: absolute; z-index: 80; pointer-events: none;
  user-select: none; height: auto; }
body.contact .page-hero { position: relative; }
body.contact .ct-fig--hero { top: -18px;
  right: min(calc((1200px - 100vw) / 2 - 6px), -6px);
  width: clamp(300px, 28vw, 430px);
  /* dissolve the plate's cut edges into the paper: a horizontal fade for the
     left edge and a vertical fade for top + bottom, intersected. Browsers
     without mask-composite union the layers instead, which simply keeps the
     full plate - an acceptable fallback, never a broken one.
     The LEFT fade is a gentle ease-in curve that runs out to ~40% of the
     width: the drop is spread evenly across the band (no steep cliff at the
     edge) so the plate dissolves softly into the paper rather than being
     clipped. The SAME horizontal gradient also fades the RIGHT edge over its
     last ~18% (82% -> 100%), mirroring the top/bottom fade, so all four sides
     dissolve alike. The vertical gradient (top + bottom) is unchanged. */
  -webkit-mask-image: linear-gradient(90deg,
                        rgba(0,0,0,0) 0%, rgba(0,0,0,.13) 3%, rgba(0,0,0,.30) 8%,
                        rgba(0,0,0,.48) 14%, rgba(0,0,0,.68) 22%, rgba(0,0,0,.84) 30%,
                        #000 40%, #000 82%, transparent 100%),
                      linear-gradient(180deg, transparent 0, #000 14%, #000 82%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(90deg,
                rgba(0,0,0,0) 0%, rgba(0,0,0,.13) 3%, rgba(0,0,0,.30) 8%,
                rgba(0,0,0,.48) 14%, rgba(0,0,0,.68) 22%, rgba(0,0,0,.84) 30%,
                #000 40%, #000 82%, transparent 100%),
              linear-gradient(180deg, transparent 0, #000 14%, #000 82%, transparent 100%);
  mask-composite: intersect;
}

/* Contact hero refinement: scale the whole hero (headline, paragraph, email,
   note, all three CTAs) down ~12% and tighten the vertical rhythm so the full
   first screen fits a laptop viewport at 100% zoom without scrolling. The text
   block and the buttons beneath it slide left as one, drawing the copy into
   conversation with the candlelit plate. We translate the text ELEMENTS (not
   the .page-hero box) so the plate keeps its own independent placement below. */
body.contact .page-hero { padding-top: 52px; padding-bottom: 12px; }
body.contact .page-hero .badge { font-size: 11px; }
body.contact .page-hero h1 { font-size: clamp(40px, 7vw, 80px); margin: 8px 0 12px; }
body.contact .page-hero p { font-size: 16px; }
body.contact .page-hero .badge,
body.contact .page-hero h1,
body.contact .page-hero p { transform: translateX(clamp(-130px, -8.5vw, -88px)); }
/* email + note + button row (the section directly after the hero) ride left with it */
body.contact .page-hero + .wrap--narrow { transform: translateX(clamp(-130px, -8.5vw, -88px)); }
body.contact .page-hero + .wrap--narrow .pull { font-size: clamp(23px, 3.5vw, 40px); }
/* English wraps to two shorter lines, leaving a gap before the plate. Push the
   EN text block back to the right until it almost meets the plate. Slovak fills
   the width already, so this targets the English document only. */
html[lang="en"] body.contact .page-hero .badge,
html[lang="en"] body.contact .page-hero h1,
html[lang="en"] body.contact .page-hero p,
html[lang="en"] body.contact .page-hero + .wrap--narrow { transform: translateX(clamp(-95px, -4vw, 0px)); }
/* nudge the plate ~3% left and ~4% down so it converses with the copy. The
   constant is a small POSITIVE gap from the viewport's right edge, so the whole
   width of the plate stays on-screen (never bled off the right). Size unchanged. */
body.contact .ct-fig--hero { top: 8px;
  right: min(calc((1200px - 100vw) / 2 + 22px), 22px); }

@media (max-width: 700px) {
  body.contact .ct-fig { display: none; }
  /* no plate on phones, so the copy returns to centre (no left slide) */
  body.contact .page-hero .badge,
  body.contact .page-hero h1,
  body.contact .page-hero p,
  body.contact .page-hero + .wrap--narrow { transform: none; }
}

/* ============================================================
   LOW-POWER MODE - html.dlar-lowpower is set (js/i18n.js) on
   genuinely weak hardware: <=2 cores / <=1GB, or two measured janky scrolls
   earlier this session (js/app.js probe). Same design, with the
   per-frame GPU work stepped down. The scripts gate themselves
   (no quill cursor, no intro game, no FAQ theatre, no credo
   wave, no WebGL); CSS handles the rest here.
   ============================================================ */
/* The sticky nav's glass blur re-blurs the page under it on EVERY scrolled
   frame - the single heaviest per-frame cost on old GPUs. Near-opaque
   paper reads almost identically and costs nothing. */
html.dlar-lowpower .sitenav {
  -webkit-backdrop-filter: none; backdrop-filter: none;
  background: rgba(255,255,255,0.97);
}
/* modal scrims: skip the live blur, deepen the tint to compensate */
html.dlar-lowpower .nl-modal,
html.dlar-lowpower .pcard-detail__scrim {
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
/* craft layer steps down: no hero drift, no cue pulse on weak machines
   (app.js also stops writing --hero-drift when lowPower is set) */
html.dlar-lowpower .hero .deco--left,
html.dlar-lowpower .hero .deco--right { transform: none; }
html.dlar-lowpower .scrollcue { animation: none; }

/* alive: generic homepage (act 1) */
:root { --gen-accent: #6b7d5e; }
body.gen-home footer.site { background: #2e3a26; }   /* muted sage sign-off, no oxblood */
.gen-hero {
  max-width: 720px; margin: 0 auto; padding: 96px 24px 64px; text-align: center;
}
.gen-hero h1 {
  font-family: var(--script); font-size: clamp(48px, 8vw, 84px); font-weight: 400;
  color: var(--ink); line-height: 1.05;
}
.gen-hero__sub {
  margin-top: 18px; color: #555; font-size: 18px; line-height: 1.5;
}
.gen-btn {
  display: inline-block; margin-top: 32px; padding: 12px 28px;
  border: 1px solid #2e3a26; border-radius: 4px; background: #2e3a26;
  color: #fff; font-family: var(--serif); font-size: 15px;
  text-decoration: none;
}
.gen-btn:hover { background: #24301d; border-color: #24301d; }
.gen-section {
  max-width: 720px; margin: 28px auto; padding: 40px 36px; background: var(--cream);
  border: 1px solid rgba(46, 58, 38, 0.22); border-radius: 6px;
}
.gen-section h2 {
  font-family: var(--script); font-weight: 400; font-size: clamp(38px, 6vw, 56px);
  color: var(--gen-accent); margin-bottom: 20px; line-height: 1;
}
.gen-section p { color: #444; line-height: 1.6; margin-bottom: 14px; }
.gen-list { list-style: none; }
.gen-list li { padding: 18px 0; border-top: 1px solid var(--rule); }
.gen-list li:first-child { border-top: none; }
.gen-list h3 {
  font-family: var(--serif); font-weight: 400; font-size: 18px; color: var(--ink);
  margin-bottom: 6px;
}
.gen-list p { color: #555; margin-bottom: 0; }

/* act 2: the pretty upgrade. An engraved catalogue: Envato display serif,
   licensed paper, hairline plate frames, figure captions. Everything framed,
   everything in its place. For now. */
@font-face {
  font-family: "BD Megalona";
  src: url("../assets/fonts/bd-megalona-regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "BD Megalona";
  src: url("../assets/fonts/bd-megalona-italic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
}
body.p2 {
  --display: "BD Megalona", Georgia, "Times New Roman", serif;
  --frame: #cfc4ac;             /* engraved hairline, one tone deeper than --rule */
  --paperlay: linear-gradient(rgba(251,248,239,.78), rgba(251,248,239,.78)), url('../assets/envato-paper-2.webp');
  background: #fbf8ef;
}
body.p2 .lead-serif { font-family: var(--display); letter-spacing: .01em; }
.p2 .section-label { font-family: var(--display); font-style: italic; letter-spacing: .24em; }

/* ---- the frontispiece ---- */
.p2-hero { max-width: var(--maxw); margin: 26px auto 0; padding: 0 24px; }
.p2-hero__plate { border: 1px solid var(--rule); background: var(--cream); padding: 10px; }
.p2-hero__inner {
  position: relative; overflow: hidden; text-align: center;
  border: 1px solid var(--frame); outline: 1px solid var(--rule); outline-offset: -6px;
  padding: clamp(38px, 6.5vh, 68px) clamp(20px, 3vw, 40px) clamp(24px, 4vh, 40px);
}
.p2-hero__paper { position: absolute; inset: 0; z-index: 0; }
.p2-hero__paper img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  opacity: .34; mix-blend-mode: multiply;
}
.p2-hero__grid {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: 1.9fr minmax(0, 1.9fr) 1.9fr;
  gap: clamp(10px, 1.6vw, 22px); align-items: center;
}
.p2-hero .eyebrow {
  font-family: var(--display); font-size: 12px; letter-spacing: .26em;
  text-transform: uppercase; color: var(--blue);
}
.p2-lockup { display: block; margin-top: 18px; }
.p2-lockup .d, .p2-lockup .r {
  display: block; font-family: var(--display); font-weight: 400;
  font-size: clamp(52px, 8.4vw, 122px); line-height: .96; letter-spacing: .045em;
  text-transform: uppercase; color: var(--ink);
}
.p2-lockup .mid {
  display: block; font-family: var(--script); font-weight: 400; color: var(--blue);
  font-size: clamp(38px, 5.8vw, 80px); line-height: .72; margin: 0;
}
.p2-hero__tagline {
  margin: 24px auto 0; max-width: 44ch; font-style: italic; color: #444;
  font-size: clamp(16px, 1.6vw, 19px); line-height: 1.55;
}
/* engraved rule with a printer's star, splitting title from actions */
.p2-hero__rule {
  display: flex; align-items: center; justify-content: center; gap: 16px;
  margin: 26px auto 0; color: var(--blue); font-size: 13px;
}
.p2-hero__rule::before, .p2-hero__rule::after {
  content: ""; height: 1px; width: min(120px, 16vw);
}
.p2-hero__rule::before { background: linear-gradient(to left, var(--frame), transparent); }
.p2-hero__rule::after  { background: linear-gradient(to right, var(--frame), transparent); }
.p2-ctas { margin-top: 24px; display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }
.p2-ctas a {
  display: inline-block; border: 1px solid var(--blue); color: var(--blue);
  background: rgba(255,255,255,.4); text-decoration: none;
  padding: 12px 26px 11px; font-size: 12.5px; letter-spacing: .18em; text-transform: uppercase;
}
.p2-ctas a:hover { background: var(--blue); color: var(--cream); }
/* the figures stand free, no frame, sized large and centered at the text's flank */
.p2-fig { margin: 0; pointer-events: none; }
.p2-fig img {
  display: block; margin: 0 auto; width: 100%; max-width: 100%; height: auto;
  object-fit: contain;
}
.p2-fig--glove img { transform: translateX(9%) scale(.85); transform-origin: center; }
.p2-fig figcaption {
  font-family: var(--display); font-style: italic; font-size: 12px;
  letter-spacing: .14em; color: var(--muted); margin-top: 10px;
}
.p2-hero__caption {
  margin-top: 12px; text-align: center; font-style: italic; font-family: var(--display);
  font-size: 12px; letter-spacing: .08em; color: var(--muted);
}

/* ---- the manifesto reads as a two-column printed spread ---- */
.p2 .manifesto {
  border: 1px solid var(--rule);
  background: var(--paperlay) center/cover;
  padding: clamp(18px, 3vw, 40px) clamp(20px, 3.4vw, 48px);
}
.p2 .manifesto-list {
  display: grid; grid-template-columns: 1fr 1fr; gap: 0 clamp(32px, 4.5vw, 64px);
}

/* ---- directory thumbs become catalogue plates ---- */
.p2 .card-link .thumb {
  border: 1px solid var(--rule);
  background: var(--paperlay) center/cover;
}
.p2 .card-link .num { font-family: var(--display); font-style: italic; }

/* ---- consulting: the figure is a captioned plate, the callout a letter ---- */
.p2 .consult-grid { grid-template-columns: minmax(0, 1fr) 495px; gap: 44px; align-items: center; }
.p2 .consult-grid > .consult-fig { width: 100%; max-width: 495px; position: static; margin: 0; }
.p2-plate { border: 0; background: none; padding: 0; }
.p2-plate img { width: 100%; height: auto; display: block; }
.p2-plate figcaption {
  font-family: var(--display); font-style: italic; font-size: 12px;
  letter-spacing: .14em; color: var(--muted); margin-top: 10px; text-align: center;
}
.p2 .callout--paper {
  position: relative;
  border: 1px solid var(--frame); outline: 1px solid var(--rule); outline-offset: -5px;
  background: linear-gradient(rgba(251,248,239,.62), rgba(251,248,239,.62)), url('../assets/envato-paper-2.webp') center/cover;
}
.p2 .callout--paper::before {
  content: "\2736"; display: block; text-align: center;
  color: var(--blue); font-size: 13px; margin-bottom: 12px;
}

/* ---- small engraved ornament above signatures ---- */
.p2-orn {
  display: flex; align-items: center; justify-content: center; gap: 16px;
  color: var(--blue); font-size: 13px; margin-bottom: 4px;
}
.p2-orn::before, .p2-orn::after { content: ""; height: 1px; width: min(90px, 14vw); }
.p2-orn::before { background: linear-gradient(to left, var(--frame), transparent); }
.p2-orn::after  { background: linear-gradient(to right, var(--frame), transparent); }

@media (max-width: 980px) {
  .p2-hero__grid { grid-template-columns: 1fr minmax(0, 2.2fr) 1fr; }
  .p2-fig img { max-height: min(44vh, 400px); }
}
@media (max-width: 860px) {
  .p2-hero { margin-top: 14px; padding: 0 14px; }
  .p2-hero__inner { padding: 38px 16px 28px; }
  .p2-hero__grid { grid-template-columns: 1fr; gap: 20px; }
  .p2-fig { display: none; }
  .p2-fig--show-m {
    display: block; width: min(62%, 300px); margin: 6px auto 0;
  }
  .p2-fig--show-m img { max-height: 300px; }
  .p2 .manifesto-list { grid-template-columns: 1fr; }
  .p2 .consult-grid { grid-template-columns: 1fr; gap: 20px; }
  .p2 .consult-grid > .consult-fig { max-width: 320px; margin: 0 auto; }
}

/* ============================================================
   ALIVE layer (v143): the original hero comes home.
   The page ground becomes aged paper (quiet luxury), the
   engravings get bolder and keep standing in front of the nav,
   oxblood carries the accents. Built to receive the coming
   theatre: the Red Pen, the manifesto cut, the living hero.
   ============================================================ */
body.alive {
  --display: "BD Megalona", Georgia, "Times New Roman", serif;
  background: #fbf8ef;
}
/* one fixed paper sheet under the whole page: no tiling seams,
   no scroll repaint; sections keep their own grounds above it */
body.alive::before {
  content: ""; position: fixed; inset: 0; z-index: -1;
  background: url('../assets/envato-paper-2.webp') center / cover no-repeat;
  opacity: .18; pointer-events: none;
}
/* editorial voice: the Envato display serif carries labels + leads */
body.alive .section-label {
  font-family: var(--display); font-style: italic;
  letter-spacing: .24em; color: var(--blue);
}
/* Y2K marks (Envato, sagesmask): the eight-point star replaces the old
   printer's star on labels; the twin sparkles flank the script headings;
   the target aims the scroll cue. All inked with currentColor via mask */
body.alive .section-label::before,
body.alive .hero .card .eyebrow::before {
  content: ""; display: inline-block; width: .95em; height: .95em;
  margin-right: .55em; vertical-align: -.12em; background: currentColor;
  -webkit-mask: url('../assets/y2k-star.svg') center / contain no-repeat;
  mask: url('../assets/y2k-star.svg') center / contain no-repeat;
}
body.alive .script-h::after {
  content: ""; display: inline-block; width: .34em; height: .24em;
  margin-left: .18em; vertical-align: .06em; background: currentColor;
  opacity: .85;
  -webkit-mask: url('../assets/y2k-sparkles.svg') center / contain no-repeat;
  mask: url('../assets/y2k-sparkles.svg') center / contain no-repeat;
}
body.alive .scrollcue::before {
  content: ""; display: inline-block; width: 13px; height: 13px;
  margin-right: 9px; vertical-align: -2px; background: currentColor;
  -webkit-mask: url('../assets/y2k-target.svg') center / contain no-repeat;
  mask: url('../assets/y2k-target.svg') center / contain no-repeat;
}
body.alive .lead-serif { font-family: var(--display); letter-spacing: .01em; }

/* hero: cream card framed like an engraved plate, warmer shadow.
   Desktop only: the mobile hero is deliberately one flat cream panel */
@media (min-width: 701px) {
  body.alive .hero .card {
    border: 1px solid #cfc4ac;
    outline: 1px solid var(--rule); outline-offset: -6px;
    box-shadow: 0 26px 52px rgba(60, 42, 20, .16);
  }
}
/* the figures grow a step bolder; the ghost twin follows automatically
   because it shares .deco--right */
@media (min-width: 861px) {
  body.alive .hero .deco--left  { width: min(37.8vw, 589px); }
  body.alive .hero .deco--right { width: min(31.31vw, 467px); }
}

/* directory: staggered baseline, editorial rhythm (desktop only).
   margin, not transform: the cards' hover transforms stay untouched */
@media (min-width: 1001px) {
  body.alive .dir-grid > .card-link:nth-child(even) { margin-top: 30px; }
}


/* ---- the living hero: the three figures move like beings, not banners.
   Pure compositor transforms (same license as the dagger's breathe loop).
   Each keyframe composes with --ax/--ay, the JS-written attention offset,
   so the hand can lean toward the visitor's cursor WHILE its own loop
   plays. The global prefers-reduced-motion kill switch already stops
   these; low-power gets its own kill below. ---- */

/* THE ARRIVAL: alive-hero.js walks Diana in from off-stage (WAAPI, a
   cut-out-theatre gait), raises the glove to meet her, steps the woman
   in when her section is reached, and stamps .is-settled on each figure
   when it hits its mark. The idle loops below only begin once settled,
   so the entrance and the idling never fight over transform. */

/* the statue: a person standing long at a window. Weight shifts from one
   foot to the other around her base; the hound holds still */
body.alive .hero .deco--left { transform-origin: 50% 96%; }
body.alive .hero .deco--left.is-settled {
  animation: alive-statue 11s ease-in-out infinite;
}
@keyframes alive-statue {
  0%, 100% { transform: rotate(-.28deg) translateY(0); }
  38%      { transform: rotate(.22deg)  translateY(-2px); }
  72%      { transform: rotate(-.1deg)  translateY(-1px); }
}

/* the gloved hand: a slow reach toward the nav it points at, hinged at
   the wrist. Both copies (base + ghost twin) carry the same animation and
   the same --ax/--ay, so they stay pixel-locked */
@media (min-width: 861px) {
  body.alive .hero .deco--right { transform-origin: 82% 100%; }
  body.alive .hero .deco--right.is-settled {
    animation: alive-hand 8.5s ease-in-out infinite;
  }
}
@keyframes alive-hand {
  0%, 100% { transform: translate(var(--ax, 0px), var(--ay, 0px)) rotate(0deg); }
  50%      { transform: translate(calc(var(--ax, 0px) - 4px), calc(var(--ay, 0px) - 7px)) rotate(-.4deg); }
}

/* the woman and her dog carry their own motion in the looping clip, so the box
   itself must NOT animate: a transform here would create a stacking context and
   trap the clip's multiply (on narrow the clip is a child of this box), and it
   would fight the position:sticky pin. So no idle transform on .consult-fig. */

/* weak machines get statues that behave like statues */
.dlar-lowpower body.alive .hero .deco--left,
.dlar-lowpower body.alive .hero .deco--right,
.dlar-lowpower body.alive .consult-fig { animation: none !important; }

/* ---- THE RED PEN (v151): the editor's line, drawn by js/red-pen.js.
   Full-page SVG overlay in document flow coordinates. z-index 1: above
   the paper grounds and the manifesto sheets (so the marks land on the
   words), below every engraving (decos 40/60, consult-fig 2, hero card 3).
   mix-blend-mode: multiply is what makes it read as ink absorbed INTO the
   paper (darkening the fibres + letters it crosses, paper grain showing
   through the stroke) instead of a flat plane floating over the page.
   Pointer-transparent, no layout, no CPU while idle. ---- */
.red-pen { position: absolute; left: 0; top: 0; width: 100%; z-index: 1; pointer-events: none; mix-blend-mode: multiply; }
.red-pen svg { display: block; width: 100%; height: 100%; }
/* the corner tail rides its own layer in normal blend: on the near black
   footer, multiply would swallow the rose ink entirely */
.red-pen--foot { mix-blend-mode: normal; }
/* the pen is desktop theatre; weak machines never see it */
html.dlar-lowpower .red-pen { display: none; }
@media (max-width: 899px) { .red-pen { display: none; } }

/* ================= HOME PAGE TYPE SCALE (v197): every size x1.134 ==============
   Every font-size in this sheet is a fixed px or a clamp(px, vw, px), so there is
   no single root lever: each size that lands on index.html is restated here at
   1.134x, scoped to body.home so no other page moves. Two rules carry the rest:
   the base bump lifts everything that never declared a size (all body copy), and
   the .foot pin holds the footer strip at today's size, per Natalie.

   1.134 = the original 8% pass (1.08) plus the 5% on top she asked for after
   seeing it live. Every value below is the ORIGINAL size x 1.134, never a second
   multiplier stacked on the 1.08 numbers, so the arithmetic stays checkable
   against the rules earlier in this sheet.
   Keep the two blocks in sync: if a size above changes, change its twin here. */
body.home { font-size: 18.14px; }     /* 16 x 1.134: all inherited copy */
body.home .foot { font-size: 16px; }  /* the bottom strip stays exactly as it was */

/* nav (home page only) */
body.home .sitenav .logo .small { font-size: 11.34px; }
body.home .sitenav .logo .script { font-size: 34.02px; }
body.home .sitenav .links a { font-size: 18.14px; }
body.home .nav-toggle { font-size: 17.01px; }
body.home .lang-switch button { font-size: 14.74px; }
body.home .lang-switch .lang-sep { font-size: 13.61px; }
body.home .areas-trigger .caret { font-size: 12.47px; }
body.home .sitenav .links .area-name { font-size: 18.14px; }
body.home .area-row.is-live > .area-name::after { font-size: 20.41px; }
body.home .area-flag { font-size: 11.34px; }
body.home .sitenav .area-sub a { font-size: 17.01px; }
body.home .sitenav .links .house-menu a { font-size: 18.14px; }

/* hero card: its width is min(64vw, 840px), set independently of the type, so
   the bigger lockup grows the card downward and never out into the engravings */
body.home .card .eyebrow { font-size: 13.61px; }
body.home .card .lockup .d,
body.home .card .lockup .r { font-size: clamp(41.96px, 7.416vw, 94.12px); }
body.home .card .lockup .mid { font-size: clamp(36.29px, 6.305vw, 80.51px); }
body.home .card .tagline { font-size: clamp(15.88px, 1.814vw, 20.41px); }
body.home .card .cats a { font-size: 13.61px; }
body.home .scrollcue { font-size: 12.47px; }

/* section scaffolding, headings, links, buttons */
body.home .section-label { font-size: 14.74px; }
body.home .lead-serif { font-size: clamp(24.95px, 3.402vw, 38.56px); }
body.home .script-h { font-size: clamp(40.82px, 6.804vw, 81.65px); }
body.home .xlink { font-size: 14.74px; }
body.home .btn { font-size: 17.01px; }

/* the manifesto sheets */
body.home .manifesto-item .n { font-size: 49.9px; }
body.home .manifesto-item h3 { font-size: 24.95px; }

/* the directory cards */
body.home .card-link .num { font-size: 13.61px; }
body.home .card-link h3 { font-size: 20.41px; }
body.home .card-link .tags { font-size: 13.61px; }
body.home .status-pill { font-size: 11.34px; }
body.home .dir-grid .card-link h3 { font-size: 17.01px; }
body.home .dir-grid .card-link .tags { font-size: 12.47px; }
body.home .dir-grid .card-link .num { font-size: 12.47px; }
body.home .dir-grid .status-pill { font-size: 10.21px; }

@media (min-width: 1440px) {
  body.home .dir-grid .card-link h3 { font-size: 19.28px; }
  body.home .dir-grid .card-link .tags { font-size: 13.61px; }
}

@media (max-width: 700px) {
  body.home .hero .card .eyebrow { font-size: 11.91px; }
  body.home .hero .card .lockup .d,
  body.home .hero .card .lockup .r { font-size: clamp(27.22px, 9.151vw, 54.43px); }
  body.home .hero .card .lockup .mid { font-size: clamp(23.81px, 7.79vw, 45.36px); }
  body.home .hero .card .tagline { font-size: 15.31px; }
}

@media (max-width: 600px) {
  body.home .manifesto-item .n { font-size: 36.29px; }
}

/* At 1.134 the pills need ~910px to hold one row while the hamburger only takes
   over below 861px, so 861-909px would wrap the nav onto two lines. Tighten the
   bar's padding, the gap between pills, and the pills' own side padding across
   exactly that band. Above it the untightened nav already fits; below it the
   hamburger owns the nav. Re-measure this band whenever the type scale moves. */
@media (min-width: 861px) and (max-width: 915px) {
  body.home .sitenav { padding-left: 10px; padding-right: 10px; }
  body.home .sitenav .links { gap: 6px; }
  body.home .sitenav .links > a { padding-left: 13px; padding-right: 13px; }
}
