/* ============================================================
   Cairns - one stylesheet for the whole series (issue page + the
   /cairns archive index).

   Ported from Dia's _proto/cairns-build/cairns/cairns.css (LET1c,
   docs/design/2026-09-24-cairns-prototype-port.md). Cairns is a
   sibling of Clarity & Perspective in FEEL but does not sit under
   that route, so it does NOT pull in series-scene.* (the canvas
   world) — it reads as the same site by inheriting the canonical
   tokens from /clarity-perspective/colors_and_type.css (paper +
   deep-field palettes, kintsugi surface, the gold thread) and is
   set apart by its own motif: the cairn.

   ADAPTED FROM THE PROTOTYPE (LET1c decision 3 — no new HTML
   vocabulary, no change to shared/blocks-to-html.mjs): every
   selector below targets what the CORE block mapper actually
   emits inside a slot, not Dia's own classes. The mapping:
     .s-body / .question   -> .slot-observation .body p / .slot-question .body p
     .borrowed .q / .src   -> .slot-borrowed blockquote / .slot-borrowed p.aside
     .path-body / a.waymarker -> .path-card .body p / .path-card a.waymarker
     .shot (custom lightbox)  -> figure.plate .plate-img (shared/series-article.js
       owns the inline-expand behavior; no lightbox overlay is built here)
   .embed/video/p.caption ARE real core output (YouTube/Vimeo/a downloaded
   Notion mp4 — shared/blocks-to-html.mjs's "video"/"embed" cases) and are
   styled below, even though they're not in the brief's 6-mapping table for
   the 22 Sep issue specifically. AUD1 (24 Sep) added a 7th: .audio (the
   shared player, shared/audio-player.css's baseline, restyled below for a
   slot) and .embed.podcast (a Spotify/Apple Podcasts iframe, NOT 16:9 like
   a video embed). Gallery / .portal are still not core output at all (no
   block type maps to them), so that CSS is not carried over — it would be
   dead weight styling markup the engine never emits.

   Contract notes (unchanged from the prototype):
     - No OS-level motion media query anywhere (CLAUDE.md #6). All motion
       gates on body.reduced (the footer Motion toggle) via window.motionReduced().
     - 16px hard type floor; reading text sits at 17-19px.
     - Never overrides --display or any nav/font token the chrome reads.
   ============================================================ */

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;overflow-x:clip}

/* ---- local tokens: STONE + TRAIL, derived from the system tokens so they
   flip light<->dark. Nothing here shadows a system or nav token. ---- */
body{
  --stone:color-mix(in srgb,var(--ink) 10%,var(--page-bg));
  --stone-2:color-mix(in srgb,var(--ink) 16%,var(--page-bg));
  --stone-edge:color-mix(in srgb,var(--ink) 26%,transparent);
  --cap:var(--thread-solid);                                  /* gold capstone */
  --trail:color-mix(in srgb,var(--accent) 34%,transparent);   /* the drawn path line */
  --panel:color-mix(in srgb,var(--page-bg) 74%,transparent);  /* media surfaces */

  font-family:var(--serif);
  color:var(--ink);
  background:transparent;
  min-height:100vh;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  transition:color .6s var(--exhale);
}

/* ============================================================
   THE GROUND - a quiet, static, theme-aware backdrop.
   ============================================================ */
.ground{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;
  background:
    radial-gradient(130% 90% at 50% -20%, color-mix(in srgb,var(--accent) 7%,transparent), transparent 62%),
    linear-gradient(180deg, var(--page-bg) 0%, var(--page-bg2) 100%);
}
.ground::before{content:"";position:absolute;inset:0;background-image:var(--grain);background-size:240px 240px;opacity:.5}

/* ============================================================
   NAV DOCK - the sticky title tab chrome.js injects from data-dock.
   ============================================================ */
