/* ============================================================
   chrome.css — the navbar and the footer, for every page.

   These used to live in page.css, which only the homepage loads, so the
   fourteen workshop and fieldnote pages carried a second navbar of their
   own: a different height, a different brand, a different button. No
   amount of matching numbers between two files would have held, because
   nothing made them one thing. This file is that one thing.

   The navbar sets its own line-height on purpose. Inheriting an article's
   is what made it render differently inside a reading page.
   ============================================================ */
/* ============================================================
   page.css — the one-poster page.
   Joi's formula in Mental's design code: one sentence, one lit
   object (the real app, on film), one button. All animation is
   transform/opacity/filter. No SVG blur filters anywhere.
   ============================================================ */
* { margin: 0; padding: 0; box-sizing: border-box; }
html {
  scroll-behavior: smooth;
  /* iOS: body-level clip alone does not stop sideways touch panning */
  overflow-x: clip;
  /* iOS: don't let Safari's text autosizing inflate past our clamp()s */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--t-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip; /* not `hidden` — that would break position:sticky */
}
::selection { background: var(--ink-soft); color: #fff; }
a { color: inherit; text-decoration: none; }
.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}


/* ---------- Entrance: tiny staggered fades, then stillness ----------
   CSS-driven, not JS. The h1 is the page's LCP element, and an element at
   opacity:0 is not an LCP candidate — gating the reveal on a module script
   pushed the largest paint a full script fetch + 230ms behind the
   stylesheet, for no visual gain. The headline now enters on the first
   frame the stylesheet resolves; the rest cascade in behind it. */
.enter {
  /* `backwards`, NOT `both`. A forwards-filled animation outranks normal
     declarations for the properties it animates, so `both` pinned the nav's
     transform and opacity and .nav.tucked could no longer move or hide the
     bar — while its pointer-events:none still applied. The nav stayed on
     screen with nothing in it clickable. `backwards` still supplies the
     pre-delay hidden state the stagger needs, then hands the properties back
     to the cascade. */
  animation: enter 0.9s var(--ease-soft) backwards;
  animation-delay: var(--enter-delay, 0ms);
}
@keyframes enter {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
.nav.enter { --enter-delay: 120ms; }
@media (prefers-reduced-motion: reduce) {html { scroll-behavior: auto; }.enter { animation: enter-fade 0.3s ease backwards; animation-delay: 0ms; }
}
.nav { view-transition-name: nav; }
footer { view-transition-name: footer; }
@media (prefers-reduced-motion: no-preference) {::view-transition-old(root) { animation: vt-leave 140ms ease both; }::view-transition-new(root) { animation: vt-arrive 320ms var(--ease-soft) both; }
}
@keyframes vt-leave { to   { opacity: 0; } }
@keyframes vt-arrive { from { opacity: 0; transform: translateY(8px); } }


/* Asked for no motion: the pages still swap without a flash, but
   nothing slides. */@media (prefers-reduced-motion: reduce) {::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none; }
}


/* ---------- Nav — liquid muted glass, reveals on scroll-up ---------- */
.nav {
  /* Pinned here on purpose: inheriting an article's line-height is what
     made the navbar render differently inside a reading page. */
  line-height: 1.6;
  position: sticky;
  top: 14px;
  /* Nothing else on the site claims a stacking order, so this only has to beat
     the grid's z-index:1 — but it costs nothing to be unambiguous. Note the
     dead-nav bug was NEVER z-index: .nav.tucked's pointer-events:none was
     applying while animation-fill-mode:both pinned the transform that should
     have carried the bar off screen. See the .enter comment above. */
  z-index: 1000;
  width: min(calc(100% - 28px), 1040px);
  margin: 14px auto 0;
  transition:
    transform 0.45s var(--ease-soft),
    opacity 0.45s var(--ease-soft);
}
.nav-surface {
  width: 100%;
  min-height: 70px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  padding: 12px 12px 12px 20px;
  border-radius: var(--r-pill);
  background: rgba(16, 16, 18, 0.55);
  -webkit-backdrop-filter: blur(22px) saturate(1.5);
  backdrop-filter: blur(22px) saturate(1.5);
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),   /* glass top light  */
    inset 0 -1px 0 rgba(0, 0, 0, 0.35),        /* glass under-edge */
    0 12px 40px rgba(0, 0, 0, 0.45);
}
.nav.tucked {
  transform: translateY(-160%);
  opacity: 0;
  pointer-events: none;
}
.nav.tucked:focus-within {
  transform: none;
  opacity: 1;
  pointer-events: auto;
}
.nav .brand {
  display: flex;
  align-items: center;
  min-width: 44px;
  min-height: 44px;
  gap: 5px;
  flex: none;
  margin-right: 26px;
}
.nav .brand-mark {
  width: 28px; height: 29px;
  display: block;
}
.nav .brand-name {
  color: var(--text-2);
  font-size: 16px;
  font-weight: 650;
  letter-spacing: -0.2px;
}
.nav .links {
  display: flex;
  align-items: center;
  flex: none;
  justify-content: flex-start;
  min-width: 0;
  gap: 26px;
  white-space: nowrap;
}
.nav .pill { margin-left: auto; }
.nav .links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--text-2);
  font-size: var(--t-nav);
  transition: color 0.25s ease;
}
.nav .links a:hover, .nav .links a:focus-visible, .nav .links a[aria-current="page"] { color: var(--text); }


