/* ============================================================================
   gabriel no café — a coffee zine
   ----------------------------------------------------------------------------
   The page is built as a sequence of "pages" (.page), each one carrying its own
   background/ink/accent palette. Rhythm comes from those palettes alternating —
   dark, dark, CREAM, dark, dark, CREAM — not from dividers. The cream page is
   rare on purpose: it lands like a printed page flashing through a dark reel.

   Type has four jobs and never mixes them:
     Anton      → zine structure (chapter numbers, chapter titles, back cover)
     Fredoka    → Gabriel's voice (wordmark, product names)
     Space Mono → metadata (labels, notes, CTAs, folio)
     Caveat     → handwriting (margin notes)
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  /* --- ink family: three dark tints, each with its own temperature --------- */
  --ink:        #14100c;  /* base near-black */
  --ink-warm:   #1c1410;  /* brown-ink, chapter pages */
  --ink-deep:   #0d0b09;  /* near-absolute, interludes + back cover */

  /* --- paper -------------------------------------------------------------- */
  --paper:      #f4ece0;
  --paper-2:    #fbf7f0;

  /* --- accents ------------------------------------------------------------ */
  --burnt:      #c4562a;
  --amber:      #e8a856;
  --lime:       #dfe2a8;
  --coffee:     #6b4a2f;

  /* --- per-page tokens: every .page overrides these ----------------------- */
  --bg:      var(--ink);
  --fg:      var(--paper);
  --accent:  var(--amber);
  --muted:   rgba(244, 236, 224, .58);
  /* .30 measured 2.5:1 against --ink and this token carries real content —
     the affiliate note, the copy-link button, chapter counts. .52 lands at
     ~5:1 (AA) while staying clearly quieter than --muted. */
  --faint:   rgba(244, 236, 224, .52);
  --rule:    rgba(244, 236, 224, .14);

  /* --- editorial widths --------------------------------------------------- */
  --gutter:  20px;
  --wide:    1320px;   /* full editorial spread */
  --column:  1080px;   /* standard chapter column */
  --narrow:  640px;    /* reading measure */

  /* --- spacing scale -------------------------------------------------------
     Small, fixed steps for anything relating two adjacent pieces of the same
     idea (a label to its title, a button to its neighbour). Section-level
     rhythm (the gap BETWEEN ideas) stays on its own clamp()s below — that's
     deliberately larger and viewport-aware, not on this scale. --------------- */
  --sp-1:  4px;
  --sp-2:  8px;
  --sp-3:  12px;
  --sp-4:  16px;
  --sp-5:  24px;
  --sp-6:  32px;
  --sp-7:  48px;

  /* --- type scale — six tiers, one job each -------------------------------
     hero      → the cover headline, nothing bigger exists on the page
     display   → chapter numbers/titles, back-cover sign-off
     product   → a product's name, the protagonist of its fiche
     body      → reading copy
     meta      → labels, folio, CTAs — always Space Mono, always quiet
     hand      → Caveat annotations — the one handwritten voice, one size ---- */
  --fs-hero:    clamp(72px, 19vw, 250px);
  --fs-display: clamp(46px, 12vw, 130px);
  --fs-product: clamp(30px, 6.4vw, 56px);
  --fs-body:    clamp(13px, 1.4vw, 14px);
  --fs-meta:    10.5px;
  --fs-hand:    clamp(19px, 2.8vw, 26px);
}

html {
  scroll-behavior: smooth;
  overflow-x: hidden;
  /* the folio bar is sticky; anchors must not slide under it */
  scroll-padding-top: 72px;
  background: var(--ink);
}

body {
  font-family: 'Space Mono', monospace;
  background: var(--ink);
  color: var(--paper);
  /* overflow-x on body (even x-only) is a known iOS Safari bug that breaks
     position:sticky on direct children — the masthead needs the body clean.
     html's own overflow-x:hidden above already blocks horizontal scroll. */
  max-width: 100vw;
  position: relative;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* the actual horizontal-scroll guard now lives here instead of on body —
   #app holds every full-bleed photo/section, .masthead is a sibling so its
   sticky positioning is never affected by this element's own overflow */
#app { overflow-x: hidden; }

img { max-width: 100%; display: block; }
a { -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* visually hidden but still reachable by screen readers — for content
   that has a decorative, aria-hidden twin elsewhere on the page */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* invisible until a keyboard user tabs to it — then jumps straight past
   the masthead to the main content */
.skip-link {
  position: absolute;
  top: -100px;
  left: 12px;
  z-index: 200;
  background: var(--ink);
  color: var(--paper);
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  font-weight: 700;
  padding: 12px 18px;
  text-decoration: none;
  border: 1px solid var(--amber);
  transition: top .15s ease;
}
.skip-link:focus { top: 12px; }

/* --- analog grain: fixed, so it never repaints while scrolling ------------ */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 60;
  opacity: .042;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ============================================================================
   PAGE SYSTEM
   Each .page paints its own background edge-to-edge and re-declares the
   palette tokens its children inherit. Colour change *is* the divider.
   ========================================================================== */

.page {
  position: relative;
  background: var(--bg);
  color: var(--fg);
  /* isolate so a page's own blend/absolute children never leak upward */
  isolation: isolate;
}

.page--ink      { --bg: var(--ink);      --fg: var(--paper); --accent: var(--amber); }
.page--ink-warm { --bg: var(--ink-warm); --fg: var(--paper); --accent: var(--burnt); }
.page--ink-deep { --bg: var(--ink-deep); --fg: var(--paper); --accent: var(--lime);  }

/* the rare one: reads as an actual printed page dropped into the dark reel */
.page--paper {
  --bg: var(--paper);
  --fg: var(--ink);
  --accent: var(--burnt);
  --muted: rgba(20, 16, 12, .62);
  --faint: rgba(20, 16, 12, .62);   /* ~5:1 on --paper (was .34 → 2.6:1) */
  --rule:  rgba(20, 16, 12, .16);
}
/* paper pages get a whisper of vignette — scanner, not vignette-filter */
.page--paper::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background: radial-gradient(120% 90% at 50% 40%, transparent 55%, rgba(107, 74, 47, .07) 100%);
}
.page--paper > * { position: relative; z-index: 1; }

/* --- shared inner widths -------------------------------------------------- */
.wrap        { max-width: var(--column); margin-inline: auto; padding-inline: var(--gutter); }
.wrap--wide  { max-width: var(--wide);   margin-inline: auto; padding-inline: var(--gutter); }
.wrap--narrow{ max-width: var(--narrow); margin-inline: auto; padding-inline: var(--gutter); }

/* ============================================================================
   TYPE PRIMITIVES
   ========================================================================== */

.t-display {
  font-family: 'Anton', 'Fredoka', sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  line-height: .84;
  letter-spacing: -.005em;
}

.t-voice {
  font-family: 'Fredoka', sans-serif;
  font-weight: 700;
  line-height: 1.05;
}

.t-meta {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 10.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
}

.t-hand {
  font-family: 'Caveat', cursive;
  font-weight: 600;
  line-height: 1.3;
}

.t-body {
  font-family: 'Space Mono', monospace;
  font-weight: 400;
  font-size: var(--fs-body);
  line-height: 1.72;
  color: var(--muted);
}

/* margin note: a rule on the left, like an annotation in a magazine gutter */
.note-side {
  border-left: 2px solid var(--accent);
  padding-left: 14px;
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  line-height: 1.7;
  color: var(--muted);
  max-width: 34ch;
}

/* ============================================================================
   MASTHEAD — a publication header, not a navbar
   ========================================================================== */

.masthead {
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in srgb, var(--ink) 92%, transparent);
  backdrop-filter: saturate(140%) blur(8px);
  border-bottom: 1px solid rgba(244, 236, 224, .1);
  transition: padding .25s ease, background-color .4s ease;
}
/* the sticky header borrows the current chapter's own ink tint — one more
   quiet confirmation of "you're in a different chapter now," right where
   the eye already lands to check position. Text stays --paper regardless
   (every ink-* palette is dark), so contrast never suffers. */