.nav .dock{position:absolute;left:50%;top:100%;transform:translateX(-50%) translateY(-8px);
  display:flex;align-items:center;gap:9px;opacity:0;pointer-events:none;z-index:99;
  padding:8px 18px;border-radius:0 0 var(--r-md) var(--r-md);
  background:color-mix(in srgb,var(--accent) 18%,var(--nav-glass));
  backdrop-filter:blur(16px) saturate(1.4);-webkit-backdrop-filter:blur(16px) saturate(1.4);
  border:1px solid color-mix(in srgb,var(--accent) 38%,var(--nav-border));border-top:none;box-shadow:var(--nav-shadow);
  transition:opacity .4s var(--exhale),transform .5s var(--breath);max-width:min(80vw,520px)}
.nav.docked .dock{opacity:1;transform:translateX(-50%) translateY(0)}
.nav .dock .dg{width:18px;height:18px;color:var(--accent);flex:none}
.nav .dock .dg svg{width:100%;height:100%}
.nav .dock .dt{font-family:var(--display);font-size:14px;font-weight:800;text-transform:lowercase;letter-spacing:-.01em;
  color:var(--nav-ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* ============================================================
   SHARED: the cairn glyph. A stack of stones, largest at the base, a gold
   capstone. Drawn inline with 1-4 stones so the stack visibly grows across
   the sections. Stones settle in on reveal.
   ============================================================ */
.cairn{display:inline-block;line-height:0;aspect-ratio:64/96}
.cairn svg{display:block;width:100%;height:auto;overflow:visible}
.stone{transform-box:fill-box;transform-origin:center;fill:var(--stone);stroke:var(--stone-edge);stroke-width:1;
  filter:drop-shadow(0 1.6px 1px rgba(0,0,0,.28));
  opacity:0;transform:translateY(-10px) scale(.88) rotate(var(--rot,0deg));
  transition:opacity .55s var(--exhale),transform .75s var(--breath)}
.stone.s-alt{fill:var(--stone-2)}
.stone.s-cap{fill:var(--cap);stroke:color-mix(in srgb,var(--cap) 60%,var(--ink))}
.in .stone,.reveal.in .stone{opacity:1;transform:rotate(var(--rot,0deg))}
.in .stone:nth-child(1){transition-delay:.04s}
.in .stone:nth-child(2){transition-delay:.16s}
.in .stone:nth-child(3){transition-delay:.28s}
.in .stone:nth-child(4){transition-delay:.40s}
.in .stone:nth-child(5){transition-delay:.52s}
.in .stone:nth-child(6){transition-delay:.64s}

/* ============================================================
   ISSUE PAGE
   ============================================================ */
.issue{position:relative;z-index:1;max-width:900px;margin:0 auto;padding:0 24px 40px}

.c-head{text-align:center;padding:72px 0 8px}
.crumb{font-family:var(--mono);font-size:16px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-faint);margin-bottom:22px}
.crumb a{color:var(--ink-faint);transition:color .25s}
.crumb a:hover{color:var(--accent)}
.c-mark{display:block;margin:0 auto 18px;color:var(--accent);width:58px}
h1.c-title{font-family:var(--display);font-size:clamp(32px,5.4vw,52px);font-weight:800;letter-spacing:-.02em;line-height:1.03;color:var(--ink);margin-bottom:14px}
.c-date{font-family:var(--mono);font-size:16px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-faint)}

/* the sections: a two-column climb. Left gutter carries the numeral and the
   growing cairn; the body reads at measure. A single trail line runs down
   the gutter, connecting the cairns. */
.slots{position:relative;margin-top:48px}
.slots::before{content:"";position:absolute;top:10px;bottom:120px;left:65px;width:1.5px;
  background:linear-gradient(var(--trail),color-mix(in srgb,var(--trail) 20%,transparent));z-index:0}

.slot{position:relative;z-index:1;display:grid;grid-template-columns:132px minmax(0,1fr);gap:34px;align-items:start;
  padding:30px 0}
.slot + .slot{border-top:1px solid var(--line)}

.slot-mark{position:sticky;top:96px;text-align:center;display:flex;flex-direction:column;align-items:center;gap:12px}
.slot-mark .numeral{font-family:var(--display);font-size:26px;font-weight:800;letter-spacing:.02em;color:var(--accent);line-height:1}
.slot-mark .cairn{color:var(--accent);width:52px}

