/* Entropic Labs — Butterfly Trails.
   ==========================================================================
   Same building, warmest room. The palette, fonts and spacing conventions are
   the studio's; what changes is the temperature. The Observatory is teal and
   instrumental because it is looking outward at things nobody owns. This room
   is amber and low-lit because everything in it belongs to somebody.

   One stylesheet serves phone and desktop: this is a canvas world whose
   layout is decided at runtime, so it has no separate m/ build.
   ========================================================================== */

:root{
  /* --- the studio's tokens, unchanged --- */
  --ink: #07050F;
  --panel: #130E22;
  --ash: #9C93B8;
  --paper: #F1EEFB;
  --signal: #FF3FA0;
  --trace: #2FE0C7;
  --violet: #7C4DFF;
  --hairline: rgba(241,238,251,0.12);
  --hairline-strong: rgba(241,238,251,0.22);

  --font-display: "Arial Narrow", "Helvetica Neue Condensed", "Roboto Condensed", Arial, sans-serif;
  --font-body: -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;

  /* --- this room only --- */
  --dusk: #05040C;
  --ember: #FFC46B;
  --ember-deep: #C9873A;
  --ember-wash: rgba(255,196,107,0.14);
  --glass: rgba(11,8,18,0.84);
  --glass-solid: rgba(9,7,15,0.965);
  --paper-warm: #EFE7DA;      /* photograph mounts and handwriting */
  --bar-h: 3.25rem;
  --pad: 1.1rem;
  --sheet-top: 26vh;
}

*{ box-sizing: border-box; }

html, body{
  height: 100%;
  margin: 0;
  background: var(--dusk);
}
html{ -webkit-text-size-adjust: 100%; }

body{
  color: var(--paper);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
  overscroll-behavior: none;
  /* One warm source, low and slightly off-centre, as if a lamp were on in
     the next room. Everything else falls away cold. */
  background:
    radial-gradient(105% 80% at 46% 58%, #120C16 0%, rgba(10,7,17,0.35) 46%, transparent 74%),
    radial-gradient(70% 60% at 84% 84%, rgba(255,196,107,0.075) 0%, transparent 68%),
    radial-gradient(60% 55% at 14% 12%, rgba(124,77,255,0.075) 0%, transparent 70%),
    var(--dusk);
}
::selection{ background: var(--ember); color: var(--ink); }

a{ color: inherit; -webkit-tap-highlight-color: rgba(255,196,107,0.16); }
a:focus-visible, button:focus-visible, summary:focus-visible{
  outline: 2px solid var(--ember);
  outline-offset: 3px;
}
h1, h2, h3, h4{
  font-family: var(--font-display);
  text-transform: uppercase;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-wrap: balance;
  margin: 0;
}
.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;
}

/* ==========================================================================
   THE WORLD
   ========================================================================== */
#trails{
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: 0;
  touch-action: none;      /* the canvas owns pan and pinch */
}

/* Air: grain and a vignette. One non-painting layer, no per-frame cost. */
.haze{
  position: fixed;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}
.haze::before{
  content: "";
  position: absolute;
  inset: -50%;
  opacity: 0.038;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
  background-size: 140px 140px;
  animation: drift 9s steps(6) infinite;
}
.haze::after{
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(118% 96% at 50% 52%, transparent 48%, rgba(2,1,5,0.62) 100%);
}
@keyframes drift{
  0%   { transform: translate(0,0); }
  25%  { transform: translate(-5px,3px); }
  50%  { transform: translate(4px,-4px); }
  75%  { transform: translate(-3px,-2px); }
  100% { transform: translate(0,0); }
}

/* ==========================================================================
   NAV — the studio bar, kept recognisable
   ========================================================================== */
.bt-nav{
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 30;
  height: var(--bar-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0 clamp(1.1rem, 3vw, 2.2rem);
  background: linear-gradient(rgba(5,4,12,0.92) 55%, rgba(5,4,12,0));
}
.bt-nav .brand{
  font-family: var(--font-display);
  text-transform: uppercase;
  font-weight: 700;
  font-size: 1.02rem;
  letter-spacing: 0.03em;
  text-decoration: none;
  white-space: nowrap;
}
.bt-nav .brand span{ color: var(--signal); }
.navlinks{
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 2vw, 1.7rem);
  list-style: none;
  margin: 0; padding: 0;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.navlinks a{ text-decoration: none; color: var(--ash); transition: color .15s ease; }
.navlinks a:hover{ color: var(--paper); }
.navlinks a[aria-current="page"]{ color: var(--paper); }
.navlinks .nav-exit{ display: none; }
@media (max-width: 760px){
  .navlinks li:not(.nav-exit){ display: none; }
  .navlinks .nav-exit{ display: block; }
  .navlinks .nav-exit a{ color: var(--ash); }
}

/* ==========================================================================
   BUTTONS
   ========================================================================== */
.bt-btn{
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--paper);
  background: rgba(11,8,18,0.78);
  backdrop-filter: blur(9px);
  -webkit-backdrop-filter: blur(9px);
  border: 1px solid var(--hairline-strong);
  border-radius: 2px;
  min-height: 3rem;
  padding: 0 1.2rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.7em;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color .18s ease, color .18s ease, background .18s ease;
}
.bt-btn:hover{ border-color: var(--ember); color: var(--ember); }
.bt-btn:active{ transform: translateY(1px); }
.bt-btn.ghost{ background: transparent; color: var(--ash); border-color: var(--hairline); }
.bt-btn.ghost:hover{ color: var(--paper); border-color: var(--hairline-strong); }
.bt-btn[hidden]{ display: none; }

/* The mark is a butterfly at the size of a bullet: two wings and a body,
   drawn in CSS so it costs nothing and inherits the current colour. */
.mark{
  position: relative;
  width: 11px; height: 10px;
  flex: none;
  display: inline-block;
}
.mark::before, .mark::after{
  content: "";
  position: absolute;
  top: 0;
  width: 5px; height: 10px;
  background: currentColor;
  opacity: 0.85;
  border-radius: 60% 40% 45% 55%;
}
.mark::before{ left: 0; transform: rotate(-16deg); transform-origin: right center; }
.mark::after{ right: 0; transform: rotate(16deg); transform-origin: left center; }
.bt-btn:hover .mark::before{ animation: flap-l 1.1s ease-in-out infinite; }
.bt-btn:hover .mark::after{ animation: flap-r 1.1s ease-in-out infinite; }
@keyframes flap-l{ 0%,100%{ transform: rotate(-16deg) scaleX(1); } 50%{ transform: rotate(-34deg) scaleX(0.5); } }
@keyframes flap-r{ 0%,100%{ transform: rotate(16deg) scaleX(1); } 50%{ transform: rotate(34deg) scaleX(0.5); } }

/* ==========================================================================
   THE GATE — the way in
   ========================================================================== */
.gate{
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: calc(var(--bar-h) + 1rem) var(--pad) 4rem;
  text-align: center;
  /* Dark, but not opaque: the trail is already alive behind it. */
  background:
    radial-gradient(90% 70% at 50% 50%, rgba(5,4,12,0.55) 0%, rgba(5,4,12,0.88) 70%, rgba(5,4,12,0.96) 100%);
  transition: opacity .9s ease;
}
.gate[hidden]{ display: none; }
.gate.leaving{ opacity: 0; pointer-events: none; }
.gate-inner{ max-width: 40rem; }
.gate-eyebrow{
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: rgba(156,147,184,0.6);
  margin: 0 0 1.5rem;
}
.gate-title{
  font-size: clamp(2.1rem, 7vw + 0.4rem, 4.6rem);
  line-height: 0.98;
  letter-spacing: 0.02em;
  color: var(--paper);
  text-shadow: 0 0 42px rgba(255,196,107,0.18);
}
.gate-tagline{
  font-family: var(--font-mono);
  font-size: clamp(0.66rem, 1.7vw, 0.8rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ash);
  margin: 1.5rem 0 0;
}
.gate-line{
  font-size: clamp(1.05rem, 2.4vw, 1.4rem);
  line-height: 1.55;
  color: var(--paper-warm);
  max-width: 30ch;
  margin: clamp(2.4rem, 8vh, 4.4rem) auto 0;
  min-height: 3.2em;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 1.4s ease, transform 1.4s ease;
}
.gate-line.on{ opacity: 1; transform: none; }
.gate-actions{
  margin-top: clamp(1.6rem, 5vh, 2.8rem);
  display: flex;
  justify-content: center;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .8s ease, transform .8s ease;
}
.gate-actions.on{ opacity: 1; transform: none; }
.gate-actions{ flex-direction: column; align-items: center; gap: 1.1rem; }
.gate-actions .bt-btn{
  border-color: rgba(255,196,107,0.45);
  color: var(--ember);
  padding: 0 1.6rem;
}

/* The two doors. One archive, two ways of drawing it, offered before the
   room opens rather than discovered inside it. They stack on a phone and
   sit side by side the moment there is room for both. */
.gate-choose{
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: rgba(156,147,184,0.72);
}
.gate-choose[hidden]{ display: none; }
/* A grid rather than a flex row, so the doors are the same size as each
   other however long their copy runs and however many of them there are. */
.gate-doors{
  display: grid;
  grid-auto-rows: 1fr;
  gap: 0.7rem;
  width: 100%;
  max-width: 24rem;
}
.gate-door{
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.85rem;
  width: 100%;
  min-height: 3.4rem;
  padding: 0.85rem 1.1rem;
  text-align: left;
  cursor: pointer;
  color: var(--paper);
  background: rgba(255,255,255,0.028);
  border: 1px solid rgba(156,147,184,0.26);
  border-radius: 2px;
  font: inherit;
  transition: border-color .25s ease, background .25s ease, transform .25s ease;
}
.gate-door:hover{
  border-color: rgba(255,196,107,0.5);
  background: rgba(255,196,107,0.06);
}
.gate-door:active{ transform: translateY(1px); }
.gate-door-glyph{
  flex: none;
  width: 1.9rem;
  text-align: center;
  font-size: 1.15rem;
  color: var(--ember);
  opacity: 0.85;
}
.gate-door-text{ min-width: 0; }
.gate-door-name{
  display: block;
  font-family: var(--font-display);
  font-size: 0.9rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.gate-door-line{
  display: block;
  margin-top: 0.18rem;
  font-size: 0.76rem;
  line-height: 1.4;
  color: var(--ash);
}
/* The door they came out of last time. Marked, not chosen for them — and
   marked in the corner rather than in the row, so the two doors stay the
   same size whichever one carries it. */
/* The door they came out of last time says so in words, under its own
   copy rather than crammed into a corner — the grid keeps both doors the
   same size, so the extra line costs the pair nothing. */
.gate-door[data-last]{
  border-color: rgba(255,196,107,0.42);
  background: rgba(255,196,107,0.05);
}
.gate-door-last{
  display: block;
  margin-top: 0.34rem;
  font-family: var(--font-mono);
  font-size: 0.52rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255,196,107,0.72);
}
@media (min-width: 34rem){
  .gate-doors{
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    grid-auto-rows: auto;
    max-width: 38rem;
  }
}
@media (prefers-reduced-motion: reduce){
  .gate-door{ transition: none; }
  .gate-door:active{ transform: none; }
}
/* The mark in the corner. Not a tagline and not a heading — a phrase the
   place likes, set down quietly where the room begins. */