.masthead[data-palette="page--ink-warm"] { background: color-mix(in srgb, var(--ink-warm) 92%, transparent); }
.masthead[data-palette="page--ink-deep"] { background: color-mix(in srgb, var(--ink-deep) 92%, transparent); }

.masthead-in {
  max-width: var(--wide);
  margin-inline: auto;
  padding: 14px var(--gutter);
  padding-top: max(14px, calc(env(safe-area-inset-top) + 8px));
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 56px;
}

.mast-brand {
  font-family: 'Fredoka', sans-serif;
  font-weight: 700;
  font-size: 16px;
  color: var(--paper);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  letter-spacing: -.01em;
}
.mast-brand .star { color: var(--amber); font-size: 13px; }

/* desktop: navigation distributed across the bar, numbered like a contents
   list. Every chapter renders here now (not just the first 3) — scrolls
   horizontally on its own, invisibly, if the list ever outgrows the bar
   instead of wrapping or overflowing the page. */
.mast-nav {
  display: none;
  gap: 22px;
  align-items: center;
  margin-left: 30px;
  overflow-x: auto;
  scrollbar-width: none;
  min-width: 0;
}
.mast-nav::-webkit-scrollbar { display: none; }
.mast-nav a {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 10.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(244, 236, 224, .55);
  text-decoration: none;
  padding: 6px 0;
  border-bottom: 1px solid transparent;
  transition: color .18s, border-color .18s;
}
.mast-nav a .n { color: var(--amber); margin-right: 7px; }
.mast-nav a:hover, .mast-nav a:focus-visible { color: var(--paper); border-bottom-color: var(--amber); }
.mast-nav a.current { color: var(--paper); border-bottom-color: var(--amber); }

/* running folio — tells you which chapter you're in, like a magazine footer.
   On mobile there's no room beside the brand, so the folio REPLACES it once
   you've scrolled into a chapter — the one place you most need to know
   where you are, since the desktop mast-nav's .current highlight doesn't
   exist there either. */
.mast-folio {
  display: none;
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(244, 236, 224, .62);   /* AA — was .4 (3.5:1) */
  margin-left: auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 30ch;
}
.mast-folio .n { color: var(--amber); }

@media (max-width: 759px) {
  .masthead[data-current-anchor] .mast-brand { display: none; }
  .masthead[data-current-anchor] .mast-folio {
    display: block;
    font-size: 11px;
    color: var(--paper);
    max-width: 62vw;
  }
}

.mast-right {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-shrink: 0;
}
.mast-folio + .mast-right { margin-left: 20px; }

.mast-index-btn {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 10.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--paper);
  background: none;
  border: none;
  cursor: pointer;
  padding: 10px 0;
  min-height: 40px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.mast-index-btn .bars {
  display: inline-flex;
  flex-direction: column;
  gap: 3px;
  width: 15px;
}
.mast-index-btn .bars i {
  height: 1.5px;
  background: var(--amber);
  display: block;
  transition: transform .22s ease;
}
.mast-index-btn .bars i:nth-child(2) { width: 68%; }
.mast-index-btn:hover .bars i:nth-child(2) { transform: translateX(32%); }

.lang {
  display: flex;
  align-items: center;
  gap: 5px;
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  letter-spacing: .1em;
}
.lang button {
  background: none;
  border: none;
  font: inherit;
  letter-spacing: inherit;
  color: rgba(244, 236, 224, .62);   /* AA — the inactive language is still a control */
  cursor: pointer;
  padding: 10px 2px;
  min-height: 40px;
  text-transform: uppercase;
  font-weight: 700;
}
.lang button.active { color: var(--amber); }
.lang .sep { color: rgba(244, 236, 224, .38); }

/* ============================================================================
   INDEX OVERLAY — the contents page of the zine
   ========================================================================== */

.index-overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: var(--paper);
  color: var(--ink);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 0 60px;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity .28s ease, transform .28s ease, visibility .28s;
}
.index-overlay.open { opacity: 1; visibility: visible; transform: none; }