/* Desktop gives the navigation its own flexible middle track. Centering the
   links inside that track keeps the open space to the brand and CTA equal. */@media (min-width: 900px) {.nav-surface {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr) max-content;
  }.nav .brand { margin-right: 0; }.nav .links { justify-self: center; }.nav .pill { margin-left: 0; }
}


/* Compact layouts use one wrapping surface. Links move to a new flex line
   only when their labels no longer fit. */@media (max-width: 899px) {.nav {
    width: min(96%, 720px);
  }.nav-surface {
    gap: 8px 20px;
    border-radius: var(--r-card);
  }
}


/* Phones hide the redundant nav CTA and let the remaining links wrap as
   available space dictates. Download actions inside the page remain. */@media (max-width: 760px) {.nav-surface {
    align-items: center;
    justify-content: flex-start;
    gap: 8px 8px;
    padding: 8px 36px;
    border-radius: 999px;
  }.nav .brand {
    min-width: 28px;
    margin-right: 0;
  }.nav .brand-name { display: none; }.nav .links {
    --nav-link-gap: clamp(10px, 3vw, 16px);
    flex: 1 1 0;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-content: center;
    gap: 0 var(--nav-link-gap);
  }.nav .links a {
    min-height: calc(16px + var(--nav-link-gap));
    font-size: 13px;
    line-height: 16px;
  }.nav > .nav-surface > .pill { display: none; }
}
@media (prefers-reduced-motion: reduce) {.nav, .nav-surface { transition-duration: 0.01ms; }
}