.gate-mark{
  position: absolute;
  left: clamp(1rem, 3vw, 2rem);
  bottom: calc(clamp(1rem, 3vw, 2rem) + env(safe-area-inset-bottom));
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(255,196,107,0.5);
  pointer-events: none;
}
.gate-mark::before{
  content: "";
  display: inline-block;
  width: 14px;
  height: 1px;
  background: currentColor;
  vertical-align: middle;
  margin-right: 0.7em;
  opacity: 0.7;
}

.gate-skip{
  position: absolute;
  right: clamp(1rem, 3vw, 2rem);
  bottom: calc(clamp(1rem, 3vw, 2rem) + env(safe-area-inset-bottom));
  background: none;
  border: 0;
  color: rgba(156,147,184,0.6);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
  min-height: 2.75rem;
  padding: 0 0.5rem;
}
.gate-skip:hover{ color: var(--paper); }

/* Everything in the room stays back until the gate is done with it. */
body[data-gate="1"] .plate,
body[data-gate="1"] .dock,
body[data-gate="1"] .views,
body[data-gate="1"] .lenses,
body[data-gate="1"] .folk,
body[data-gate="1"] .eras,
body[data-gate="1"] .readout,
body[data-gate="1"] .beginning{
  opacity: 0;
  pointer-events: none;
}

/* ==========================================================================
   TITLE PLATE
   ========================================================================== */
.plate{
  position: fixed;
  top: calc(var(--bar-h) + clamp(0.6rem, 3vh, 2rem));
  left: 0; right: 0;
  z-index: 10;
  text-align: center;
  padding: 0 var(--pad);
  pointer-events: none;
  transition: opacity .6s ease, transform .6s ease;
}
.plate h1{
  font-size: clamp(1.4rem, 3vw + 0.6rem, 2.4rem);
  letter-spacing: 0.03em;
  line-height: 1.05;
}
.plate .hint{
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(156,147,184,0.5);
  margin: 0.6rem 0 0;
}

/* The one thing in the plate that can be clicked. */
/* The premise, asked at the door. It was `.what-is` on the plate inside the
   room; the rule set is the same because it is the same control, moved. */
.gate-essay{
  pointer-events: auto;
  margin-top: 0.3rem;
  background: none;
  border: 0;
  border-bottom: 1px solid rgba(47,224,199,0.35);
  color: var(--trace);
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  padding: 0.5rem 0.15rem;
  min-height: 2.4rem;
  transition: color .16s ease, border-color .16s ease;
}
.gate-essay:hover{ color: var(--paper); border-bottom-color: var(--paper); }
.gate-essay[hidden]{ display: none; }

body[data-panel="1"] .plate{
  opacity: 0;
  transform: translateY(-8px);
}
body[data-panel="1"] .plate{ pointer-events: none; }

/* ==========================================================================
   READOUT — what the archive currently holds, and what it is doing
   ========================================================================== */
.readout{
  position: fixed;
  z-index: 20;
  left: clamp(1.1rem, 3vw, 2.2rem);
  bottom: calc(clamp(1.1rem, 3vw, 2.2rem) + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  font-family: var(--font-mono);
  pointer-events: none;
  max-width: min(22rem, 60vw);
  transition: opacity .5s ease;
}
.counts{
  font-size: 0.62rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: rgba(156,147,184,0.72);
}
.counts b{ color: var(--ember); font-weight: 400; }
.whisper{
  font-size: 0.68rem;
  line-height: 1.5;
  letter-spacing: 0.04em;
  color: var(--paper-warm);
  opacity: 0;
  transition: opacity .5s ease;
  text-wrap: balance;
}
.whisper.on{ opacity: 0.86; }
.whisper::before{ content: "🦋 "; filter: grayscale(1) brightness(1.6); opacity: 0.5; }

/* ==========================================================================
   THE BEGINNING — the empty state, which is a state and not a hole
   ========================================================================== */
.beginning{
  position: fixed;
  z-index: 18;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(9.5rem + env(safe-area-inset-bottom));
  width: min(34rem, calc(100vw - 2.4rem));
  background: linear-gradient(rgba(11,8,18,0.78), rgba(11,8,18,0.58));
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--hairline);
  border-left: 2px solid rgba(255,196,107,0.5);
  text-align: left;
  transition: opacity .6s ease;
}
.beginning[hidden]{ display: none; }
.beginning > summary{
  list-style: none;
  cursor: pointer;
  padding: 1rem clamp(1.1rem, 3vw, 1.6rem);
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  min-height: 3rem;
}
.beginning > summary::-webkit-details-marker{ display: none; }
.beginning h2{
  font-size: 1.1rem;
  letter-spacing: 0.03em;
  color: var(--paper);
}
.beginning .soon{
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ember);
  display: flex;
  align-items: center;
  gap: 0.6em;
}
/* the affordance, written rather than drawn */
.beginning .soon::after{
  content: "Read";
  color: rgba(156,147,184,0.7);
  letter-spacing: 0.14em;
}
.beginning[open] .soon::after{ content: "Close"; }
.beginning .b-body{
  padding: 0 clamp(1.1rem, 3vw, 1.6rem) 1.2rem;
}
.beginning p{
  margin: 0 0 0.8rem;
  font-size: 0.92rem;
  line-height: 1.62;
  color: #DDD5CB;
  max-width: 52ch;
}
.beginning .dismiss{
  background: none;
  border: 0;
  border-bottom: 1px solid var(--hairline);
  color: var(--ash);
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  padding: 0.5rem 0.1rem;
  min-height: 2.4rem;
}
.beginning .dismiss:hover{ color: var(--paper); border-color: var(--paper); }

/* ==========================================================================
   THE DOCK — follow a butterfly
   ========================================================================== */
.dock{
  position: fixed;
  z-index: 22;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(clamp(1.1rem, 3vw, 2.2rem) + env(safe-area-inset-bottom));
  display: flex;
  align-items: center;
  gap: 0.6rem;
  max-width: calc(100vw - 2rem);
  transition: opacity .5s ease;
}
.dock-cats{
  display: flex;
  align-items: center;
  gap: 0.4rem;
  overflow-x: auto;
  scrollbar-width: none;
  padding: 0.15rem;
}
.dock-cats::-webkit-scrollbar{ display: none; }

.cat-chip{
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  flex: none;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ash);
  /* Colour-coded at rest, not only on hover: six butterflies that have to
     be told apart at a glance. The tone carries it in the wings, the edge
     and a wash of the ground — never in the label, because three of the six
     tones are too dark to set 0.62rem uppercase mono on. */
  background: color-mix(in srgb, var(--tone, var(--ember)) 7%, rgba(11,8,18,0.72));
  backdrop-filter: blur(9px);
  -webkit-backdrop-filter: blur(9px);
  border: 1px solid color-mix(in srgb, var(--tone, var(--ember)) 30%, transparent);
  border-radius: 2px;
  min-height: 2.9rem;
  padding: 0 0.85rem;
  cursor: pointer;
  white-space: nowrap;
  transition: color .16s ease, border-color .16s ease, background .16s ease;
}
/* The chip's mark is the butterfly itself, in that butterfly's colour —
   same two wings the buttons use, drawn in CSS and costing nothing. */
.cat-chip .wing{
  position: relative;
  width: 12px; height: 11px;
  flex: none;
  display: inline-block;
  filter: drop-shadow(0 0 5px color-mix(in srgb, var(--tone, var(--ember)) 50%, transparent));
}
.cat-chip .wing::before,
.cat-chip .wing::after{
  content: "";
  position: absolute;
  top: 0;
  width: 5.5px; height: 11px;
  background: var(--tone, var(--ember));
  border-radius: 60% 40% 45% 55%;
}
.cat-chip .wing::before{ left: 0; transform: rotate(-16deg); transform-origin: right center; }
.cat-chip .wing::after{ right: 0; transform: rotate(16deg); transform-origin: left center; }
.cat-chip:hover .wing::before,
.cat-chip:focus-visible .wing::before{ animation: flap-l 1.1s ease-in-out infinite; }
.cat-chip:hover .wing::after,
.cat-chip:focus-visible .wing::after{ animation: flap-r 1.1s ease-in-out infinite; }
.cat-chip:hover, .cat-chip:focus-visible{
  color: var(--paper);
  border-color: color-mix(in srgb, var(--tone, var(--ember)) 55%, transparent);
}
.cat-chip[aria-pressed="true"]{
  color: var(--paper);
  background: color-mix(in srgb, var(--tone, var(--ember)) 12%, rgba(11,8,18,0.8));
  border-color: color-mix(in srgb, var(--tone, var(--ember)) 60%, transparent);
}
/* An empty category is not broken, only waiting — it says so on the chip.
   Its butterfly keeps its colour and loses its light. */
.cat-chip[data-empty="1"] .wing{ opacity: 0.42; filter: none; }
.cat-chip[data-empty="1"]{
  color: rgba(156,147,184,0.6);
  background: rgba(11,8,18,0.72);
  border-color: var(--hairline);
}
.cat-chip .count{
  font-size: 0.56rem;
  color: rgba(156,147,184,0.65);
  letter-spacing: 0.08em;
}

.dock-tools{ display: flex; gap: 0.5rem; flex: none; }
.bt-btn.surprise{ min-height: 2.9rem; font-size: 0.62rem; padding: 0 1rem; }

/* ==========================================================================
   VIEWS + ERAS
   ========================================================================== */
.views{
  position: fixed;
  z-index: 21;
  right: clamp(1.1rem, 3vw, 2.2rem);
  top: calc(var(--bar-h) + 4rem);
  display: flex;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  overflow: hidden;
  background: rgba(11,8,18,0.7);
  backdrop-filter: blur(9px);
  -webkit-backdrop-filter: blur(9px);
  transition: opacity .5s ease;
}
.views button{
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ash);
  background: none;
  border: 0;
  border-right: 1px solid var(--hairline);
  min-height: 2.75rem;
  padding: 0 0.85rem;
  cursor: pointer;
  transition: color .15s ease, background .15s ease;
}
.views button:last-child{ border-right: 0; }
.views button:hover{ color: var(--paper); }
.views button[aria-pressed="true"]{
  color: var(--ink);
  background: var(--ember);
}