.index-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px var(--gutter);
  padding-top: max(18px, calc(env(safe-area-inset-top) + 12px));
  border-bottom: 1.5px solid rgba(20, 16, 12, .18);
  position: sticky;
  top: 0;
  background: var(--paper);
  z-index: 2;
}
.index-top .lbl {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 10.5px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--coffee);
}
.index-close {
  background: none;
  border: none;
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink);
  cursor: pointer;
  padding: 10px 0;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.index-close:hover { color: var(--burnt); }

.index-list { max-width: var(--wide); margin-inline: auto; padding: 8px var(--gutter) 0; }

.index-group-label {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--burnt);
  padding: 26px 0 6px;
}

.index-item {
  display: flex;
  align-items: baseline;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid rgba(20, 16, 12, .12);
  text-decoration: none;
  color: var(--ink);
  transition: color .18s;
}
.index-item:hover, .index-item:focus-visible { color: var(--burnt); }
.index-item .num {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .1em;
  color: var(--burnt);
  flex-shrink: 0;
  width: 2.5ch;
}
.index-item .name {
  font-family: 'Anton', sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  font-size: clamp(26px, 7vw, 44px);
  line-height: 1;
  letter-spacing: -.01em;
  flex: 1;
  overflow-wrap: break-word;
  min-width: 0;
}
.index-item .count {
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  color: rgba(20, 16, 12, .60);   /* AA — was .45 (3:1) */
  flex-shrink: 0;
}
.index-item.current .name { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 5px; }

.index-foot {
  max-width: var(--wide);
  margin-inline: auto;
  padding: 30px var(--gutter) 0;
  display: flex;
  flex-wrap: wrap;
  gap: 20px 26px;
  align-items: center;
}
.index-foot .soon {
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(20, 16, 12, .60);   /* AA — was .38 (2.4:1) */
  cursor: default;
}
.index-foot a {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1.5px solid var(--burnt);
  padding-bottom: 2px;
}
.index-foot a:hover { color: var(--burnt); }

body.index-open { overflow: hidden; }

/* ============================================================================
   01 — THE COVER
   ========================================================================== */

.cover {
  --bg: var(--ink);
  position: relative;
  padding: clamp(28px, 6vw, 70px) 0 clamp(40px, 7vw, 90px);
  overflow: hidden;
}

.cover-in {
  max-width: var(--wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
  position: relative;
}

.cover-kicker {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 10.5px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--amber);
  margin-bottom: clamp(20px, 4vw, 42px);
  display: block;
}

/* the headline: type as the composition, breaking the margin on purpose */
.cover-title {
  font-family: 'Anton', 'Fredoka', sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  font-size: var(--fs-hero);
  line-height: .82;
  letter-spacing: -.015em;
  color: var(--paper);
  position: relative;
  z-index: 2;
  overflow-wrap: break-word;
}
.cover-title .l1 { display: block; margin-left: -.02em; }
.cover-title .l2 { display: block; }
.cover-title .l3 { display: block; position: relative; width: fit-content; }
.cover-title .dot { color: var(--burnt); }

/* the one big doodle on the page — a circle drawn around the last word */
.cover-circle {
  position: absolute;
  left: -6%;
  top: -14%;
  width: 112%;
  height: 128%;
  pointer-events: none;
  overflow: visible;
}
.cover-circle path {
  fill: none;
  stroke: var(--amber);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-dasharray: var(--len, 1200);
  stroke-dashoffset: var(--len, 1200);
}
.cover-circle.drawn path { animation: draw 900ms cubic-bezier(.6, .05, .3, 1) forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }

/* photo overlaps the type — layered, not a neighbouring column */
.cover-photo {
  position: relative;
  z-index: 1;
  margin-top: -6%;
  margin-left: auto;
  width: min(62%, 340px);
  aspect-ratio: 4 / 5;
}
.cover-photo .ph { height: 100%; }
.cover-photo .ph img { object-position: center var(--photo-y, 68%); }

.cover-meta {
  margin-top: clamp(26px, 4vw, 48px);
  display: flex;
  flex-wrap: wrap;
  gap: 24px 40px;
  align-items: flex-end;
  justify-content: space-between;
  border-top: 1px solid var(--rule);
  padding-top: 20px;
}
/* a handwritten note scrawled across almost the whole cover photo, bleeding
   past its edges into the page — positioned against .cover-in (which is
   already position:relative and never has an ambiguous/auto height, unlike
   .cover-photo at mobile widths, which is what made an earlier version of
   this invisible on iOS Safari). Sits low, clear of the face. Every
   character is its own span (typeChars() in render-shared.js) so it can be
   revealed one letter at a time, like it's being written in real time —
   triggered by the same "drawn" IntersectionObserver the doodle SVGs use. */
.cover-role {
  position: absolute;
  left: 4%;
  right: 4%;
  bottom: -4%;
  z-index: 2;
  text-align: right;
  pointer-events: none;
}
.cover-role > span {
  display: inline-block;
  font-family: 'Caveat', cursive;
  font-weight: 600;
  font-size: clamp(26px, 8vw, 68px);
  line-height: 1.15;
  color: var(--paper);
  text-shadow: 0 2px 18px rgba(0, 0, 0, .6);
  transform: rotate(-2deg);
}
.cover-role > span > span { opacity: 0; }
.cover-role.drawn > span > span {
  animation: cover-role-letter .01s linear forwards;
  animation-delay: calc(.2s + var(--i) * 28ms);
}
@keyframes cover-role-letter { to { opacity: 1; } }
.cover-scroll {
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--faint);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  text-decoration: none;
}
.cover-scroll:hover { color: var(--amber); }
.cover-scroll .arr { animation: nudge 2.4s ease-in-out infinite; }
@keyframes nudge { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(3px); } }

/* ============================================================================
   02 — COLOPHON (who Gabriel is + contents)
   ========================================================================== */