/* The one pill — Liquid Glass button: white, dark label (#1A1A1A) */
.pill {
  display: inline-flex; align-items: center; gap: 10px;
  white-space: nowrap;
  background: #fff;
  color: var(--btn-label);
  font-size: 19px; font-weight: 700;
  line-height: 1;
  padding: 18px 32px;
  border-radius: var(--r-pill);
  transition: transform 0.3s var(--ease-soft), background 0.3s ease;
}
.pill:hover { transform: scale(1.02); background: #ececec; }
.pill:active { transform: scale(0.97); }
.pill svg { display: block; width: 16px; height: 19px; }

/* the nav pill keeps its compact size (unchanged paddings) */
.nav .pill { min-height: 44px; font-size: 16px; padding: 13px 22px; gap: 8px; }
.nav .pill svg { width: 13px; height: 16px; }
@media (max-width: 760px) {.nav .pill { font-size: 14px; padding: 11px 15px; gap: 7px; }
}

/* very narrow (SE zoom modes, Slide Over, page-zoom): icon-only CTA */@media (max-width: 340px) {.nav .pill { font-size: 0; padding: 11px 13px; gap: 0; }.nav .pill svg { width: 12px; height: 14px; }
}


/* ---------- Footer ----------
   Ten links in one centred row told a visitor nothing about which
   of them mattered. They are the same ten, grouped, with the brand
   given its own block and a rule to part the footer from the page. */
footer {
  max-width: 1080px;
  margin: 0 auto;
  padding: clamp(56px, 8vh, 80px) var(--s-screen-pad) 72px;
}
.footer-top {
  display: grid;
  grid-template-columns: minmax(240px, 1.5fr) repeat(3, minmax(0, 1fr));
  gap: clamp(32px, 5vw, 64px);
  padding-top: clamp(40px, 6vh, 56px);
  border-top: 1px solid var(--hair);
}
/* A page that exists in more than one language adds a fourth column: its
   languages (written by scripts/l10n.mjs). Narrow screens keep their own
   two- and one-column grids below. */
@media (min-width: 861px) {.footer-top:has(.footer-languages) {
    grid-template-columns: minmax(240px, 1.5fr) repeat(4, minmax(0, 1fr));
  }
}
footer .wordmark {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 22px;
  font-weight: 650;
  letter-spacing: -0.2px;
  color: var(--text);
}
footer .wordmark-mark { width: 38px; height: 39px; display: block; }
.footer-line {
  max-width: 28ch;
  margin-top: 16px;
  color: var(--text-2);
  font-size: 15px;
  line-height: 1.55;
}
.footer-contact {
  display: inline-block;
  margin-top: 18px;
  color: var(--text);
  font-size: 15px;
  border-bottom: 1px solid var(--hair-2);
  transition: border-color 0.25s ease;
}
.footer-contact:hover, .footer-contact:focus-visible { border-bottom-color: var(--text); }
.footer-column h2 {
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: normal;
}
.footer-column ul {
  margin-top: 16px;
  list-style: none;
}
.footer-column li + li { margin-top: 11px; }
.footer-column a {
  color: var(--text-2);
  font-size: 15px;
  transition: color 0.25s ease;
}
.footer-column a:hover, .footer-column a:focus-visible, .footer-column a[aria-current="page"] { color: var(--text); }
.signoff {
  margin-top: clamp(48px, 7vh, 72px);
  color: var(--text-3);
  font-size: var(--t-micro);
}
@media (max-width: 860px) {.footer-top {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 40px 32px;
  }.footer-brand { grid-column: 1 / -1; }
}
@media (max-width: 420px) {.footer-top { grid-template-columns: 1fr; gap: 34px; }
}

/* ------------------------------------------------------------------
   Reduced motion
   Each stylesheet used to name its own subset by hand, and the subsets
   drifted: a hover that scaled the download pill survived in one, a
   border transition in another. The retired journal-workshops.css ended
   with a blanket kill, which is the right shape — a reader who asks for
   no motion should not depend on someone remembering them.

   Transitions stop outright. Animations fall back to whatever a rule
   below sets, because .enter deliberately swaps its 10px rise for a
   plain fade here: a fade is the accommodation, not a violation of it.
   ------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition: none !important;
    animation-name: none;
    scroll-behavior: auto !important;
  }
}


/* ------------------------------------------------------------------
   Paper
   A black page prints as a black page: browsers do not paint background
   colours, so white text lands on white paper. Thirteen pages carried
   this rule and twenty-one did not, because it lived in the per-page
   stylesheets that were retired. It belongs with the chrome — the one
   file every page loads.
   ------------------------------------------------------------------ */

@media print {
  @page { margin: 16mm; }

  :root {
    --bg: #fff;
    --lum-1: #000;
    --lum-2: #000;
    --lum-3: #000;
    --lum-4: #333;
    --lum-e: #000;
    --text: #000;
    --text-2: #333;
    --text-read: #000;
    --card-line: #000;
    --card-line-hi: #000;
    --border: rgba(0, 0, 0, 0.25);
    --hair: rgba(0, 0, 0, 0.25);
  }

  html,
  body {
    background: #fff;
    color: #000;
    overflow: visible;
  }

  /* Chrome is for a screen. So is anything the reader would have
     clicked: no control takes ink, and none of them carries the text. */
  .nav,
  footer,
  .skip,
  .ring-stage,
  .light-stage,
  .word-search,
  [role="search"],
  input,
  select,
  button { display: none !important; }

  .enter { animation: none; }

  /* The reading column is the page now; there is nothing beside it to
     leave air for. */
  main.read,
  .editorial-main {
    max-width: none;
    padding: 0;
  }

  main a { color: #000; text-decoration-color: #000; }

  /* Paper has no disclosure triangles. Whatever the page keeps behind a
     control is part of what the reader is printing — the whole library
     of prompts, not the one card left on screen. The exceptions are the
     kinds that are never prose: a live region, a dialog, a label for a
     screen reader. Naming kinds rather than pages is what keeps this
     from going stale the next time a page adds a note. */
  main [hidden]:not(dialog, [role="status"], [role="alert"], [aria-live], .sr-only, template) {
    display: block !important;
  }

  main :is(img, figure, table, li) { break-inside: avoid; }
}