.eras{
  position: fixed;
  z-index: 21;
  right: clamp(1.1rem, 3vw, 2.2rem);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  align-items: flex-end;
  max-height: 52vh;
  overflow-y: auto;
  scrollbar-width: none;
  transition: opacity .5s ease;
}
.eras[hidden]{ display: none; }
.eras::-webkit-scrollbar{ display: none; }
.era-btn{
  display: flex;
  align-items: center;
  gap: 0.55em;
  background: none;
  border: 0;
  color: rgba(156,147,184,0.7);
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  min-height: 2.4rem;
  padding: 0 0.2rem;
  white-space: nowrap;
}
.era-btn::after{
  content: "";
  width: 16px; height: 1px;
  background: currentColor;
  opacity: 0.5;
}
.era-btn:hover, .era-btn[aria-pressed="true"]{ color: var(--ember); }
.era-btn[aria-pressed="true"]::after{ width: 26px; opacity: 1; }

/* ==========================================================================
   THE MEMORY — one story, opened
   ========================================================================== */
.panel{
  position: fixed;
  z-index: 25;
  background: var(--glass-solid);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.panel[hidden]{ display: none; }
.story{
  right: 0; top: 0; bottom: 0;
  width: min(38rem, 47vw);
  border-top: 0; border-right: 0; border-bottom: 0;
  border-left: 2px solid var(--ember);
}
/* The essay is not a memory, so it reads in the Observatory's colour: this
   is the sourced, checkable kind of writing, not the remembered kind. */
.essay{
  right: 0; top: 0; bottom: 0;
  width: min(38rem, 47vw);
  border-top: 0; border-right: 0; border-bottom: 0;
  border-left: 2px solid var(--trace);
}
.essay .st-index{ color: var(--trace); }
.essay .st-section > h3{ color: var(--trace); }
.essay .panel-close:hover{ color: var(--trace); border-color: var(--trace); }
.essay .st-body.plain > p:first-child::first-letter{
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  float: none;
  padding: 0;
  color: inherit;
}
.essay .st-body{ margin-top: 0; }

.panel-scroll{
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  flex: 1;
}
.panel-head{
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: calc(var(--bar-h) + 0.4rem) clamp(1.1rem, 2.5vw, 1.8rem) 0.9rem;
  border-bottom: 1px solid var(--hairline);
}
.st-index{
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ember);
}
.panel-close{
  flex: none;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ash);
  background: none;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  min-height: 2.75rem;
  min-width: 2.75rem;
  padding: 0 0.7rem;
  cursor: pointer;
}
.panel-close:hover{ color: var(--ember); border-color: var(--ember); }

.story-inner{ padding: 0 clamp(1.2rem, 2.6vw, 2rem) 3.5rem; }
.st-era{
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ash);
  margin: 1.6rem 0 0;
}
.st-era b{ color: var(--ember); font-weight: 400; }
.st-title{
  font-size: clamp(1.7rem, 2.6vw + 0.8rem, 2.6rem);
  line-height: 1.03;
  margin: 0.7rem 0 0;
}
.st-title:focus{ outline: none; }
.st-hook{
  font-size: clamp(1.02rem, 1.4vw + 0.6rem, 1.2rem);
  line-height: 1.5;
  color: var(--paper-warm);
  margin: 1rem 0 0;
  max-width: 46ch;
}

/* ---- where it happened: a small artifact pinned to the memory ---- */
.st-where{
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  line-height: 1.6;
  color: var(--ash);
  margin: 1.1rem 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4em;
}
.st-where .pin{ font-size: 0.8rem; filter: grayscale(1) brightness(1.5); opacity: 0.7; }
.where-link{
  color: var(--paper);
  text-decoration: none;
  border-bottom: 1px solid rgba(255,196,107,0.45);
  padding-bottom: 1px;
  transition: color .16s ease, border-color .16s ease;
}
.where-link:hover{ color: var(--ember); border-bottom-color: var(--ember); }
.where-out{
  display: inline-flex;
  align-items: center;
  margin-top: 0.7rem;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ember);
  text-decoration: none;
  border: 1px solid rgba(255,196,107,0.3);
  border-radius: 2px;
  padding: 0 0.8rem;
  min-height: 2.5rem;
  transition: border-color .16s ease, background .16s ease;
}
.where-out:hover{ border-color: var(--ember); background: rgba(255,196,107,0.07); }

/* ---- flags: the archive's own marginalia ---- */
.flags{ display: flex; flex-direction: column; gap: 0.55rem; margin: 1.6rem 0 0; }
.flag{
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  border: 1px solid var(--hairline);
  border-left: 2px solid var(--ash);
  padding: 0.7rem 0.85rem;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  line-height: 1.6;
  letter-spacing: 0.04em;
  color: var(--ash);
}
.flag .flag-label{
  display: block;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-size: 0.6rem;
  margin-bottom: 0.25rem;
}
.flag[data-kind="classified"]{ border-left-color: var(--signal); }
.flag[data-kind="classified"] .flag-label{ color: var(--signal); }
.flag[data-kind="disputed"]{ border-left-color: var(--violet); }
.flag[data-kind="disputed"] .flag-label{ color: var(--violet); }
.flag[data-kind="chaos"]{ border-left-color: var(--ember); }
.flag[data-kind="chaos"] .flag-label{ color: var(--ember); }
.flag .glyph{ font-size: 0.9rem; line-height: 1.2; flex: none; opacity: 0.85; }

/* ---- meta ---- */
.st-meta{
  margin: 1.7rem 0 0;
  padding: 0;
  border-top: 1px solid var(--hairline);
  font-family: var(--font-mono);
  font-size: 0.68rem;
}
.st-meta .row{
  display: flex;
  justify-content: space-between;
  gap: 1.2rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid rgba(241,238,251,0.07);
}
.st-meta dt{ color: var(--ash); letter-spacing: 0.12em; text-transform: uppercase; white-space: nowrap; }
.st-meta dd{ margin: 0; text-align: right; color: var(--paper); }

/* ---- the story ---- */
.st-body{ margin-top: 1.9rem; }
.st-body p{
  color: #E6DFD6;
  margin: 0 0 1.05rem;
  font-size: 1.02rem;
  line-height: 1.72;
}
.st-body > p:first-child::first-letter{
  font-family: var(--font-display);
  font-size: 2.9em;
  line-height: 0.82;
  float: left;
  padding: 0.06em 0.12em 0 0;
  color: var(--ember);
}
.st-body p:last-child{ margin-bottom: 0; }

/* ---- a memory that travels -----------------------------------------------
   The strip holds still at the top of the reading and says where the telling
   currently is. It is a caption, not a dashboard: one line, no chrome. */
.travelling{ position: relative; }
.at-strip{
  position: sticky;
  top: 0;
  z-index: 2;
  margin: 1.9rem 0 0;
  padding: 0.55rem 0;
  background: linear-gradient(var(--glass-solid) 88%, rgba(9,7,15,0));
  padding-bottom: 0.75rem;
  border-bottom: 1px solid rgba(255,196,107,0.16);
}
.at-now{
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.55em;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  color: var(--ash);
}
.at-now.moved{ animation: at-move .7s ease; }
@keyframes at-move{
  from{ opacity: 0; transform: translateY(3px); }
  to{ opacity: 1; transform: none; }
}
.at-strip[data-arrival="1"] .stop-label{ color: var(--signal); }
.stop-flag{ font-size: 0.8rem; line-height: 1; opacity: 0.9; }
.stop-label{ color: var(--paper); letter-spacing: 0.08em; }
.at-now .stop-note{ color: rgba(156,147,184,0.7); }

/* The route itself, set out after the telling — because that is when a
   trail becomes visible. Same luminous stem as the causal chain. */
.journey{ list-style: none; margin: 0; padding: 0; }
.journey li{
  position: relative;
  padding: 0 0 0 1.6rem;
  margin: 0 0 1.1rem;
  transition: opacity .4s ease;
}
.journey li:last-child{ margin-bottom: 0; }
.journey li::before{
  content: "";
  position: absolute;
  left: 4px; top: 0.5em;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--ember);
  box-shadow: 0 0 0 3px rgba(255,196,107,0.14);
}
.journey li + li::after{
  content: "";
  position: absolute;
  left: 6px; top: -0.95rem;
  width: 1px; height: 1.4rem;
  background: linear-gradient(rgba(255,196,107,0), rgba(255,196,107,0.5));
}
/* the stop that is not a place at all — a person, a skill: the trail
   leaves the map */
.journey li.arrival::before{
  background: var(--signal);
  box-shadow: 0 0 0 3px rgba(255,63,160,0.16);
}
.journey li.arrival + li::after,
.journey li.arrival::after{ background: linear-gradient(rgba(255,63,160,0), rgba(255,63,160,0.45)); }
.journey li.here::before{ box-shadow: 0 0 0 5px rgba(255,196,107,0.2); }
.journey .stop-head{
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5em;
  font-size: 0.96rem;
}
.journey .stop-note{
  margin: 0.2rem 0 0;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  color: var(--ash);
}
.journey li.arrival .stop-note{ color: rgba(255,63,160,0.75); }

/* a chapter break inside a long story — the display face, so it reads as
   part of the telling rather than as one of the record's own labels */
.st-heading{
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: 1.02rem;
  letter-spacing: 0.08em;
  color: var(--ember);
  margin: 2.7rem 0 1.15rem;
}
.st-body > .st-heading:first-child{ margin-top: 0; }

/* a word the story turns on */
.st-body em.warm{
  font-style: normal;
  color: var(--ember);
  border-bottom: 1px solid rgba(255,196,107,0.3);
  padding-bottom: 1px;
}

/* words read off a page, set as they were seen */
.found{
  margin: 1.4rem 0;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--hairline);
  border-left: 2px solid var(--ember);
  background: rgba(255,196,107,0.04);
}
.found p{
  margin: 0 !important;
  font-family: var(--font-mono);
  font-size: 0.86rem !important;
  letter-spacing: 0.12em;
  line-height: 2 !important;
  color: var(--ember) !important;
}
.found p + p{ color: var(--ash) !important; letter-spacing: 0.1em; }

/* ---- beats: the few places a paragraph is not enough ----------------------
   All three are set as ordinary type that has been given room, rather than as
   effects laid over the writing. Nothing moves until it is read, nothing
   moves twice, and under reduced motion nothing moves at all. */