.colophon { padding: clamp(44px, 7vw, 96px) 0; }
.colophon-grid {
  max-width: var(--wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: grid;
  gap: clamp(32px, 5vw, 70px);
}

.colophon-lead {
  font-family: 'Fredoka', sans-serif;
  font-weight: 700;
  font-size: clamp(21px, 3.2vw, 36px);
  line-height: 1.28;
  letter-spacing: -.01em;
  color: var(--fg);
  max-width: 20ch;
}
.colophon-body { margin-top: 20px; max-width: 46ch; }
.colophon-hand {
  font-family: 'Caveat', cursive;
  font-weight: 600;
  font-size: var(--fs-hand);
  color: var(--amber);
  margin-top: var(--sp-5);
  line-height: 1.35;
}

.socials { display: flex; flex-wrap: wrap; gap: 8px 22px; margin-top: 26px; }
.social-a {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--fg);
  text-decoration: none;
  border-bottom: 1.5px solid var(--accent);
  padding: 8px 0 3px;
  min-height: 38px;
  display: inline-flex;
  align-items: center;
  transition: color .18s;
}
.social-a:hover, .social-a:focus-visible { color: var(--accent); }

/* ============================================================================
   03 — EVERY SINGLE DAY (dailyUse, as a typographic band)
   ========================================================================== */

.daily { padding: clamp(40px, 6vw, 84px) 0; overflow: hidden; }
.daily-head {
  max-width: var(--wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin-bottom: clamp(20px, 3vw, 34px);
}
.daily-head .lbl {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 10.5px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--accent);
}
.daily-head .rule { flex: 1; height: 1px; background: var(--rule); }

.daily-list {
  max-width: var(--wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.daily-item {
  display: flex;
  align-items: baseline;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--rule);
  text-decoration: none;
  color: var(--fg);
  transition: color .2s;
}
.daily-item:first-child { border-top: 1px solid var(--rule); }
.daily-item .nm {
  font-family: 'Anton', sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  font-size: clamp(24px, 5.2vw, 52px);
  line-height: 1;
  letter-spacing: -.005em;
  transition: transform .2s ease;
  overflow-wrap: break-word;
  min-width: 0;
}
.daily-item .lb {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--faint);
  margin-left: auto;
  flex-shrink: 0;
  white-space: nowrap;
}
.daily-item:hover { color: var(--accent); }
.daily-item:hover .nm { transform: translateX(6px); }

/* ============================================================================
   CHAPTERS — opener + fiches
   ========================================================================== */

/* no padding-bottom here on purpose — the last product's photo runs right
   into the next chapter's own opening (which already carries a big
   padding-top). A gap here read as a stray empty beat between two
   chapters, especially when the one in between is short. */

/* a small step of luminosity separates the chapter's own opening beat from
   the product list beneath it — same palette, no new colour, just enough
   of a plane change that "header" and "list" stop reading as one wash of
   the same background. The tint is a full-bleed ::before (chapter-open
   itself stays a centred/padded container, so the tint can't just live on
   its own background without being clipped to --wide). */
.chapter-open {
  max-width: var(--wide);
  margin-inline: auto;
  padding: clamp(46px, 8vw, 110px) var(--gutter) clamp(34px, 5vw, 60px);
  position: relative;
  display: grid;
  gap: clamp(22px, 3vw, 44px);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.chapter-open::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 100vw;
  transform: translateX(-50%);
  background: color-mix(in srgb, var(--fg) 4%, transparent);
  border-bottom: 1px solid var(--rule);
  z-index: -1;
  transition: background-color .2s ease;
}
.chapter-open:hover::before { background: color-mix(in srgb, var(--fg) 7%, transparent); }
.chapter-open:focus-visible { outline: 2px solid var(--accent); outline-offset: -4px; }

/* the little "reveal the products" cue, beside the item count */
.chapter-toggle-hint {
  display: inline-flex;
  align-items: center;
  margin-left: 10px;
}
.chapter-toggle-arr {
  display: inline-block;
  color: var(--faint);
  transition: transform .25s cubic-bezier(.6, .05, .3, 1);
}
.chapter-open[aria-expanded="true"] .chapter-toggle-arr { transform: rotate(180deg); }

.chapter-mark { position: relative; }

/* the giant number sits behind the word on mobile, beside it on desktop */
.chapter-num {
  font-family: 'Anton', sans-serif;
  font-weight: 400;
  font-size: clamp(120px, 34vw, 250px);
  line-height: .74;
  letter-spacing: -.03em;
  color: var(--accent);
  opacity: .16;
  position: absolute;
  top: -.12em;
  left: -.04em;
  pointer-events: none;
  user-select: none;
  z-index: 0;
}

.chapter-title {
  font-family: 'Anton', 'Fredoka', sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  font-size: var(--fs-display);
  line-height: .86;
  letter-spacing: -.015em;
  color: var(--fg);
  position: relative;
  z-index: 1;
  overflow-wrap: break-word;
  width: fit-content;
  max-width: 100%;
}

/* hand-drawn underline under the chapter word */
.chapter-underline {
  display: block;
  width: 100%;
  height: 12px;
  margin-top: 4px;
  overflow: visible;
}
.chapter-underline path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-dasharray: var(--len, 400);
  stroke-dashoffset: var(--len, 400);
}
.chapter-underline.drawn path { animation: draw 700ms cubic-bezier(.6, .05, .3, 1) forwards; }

.chapter-intro { display: flex; align-items: center; gap: 18px; }
.chapter-count {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 10.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--faint);
}

.chapter-items {
  max-width: var(--wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ============================================================================
   PHOTO SLOTS + PLACEHOLDERS
   Real images render as-is. Empty slots render a clearly-marked placeholder
   so the composition holds its shape until Gabriel drops the photo in.
   ========================================================================== */

.ph {
  position: relative;
  width: 100%;
  background: color-mix(in srgb, var(--fg) 5%, transparent);
  border: 1px solid var(--rule);
  overflow: hidden;
}
.ph img { width: 100%; height: 100%; object-fit: cover; }
.ph--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  background-image:
    repeating-linear-gradient(
      -45deg,
      transparent 0 11px,
      color-mix(in srgb, var(--fg) 4%, transparent) 11px 12px
    );
}
.ph--empty span {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 9.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--faint);
  text-align: center;
  padding: 10px;
  line-height: 1.8;
}
.ph--4x5  { aspect-ratio: 4 / 5; }
.ph--3x4  { aspect-ratio: 3 / 4; }
.ph--1x1  { aspect-ratio: 1 / 1; }
.ph--16x9 { aspect-ratio: 16 / 9; }
.ph--3x2  { aspect-ratio: 3 / 2; }
.ph img { transform-origin: center; }