.slot-body{max-width:64ch}

/* prose — slot I (observation) and slot III (question) both come through as
   plain core .body > p; scope by the slot-wrap's slot-observation/slot-question
   modifier class (shared/cairns-slots.mjs), not by a class the engine emits.
   CAIRNS2 item 4: body 22px, opening paragraph 24px — this page's own scale,
   overriding CLAUDE.md #9's 17-19px target by Zaheer's decision (27 Sep). */
.slot-observation .body p{font-family:var(--serif);font-size:22px;line-height:1.68;color:var(--ink-soft);margin-bottom:20px;hyphens:none;text-wrap:pretty}
.slot-observation .body p:first-child{font-size:24px;line-height:1.6;color:var(--ink)}
.slot-observation .body p:last-child{margin-bottom:0}
.slot-observation .body strong{color:var(--ink);font-weight:600}
.slot-observation .body em{font-style:italic}
.slot-observation .body a{color:var(--accent);text-decoration:none;border-bottom:1px solid color-mix(in srgb,var(--accent) 40%,transparent);transition:border-color .25s}
.slot-observation .body a:hover{border-bottom-color:var(--accent)}

/* a borrowed fragment: the core's bare <blockquote> + the paired <p class="aside">
   pulled adjacent by pairQuoteSource() (shared/cairns-slots.mjs) — no .borrowed
   wrapper exists in core output, so these key straight off .slot-borrowed.
   CAIRNS2 item 4: quotes 26px, flat (dropped the vw clamp — this page's scale
   is fixed, not fluid).
   CAIRNS2 item 1 (planning review, 27 Sep): the blockquote's own trailing
   space used to be padding-bottom — internal to the box, so it read fine
   but measured as a literal 0px gap to the next sibling. Real margin-bottom
   instead, so there's always a measurable >=18px-floor gap after a quote,
   whatever follows it (a paired p.aside, an unrelated paragraph, or another
   blockquote — section II has three). */
.slot-borrowed blockquote{font-family:var(--serif);font-style:italic;font-size:26px;line-height:1.45;color:var(--ink);
  padding-top:8px;margin:0 0 20px;position:relative;quotes:none}
.slot-borrowed blockquote::before{content:"";display:block;width:54px;height:2px;background:var(--thread);margin:0 0 20px}
.slot-borrowed p.aside{font-family:var(--mono);font-size:16px;letter-spacing:.04em;color:var(--ink-faint);margin-bottom:22px}
.slot-borrowed p.aside a{color:var(--accent);border-bottom:1px solid var(--nav-border)}

/* CAIRNS2 item 1(b): a borrowed slot can carry plain prose beyond the quote
   itself (e.g. an "Image sources: …" credits line and commentary following
   a gallery) — core emits these as ordinary .body > p, same as slot I, so
   give them the same reading treatment + the same >=18px-floor gap before
   the next paragraph (was unstyled/0-margin: the brief's exact complaint).
   No :last-child margin reset here (unlike slot-observation) — a borrowed
   slot can have several quote/paragraph pairs in sequence, so "last child
   of this particular div.body" is not "last thing in the slot"; zeroing it
   was what collapsed the paragraph-before-a-blockquote gap to 0 (planning
   review, 27 Sep). p.credit (item 3, same review): the credits line
   markGalleryCredits() marks right after a carousel — same caption
   treatment as p.aside/figcaption, 16px mono. */
.slot-borrowed .body p{font-family:var(--serif);font-size:22px;line-height:1.68;color:var(--ink-soft);margin-bottom:20px}
.slot-borrowed .body p.credit{font-family:var(--mono);font-size:16px;letter-spacing:.04em;color:var(--ink-faint)}
.slot-borrowed .body a{color:var(--accent);text-decoration:none;border-bottom:1px solid color-mix(in srgb,var(--accent) 40%,transparent);transition:border-color .25s}
.slot-borrowed .body a:hover{border-bottom-color:var(--accent)}