/* the idea, numbered with more confidence than it turned out to deserve */
.plan-lead{ margin-bottom: 0.8rem !important; }
.plan{
  list-style: none;
  counter-reset: step;
  margin: 0 0 1.4rem;
  padding: 0 0 0 0.2rem;
  border-left: 1px solid rgba(255,196,107,0.3);
}
.plan li{
  counter-increment: step;
  position: relative;
  padding: 0.1rem 0 0 2.6rem;
  margin: 0 0 0.85rem;
  font-size: 1rem;
  line-height: 1.6;
  color: #E6DFD6;
}
.plan li:last-child{ margin-bottom: 0; }
.plan li::before{
  content: counter(step);
  position: absolute;
  left: 0.9rem;
  top: 0.05rem;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  color: var(--ember);
  opacity: 0.85;
}

/* said far too loudly, and already committed to */
.shout{
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: clamp(1.5rem, 4.5vw, 2.1rem) !important;
  line-height: 1.05 !important;
  letter-spacing: 0.01em;
  color: var(--ember) !important;
  margin: 1.6rem 0 1.2rem !important;
  transform-origin: left center;
}
.shout.seen{ animation: shout-wobble 1.1s cubic-bezier(.34,1.4,.5,1) 1; }
@keyframes shout-wobble{
  0%   { transform: rotate(-1.6deg) scale(0.97); opacity: 0.6; }
  35%  { transform: rotate(1.1deg)  scale(1.03); opacity: 1; }
  70%  { transform: rotate(-0.5deg) scale(1); }
  100% { transform: none; }
}

/* the moment it lands */
.beat{
  font-family: var(--font-mono);
  font-size: 0.86rem !important;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--signal) !important;
  margin: 1.4rem 0 1.6rem !important;
}
.beat.seen{ animation: beat-jolt 0.42s ease-out 1; }
@keyframes beat-jolt{
  0%   { transform: translate(0,0); }
  15%  { transform: translate(-5px, 2px); }
  30%  { transform: translate(4px, -2px); }
  45%  { transform: translate(-3px, 1px); }
  60%  { transform: translate(2px, 1px); }
  80%  { transform: translate(-1px, 0); }
  100% { transform: translate(0,0); }
}

/* a noise, written down rather than described. It does not shout and it
   does not jolt — it just arrives, one syllable after the one before, which
   is the only way a rhythm survives being set as a paragraph. */
.sound{
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 1.15rem;
  font-family: var(--font-mono);
  font-size: 0.95rem !important;
  letter-spacing: 0.24em;
  color: var(--ember) !important;
  margin: 1.5rem 0 !important;
  padding-left: 1.1rem;
  border-left: 1px solid rgba(255,196,107,0.28);
}
.sound .syll{ opacity: 0.16; transition: opacity 0.5s ease; }
.sound.seen .syll{ opacity: 1; }

/* What the reader is walking into. Stated plainly and got out of the way —
   a warning that performs is a warning nobody believes. */
.st-warning{
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  margin: 1.4rem 0 0;
  padding: 0.85rem 1rem;
  border: 1px solid rgba(255,196,107,0.28);
  border-left-width: 2px;
  background: rgba(255,196,107,0.05);
  border-radius: 2px;
}
.st-warning .warn-mark{ font-size: 0.9rem; line-height: 1.5; flex: none; }
.st-warning .warn-body{ min-width: 0; }
.st-warning p{
  font-family: var(--font-mono);
  font-size: 0.68rem !important;
  letter-spacing: 0.06em;
  line-height: 1.85 !important;
  color: var(--ash) !important;
  margin: 0 !important;
}
.st-warning p + p{ margin-top: 0.5rem !important; }

/* A memory naming another one mid-sentence, and going there. Set as the
   surrounding prose with the room's underline, so it reads as a word and
   not as a button that wandered into a paragraph. */
.st-jump{
  font: inherit;
  color: var(--ember);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: rgba(255,196,107,0.4);
  text-underline-offset: 3px;
  transition: text-decoration-color .16s ease;
}
.st-jump:hover{ text-decoration-color: var(--ember); }

/* A drawing the room cannot compute, supplied by the story itself. */
.st-figure{
  margin: 1.9rem 0;
  padding: 0;
}
.st-figure .fig-art{
  border: 1px solid var(--hairline);
  border-radius: 2px;
  background: rgba(255,196,107,0.03);
  padding: 0.9rem 0.7rem 0.6rem;
}
.st-figure .fig-art svg,
.st-figure .fig-art img{ display: block; width: 100%; height: auto; }
.st-figure .fig-art img{ border-radius: 1px; }
.st-figure figcaption{
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  line-height: 1.9;
  color: var(--ash);
  margin-top: 0.7rem;
}
/* A date on a document sits under the caption, not against the end of it. */
.st-figure figcaption .stamp{
  display: block;
  font-size: 0.55rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(156,147,184,0.62);
  margin-top: 0.25rem;
}

/* A photograph standing in the telling rather than in the gallery at the
   end. It borrows the found-photograph mount and only has to sit like a
   paragraph instead of like a grid cell. */
.photo.inline{
  margin: 2rem auto;
  max-width: 30rem;
}
.st-figure .fig-open{
  display: block;
  width: 100%;
  padding: 0.9rem 0.7rem 0.6rem;
  background: rgba(255,196,107,0.03);
  border: 1px solid var(--hairline);
  border-radius: 2px;
  cursor: zoom-in;
  transition: border-color .16s ease;
}
.st-figure .fig-open:hover{ border-color: rgba(255,196,107,0.4); }

/* Verse, kept as verse: the line breaks are the writing, not the layout. */
.poem{
  margin: 2rem 0;
  padding: 0 0 0 1.3rem;
  border-left: 1px solid rgba(255,196,107,0.3);
}
.poem-title{
  font-family: var(--font-mono) !important;
  font-size: 0.62rem !important;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ember) !important;
  margin: 0 0 1.1rem !important;
}
.poem .stanza{
  font-family: var(--font-body);
  font-size: 1rem !important;
  line-height: 1.95 !important;
  color: var(--paper-warm) !important;
  margin: 0 0 1.3rem !important;
  text-wrap: initial;
}
.poem .stanza:last-of-type{ margin-bottom: 0 !important; }
.poem-by{
  font-family: var(--font-mono) !important;
  font-size: 0.62rem !important;
  letter-spacing: 0.14em;
  color: var(--ash) !important;
  margin: 1.2rem 0 0 !important;
}

/* A line in another language, and what it means. Same left rule as a
   transcribed noise, because both are lines lifted out of the telling and
   set down as they were — but this one is spoken, so it keeps the display
   face and the original stays the larger of the two. */
.verse{
  margin: 1.7rem 0;
  padding-left: 1.15rem;
  border-left: 1px solid rgba(255,196,107,0.28);
}
.verse-line{
  font-family: var(--font-display);
  text-transform: none;
  font-size: clamp(1.02rem, 2.4vw, 1.26rem) !important;
  line-height: 1.5 !important;
  color: var(--ember) !important;
  margin: 0 !important;
}
.verse-meaning{
  font-family: var(--font-mono);
  font-size: 0.66rem !important;
  letter-spacing: 0.12em;
  line-height: 1.95 !important;
  color: var(--ash) !important;
  margin: 0.55rem 0 0 !important;
}

/* Who the telling was for. A rule, a lot of air, and two quiet lines.
   The only motion is a fade, and under reduced motion not even that. */
.dedication{
  margin: 3rem 0 0.5rem;
  padding-top: 2rem;
  border-top: 1px solid rgba(255,196,107,0.2);
  text-align: center;
  opacity: 0;
  transition: opacity 1.8s ease;
}
.dedication.seen{ opacity: 1; }
.dedication .ded-for{
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: clamp(1.05rem, 2.4vw, 1.3rem) !important;
  letter-spacing: 0.06em;
  line-height: 1.3 !important;
  color: var(--ember) !important;
  margin: 0 !important;
}
.dedication .ded-line{
  font-family: var(--font-mono);
  font-size: 0.66rem !important;
  letter-spacing: 0.14em;
  line-height: 1.9 !important;
  color: var(--ash) !important;
  margin: 0.9rem auto 0 !important;
  max-width: 46ch;
  text-wrap: balance;
}

/* the line a story turns on. Out of focus until it is reached, then
   resolved — the thing was already true, you just could not see it yet. */
.reveal{
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 3vw, 1.65rem) !important;
  line-height: 1.28 !important;
  color: var(--paper-warm) !important;
  margin: 1.9rem 0 !important;
  opacity: 0.3;
  filter: blur(10px);
  transition: filter 1.2s cubic-bezier(.2,.7,.2,1), opacity 1.2s ease;
}
.reveal.seen{ opacity: 1; filter: blur(0); }

/* the last line, given room to sit */
.landing{
  font-family: var(--font-display);
  text-transform: none;
  font-size: clamp(1.3rem, 3vw, 1.7rem) !important;
  line-height: 1.3 !important;
  color: var(--paper-warm) !important;
  margin: 2.4rem 0 0.6rem !important;
  opacity: 0;
  transition: opacity 1.6s ease;
}
.landing.seen{ opacity: 0.92; }

.st-section{ margin-top: 2.3rem; }
.st-section > h3{
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ember);
  font-weight: 400;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--hairline);
  margin-bottom: 1.1rem;
}

/* ---- photographs: found objects, not a gallery ---- */
.photos{ display: flex; flex-direction: column; gap: 1.6rem; }
.photo{
  margin: 0;
  /* the mount is the frame; the photograph itself is never touched */
  background: var(--paper-warm);
  padding: 0.7rem 0.7rem 0.6rem;
  box-shadow: 0 14px 34px rgba(0,0,0,0.5), 0 0 0 1px rgba(0,0,0,0.35);
  transform: rotate(var(--tilt, -0.6deg));
  transition: transform .5s cubic-bezier(.22,.61,.36,1);
  align-self: flex-start;
  max-width: 100%;
  cursor: zoom-in;
}
.photo:hover, .photo:focus-within{ transform: rotate(0deg) translateY(-3px); }
.photo img{
  display: block;
  width: 100%;
  height: auto;
  background: #1a1520;
}
.photo figcaption{
  font-family: "Segoe Script", "Bradley Hand", "Snell Roundhand", cursive;
  font-size: 0.95rem;
  line-height: 1.4;
  color: #3B3128;
  padding: 0.55rem 0.2rem 0.1rem;
  text-align: left;
}
.photo .stamp{
  display: block;
  font-family: var(--font-mono);
  font-size: 0.55rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(59,49,40,0.6);
  margin-top: 0.3rem;
}
.photo-btn{
  display: block;
  background: none;
  border: 0;
  padding: 0;
  width: 100%;
  cursor: zoom-in;
}