/* ============================================================================
   PRODUCT PHOTO CAROUSEL — same frame, 2+ photos. Native horizontal
   scroll-snap does the swiping (mobile) for free; arrows + dots (desktop,
   also touch-usable) call scrollTo on the same track — no external library.
   ========================================================================== */
.ph--carousel { overflow: visible; border: none; background: none; }
.ph--carousel .ph-track {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  border: 1px solid var(--rule);
  background: color-mix(in srgb, var(--fg) 5%, transparent);
  /* hide the native scrollbar — the dots are the real affordance */
  scrollbar-width: none;
}
.ph--carousel .ph-track::-webkit-scrollbar { display: none; }
.ph-slide {
  position: relative;
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
.ph-slide img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* arrows: desktop/pointer only — touch already has native swipe */
.ph-nav {
  display: none;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: none;
  background: color-mix(in srgb, var(--ink) 55%, transparent);
  color: var(--paper);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  z-index: 2;
  transition: background-color .15s ease;
}
.ph-nav:hover { background: color-mix(in srgb, var(--ink) 75%, transparent); }
.ph-nav--prev { left: 10px; }
.ph-nav--next { right: 10px; }
@media (hover: hover) and (pointer: fine) {
  .ph-nav { display: flex; }
}

.ph-dots {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 10px;
  z-index: 2;
  display: flex;
  justify-content: center;
  gap: 6px;
  pointer-events: none;
}
.ph-dot {
  pointer-events: auto;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  border: none;
  padding: 0;
  background: rgba(255, 255, 255, .4);
  cursor: pointer;
  transition: background-color .15s ease, transform .15s ease;
}
.ph-dot.is-active { background: var(--paper); transform: scale(1.3); }

/* ============================================================================
   PRODUCT PHOTO TREATMENTS — the frame never changes size; the art
   direction happens inside it. Five reusable interventions, one per photo,
   chosen in admin (item.editorialTreatment). .ph already clips overflow, so
   anything bleeding toward an edge is safely cropped by the frame — never
   the page.
   ========================================================================== */

.ph-treat {
  position: absolute;
  z-index: 2;
  pointer-events: none;
  max-width: calc(100% - 16px);
}
.ph-treat.pos-tl { top: 10px; left: 10px; }
.ph-treat.pos-tr { top: 10px; right: 10px; text-align: right; }
.ph-treat.pos-bl { bottom: 10px; left: 10px; }
.ph-treat.pos-br { bottom: 10px; right: 10px; text-align: right; }
.ph-treat.pos-center { top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; }

/* A — oversized type: one big word, printed onto the photo, low contrast so
   the photograph still reads underneath. */
.ph-treat--type {
  font-family: 'Fredoka', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(34px, 8.5vw, 78px);
  line-height: .86;
  letter-spacing: -.02em;
  color: var(--paper);
  opacity: .85;
  mix-blend-mode: overlay;
  overflow-wrap: break-word;
}
.ph-treat--type.pos-bl, .ph-treat--type.pos-br { margin: 0 -6px; }

/* B — handwritten note: a short aside with a small drawn arrow, taped on. */
.ph-treat--note {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: 'Caveat', cursive;
  font-weight: 600;
  font-size: clamp(18px, 3vw, 23px);
  color: var(--paper);
  background: color-mix(in srgb, var(--ink) 60%, transparent);
  padding: 5px 12px 6px;
  transform: rotate(-2deg);
}
.ph-treat--note .note-arrow { width: 26px; height: 22px; flex-shrink: 0; overflow: visible; }
.ph-treat--note .note-arrow path { fill: none; stroke: var(--paper); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }

/* C — editorial number: big outlined numeral, a graphic mark, not a label. */
.ph-treat--number {
  font-family: 'Fredoka', sans-serif;
  font-weight: 700;
  font-size: clamp(64px, 15vw, 132px);
  line-height: .8;
  color: transparent;
  -webkit-text-stroke: 2px var(--paper);
  paint-order: stroke fill;
  opacity: .65;
}

/* D — type across: a sash of text crossing the frame at a slight tilt. */
.ph-treat--across {
  position: absolute;
  left: -6%;
  right: -6%;
  top: 50%;
  transform: translateY(-50%) rotate(-3deg);
  background: var(--accent);
  color: var(--ink);
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  font-size: clamp(12px, 2vw, 16px);
  text-align: center;
  padding: 9px 4px;
  max-width: none;
}

/* E — minimal doodle: a single loose mark, for breathing room between
   stronger compositions. */
.ph-treat--doodle svg { width: 34px; height: 34px; overflow: visible; }
.ph-treat--doodle path { fill: none; stroke: var(--paper); stroke-width: 2.2; stroke-linecap: round; }

@media (max-width: 759px) {
  .ph-treat--type { font-size: clamp(30px, 13vw, 60px); }
  .ph-treat--number { font-size: clamp(52px, 24vw, 100px); }
}

/* ============================================================================
   FICHES — three editorial layouts, alternating by position
   ========================================================================== */

.fiche {
  padding: clamp(30px, 4.5vw, 60px) 0;
  border-top: 1px solid var(--rule);
  position: relative;
}
.fiche:first-child { border-top: none; }

.fiche-label {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--accent);
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.fiche-flag {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 9px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--faint);
  border: 1px solid var(--rule);
  padding: 3px 8px;
}

.fiche-name {
  font-family: 'Fredoka', sans-serif;
  font-weight: 700;
  font-size: var(--fs-product);
  line-height: 1.02;
  letter-spacing: -.02em;
  /* a shade quieter than the chapter title's full-strength --fg — products
     read calmer than the opener that introduces them, weight not just size */
  color: color-mix(in srgb, var(--fg) 92%, transparent);
  margin-bottom: var(--sp-3);
  overflow-wrap: break-word;
}