/* a question (CAIRNS2 item 3): the most prominent line on the page — accent
   colour, and sized so it is always larger than every other body text at
   every viewport (min 28px clears the 26px quote size at mobile widths,
   where the old clamp's vw term collapsed toward its floor). Notion authors
   this section as either a plain paragraph (core: .body > p, no wrapper) or
   a quote block (core: a bare <blockquote>, wrapBody() leaves it unwrapped)
   — style both so the question reads the same either way; the observed
   issue ("The stones show the way") uses the quote form. */
.slot-question .body p,
.slot-question blockquote{font-family:var(--serif);font-size:clamp(28px,3.6vw,34px);line-height:1.3;color:var(--accent);font-weight:500;max-width:26ch;quotes:none}

/* a Notion divider -> the ◐ glyph beat (core: shared/blocks-to-html.mjs's
   MOVEMENT constant, `div.movement > span.g > svg`, emitted as its own
   top-level sibling wherever a divider sits, same as a blockquote — never
   wrapped in div.body). Ported from shared/reader-page.css's
   `.reader-body .movement` rules (CAIRNS2, planning review, 27 Sep) — this
   was the one core-emitted element cairns.css had zero styling for.
   Re-tokened for Cairns: --accent for the glyph (the same gold used for the
   cairn capstone and the numerals), no reader-specific wrapper needed. */
.movement{text-align:center;margin:30px 0;color:var(--accent);opacity:.6}
.movement .g{display:inline-block;width:20px;height:20px}
.movement svg{width:100%;height:100%}

/* ============================================================
   MEDIA — a single image, framed by the core's figure.plate. The
   inline-expand toggle is /shared/series-article.js's job (figure.plate
   .plate-img -> .expanded); this file only supplies the stone-era look.
   ============================================================ */