/* ---- what the memory left behind: a museum caption, not a trophy ---- */
.artifact{
  border: 1px solid var(--hairline);
  border-left: 2px solid var(--ash);
  padding: 1.1rem 1.2rem;
  background: rgba(241,238,251,0.02);
}
.artifact .art-title{
  margin: 0 !important;
  font-size: 1.05rem !important;
  line-height: 1.4 !important;
  color: var(--paper) !important;
}
.artifact .art-reading{
  margin: 0.7rem 0 0 !important;
  font-size: 0.94rem !important;
  line-height: 1.6 !important;
  color: #DDD5CB !important;
}
.artifact .art-key{
  display: block;
  font-family: var(--font-mono);
  font-size: 0.56rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ash);
  margin-bottom: 0.2rem;
}
.artifact .art-line{
  margin: 0.5rem 0 0 !important;
  font-family: var(--font-mono);
  font-size: 0.66rem !important;
  letter-spacing: 0.1em;
  line-height: 1.7 !important;
  color: var(--ash) !important;
}

/* ---- the voice ---- */
.audio{
  border: 1px solid var(--hairline);
  border-left: 2px solid var(--ember);
  padding: 1rem 1.1rem;
  background: rgba(255,196,107,0.045);
}
.audio-lead{
  display: flex;
  align-items: center;
  gap: 0.7rem;
  background: none;
  border: 0;
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  min-height: 2.75rem;
  padding: 0;
  text-align: left;
}
.audio-lead:hover{ color: var(--ember); }
.audio-lead .mic{ font-size: 1rem; filter: grayscale(1) brightness(1.7); }
.audio-note{
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.1em;
  color: rgba(156,147,184,0.7);
  margin: 0.5rem 0 0;
}
.audio audio{ width: 100%; margin-top: 0.9rem; }
.audio details{ margin-top: 0.9rem; }
.audio summary{
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash);
  cursor: pointer;
  min-height: 2.4rem;
  display: flex;
  align-items: center;
}
.audio .transcript p{ font-size: 0.92rem; color: #DDD5CB; margin: 0.6rem 0 0; }

/* ---- people, tags, sources ---- */
.chips{ display: flex; flex-wrap: wrap; gap: 0.4rem; }
.chip{
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  color: var(--ash);
  border: 1px solid var(--hairline);
  border-radius: 2px;
  padding: 0.35rem 0.6rem;
}
.chip b{ color: var(--paper); font-weight: 400; }
.chip.tag{ text-transform: lowercase; letter-spacing: 0.06em; }

.told-by{
  font-family: var(--font-mono);
  font-size: 0.66rem;
  line-height: 1.7;
  color: var(--ash);
  border-left: 1px solid var(--hairline);
  padding-left: 0.85rem;
}
.told-by b{ color: var(--paper); font-weight: 400; }

.notes{ list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.9rem; }
.notes li{
  border-left: 1px dashed rgba(124,77,255,0.45);
  padding-left: 0.9rem;
  font-size: 0.92rem;
  line-height: 1.62;
  color: #D8D1E4;
}
.notes .who{
  display: block;
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--violet);
  margin-bottom: 0.25rem;
}

/* ---- because of this ---- */
.because{
  border: 1px solid rgba(255,196,107,0.28);
  border-left: 2px solid var(--ember);
  padding: 1.1rem;
  background: rgba(255,196,107,0.05);
}
.because .lead{
  display: block;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ember);
  margin-bottom: 0.8rem;
}
.chain{ list-style: none; margin: 0; padding: 0; }
.chain li{ position: relative; padding: 0 0 0 1.5rem; }
.chain li + li{ margin-top: 0.45rem; }
/* the connector: a short luminous stem, the same idea as the trail itself */
.chain li::before{
  content: "";
  position: absolute;
  left: 4px; top: 0.85em;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--ember);
  box-shadow: 0 0 0 3px rgba(255,196,107,0.14);
}
.chain li + li::after{
  content: "";
  position: absolute;
  left: 6px; top: -0.45rem;
  width: 1px; height: 1.3rem;
  background: linear-gradient(rgba(255,196,107,0), rgba(255,196,107,0.5));
}
.chain button{
  background: none;
  border: 0;
  color: var(--paper);
  font: inherit;
  font-size: 0.96rem;
  text-align: left;
  padding: 0.45rem 0;
  min-height: 2.5rem;
  cursor: pointer;
  width: 100%;
}
.chain button:hover{ color: var(--ember); }
.chain .when{
  display: block;
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.12em;
  color: var(--ash);
}
.chain li.pending button{ color: var(--ash); }
.chain li.active button{ color: var(--ember); }
.because .none{
  font-size: 0.9rem;
  color: var(--ash);
  margin: 0;
}

/* ---- the decision ---- */
.fork{
  border: 1px solid var(--hairline);
  border-left: 2px solid var(--violet);
  padding: 1.2rem;
}
.fork .prompt{
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--violet);
  margin: 0 0 0.5rem;
}
.fork .question{
  font-size: 1.05rem;
  line-height: 1.55;
  color: var(--paper);
  margin: 0 0 1.1rem;
}
.fork-choices{ display: flex; flex-direction: column; gap: 0.6rem; }
.fork-choice{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  text-align: left;
  background: none;
  border: 1px solid var(--hairline);
  border-left: 2px solid var(--hairline-strong);
  border-radius: 2px;
  color: var(--paper);
  font: inherit;
  font-size: 0.98rem;
  cursor: pointer;
  padding: 0.85rem 0.9rem;
  min-height: 3.2rem;
  transition: border-color .16s ease, background .16s ease;
}
.fork-choice:hover{ border-left-color: var(--violet); background: rgba(124,77,255,0.07); }
.fork-choice .pick{
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ash);
}
.fork-outcome{ margin-top: 1.1rem; }
.fork-outcome .verdict{
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin: 0 0 0.6rem;
}
.fork-outcome p{ margin: 0; font-size: 0.98rem; line-height: 1.65; color: #E6DFD6; }
/* the hypothetical is drawn as clearly not-history: violet, dashed, dimmer */
.fork-outcome.never{
  border: 1px dashed rgba(124,77,255,0.5);
  padding: 1rem;
  background: rgba(124,77,255,0.06);
}
.fork-outcome.never .verdict{ color: var(--violet); }
.fork-outcome.never p{ color: #CFC7E4; font-style: italic; }
.fork-correction{
  margin-top: 0.9rem;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  color: var(--ember);
}
.fork-outcome.real .verdict{ color: var(--ember); }

/* ---- classified: a sealed record ---- */
.sealed{
  margin-top: 2rem;
  border: 1px dashed rgba(255,63,160,0.42);
  padding: 1.3rem;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  line-height: 1.9;
  letter-spacing: 0.06em;
  color: var(--ash);
  text-align: center;
}
.sealed .seal{
  display: block;
  font-size: 0.62rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--signal);
  margin-bottom: 0.8rem;
}
.sealed .bars{ display: flex; flex-direction: column; gap: 0.45rem; margin: 1rem 0; }
.sealed .bars span{
  height: 0.72rem;
  background: rgba(156,147,184,0.18);
  border-radius: 1px;
}
.sealed .bars span:nth-child(2){ width: 86%; }
.sealed .bars span:nth-child(3){ width: 64%; }

/* ---- citations, for the writing that has sources ---- */
.sources{ list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.85rem; }
.sources li{
  font-family: var(--font-mono);
  font-size: 0.68rem;
  line-height: 1.65;
  color: var(--ash);
  padding-left: 0.85rem;
  border-left: 1px solid var(--hairline);
}
.sources a{ color: var(--paper); text-decoration: none; border-bottom: 1px solid var(--hairline-strong); }
.sources a:hover{ color: var(--trace); border-color: var(--trace); }
.sources-note{
  font-family: var(--font-mono);
  font-size: 0.58rem;
  line-height: 1.65;
  letter-spacing: 0.04em;
  color: rgba(156,147,184,0.6);
  margin: 1rem 0 0;
}

/* ---- related ---- */
.related{ display: flex; flex-direction: column; gap: 0.5rem; }
.rel-item{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  text-align: left;
  background: none;
  border: 1px solid var(--hairline);
  border-left: 2px solid var(--hairline-strong);
  border-radius: 2px;
  color: inherit;
  font: inherit;
  cursor: pointer;
  padding: 0.7rem 0.85rem;
  min-height: 3rem;
  transition: border-color .15s ease, background .15s ease;
}
.rel-item:hover{ border-left-color: var(--ember); background: rgba(241,238,251,0.04); }
.rel-item .rl-title{ font-size: 0.94rem; }
.rel-item .rl-when{
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.12em;
  color: var(--ash);
  white-space: nowrap;
}

.st-foot{
  margin-top: 2.4rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
}
.st-foot .bt-btn{ flex: 1 1 12rem; }

/* On a wide screen the memory takes the right edge, so the floating chrome
   steps aside rather than hiding under it. */
@media (min-width: 901px){
  body[data-panel="1"] .views,
  body[data-panel="1"] .eras{ opacity: 0; pointer-events: none; }
  body[data-panel="1"] .dock{
    left: calc((100vw - min(38rem, 47vw)) / 2);
  }
  /* The dock moves into the lane the readout was using, so the readout
     stands down rather than sitting underneath it. */
  body[data-panel="1"] .readout{ opacity: 0; }
}

/* ==========================================================================
   LIGHTBOX — a photograph held up to the light
   ========================================================================== */
.lightbox{
  position: fixed;
  inset: 0;
  z-index: 70;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: rgba(3,2,7,0.94);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.lightbox[hidden]{ display: none; }
.lightbox img{
  max-width: 100%;
  max-height: 78vh;
  display: block;
  background: var(--paper-warm);
  padding: 0.6rem;
  box-shadow: 0 20px 60px rgba(0,0,0,0.7);
}
.lightbox figcaption{
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  color: var(--ash);
  text-align: center;
  margin-top: 1rem;
  max-width: 46ch;
}
.lightbox .close{
  position: absolute;
  top: clamp(0.8rem, 3vw, 1.6rem);
  right: clamp(0.8rem, 3vw, 1.6rem);
  background: none;
  border: 1px solid var(--hairline);
  border-radius: 2px;
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  min-height: 2.75rem;
  min-width: 2.75rem;
  padding: 0 0.8rem;
  cursor: pointer;
}
.lightbox .close:hover{ border-color: var(--ember); color: var(--ember); }

/* ==========================================================================
   KEYBOARD ROUTE — real controls for people not using a pointer
   ========================================================================== */
.keynav{
  position: fixed;
  z-index: 40;
  left: 0; top: 0;
  width: 1px; height: 1px;
  overflow: hidden;
}
.keynav.open,
.keynav:focus-within{
  width: auto; height: auto;
  max-width: min(26rem, calc(100vw - 2rem));
  max-height: calc(100vh - 2rem);
  overflow-y: auto;
  margin: 0.6rem;
  padding: 0.9rem;
  background: var(--glass-solid);
  border: 1px solid var(--ember);
}
/* Opened deliberately rather than by focus, it sits above the dock instead of
   in the corner — that is where the hand already is. */
.keynav.open{
  /* opaque, unlike the rest of the glass in here: this one is read rather
     than looked through, and the dock behind it was showing in the type */
  background: rgb(9,7,15);
  left: auto; top: auto;
  right: 0.6rem;
  bottom: calc(var(--pad) + 4.4rem);
  max-height: min(60vh, 30rem);
}
@media (max-width: 760px){
  .keynav.open{
    left: 0.6rem; right: 0.6rem;
    max-width: none;
    bottom: calc(var(--pad) + 7.6rem);
  }
}
.keynav .keynav-group{
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ash);
  font-weight: 400;
  margin: 1rem 0 0.4rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--hairline);
}
.keynav ul:first-of-type:empty + .keynav-group,
.keynav h2 + .keynav-group{ margin-top: 0.2rem; padding-top: 0; border-top: 0; }
.keynav h2{
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  color: var(--ember);
  font-weight: 400;
  margin-bottom: 0.6rem;
}
.keynav ul{ list-style: none; margin: 0; padding: 0; }
.keynav button{
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--hairline);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  padding: 0.6rem 0.2rem;
  min-height: 2.6rem;
  cursor: pointer;
}
.keynav button:hover{ color: var(--ember); }
.keynav .keynav-note{
  font-family: var(--font-mono);
  font-size: 0.58rem;
  line-height: 1.7;
  color: var(--ash);
  margin: 0.8rem 0 0;
}