.fiche-desc {
  font-family: 'Space Mono', monospace;
  font-size: var(--fs-body);
  line-height: 1.72;
  color: var(--muted);
  max-width: 52ch;
}

/* the personal aside, pulled from the last sentence of the description */
.fiche-note {
  font-family: 'Caveat', cursive;
  font-weight: 600;
  font-size: var(--fs-hand);
  line-height: 1.3;
  color: var(--accent);
  margin-top: var(--sp-4);
  padding-left: var(--sp-5);
  position: relative;
  max-width: 32ch;
}
.fiche-note::before {
  content: '';
  position: absolute;
  left: 0;
  top: .32em;
  bottom: .28em;
  width: 2px;
  background: var(--accent);
  opacity: .55;
}

.fiche-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  flex-wrap: wrap;
  margin-top: var(--sp-5);
}

/* ============================================================================
   BLOCK GESTURE — one optional graphic move living in the block's own empty
   space (not on the photo). item.editorialStyle picks at most one of these;
   "clean" (the default for most items) renders nothing.
   ========================================================================== */

/* personal-note: a short aside in the writer's own voice, just past the CTA.
   annotationPosition ("tr"/"br"/etc, reused from the photo-overlay system)
   only ever nudges text-align here — there's no absolute positioning inside
   a block that's still in normal document flow. */
.block-note {
  font-family: 'Caveat', cursive;
  font-weight: 600;
  font-size: var(--fs-hand);
  color: var(--accent);
  margin-top: var(--sp-5);
  transform: rotate(-1.5deg);
  max-width: 28ch;
}
.block-note.pos-tr, .block-note.pos-br { margin-left: auto; text-align: right; }

/* oversized-word: a big word as pure shape, low-contrast, never competing
   with the product name above it. Sits in flow so it can never overlap text
   or bleed past the block on narrow screens. */
.block-word {
  display: block;
  font-family: 'Anton', sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  font-size: clamp(40px, 11vw, 90px);
  line-height: .85;
  letter-spacing: -.01em;
  color: var(--accent);
  opacity: .16;
  margin-top: var(--sp-4);
  pointer-events: none;
  user-select: none;
  overflow-wrap: break-word;
}
.block-word.pos-tr, .block-word.pos-br { text-align: right; }

/* editorial-number: a big number as pure graphic — never reads as an index */
.block-number {
  display: block;
  font-family: 'Anton', sans-serif;
  font-weight: 400;
  font-size: clamp(56px, 14vw, 110px);
  line-height: .8;
  color: var(--accent);
  opacity: .18;
  margin-top: var(--sp-4);
  pointer-events: none;
  user-select: none;
}
.block-number.pos-tr, .block-number.pos-br { text-align: right; }

/* arrow-note: a short hand-drawn arrow leading into a personal aside —
   the transition device between this block and the photo/next block */
.block-arrow-note {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  margin-top: var(--sp-5);
}
.block-arrow-note .item-arrow { width: 22px; height: 40px; flex-shrink: 0; }
.block-arrow-note .item-arrow path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.block-arrow-note span {
  font-family: 'Caveat', cursive;
  font-weight: 600;
  font-size: var(--fs-hand);
  color: var(--accent);
  padding-top: 2px;
}

/* CTA is a word, not a button: underline grows from the left on hover */
.cta {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 12.5px;
  letter-spacing: .06em;
  color: var(--fg);
  text-decoration: none;
  position: relative;
  padding: 10px 0 6px;
  min-height: 40px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.cta::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 4px;
  height: 1.5px;
  background: var(--accent);
  transform: scaleX(1);
  transform-origin: left;
  transition: transform .28s cubic-bezier(.6, .05, .3, 1);
}
.cta .arr { transition: transform .28s cubic-bezier(.6, .05, .3, 1); display: inline-block; }
.cta:hover { color: var(--accent); }
.cta:hover .arr { transform: translate(2px, -2px); }
@media (hover: hover) {
  .cta::after { transform: scaleX(0); }
  .cta:hover::after, .cta:focus-visible::after { transform: scaleX(1); }
}

/* secondary action, almost invisible — as specified */
.copy-link {
  font-family: 'Space Mono', monospace;
  font-weight: 400;
  font-size: 10px;
  letter-spacing: .1em;
  color: var(--faint);
  background: none;
  border: none;
  cursor: pointer;
  padding: 10px 0;
  min-height: 38px;
  display: inline-flex;
  align-items: center;
  transition: color .18s;
}
.copy-link:hover, .copy-link:focus-visible { color: var(--muted); }
.copy-link.is-copied { color: var(--accent); }

/* --- unified item layout: text first, photo below — same order everywhere.
   Items with no photo just run text full-width (.fiche--no-media). --- */
.fiche--item { display: flex; flex-direction: column; gap: clamp(16px, 2.4vw, 24px); }
.fiche--item .fiche-media { position: relative; width: 100%; max-width: 340px; }

/* hand pointing from the copy to its photo — a gesture, not a UI control */
.item-arrow-wrap { align-self: center; flex-shrink: 0; }
.item-arrow { display: block; width: 30px; height: 68px; overflow: visible; }
.item-arrow path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --- fiche C: archive line, dense and fast -------------------------------- */
.fiche--c { padding: 16px 0; }
.fiche--c .fiche-row {
  display: flex;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
}
.fiche--c .fiche-label { margin-bottom: 6px; }
.fiche--c .fiche-name {
  font-size: clamp(19px, 3.4vw, 28px);
  margin-bottom: 0;
  flex: 1;
  min-width: 0;
}
.fiche--c .fiche-desc { font-size: 12px; margin-top: 8px; max-width: 60ch; }
.fiche--c .fiche-actions { margin-top: 10px; }
.fiche--c .cta { font-size: 11.5px; }