.plate-img{all:unset;position:relative;display:block;width:100%;cursor:zoom-in;border-radius:var(--r-md);overflow:hidden;
  border:1px solid color-mix(in srgb,var(--accent) 20%,var(--line));
  background:linear-gradient(160deg,#c9b48e,#7d95a0 45%,#4a5a63);
  box-shadow:0 20px 46px -34px color-mix(in srgb,var(--accent) 40%,rgba(70,55,30,.5));
  transition:transform .4s var(--exhale),box-shadow .4s var(--exhale)}
.plate-img::after{content:"";display:block;padding-top:66%}
.plate-img img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.plate-img:hover{transform:translateY(-2px);box-shadow:0 26px 54px -32px color-mix(in srgb,var(--accent) 52%,rgba(70,55,30,.5))}
figure.plate.expanded .plate-img{cursor:zoom-out}
figure.plate.expanded .plate-img::after{padding-top:110%}
figure.plate.expanded .plate-img img{object-fit:contain;background:#0d0e0e}

/* CAIRNS2 item 1: the image-sources line needs the same clear-space-before-
   next-paragraph treatment as a quote's source line — bottom margin raised
   from 4px to 20px (a little more than the 18px quote-to-source floor). */
figure.plate{margin:26px auto 20px;max-width:64ch}
figure.plate figcaption{font-family:var(--mono);font-size:16px;letter-spacing:.04em;color:var(--ink-faint);padding:10px 2px 0;text-align:center}

/* a video: YouTube/Vimeo iframe, or a downloaded Notion-hosted mp4 <video>
   (shared/blocks-to-html.mjs "video"/"embed" cases). Same stone-era frame as
   figure.plate; the caption sits below, gray and quiet, 16px floor. */
.embed{position:relative;margin:26px auto 4px;max-width:64ch;border-radius:var(--r-md);overflow:hidden;
  border:1px solid color-mix(in srgb,var(--accent) 20%,var(--line));aspect-ratio:16/9;background:#0d0e0e;
  box-shadow:0 20px 46px -34px color-mix(in srgb,var(--accent) 40%,rgba(70,55,30,.5))}
.embed iframe,.embed video{position:absolute;inset:0;width:100%;height:100%;border:0;display:block}
p.caption{font-family:var(--mono);font-size:16px;letter-spacing:.04em;color:var(--ink-faint);padding:10px 2px 0;text-align:center;max-width:64ch;margin:0 auto 20px}

/* ============================================================
   IMAGE CAROUSEL (CAIRNS2 item 2) — consecutive plate images in a slot
   (shared/cairns-slots.mjs's wrapImageCarousels()) become one raised,
   swipeable carousel instead of a vertical stack. Single image stays a
   plain figure.plate (untouched above) — this only styles a run of 2+.
   Same frame ratio as a single plate (padding-top 66%, i.e. ~3:2 landscape)
   so the two read as one family; object-fit:cover crops every slide to
   that one fixed frame — no letterboxing — and no border, per the brief.
   Motion (the crossfade + drag) has no gate of its own: it rides the
   existing `body.reduced *{transition:none!important}` rule below, never
   an OS media query (CLAUDE.md #6). */
.carousel{position:relative;margin:26px auto 20px;max-width:64ch}
.carousel-track{position:relative;width:100%;border-radius:var(--r-md);overflow:hidden;
  background:linear-gradient(160deg,#c9b48e,#7d95a0 45%,#4a5a63);
  box-shadow:0 20px 46px -34px color-mix(in srgb,var(--accent) 40%,rgba(70,55,30,.5));
  touch-action:pan-y;cursor:grab}
.carousel-track:active{cursor:grabbing}
.carousel-track::after{content:"";display:block;padding-top:66%}
.carousel-slide{position:absolute;inset:0;opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .4s var(--exhale),transform .3s var(--exhale)}
.carousel-slide.active{opacity:1;visibility:visible;pointer-events:auto;z-index:1}
.carousel-slide .plate-img{all:unset;position:absolute;inset:0;display:block;width:100%;height:100%;
  border:none;border-radius:0;box-shadow:none;cursor:default}
.carousel-slide .plate-img::after{content:none}
.carousel-slide .plate-img:hover{transform:none;box-shadow:none}
.carousel-slide .plate-img img,.carousel-slide .plate-img picture{position:absolute;inset:0;width:100%;height:100%}
.carousel-slide img{width:100%;height:100%;object-fit:cover;display:block}

.car-btn{all:unset;position:absolute;top:50%;translate:0 -50%;z-index:2;width:40px;height:40px;border-radius:50%;
  border:1px solid color-mix(in srgb,var(--accent) 30%,transparent);
  background:color-mix(in srgb,var(--page-bg) 70%,transparent);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  color:var(--ink);font-size:22px;line-height:1;display:flex;align-items:center;justify-content:center;
  cursor:pointer;transition:background .25s var(--exhale)}
.car-btn:hover{background:color-mix(in srgb,var(--accent) 22%,var(--page-bg))}
.car-prev{left:10px}
.car-next{right:10px}
.car-btn:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

/* check:typesize floor (CLAUDE.md #9) — was 14px; raised to 16px and the
   letter-spacing/padding tuned back down/up so the pill still reads as a
   compact badge, not a stretched-out label, at the new size. */
.carousel-count{position:absolute;right:12px;bottom:10px;z-index:2;font-family:var(--mono);font-size:16px;
  letter-spacing:.02em;color:var(--page-bg);background:color-mix(in srgb,var(--ink) 55%,transparent);
  padding:3px 10px;border-radius:999px;pointer-events:none}

.carousel-dots{display:flex;justify-content:center;gap:8px;margin-top:12px}
.carousel-dot{all:unset;width:8px;height:8px;border-radius:50%;
  background:color-mix(in srgb,var(--ink) 22%,transparent);cursor:pointer;transition:background .25s var(--exhale),transform .25s var(--exhale)}
.carousel-dot.active{background:var(--accent);transform:scale(1.25)}
.carousel-dot:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

.carousel-captions{margin-top:8px;text-align:center}
.carousel-caption{display:none;font-family:var(--mono);font-size:16px;letter-spacing:.04em;color:var(--ink-faint)}
.carousel-caption.active{display:block}
@media(max-width:600px){.carousel-track{cursor:default}}

/* AUD1 - a podcast embed (Spotify/Apple Podcasts): NOT 16:9 - Spotify's own
   episode embed is a short, fixed-height card, so it overrides the video
   .embed's aspect-ratio/absolute-iframe rules rather than inheriting them. */
.embed.podcast{aspect-ratio:auto;height:152px;background:transparent;border:none;box-shadow:none}
.embed.podcast iframe{position:static;width:100%;height:100%;border-radius:var(--r-md)}

/* AUD1 - the shared audio player (shared/audio-player.css's baseline),
   restyled to sit inside a slot: kintsugi-adjacent stone surface, gold
   accent play button and progress fill matching the cairn capstone, same
   measure as the slot's prose. */
.audio{max-width:64ch;margin:26px auto 4px;
  background:color-mix(in srgb,var(--page-bg) 74%,transparent);
  border:1px solid color-mix(in srgb,var(--accent) 20%,var(--line));border-radius:var(--r-md);
  box-shadow:0 20px 46px -34px color-mix(in srgb,var(--accent) 40%,rgba(70,55,30,.5))}
.audio button.play{background:var(--accent);color:var(--page-bg)}
.audio button.skip{border-color:color-mix(in srgb,var(--accent) 30%,var(--line))}
.audio .meta .track i{background:var(--thread-solid,var(--accent))}
.audio .time{font-variant-numeric:tabular-nums}

/* ============================================================
   THE MARKER (internally "the path") - the point of the page. A raised
   kintsugi surface at the crest of the climb, a gold seam across the top,
   one invitation, exactly one link. Core emits a plain <div class="body">
   <p>…<a>…</a></p></div> (Notion: "a paragraph with its one link");
   shared/cairns-slots.mjs's extractWaymarker() (LET1e, 24 Sep) lifts that
   inline <a> out of the sentence onto its own line below the body, as
   a.waymarker — styling it in place overlapped the button padding with
   the paragraph's line-height (Zaheer, 24 Sep).
   ============================================================ */
/* CAIRNS2 item 3: a short drawn trail (--trail, same token as the gutter
   line above) leads from the question down into the marker — the gap that
   used to be plain margin is now the section's own top padding, so the
   line has a box to render in. */
.path{position:relative;z-index:1;max-width:720px;margin:0 auto;padding:64px 24px 0}
.path::before{content:"";position:absolute;left:50%;top:10px;width:1.5px;height:46px;
  translate:-50% 0;background:linear-gradient(color-mix(in srgb,var(--trail) 15%,transparent),var(--trail));z-index:0}
.path-card{position:relative;overflow:hidden;border-radius:var(--r-lg);
  background:var(--kin-stone);border:1px solid var(--kin-border);box-shadow:var(--kin-inset),0 40px 90px -50px color-mix(in srgb,var(--accent) 45%,rgba(70,55,30,.6));
  padding:clamp(30px,5vw,52px);text-align:center}
.path-card::before{content:"";position:absolute;top:0;left:0;right:0;height:2px;background:var(--thread)}
.path-card::after{content:"";position:absolute;width:280px;height:280px;border-radius:50%;pointer-events:none;
  right:-90px;top:-90px;background:radial-gradient(circle,var(--kin-bloom-1),transparent 70%)}
.path-crest{display:block;color:var(--accent);width:66px;margin:0 auto 18px}
/* CAIRNS2 item 4, revised (Zaheer, 27 Sep): CTA copy 24px -> 20px, button
   label 17px -> 20px — the two now match, reading as one deliberate voice
   at the bottom of the card rather than the copy stepping down to the
   quote's size and the button separately stepping up from the mono-UI
   floor. Button padding/letter-spacing rebalanced for the larger label:
   letter-spacing loosened at 17px reads cramped at 20px (CLAUDE.md #9:
   raising a size usually means lowering letter-spacing), so .02em -> .01em;
   padding grown 10px 20px -> 12px 22px to keep the pill's proportions. */
.path-card .body p{font-family:var(--serif);font-size:20px;line-height:1.5;color:var(--kin-text);max-width:44ch;margin:0 auto;position:relative;z-index:1}
.path-card .body p strong{font-weight:600}
.path-card a.waymarker{position:relative;z-index:1;display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);font-size:20px;letter-spacing:.01em;
  color:var(--page-bg);background:var(--accent);border-radius:var(--r-sm);padding:12px 22px;margin-top:18px;
  text-decoration:none;box-shadow:0 16px 34px -18px color-mix(in srgb,var(--accent) 80%,transparent);
  transition:transform .3s var(--exhale),box-shadow .3s var(--exhale)}
.path-card a.waymarker::after{content:"→";transition:transform .3s var(--exhale)}
.path-card a.waymarker:hover{transform:translateY(-2px);box-shadow:0 22px 44px -18px color-mix(in srgb,var(--accent) 90%,transparent)}
.path-card a.waymarker:hover::after{transform:translateX(2px)}
.path-card a.waymarker:focus-visible{outline:2px solid var(--accent);outline-offset:4px}

.path{margin-bottom:clamp(40px,6vh,72px)}

/* LET3b: the quiet standing line below the path (outside the card). */
.cs-line{position:relative;z-index:1;max-width:720px;margin:calc(-1 * clamp(16px,3vh,40px)) auto clamp(40px,6vh,72px);padding:0 24px;
  font-family:var(--serif);font-size:18px;line-height:1.6;color:var(--ink-soft);text-align:center}
.cs-line a{color:inherit;text-decoration:underline;text-decoration-color:var(--trail);text-underline-offset:3px}
.cs-line a:hover{color:var(--accent)}
.cs-line a:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

/* the vista: open scroll below the marker where a single landscape lives
   large - sky above, the scene filling most of the view, the footer arriving
   well after. One scene per page (chosen in cairns.js), never stacked. */
/* CAIRNS2 item 6: the vista is the empty run between the article and the
   footer — halved (100vh->50vh; scene height halved to match so it isn't
   clipped by the shorter box). */
.vista{position:relative;z-index:1;min-height:50vh;overflow:hidden;width:100vw;margin-left:calc(50% - 50vw)}
.vista .scene{position:absolute;left:0;right:0;bottom:0;height:35vh;color:var(--ink)}
.vista .scene svg{display:block;width:100%;height:100%}
.vista .scene .sun{fill:var(--accent)}
.vista .scene .m-far{fill:color-mix(in oklab, var(--ink) 22%, var(--page-bg))}
.vista .scene .m-mid{fill:color-mix(in oklab, var(--ink) 38%, var(--page-bg))}
.vista .scene .m-near{fill:color-mix(in oklab, var(--ink) 54%, var(--page-bg))}
.vista .scene .treeline{fill:color-mix(in oklab, var(--ink) 70%, var(--page-bg))}
.vista .scene .water{fill:color-mix(in oklab, var(--ink) 14%, var(--page-bg))}
.vista .scene .fg{fill:color-mix(in oklab, var(--ink) 90%, var(--page-bg))}
.vista .scene .blades{stroke:color-mix(in oklab, var(--ink) 90%, var(--page-bg))}
@media(max-width:600px){.vista{min-height:42vh}.vista .scene{height:28vh}}

/* ============================================================
   THE ARCHIVE INDEX (/cairns) - dated, text-first (not photo cards):
   Cairns issues are known by their date and their one idea.
   ============================================================ */
.c-index{position:relative;z-index:1;max-width:760px;margin:0 auto;padding:0 24px 60px}
.ix-head{text-align:center;padding:80px 0 8px}
h1.ix-title{font-family:var(--display);font-size:clamp(40px,7vw,72px);font-weight:800;letter-spacing:-.02em;line-height:1;color:var(--ink)}
.ix-mark{display:block;color:var(--accent);width:64px;margin:22px auto 0}
.ix-head .lead{font-family:var(--serif);font-size:18px;line-height:1.7;color:var(--ink-soft);max-width:720px;margin:22px auto 0;text-align:center}

.issues{margin-top:52px;border-top:1px solid var(--line)}
.issue-row{display:grid;grid-template-columns:56px 1fr;gap:22px;align-items:start;padding:26px 8px;border-bottom:1px solid var(--line);
  text-decoration:none;color:inherit;transition:background .3s var(--exhale)}
.issue-row:hover{background:color-mix(in srgb,var(--accent) 6%,transparent)}
.issue-row .ir-cairn{color:var(--accent);width:46px;justify-self:center;margin-top:2px}
.issue-row .ir-date{font-family:var(--mono);font-size:16px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-faint);margin-bottom:7px;display:block}
.issue-row .ir-title{font-family:var(--display);font-size:clamp(22px,3vw,28px);font-weight:800;letter-spacing:-.01em;color:var(--ink);line-height:1.1;margin-bottom:8px}
.issue-row:hover .ir-title{color:var(--accent)}
.issue-row .ir-path{font-family:var(--serif);font-size:17px;line-height:1.55;color:var(--ink-soft)}
.issue-row .ir-read{display:block;font-family:var(--mono);font-size:16px;letter-spacing:.02em;color:var(--accent);margin-top:10px}

/* ============================================================
   REVEAL + MOTION. Every animation gates on body.reduced and nothing else.
   ============================================================ */
.reveal{opacity:0;transform:translateY(16px);transition:opacity .7s var(--exhale),transform .7s var(--exhale)}
.reveal.in{opacity:1;transform:none}
body.reduced *{animation:none!important;transition:none!important}
body.reduced .reveal{opacity:1;transform:none}
body.reduced .stone{opacity:1;transform:rotate(var(--rot,0deg))}

/* ============================================================
   RESPONSIVE - standard site matrix.
   ============================================================ */
@media(min-width:601px) and (max-width:1024px){
  .issue{max-width:760px}
  .slot{grid-template-columns:112px minmax(0,1fr);gap:26px}
  .slots::before{left:55px}
  .slot-mark{top:88px}
}
@media(max-width:600px){
  .c-head{padding:52px 0 6px}
  .issue,.c-index{padding-left:18px;padding-right:18px}
  .slots::before{display:none}
  .slot{grid-template-columns:1fr;gap:16px;padding:26px 0}
  .slot-mark{position:static;flex-direction:row;justify-content:flex-start;gap:14px;text-align:left}
  .slot-mark .cairn{width:34px}
  .slot-body{max-width:100%}
  /* CAIRNS2 item 4: dropped the mobile down-size of body copy (was 17px/18px
     here) - Zaheer's decision overrides CLAUDE.md #9's mobile-scanned-text
     leeway for Cairns; the measure (slot-body:100% width) still holds the
     line length, so 22px/24px doesn't break it. */
  /* AUD1 - 64ch (shared/audio-player.css's baseline) is a mono-font measure
     that overflows a narrow slot; the player follows the slot's own 100%. */
  .audio,.embed.podcast{max-width:100%}
  .audio .meta .t1,.audio .meta .t2{max-width:100%}
  .path{padding:0 18px}
  h1.ix-title{font-size:clamp(38px,13vw,60px)}
  .issue-row{grid-template-columns:40px 1fr;gap:16px}
}
@media(orientation:landscape) and (max-height:560px){
  .c-head{padding:36px 0 4px}
  .ix-head{padding:44px 0 6px}
}
@media(max-width:400px){
  html,body{overflow-x:clip}
  .issue,.c-index{padding-left:14px;padding-right:14px}
  h1.c-title{font-size:clamp(26px,9vw,34px)}
}

@media print{
  .ground,.nav,footer.site{display:none}
  .path-card{box-shadow:none}
}

/* CAIRNS3: the email signup line. Same type as .cs-line; on the index it
   sits inside the header under the intro, so it drops .cs-line's negative
   pull-up and side padding. On an issue it follows the Creative Space line. */
.ix-head .signup-line{margin:20px auto 0;padding:0}
.cs-line + .signup-line{margin-top:0}
.cs-line:has(+ .signup-line){margin-bottom:12px}