/* the noscript copy is a static article, not a floating sheet */
.static-fallback{
  position: static;
  height: auto;
  width: auto;
  max-width: 44rem;
  margin: 5rem auto;
  border: 1px solid var(--hairline);
  border-left: 2px solid var(--ember);
}
.static-fallback .story-inner{ padding-top: 2rem; }
.static-fallback .st-body a{ color: var(--ember); }

/* ==========================================================================
   PHONES — panels become sheets, not shrunken desktop furniture
   ========================================================================== */
@media (max-width: 900px), (pointer: coarse) and (max-width: 1100px){
  .plate{ top: calc(var(--bar-h) + 0.3rem); }
  .plate h1{ font-size: 1.5rem; }
  .plate .hint{ margin-top: 0.4rem; }
  .gate-essay{ font-size: 0.56rem; min-height: 2.2rem; padding-bottom: 0.3rem; }

  /* view switch moves under the title, where a thumb can reach it */
  .views{
    top: auto;
    right: auto;
    left: 50%;
    transform: translateX(-50%);
    bottom: calc(7.9rem + env(safe-area-inset-bottom));
  }
  .views button{ font-size: 0.58rem; padding: 0 0.75rem; }

  /* the era rail becomes a horizontal strip */
  .eras{
    top: auto;
    transform: none;
    left: 0; right: 0;
    bottom: calc(11.1rem + env(safe-area-inset-bottom));
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 0.2rem;
    max-height: none;
    overflow-x: auto;
    padding: 0 var(--pad);
  }
  .era-btn{ padding: 0 0.6rem; }
  .era-btn::after{ display: none; }
  .era-btn[aria-pressed="true"]{ border-bottom: 1px solid var(--ember); }

  .dock{
    left: 0; right: 0;
    transform: none;
    max-width: none;
    bottom: calc(0.7rem + env(safe-area-inset-bottom));
    flex-direction: column-reverse;
    align-items: stretch;
    gap: 0.5rem;
    padding: 0 var(--pad);
  }
  .dock-cats{ padding: 0.15rem 0; }
  .dock-tools .bt-btn{ width: 100%; min-height: 3rem; }

  .readout{
    left: var(--pad); right: var(--pad);
    bottom: calc(11.1rem + env(safe-area-inset-bottom));
    max-width: none;
  }
  body[data-eras="1"] .readout{ bottom: calc(13.6rem + env(safe-area-inset-bottom)); }

  .beginning{
    left: var(--pad); right: var(--pad);
    width: auto;
    transform: none;
    bottom: calc(14rem + env(safe-area-inset-bottom));
    max-height: 46vh;
    overflow-y: auto;
  }
  .beginning > summary{ padding: 0.7rem var(--pad); min-height: 2.8rem; }
  .beginning h2{ font-size: 0.95rem; }
  .beginning .b-body{ padding: 0 var(--pad) 0.9rem; }
  .beginning p{ font-size: 0.85rem; }

  /* the sheets come up from the bottom */
  .story, .essay{
    left: 0; right: 0; bottom: 0;
    top: var(--sheet-top);
    width: auto;
    border-left: 0; border-right: 0; border-bottom: 0;
    border-top: 2px solid var(--ember);
  }
  .essay{ border-top-color: var(--trace); }
  .panel-head{ padding-top: 1rem; }
  .story-inner{ padding: 0 var(--pad) 3rem; }
  .st-title{ font-size: 1.8rem; }

  /* the sheet owns the bottom of the screen while it is open */
  body[data-panel="1"] .dock,
  body[data-panel="1"] .viewbar,
  body[data-panel="1"] .views,
  body[data-panel="1"] .lenses,
  body[data-panel="1"] .rails,
  body[data-panel="1"] .folk,
  body[data-panel="1"] .eras,
  body[data-panel="1"] .readout,
  body[data-panel="1"] .beginning{ display: none; }
}

@media (max-width: 380px){
  :root{ --pad: 0.85rem; }
  .bt-nav{ padding: 0 var(--pad); }
  .plate h1{ font-size: 1.3rem; }
  .cat-chip{ font-size: 0.58rem; padding: 0 0.7rem; }
}

/* short landscape phones: the sheet takes the side instead of the bottom */
@media (max-height: 460px) and (orientation: landscape){
  :root{ --sheet-top: 0; }
  .story, .essay{
    top: 0; left: auto;
    width: min(30rem, 64vw);
    border-top: 0;
    border-left: 2px solid var(--ember);
  }
  .essay{ border-left-color: var(--trace); }
  .panel-head{ padding-top: calc(var(--bar-h) + 0.3rem); }
  .plate .hint{ display: none; }
  .navlinks li:not(.nav-exit){ display: none; }
  .navlinks .nav-exit{ display: block; }
  .beginning{ display: none; }
}

/* ==========================================================================
   MOTION
   ==========================================================================
   The room is built out of movement, so reduced motion is not a matter of
   turning off a few transitions: the canvas engine drops flight, drift and
   camera easing on its own, and what is left here is the page furniture. */
@media (prefers-reduced-motion: reduce){
  .haze::before{ animation: none; }
  .bt-btn:hover .mark::before,
  .bt-btn:hover .mark::after,
  .cat-chip:hover .wing::before,
  .cat-chip:hover .wing::after,
  .cat-chip:focus-visible .wing::before,
  .cat-chip:focus-visible .wing::after{ animation: none; }
  .gate, .gate-line, .gate-actions, .plate, .whisper, .photo,
  .beginning, .dock, .views, .lenses, .folk, .eras,
  #trails, .atlas, .atlas-wp,
  .atlas-name, .atlas-joint{ transition: none; }
  .atlas-wp[data-chaos="1"] .atlas-wp-glow{ animation: none; }
  .gate-line, .gate-actions{ opacity: 1; transform: none; }
  .photo{ transform: none; }
  /* The beats in a story are punctuation, so they keep their weight and
     their spacing and simply stop moving. */
  .shout.seen, .beat.seen{ animation: none; }
  .landing{ transition: none; opacity: 0.92; }
  .sound .syll{ transition: none; opacity: 1; }
  .reveal{ transition: none; opacity: 1; filter: none; }
  .dedication{ transition: none; opacity: 1; }
  /* the location indicator still moves — it just does not slide */
  .at-now.moved{ animation: none; }
  .journey li{ transition: none; }
  *{ scroll-behavior: auto; }
}

/* ==========================================================================
   LENSES — which experience, and the two worlds it chooses between
   ==========================================================================
   The lens is a higher-order choice than the view: TRAILS and MOUNTAIN are
   two readings of the same archive, where TRAIL / WHOLE TRAIL / PLACES are
   layouts inside the first of them. On a wide screen that hierarchy is drawn
   as two stacked bars; on a phone there is only room for one, so the two
   groups share a scrolling strip with a rule between them.

   .viewbar and .rails are grouping boxes that dissolve on a wide screen —
   display:contents hands their children straight back to the viewport, so
   each keeps the fixed position it has always had.
   ========================================================================== */
.viewbar, .rails{ display: contents; }

.lenses{
  position: fixed;
  z-index: 21;
  right: clamp(1.1rem, 3vw, 2.2rem);
  top: calc(var(--bar-h) + 0.6rem);
  display: flex;
  align-items: stretch;
  border: 1px solid var(--hairline-strong);
  border-radius: 2px;
  overflow: hidden;
  background: rgba(11,8,18,0.78);
  backdrop-filter: blur(9px);
  -webkit-backdrop-filter: blur(9px);
  transition: opacity .5s ease;
}
.lens-btn{
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ash);
  background: none;
  border: 0;
  border-right: 1px solid var(--hairline);
  min-height: 3rem;
  padding: 0 0.95rem;
  cursor: pointer;
  white-space: nowrap;
  transition: color .16s ease, background .16s ease;
}
.lens-btn:last-child{ border-right: 0; }
.lens-btn .lens-glyph{
  font-size: 0.8rem;
  line-height: 1;
  opacity: 0.65;
  transition: opacity .16s ease, text-shadow .16s ease;
}
.lens-btn:hover{ color: var(--paper); }
.lens-btn:hover .lens-glyph{ opacity: 1; }
/* The chosen lens is named in three ways at once — filled, lit and marked —
   because "which of these two am I looking through" must not be a matter of
   noticing a colour. */
.lens-btn[aria-pressed="true"]{
  color: var(--ink);
  background: var(--ember);
}
.lens-btn[aria-pressed="true"] .lens-glyph{ opacity: 1; }

/* ==========================================================================
   THE PEOPLE RAIL — follow a life
   ========================================================================== */