/* --- collapsed archive: keeps long chapters from running forever ---------- */
.more-toggle {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
  background: none;
  border: none;
  border-top: 1px solid var(--rule);
  width: 100%;
  text-align: left;
  cursor: pointer;
  padding: 20px 0;
  min-height: 46px;
  display: flex;
  align-items: center;
  gap: 10px;
  transition: color .18s;
}
.more-toggle .arr { transition: transform .24s ease; display: inline-block; }
.more-toggle[aria-expanded="true"] .arr { transform: rotate(180deg); }
.more-toggle:hover { color: var(--fg); }
.fiche-rest[hidden] { display: none; }

/* ============================================================================
   ARCHIVE — "already tried", the back of the zine
   ========================================================================== */

.archive { padding: clamp(46px, 7vw, 96px) 0; }
.archive-head {
  max-width: var(--wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
  margin-bottom: clamp(20px, 3vw, 36px);
  display: flex;
  align-items: baseline;
  gap: 16px;
  flex-wrap: wrap;
}
.archive-title {
  font-family: 'Anton', sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  font-size: clamp(30px, 7vw, 68px);
  line-height: .92;
  letter-spacing: -.01em;
  color: var(--fg);
}
.archive-sub {
  font-family: 'Space Mono', monospace;
  font-size: 11.5px;
  line-height: 1.7;
  color: var(--muted);
  max-width: 40ch;
}

/* ============================================================================
   AFFILIATE NOTE — an editorial footnote
   ========================================================================== */

.footnote {
  max-width: var(--wide);
  margin-inline: auto;
  padding: clamp(28px, 4vw, 44px) var(--gutter);
  display: flex;
  gap: 12px;
  align-items: flex-start;
  border-top: 1px solid var(--rule);
}
.footnote .star { color: var(--accent); font-size: 11px; flex-shrink: 0; line-height: 1.9; }
.footnote p {
  font-family: 'Space Mono', monospace;
  font-size: 10.5px;
  line-height: 1.85;
  color: var(--faint);
  max-width: 68ch;
}

/* ============================================================================
   BACK COVER
   ========================================================================== */

.backcover {
  min-height: 78vh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: clamp(50px, 9vw, 110px) 0 clamp(30px, 4vw, 50px);
  overflow: hidden;
}
.backcover-in {
  max-width: var(--wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
  width: 100%;
}

/* --- 1. author credit — a masthead line, not a headline. Deliberately
   quiet: it names who made this without competing with anything below. --- */
.backcover-credit { margin-bottom: clamp(40px, 6vw, 72px); }
.backcover-issue {
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 10.5px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--accent);
}
.backcover-credits {
  font-family: 'Fredoka', sans-serif;
  font-weight: 600;
  font-size: clamp(17px, 2vw, 21px);
  line-height: 1.4;
  color: var(--paper);
  margin-top: 6px;
  max-width: 32ch;
}

/* --- 2. creator gear — its own small heading, numbered groups. Name of the
   gear leads (protagonist); category is quiet metadata above it, not a
   label column. Stacks in one axis at every width — the 2-up desktop grid
   lives on .gear-group-body's own internal layout, not a page-level table. --- */
.backcover-gear {
  margin-bottom: clamp(48px, 7vw, 84px);
  max-width: 640px;
}
.gear-heading {
  display: block;
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 10.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: clamp(20px, 3vw, 28px);
}
.gear-list { display: flex; flex-direction: column; gap: clamp(18px, 2.6vw, 26px); }
.gear-group { display: flex; gap: 16px; align-items: baseline; }
.gear-number {
  flex: 0 0 auto;
  font-family: 'Space Mono', monospace;
  font-weight: 700;
  font-size: 11px;
  color: var(--accent);
  opacity: .6;
  padding-top: .15em;
}
.gear-group-body { min-width: 0; }
.gear-category {
  display: block;
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 4px;
}
.gear-items { display: flex; flex-wrap: wrap; column-gap: 14px; row-gap: 2px; }
.gear-item {
  font-family: 'Fredoka', sans-serif;
  font-weight: 600;
  font-size: clamp(17px, 2.4vw, 21px);
  color: var(--paper);
  text-decoration: none;
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
}
a.gear-item { border-bottom: 1px solid transparent; transition: border-color .18s, color .18s; }
a.gear-item:hover, a.gear-item:focus-visible { color: var(--accent); border-color: currentColor; }
.gear-item .arr { font-size: 12px; }

/* --- 3. the pause — nothing but a mark and a lot of empty space either
   side of it. The one signal that the technical part just ended. --- */
.backcover-pause {
  text-align: center;
  color: var(--accent);
  font-size: 15px;
  margin: 0 0 clamp(48px, 7vw, 84px);
}

/* --- 4. the note — a short personal aside, not more editorial prose. The
   heading uses the site's own handwriting voice, sized well below any real
   heading so it reads as a scrawled note, not a section title. Paragraphs
   get real air between them instead of running together. --- */
.backcover-note { max-width: 46ch; margin-bottom: clamp(56px, 8vw, 96px); }
.note-heading {
  font-family: 'Caveat', cursive;
  font-weight: 600;
  font-size: clamp(19px, 2.6vw, 24px);
  color: var(--amber);
  transform: rotate(-1deg);
  display: inline-block;
  margin-bottom: 14px;
}
.note-para {
  font-family: 'Space Mono', monospace;
  font-size: 12.5px;
  line-height: 1.75;
  color: var(--muted);
}
.note-para + .note-para { margin-top: 16px; }

.backcover-foot {
  max-width: var(--wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
  width: 100%;
  margin-top: clamp(40px, 6vw, 80px);
  display: flex;
  flex-wrap: wrap;
  gap: 20px 32px;
  align-items: flex-end;
  justify-content: space-between;
  border-top: 1px solid var(--rule);
  padding-top: 22px;
}
.backcover-foot .socials { margin-top: 0; }
.backcover-copy {
  font-family: 'Space Mono', monospace;
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--faint);
  line-height: 1.9;
}

/* ============================================================================
   TOAST
   ========================================================================== */

.toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%) translateY(14px);
  background: var(--amber);
  color: var(--ink);
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  padding: 11px 22px;
  opacity: 0;
  transition: opacity .25s, transform .25s;
  pointer-events: none;
  z-index: 70;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ============================================================================
   ENTRANCE — content settles in a few pixels, nothing more
   ========================================================================== */