.folk{
  position: fixed;
  z-index: 21;
  left: clamp(1.1rem, 3vw, 2.2rem);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  align-items: flex-start;
  max-height: 52vh;
  overflow-y: auto;
  scrollbar-width: none;
  transition: opacity .5s ease;
}
.folk[hidden]{ display: none; }
.folk::-webkit-scrollbar{ display: none; }
.folk-btn{
  display: flex;
  align-items: center;
  gap: 0.55em;
  background: none;
  border: 0;
  color: rgba(156,147,184,0.7);
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  min-height: 2.4rem;
  padding: 0 0.2rem;
  white-space: nowrap;
  transition: color .16s ease;
}
/* Each life carries its own light, the same one it is drawn in. The dot is
   the colour; the label never is, because 0.6rem mono in #7C4DFF is not
   text anybody can read. */
.folk-btn::before{
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  flex: none;
  background: var(--tone, var(--ember));
  box-shadow: 0 0 6px color-mix(in srgb, var(--tone, var(--ember)) 65%, transparent);
  opacity: 0.7;
  transition: opacity .16s ease, transform .16s ease;
}
.folk-btn:hover{ color: var(--paper); }
.folk-btn:hover::before{ opacity: 1; }
.folk-btn[aria-pressed="true"]{ color: var(--ember); }
.folk-btn[aria-pressed="true"]::before{ opacity: 1; transform: scale(1.45); }/* ==========================================================================
   THE TWO WORLDS — cross-fade, and only one of them running
   ==========================================================================
   Whichever lens is not being looked through stops drawing entirely: the
   canvas engine's loop is halted and the atlas's rAF is cancelled, so there
   is never a second animation burning a phone battery out of sight.
   ========================================================================== */
#trails, .atlas{ transition: opacity .26s ease; }
/* The way in belongs to the canvas whichever lens is remembered: one
   butterfly crosses the gate, and the country waits behind it. */
body[data-gate="1"] #trails{ opacity: 1; }
body[data-gate="1"] .atlas{ opacity: 0; }
body[data-lens="atlas"] #trails{ opacity: 0; pointer-events: none; }
body[data-lens="atlas"] .views{ display: none; }
.atlas[hidden]{ display: none; }
.atlas.entering{ opacity: 0; }

/* On paper the room's own furniture has to change colour or it disappears.
   Only the pieces that sit over the map are touched; every panel, sheet and
   dialogue stays exactly as dark as it has always been. */
body[data-lens="atlas"]{
  background: #E4D8BC;
}
body[data-lens="atlas"] .haze::after{
  background: radial-gradient(118% 96% at 50% 52%, transparent 52%, rgba(120,96,58,0.30) 100%);
}
body[data-lens="atlas"] .haze::before{ opacity: 0.055; mix-blend-mode: multiply; }
body[data-lens="atlas"] .bt-nav{
  background: linear-gradient(rgba(244,237,220,0.94), rgba(244,237,220,0.72) 70%, rgba(244,237,220,0));
  border-bottom-color: rgba(74,59,44,0.14);
}
body[data-lens="atlas"] .bt-nav .brand,
body[data-lens="atlas"] .navlinks a:hover,
body[data-lens="atlas"] .navlinks a[aria-current="page"]{ color: #33281E; }
body[data-lens="atlas"] .navlinks a{ color: #6B5B49; }
body[data-lens="atlas"] .plate h1{ color: #33281E; text-shadow: 0 1px 0 rgba(255,252,240,0.7); }
/* The room's own words now sit over paint rather than over a dark room, so
   they carry a paper-coloured halo instead of relying on the ground. */
body[data-lens="atlas"] .plate .hint,
body[data-lens="atlas"] .counts,
body[data-lens="atlas"] .whisper{
  text-shadow: 0 0 4px rgba(246,240,225,0.95), 0 0 9px rgba(246,240,225,0.85);
}
body[data-lens="atlas"] .plate .hint{ color: rgba(107,91,73,0.78); }
body[data-lens="atlas"] .counts{ color: rgba(74,59,44,0.78); }
body[data-lens="atlas"] .counts b{ color: #9A5A1E; }
body[data-lens="atlas"] .whisper{ color: #4A3B2C; }
body[data-lens="atlas"] .whisper::before{ filter: grayscale(1) brightness(0.5); }
body[data-lens="atlas"] .lenses,
body[data-lens="atlas"] .views{
  background: rgba(250,245,232,0.86);
  border-color: rgba(74,59,44,0.28);
}
body[data-lens="atlas"] .lens-btn{ color: #6B5B49; border-right-color: rgba(74,59,44,0.16); }
body[data-lens="atlas"] .lens-btn:hover{ color: #2C2219; }
body[data-lens="atlas"] .lens-btn[aria-pressed="true"]{ color: #FFF8E8; background: #B4432E; }
body[data-lens="atlas"] .era-btn,
body[data-lens="atlas"] .folk-btn{
  text-shadow: 0 0 4px rgba(246,240,225,0.95), 0 0 8px rgba(246,240,225,0.8);
}
body[data-lens="atlas"] .era-btn{ color: rgba(74,59,44,0.66); }
body[data-lens="atlas"] .era-btn:hover,
body[data-lens="atlas"] .era-btn[aria-pressed="true"]{ color: #B4432E; }
body[data-lens="atlas"] .folk-btn{ color: rgba(74,59,44,0.7); }
body[data-lens="atlas"] .folk-btn:hover{ color: #2C2219; }
body[data-lens="atlas"] .folk-btn[aria-pressed="true"]{ color: #B4432E; }
body[data-lens="atlas"] .cat-chip{
  background: color-mix(in srgb, var(--tone, #B4432E) 13%, rgba(250,245,232,0.88));
  color: #4A3B2C;
  border-color: color-mix(in srgb, var(--tone, #B4432E) 45%, transparent);
}
body[data-lens="atlas"] .cat-chip .count{ color: rgba(74,59,44,0.6); }
body[data-lens="atlas"] .cat-chip[data-empty="1"]{
  background: rgba(250,245,232,0.8); color: rgba(74,59,44,0.5);
  border-color: rgba(74,59,44,0.18);
}
body[data-lens="atlas"] .bt-btn{
  background: rgba(250,245,232,0.9);
  border-color: rgba(74,59,44,0.26);
  color: #4A3B2C;
}
body[data-lens="atlas"] .bt-btn:hover{ border-color: #B4432E; color: #B4432E; }
body[data-lens="atlas"] a:focus-visible,
body[data-lens="atlas"] button:focus-visible{ outline-color: #B4432E; }

/* ==========================================================================
   THE ATLAS — a trail map of one life
   ==========================================================================
   Sunlit paper, painted country, and the memories set into it as lights.
   The map is one canvas; everything with words in it lives in .atlas-layer,
   which pans and zooms as a single transform. Type counter-scales off the
   --z that layer carries, so a label is the same size at every scale, and
   --lod decides how much of it there is room to say.
   ========================================================================== */
.atlas{
  position: fixed;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  touch-action: none;          /* the map owns pan and pinch */
  cursor: grab;
  outline: none;
  background: #E4D8BC;
}
.atlas[data-drag="1"]{ cursor: grabbing; }
.atlas:focus-visible{ outline: 2px solid #B4432E; outline-offset: -3px; }
.atlas-canvas{ position: absolute; inset: 0; display: block; }
.atlas-layer{
  position: absolute;
  left: 0; top: 0;
  width: 0; height: 0;
  transform-origin: 0 0;
  pointer-events: none;        /* the paper underneath still takes the drag */
}

/* --- a memory ------------------------------------------------------------
   A numbered disc, the way a trail map numbers its segments, lit from
   inside in its category's colour. The number is the channel that does not
   depend on seeing the colour; the glow is the one that makes it a memory
   rather than a bus stop. */
.atlas-wp{
  position: absolute;
  width: 44px; height: 44px;
  margin: -22px 0 0 -22px;
  padding: 0;
  border: 0;
  background: none;
  border-radius: 50%;
  display: grid;
  place-items: center;
  cursor: pointer;
  pointer-events: auto;
  -webkit-tap-highlight-color: transparent;
  transform: scale(calc(1 / var(--z, 1)));
  transition: opacity .3s ease;
}
.atlas-wp[data-off="1"]{ opacity: 0.16; pointer-events: none; }
.atlas-wp[data-aside="1"]{ opacity: 0.42; }
.atlas-wp-glow{
  position: absolute;
  width: calc(46px * var(--w, 1)); height: calc(46px * var(--w, 1));
  border-radius: 50%;
  background: radial-gradient(circle closest-side,
              color-mix(in srgb, var(--tone, #FFC46B) 62%, transparent) 0%,
              color-mix(in srgb, var(--tone, #FFC46B) 22%, transparent) 38%,
              transparent 70%);
  filter: blur(1px);
  transition: transform .25s ease, opacity .25s ease;
}
/* A light on the ground. Small and bright, with a thin ink ring so it still
   reads where the paper behind it is pale — the ring is the part that does
   not depend on the colour being seen. */
.atlas-wp-disc{
  position: relative;
  width: 11px; height: 11px;
  border-radius: 50%;
  /* A lit bead rather than a ring: bright where the light is, its own colour
     around that, and the deepened tone at the rim so it still has an edge on
     pale paper. The ring of paper outside it is what lifts it off the
     ground, and is the part that does not depend on seeing the colour. */
  background: radial-gradient(circle at 36% 32%,
              #FFFDF6 0%,
              color-mix(in srgb, var(--tone, #FFC46B) 72%, #FFFFFF) 30%,
              var(--tone, #FFC46B) 62%,
              var(--deep, #8a6a3a) 100%);
  box-shadow:
    0 0 0 1.5px rgba(255,252,242,0.92),
    0 0 0 2.4px rgba(74,59,44,0.42),
    0 0 9px color-mix(in srgb, var(--tone, #FFC46B) 95%, transparent),
    0 0 18px color-mix(in srgb, var(--tone, #FFC46B) 60%, transparent);
}
.atlas-wp-year{
  position: absolute;
  bottom: 26px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  font-variant-numeric: tabular-nums;
  color: rgba(62,49,37,0.7);
  text-shadow: 0 0 3px rgba(250,245,232,0.98), 0 0 6px rgba(250,245,232,0.85);
  opacity: 0;
  transition: opacity .25s ease;
  pointer-events: none;
}
.atlas-layer[data-lod="mid"] .atlas-wp-year,
.atlas-layer[data-lod="near"] .atlas-wp-year{ opacity: 1; }
.atlas-wp[data-off="1"] .atlas-wp-year{ opacity: 0; }

.atlas-wp-cap{
  position: absolute;
  top: 27px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-family: Georgia, "Iowan Old Style", "Palatino Linotype", serif;
  font-style: italic;
  font-size: 11px;
  color: #3E3125;
  text-shadow: 0 0 3px rgba(250,245,232,0.95), 0 0 6px rgba(250,245,232,0.8);
  opacity: 0;
  transition: opacity .25s ease;
  pointer-events: none;
}
.atlas-layer[data-lod="near"] .atlas-wp-cap{ opacity: 0.92; }
.atlas-wp:hover .atlas-wp-glow,
.atlas-wp:focus-visible .atlas-wp-glow{ transform: scale(1.5); }
.atlas-wp:hover .atlas-wp-disc,
.atlas-wp:focus-visible .atlas-wp-disc{ transform: scale(1.16); }
.atlas-wp:focus-visible{ outline: 2px solid #B4432E; outline-offset: 3px; }
.atlas-wp[data-on="1"] .atlas-wp-disc{
  transform: scale(1.4);
  box-shadow:
    0 0 0 2.5px rgba(255,250,235,0.95),
    0 0 0 4px rgba(180,67,46,0.9),
    0 0 16px color-mix(in srgb, var(--tone, #FFC46B) 95%, transparent);
}
.atlas-wp[data-chaos="1"] .atlas-wp-glow{ animation: atlas-breathe 4.4s ease-in-out infinite; }
/* A sealed memory keeps its place on the route and gives no light away. */
/* A sealed memory keeps its place on the trail and gives no light away. */
.atlas-wp[data-classified="1"] .atlas-wp-disc{
  background: rgba(250,245,232,0.94);
  box-shadow: 0 0 0 1.5px rgba(255,252,242,0.9), 0 0 0 2.4px rgba(74,59,44,0.5);
}
.atlas-wp[data-classified="1"] .atlas-wp-glow{ opacity: 0.35; }
@keyframes atlas-breathe{
  0%, 100% { transform: scale(1);    opacity: 0.9; }
  50%      { transform: scale(1.3);  opacity: 1; }
}

/* --- whose line is whose ------------------------------------------------
   Written where a line is still going, in that life's own colour, and
   pressable: a name is how you follow somebody. */
/* Both a name and a joint are the same object: a mark pinned to the braid,
   and a piece of type hung off it at an offset the collision list worked
   out. The element sits on the anchor; only `--dx`/`--dy` move, so a
   diamond can never drift away from the two lines it marks, and a name can
   never end up nearer somebody else's line than its own. */
.atlas-name,
.atlas-joint{
  position: absolute;
  width: 0; height: 0;
  transform: translate(-50%, -50%) scale(calc(1 / var(--z, 1)));
  display: block;
  background: none;
  border: 0;
  padding: 0;
  pointer-events: none;
  transition: opacity .3s ease;
}
.atlas-name-mark,
.atlas-joint-mark{
  position: absolute;
  left: 50%; top: 50%;
  width: 7px; height: 7px;
  margin: -3.5px 0 0 -3.5px;
  border: 1.5px solid color-mix(in srgb, var(--tone, #B4432E) 75%, #4A3B2C);
  background: rgba(255,252,242,0.9);
}
.atlas-name-text,
.atlas-joint-text{
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(calc(-50% + var(--dx, 0px)), calc(-50% + var(--dy, 0px)));
  font-family: var(--font-mono);
  text-transform: uppercase;
  white-space: nowrap;
  /* a halo rather than a box: this is written on the paper, not a control
     sitting on top of it */
  text-shadow: 0 0 4px rgba(250,245,232,0.98), 0 0 9px rgba(250,245,232,0.9);
  transition: color .18s ease;
}
/* The pressable ones need a finger-sized target, which the 7px mark is not.
   It is centred on the mark and invisible, so the hit area cannot drag the
   label's own position around with it. */
button.atlas-name,
button.atlas-joint{ pointer-events: auto; cursor: pointer; }
button.atlas-name::after,
button.atlas-joint::after{
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 26px; height: 26px;
  margin: -13px 0 0 -13px;
}

/* --- whose line is whose ------------------------------------------------
   Written where a line is still going, in that life's own colour, and
   pressable: a name is how you follow somebody. */
.atlas-name-mark{ border-radius: 50%; }
.atlas-name-text{
  color: #3E3125;
  font-size: 0.56rem;
  letter-spacing: 0.16em;
}
.atlas-name:hover .atlas-name-text{ color: #17110B; }
.atlas-name[aria-pressed="true"] .atlas-name-text{
  color: #17110B;
  text-decoration: underline;
  text-decoration-color: var(--tone, #B4432E);
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
.atlas-name[aria-pressed="true"] .atlas-name-mark{
  background: var(--tone, #B4432E);
  transform: scale(1.3);
}
.atlas-name[data-off="1"]{ opacity: 0.34; }
button.atlas-name:focus-visible{ outline: 2px solid #B4432E; outline-offset: 2px; }

/* --- the joints of the braid: a life starting, two becoming one ---------- */
button.atlas-joint:hover .atlas-joint-text{ color: #17110B; }
button.atlas-joint[aria-pressed="true"] .atlas-joint-text{ color: #17110B; }
button.atlas-joint[aria-pressed="true"] .atlas-joint-mark{
  background: var(--tone, #B4432E);
  transform: scale(1.25);
}
button.atlas-joint[data-kind="union"][aria-pressed="true"] .atlas-joint-mark{
  transform: rotate(45deg) scale(1.25);
}
.atlas-joint[data-off="1"]{ opacity: 0.34; }
button.atlas-joint:focus-visible{ outline: 2px solid #B4432E; outline-offset: 2px; }
/* A birth is a fork in the line; a marriage is a diamond where two arrive.
   The shapes differ so the two never rely on their colour to be told apart. */
.atlas-joint[data-kind="birth"] .atlas-joint-mark{ border-radius: 50%; }
.atlas-joint[data-kind="union"] .atlas-joint-mark{ transform: rotate(45deg); }
.atlas-joint-text{
  font-size: 0.5rem;
  letter-spacing: 0.16em;
  color: rgba(62,49,37,0.62);
  text-shadow: 0 0 3px rgba(250,245,232,0.95);
}

/* --- where it starts, and where the paint gives out --------------------- */
.atlas-mark{
  position: absolute;
  transform: translate(-50%, -50%) scale(calc(1 / var(--z, 1)));
  font-family: var(--font-mono);
  font-size: 0.56rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #B4432E;
  text-shadow: 0 0 4px rgba(250,245,232,0.95);
  white-space: nowrap;
  pointer-events: none;
}
.atlas-mark.onward{
  color: rgba(74,59,44,0.45);
  font-style: normal;
  letter-spacing: 0.16em;
}

/* --- what a waypoint says when you point at it -------------------------- */
.atlas-tip{
  position: fixed;
  z-index: 24;
  pointer-events: none;
  max-width: min(18rem, 70vw);
  display: flex;
  flex-direction: column;
  gap: 0.12rem;
  padding: 0.5rem 0.7rem;
  background: rgba(250,245,232,0.97);
  border: 1px solid rgba(74,59,44,0.22);
  border-left: 3px solid var(--tone, #B4432E);
  border-radius: 2px;
  box-shadow: 0 6px 18px rgba(74,59,44,0.18);
}
.atlas-tip[hidden]{ display: none; }
.atlas-tip-when{
  font-family: var(--font-mono);
  font-size: 0.54rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #9A5A1E;
}
.atlas-tip-title{
  font-family: Georgia, "Iowan Old Style", "Palatino Linotype", serif;
  font-size: 0.94rem;
  line-height: 1.2;
  color: #2C2219;
}
.atlas-tip-where{
  font-family: var(--font-mono);
  font-size: 0.54rem;
  letter-spacing: 0.1em;
  color: rgba(74,59,44,0.62);
}

/* ==========================================================================
   THE FURNITURE, ON A PHONE
   ==========================================================================
   One bar for the two control groups, one strip for who and when. Nothing
   new is added to the bottom stack: the people rail moves in beside the
   decades rather than under them.
   ========================================================================== */
@media (max-width: 900px), (pointer: coarse) and (max-width: 1100px){
  .viewbar{
    display: flex;
    position: fixed;
    z-index: 21;
    left: 0; right: 0;
    bottom: calc(7.9rem + env(safe-area-inset-bottom));
    align-items: center;
    justify-content: safe center;
    gap: 0.5rem;
    padding: 0 var(--pad);
    overflow-x: auto;
    scrollbar-width: none;
    transition: opacity .5s ease;
  }
  .viewbar::-webkit-scrollbar{ display: none; }
  .lenses, .views{
    position: static;
    flex: none;
    transform: none;
    top: auto; right: auto; bottom: auto; left: auto;
  }
  .lens-btn{ font-size: 0.58rem; padding: 0 0.8rem; min-height: 2.9rem; }

  .rails{
    display: flex;
    position: fixed;
    z-index: 21;
    left: 0; right: 0;
    bottom: calc(11.1rem + env(safe-area-inset-bottom));
    align-items: center;
    gap: 0.55rem;
    padding: 0 var(--pad);
    overflow-x: auto;
    scrollbar-width: none;
    transition: opacity .5s ease;
  }
  .rails::-webkit-scrollbar{ display: none; }
  /* When runs first, exactly where the decade rail has always been, and who
     follows it behind a hairline. The strip scrolls, the way the category
     chips above it always have. */
  .folk{
    position: static;
    transform: none;
    flex-direction: row;
    align-items: center;
    gap: 0.2rem;
    max-height: none;
    overflow: visible;
    flex: none;
    order: 2;
    border-left: 1px solid var(--hairline);
    padding-left: 0.6rem;
  }
  .eras{
    position: static;
    transform: none;
    flex: none;
    order: 1;
    bottom: auto; top: auto; left: auto; right: auto;
    padding: 0;
    overflow: visible;
  }
  .eras[hidden] + .folk{ border-left: 0; padding-left: 0; }
  .folk-btn{ padding: 0 0.55rem; min-height: 2.4rem; }

  /* the country gets the whole screen behind the furniture */
  .atlas-wp-cap{ display: none; }
  .atlas-name-text{ font-size: 0.54rem; }
  .atlas-joint-text{ font-size: 0.48rem; }
}

@media (max-width: 380px){
  .lens-btn{ font-size: 0.56rem; padding: 0 0.65rem; letter-spacing: 0.12em; }
  .folk-btn{ font-size: 0.56rem; letter-spacing: 0.1em; }
}

/* Short landscape phones already give the sheet a side; the mountain rails
   would leave nothing in the middle, so who and when fold away with the
   note and the sub-heading. */
@media (max-height: 460px) and (orientation: landscape){
  .rails{ display: none; }
}