.rise { opacity: 0; transform: translateY(14px); }
.rise.in { opacity: 1; transform: none; transition: opacity .6s ease, transform .6s cubic-bezier(.4, 0, .2, 1); }
/* a beat behind the text it follows — reading order, not two things at once */
.rise--delay.in { transition-delay: .15s; }

/* ============================================================================
   DESKTOP — real use of the width, asymmetric grids
   ========================================================================== */

@media (min-width: 760px) {
  :root { --gutter: 40px; }

  /* the nav now lists every chapter (its own .current class marks position),
     so the folio would just be a second, redundant "you are here" — and it
     used to visually collide with the nav, looking like a stray orphaned
     item floating on the opposite side of the bar. Folio stays mobile-only,
     where there's no room for the full nav list. */
  .mast-nav { display: flex; }

  /* COVER: type left, photo right, overlapping */
  .cover-in {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "kick  kick"
      "title title"
      "meta  meta";
    align-items: start;
  }
  .cover-kicker { grid-area: kick; }
  .cover-title  { grid-area: title; }
  .cover-meta   { grid-area: meta; }

  .cover-photo {
    position: absolute;
    right: var(--gutter);
    bottom: clamp(70px, 10vw, 150px);
    width: min(34%, 380px);
    margin: 0;
    z-index: 3;
  }
  .cover-title { max-width: 78%; }

  /* COLOPHON: single column, capped to a comfortable reading measure — the
     contents nav that used to fill the second column was removed */
  .colophon-grid { max-width: var(--narrow); }

  /* ITEM: text left, photo right — the wide desktop column has room for
     both side by side instead of a photo stranded under the copy. */
  .fiche--item {
    flex-direction: row;
    align-items: center;
    gap: clamp(20px, 3vw, 40px);
  }
  /* the arrow turns to point sideways, from copy to photo */
  .item-arrow { width: 68px; height: 44px; transform: rotate(-90deg); }
  .fiche--item .fiche-body  { flex: 1.2; min-width: 0; }
  .fiche--item .fiche-media { flex: 1; max-width: 380px; }

  /* the number moves out beside the word instead of sitting behind it.
     Chapters now run directly into one another (no gap between them), so
     it can no longer rise a full 100% of its own (huge) height above the
     title without bleeding into the previous chapter's space — nudged up
     by a fixed, modest amount instead. */
  .chapter-num {
    opacity: .2;
    top: auto;
    bottom: 100%;
    margin-bottom: -.5em;
    left: -.02em;
    font-size: clamp(120px, 15vw, 230px);
  }

  /* FICHE C stays a line, but pushes the CTA to the right edge */
  .fiche--c .fiche-row { flex-wrap: nowrap; align-items: baseline; }
  .fiche--c .fiche-actions { margin-top: 0; margin-left: auto; flex-shrink: 0; }

  .index-list { padding-top: 20px; }

  /* BACK COVER: credit and gear share a row (credit narrow/left, gear
     wide/right) — the wide desktop column has room for an editorial split
     instead of one long stacked column. Pause/note/sign-off stay full-width
     underneath: they're the shared closing beats, not part of that split. */
  .backcover-credit-gear {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr);
    gap: clamp(40px, 6vw, 90px);
    align-items: start;
    margin-bottom: clamp(48px, 7vw, 84px);
  }
  .backcover-credit { margin-bottom: 0; }
  .backcover-gear { margin-bottom: 0; max-width: none; }
}

@media (min-width: 1100px) {
  /* the cover headline breaks the left margin — deliberate, desktop only */
  .cover-title .l1 { margin-left: -.055em; }
}

/* ============================================================================
   MOBILE — a vertical magazine, not a stacked desktop
   ========================================================================== */

@media (max-width: 759px) {
  .cover { padding-top: 26px; }

  /* photo sits behind the type, multiplied into the dark — a real cover.
     The fade/filter goes on the <img> itself, not .cover-photo, so it
     never affects anything else layered above the photo. */
  .cover-photo {
    position: absolute;
    top: 16%;
    right: -8%;
    width: 74%;
    aspect-ratio: 4 / 5;
    margin: 0;
    z-index: 0;
  }
  .cover-photo .ph img {
    opacity: .42;
    filter: grayscale(.3) contrast(1.1);
  }
  .cover-role { bottom: -13%; }
  .cover-role span { font-size: clamp(24px, 10vw, 40px); }
  .cover-title { position: relative; z-index: 2; }
  .cover-in { padding-bottom: 0; }
  /* stays above the handwritten caption, which can bleed low enough to
     otherwise sit right under "role pra ver ↓" */
  .cover-meta { margin-top: 30px; gap: 16px; position: relative; z-index: 3; }

  /* photo bleeds edge-to-edge, breaking out of the gutter that boxes the text */
  .fiche--item .fiche-media {
    max-width: none;
    width: 100vw;
    margin-inline: calc(var(--gutter) * -1);
  }
  .fiche--item .ph { border-left: none; border-right: none; }

  .fiche--c .fiche-name { flex-basis: 100%; }

  /* chapter number moves to the empty top-right corner instead of sitting
     behind/under the title, where it clipped letters like a layout bug */
  .chapter-num {
    position: absolute;
    top: 0;
    left: auto;
    right: 0;
    font-size: clamp(48px, 13vw, 80px);
    opacity: .3;
  }
  .chapter-mark { padding-right: 25vw; }
  .chapter-open { padding-top: 54px; }

  .backcover { min-height: 68vh; }
  .backcover-foot { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 400px) {
  :root { --gutter: 18px; }
  .daily-item .lb { display: none; }
}

@media (max-width: 340px) {
  :root { --gutter: 16px; }
}

/* ============================================================================
   MOTION / PRINT
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition: none !important; animation: none !important; }
  .rise { opacity: 1; transform: none; }
  .cover-circle path, .chapter-underline path { stroke-dashoffset: 0; }
  .cover-role > span > span { opacity: 1; }
}

@media print {
  body::before, .masthead, .index-overlay, .toast { display: none !important; }
  .page { background: #fff !important; color: #000 !important; }
}
