/* ============================================================================
   PLAINFORGE — /ecosystem v3 — "THE SYSTEM"
   ----------------------------------------------------------------------------
   Night-sky tones: near-black warm space, bone ink, one rationed copper.
   Verdigris is the interaction accent. In atlas mode the DOM layer turns
   into engraved chart lettering: stronger bone, wider tracking.
   ============================================================================ */

:root{
  --bg:        #060807;
  --iron:      #12161372;
  --panel:     #101412;
  --line:      #232a26;
  --bone:      #ece7dc;
  --muted:     #a9b0a6;
  --faint:     #7f8a83;   /* AA on --bg (≈5.6:1); meaning-bearing microcopy must pass */
  --ember:     #e08549;
  --verdis:    #58b08f;

  --font: ui-sans-serif, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "Cascadia Code", "SF Mono", "Segoe UI Mono", Consolas, monospace;

  color-scheme: dark;
}

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

html{ height:100%; }
body{
  min-height:100%;
  margin:0;
  background:var(--bg);
  color:var(--bone);
  font-family:var(--font);
  -webkit-font-smoothing:antialiased;
  text-transform:lowercase;   /* the plainforge voice: everything lowercase */
}

/* ==========================================================================
   BOOT VEIL — sweeps while loading, then the bar IS the sky's fade-in
   ========================================================================== */
.boot{
  position:fixed; inset:0;
  z-index:10;
  background:var(--bg);
  display:flex; flex-direction:column;
  align-items:center; justify-content:center;
  gap:18px;
  pointer-events:none;
  /* no-JS / stalled-script bail: the veil lifts on its own */
  animation:boot-linger .6s ease 9s forwards;
}
body.gl-failed .boot{ display:none; }
.boot-mark{
  margin:0;
  font-weight:350;
  font-size:1.25rem;
  letter-spacing:.045em;
  color:var(--bone);
}
.boot-mark::after{
  content:"";
  display:inline-block;
  width:.14em; height:.14em;
  margin-left:.25em;
  background:var(--ember);
}
.boot-track{
  position:relative;
  width:min(240px, 60vw);
  height:2px;
  background:var(--line);
  overflow:hidden;
}
.boot-fill{
  position:absolute; left:0; top:0; bottom:0;
  width:0;
  background:var(--ember);
}
/* before the engine arrives, progress is unknown: a quiet sweep */
body.pre-gl .boot-fill{
  width:38%;
  animation:boot-sweep 1.4s ease-in-out infinite;
}
@keyframes boot-sweep{
  0%  { left:-40%; }
  100%{ left:100%; }
}
.boot-line{
  display:flex; justify-content:space-between;
  width:min(240px, 60vw);
  margin:0;
  font-family:var(--mono);
  font-size:.68rem;
  letter-spacing:.14em;
  color:var(--faint);
}
.boot-pct{ color:var(--muted); }
@keyframes boot-linger{ to{ opacity:0; visibility:hidden; } }

/* first-contact hint */
.hint{
  position:fixed;
  left:50%; bottom:calc(64px + env(safe-area-inset-bottom,0px));
  transform:translateX(-50%);
  z-index:4;
  margin:0;
  font-family:var(--mono);
  font-size:.78rem;
  letter-spacing:.14em;
  color:var(--muted);
  background:rgba(6,8,7,.78);
  padding:10px 18px;
  white-space:normal;
  text-align:center;
  max-width:88vw;
  transition:opacity 1.1s ease;
  pointer-events:none;
}
.hint.is-off{ opacity:0; }
.hint strong{
  display:block;
  font-weight:400;
  color:var(--bone);
  letter-spacing:.12em;
  margin-bottom:5px;
}
.hint span{ display:block; }
body.pre-gl .hint, body.gl-failed .hint, body.ledger-open .hint{ display:none; }

/* the unannounced star: readable that it exists, unreadable what it is */
.blur-name{ filter:blur(3px); opacity:.8; }

/* home is the anchor: visually distinct from the constellation chips */
.hall-jump[data-jump="home"]{
  color:var(--bone);
  border-color:var(--faint);
}

body.gl-on{ overflow:hidden; height:100%; }
/* the catalogue never leaves the document: while the sky renders it sits
   beneath the canvas (still crawlable, still in the accessibility tree);
   the "list" chip and any keyboard focus into it bring it forward */
body.gl-on .ledger{ position:relative; z-index:-1; }
body.ledger-open .ledger{ display:block; }

/* desktop: the catalogue is a drawer over a living sky */
@media (min-width: 821px){
  body.ledger-open .ledger{
    position:fixed;
    top:0; right:0; bottom:0;
    width:min(620px, 92vw);
    overflow-y:auto;
    z-index:8;
    background:rgba(9,12,10,.96);
    border-left:1px solid var(--line);
    box-shadow:-30px 0 80px rgba(0,0,0,.5);
  }
  body.ledger-open #plates{ display:none; }
}
/* small screens: the catalogue takes the room, the sky rests */
@media (max-width: 820px){
  body.ledger-open{ overflow:auto; }
  body.ledger-open .ledger{ position:static; z-index:auto; }
  body.ledger-open #plates,
  body.ledger-open .minimap,
  body.ledger-open #sky{ display:none; }
}
/* the top bar stays above the desktop drawer so the list chip can close it */
body.ledger-open .top{ z-index:9; }

/* no WebGL: the catalogue is a normal document, not a drawer over a void */
body.gl-failed #sky{ display:none; }
body.gl-failed .chip-sep{ display:none; }
@media (min-width: 821px){
  body.gl-failed .ledger{
    position:static; width:auto; z-index:auto;
    background:none; border-left:none; box-shadow:none;
  }
}
/* before JS runs there is nothing the tools could do — show none of them */
body.pre-gl .top-tools{ display:none; }

#sky{
  position:fixed; inset:0;
  width:100%; height:100%;
  display:block;
  z-index:0;
  touch-action:none;
  cursor:grab;
}
#sky.dragging{ cursor:grabbing; }
body.pre-gl #sky{ visibility:hidden; }

/* ==========================================================================
   PROJECTED LABELS
   ========================================================================== */
#plates{
  position:fixed; inset:0;
  z-index:1;
  overflow:hidden;
  pointer-events:none;
}
.plate{
  position:absolute; left:0; top:0;
  pointer-events:auto;
  touch-action:none;   /* drags that start on a label pan the sky */
  appearance:none; border:none; margin:0;
  display:inline-flex; align-items:center; gap:7px;
  font-family:var(--mono);
  color:var(--muted);
  white-space:nowrap;
  cursor:pointer;
  padding:5px 8px;
  border:1px solid transparent;
  background:rgba(6,8,7,.66);
  letter-spacing:.07em;
  font-size:.78rem;
  transition:color .2s ease, border-color .2s ease, opacity .25s ease;
}
.plate:hover{ color:var(--bone); border-color:var(--line); }
.plate:focus-visible{ outline:2px solid var(--verdis); outline-offset:2px; color:var(--bone); }
.plate.is-soon{ color:var(--faint); }
.plate.is-soon::after{ content:" · soon"; }
.plate.is-new::after{ content:" · new"; color:var(--ember); letter-spacing:.12em; }
.plate.is-focused{ color:var(--bone); border-color:var(--verdis); }
.plate.is-dim{ opacity:.2; }
.plate.is-dim:focus-visible{ opacity:1; }
/* off-view plates stay in the tab order; focusing one flies the camera to
   it, so keyboard focus is always visible in the end state */
.plate.is-off{ opacity:0; pointer-events:none; }
.plate.is-off:focus-visible{ opacity:1; pointer-events:auto; }
.plate-logo{
  width:16px; height:16px;
  object-fit:contain;
  background:var(--panel);
  border:1px solid var(--line);
  padding:1px;
  display:none;
}
.plate.has-logo .plate-logo{ display:block; }
body.atlas-on .plate-logo{ display:none; }   /* the atlas stays engraved text */

/* constellation name-plates: quiet in the sky, engraved in the atlas */
.const-plate{
  position:absolute; left:0; top:0;
  pointer-events:auto;
  touch-action:none;   /* drags that start on a label pan the sky */
  appearance:none; border:none; background:none; margin:0; padding:6px 10px;
  font-family:var(--mono);
  letter-spacing:.3em;
  color:var(--faint);
  white-space:nowrap;
  cursor:pointer;
  font-size:.72rem;
  transition:color .25s ease;
}
.const-plate:hover{ color:var(--bone); }
.const-plate:focus-visible{ outline:2px solid var(--verdis); outline-offset:2px; }
.const-plate.is-here{ color:var(--muted); }
.const-plate.is-off{ opacity:0; pointer-events:none; }
.const-plate.is-off:focus-visible{ opacity:1; pointer-events:auto; }
body.atlas-on .const-plate{ color:var(--muted); }
body.atlas-on .const-plate.is-here{ color:var(--bone); }

/* ==========================================================================
   TOP BAR (same grammar as the workshop page)
   ========================================================================== */
.top{
  position:fixed; top:0; left:0; right:0;
  z-index:5;
  display:flex; align-items:center; gap:18px;
  padding:14px clamp(16px,3vw,30px);
}
.brand{
  color:var(--bone);
  text-decoration:none;
  font-weight:350;
  letter-spacing:.045em;
  font-size:1.05rem;
  white-space:nowrap;
  flex-shrink:0;
}
.brand::after{
  content:"";
  display:inline-block;
  width:.14em; height:.14em;
  margin-left:.25em;
  background:var(--ember);
}
.brand:focus-visible{ outline:2px solid var(--verdis); outline-offset:4px; }
.top-title{
  margin:0;
  font-family:var(--mono);
  font-weight:400;
  font-size:.78rem;
  letter-spacing:.22em;
  color:var(--muted);
  white-space:nowrap;
}
.top-hall{
  font-family:var(--mono);
  font-size:.78rem;
  letter-spacing:.22em;
  color:var(--faint);
  white-space:nowrap;
  background:rgba(6,8,7,.66);
  padding:3px 8px;
}
.top-hall:empty{ display:none; }
@media (max-width: 1150px){
  .top-hall{ display:none; }   /* the rail highlight already says where you are */
}
.top-tools{
  margin-left:auto;
  display:flex; align-items:center; gap:10px;
}
.modes{ display:flex; align-items:center; gap:10px; }
.dock-home{ display:none; }              /* the rail owns "home" on desktop */
body.gl-failed .modes{ display:none; }
.search input{
  width:clamp(120px, 18vw, 230px);
  background:var(--panel);
  border:1px solid var(--line);
  color:var(--bone);
  font-family:var(--mono);
  font-size:.8rem;
  letter-spacing:.05em;
  padding:8px 12px;
}
.search input::placeholder{ color:var(--faint); }
.search input:focus-visible{ outline:2px solid var(--verdis); outline-offset:1px; }

.chip{
  appearance:none;
  background:var(--panel);
  border:1px solid var(--line);
  color:var(--muted);
  font-family:var(--mono);
  font-size:.78rem;
  letter-spacing:.08em;
  padding:8px 14px;
  cursor:pointer;
  transition:color .2s ease, border-color .2s ease;
}
.chip:hover{ color:var(--bone); border-color:var(--faint); }
.chip:focus-visible{ outline:2px solid var(--verdis); outline-offset:2px; }
.chip[aria-pressed="true"]{ color:var(--verdis); border-color:var(--verdis); }
.chip-run[aria-pressed="true"]{ color:var(--ember); border-color:var(--ember); }
/* the list is a co-equal front door, not one mode among many */
.chip-list{ color:var(--bone); border-color:var(--faint); }
.chip-sep{
  width:1px; height:18px;
  background:var(--line);
  flex-shrink:0;
}

/* ==========================================================================
   CONSTELLATION RAIL + COUNTS
   ========================================================================== */
.halls{
  position:fixed; left:0; right:0;
  bottom:calc(16px + env(safe-area-inset-bottom,0px));
  z-index:5;
  display:flex; gap:8px;
  padding:0 12px;
  flex-wrap:nowrap;
  overflow-x:auto;
  scrollbar-width:none;
}
.halls::-webkit-scrollbar{ display:none; }
/* centred while it fits, scrollable (from the start) when it does not */
.hall-jump:first-child{ margin-left:auto; }
.hall-lt:last-child{ margin-right:auto; }
body.pre-gl .halls, body.ledger-open .halls{ display:none; }
.hall-jump{
  appearance:none; background:rgba(6,8,7,.74);
  border:1px solid var(--line);
  color:var(--muted);
  font-family:var(--mono);
  font-size:.72rem;
  letter-spacing:.12em;
  padding:7px 12px;
  cursor:pointer;
  transition:color .2s ease, border-color .2s ease;
}
.hall-jump:hover{ color:var(--bone); border-color:var(--faint); }
.hall-jump:focus-visible{ outline:2px solid var(--verdis); outline-offset:2px; }
.hall-jump.is-here{ color:var(--verdis); border-color:var(--verdis); }
.hall-lt{ margin-left:14px; }

/* compass: constellation bearings around the current heading */
.compass{
  pointer-events:none;
  position:fixed;
  top:56px; left:50%;
  transform:translateX(-50%);
  width:min(300px, 44vw);
  height:12px;
  z-index:4;
  border-bottom:1px solid var(--line);
  overflow:hidden;
}
body.pre-gl .compass, body.ledger-open .compass{ display:none; }
.comp-notch{
  position:absolute;
  left:50%; bottom:0;
  width:2px; height:9px;
  margin-left:-1px;
  background:var(--verdis);
}
.comp-tick{
  position:absolute;
  left:0; bottom:0;
  width:2px; height:5px;
  margin-left:-1px;
  background:var(--faint);
}
.comp-tick.is-here{ background:var(--bone); height:8px; }

/* travel-mode caption: the ledger's own words, riding along */
.tour-cap{
  pointer-events:none;
  position:fixed;
  left:50%; bottom:calc(64px + env(safe-area-inset-bottom,0px));
  transform:translateX(-50%);
  z-index:5;
  margin:0;
  max-width:min(560px, 86vw);
  text-align:center;
  font-family:var(--mono);
  font-size:.8rem;
  letter-spacing:.08em;
  line-height:1.6;
  color:var(--muted);
  background:rgba(6,8,7,.78);
  padding:8px 14px;
}

/* the identity line: the one sentence that never leaves the screen */
.counts{
  pointer-events:none;
  position:fixed;
  left:clamp(16px,3vw,30px);
  top:52px;
  z-index:4;
  margin:0;
  font-family:var(--mono);
  font-size:.72rem;
  letter-spacing:.1em;
  color:var(--muted);
  background:rgba(6,8,7,.66);
  padding:4px 8px;
}
body.pre-gl .counts, body.ledger-open .counts{ display:none; }

/* ==========================================================================
   FOCUS CARD
   ========================================================================== */
.card{
  position:fixed;
  right:clamp(14px,3vw,30px);
  top:50%;
  transform:translateY(-50%);
  z-index:6;
  width:min(340px, calc(100vw - 28px));
  background:rgba(16,20,18,.92);
  border:1px solid var(--line);
  padding:22px 24px 20px;
}
.card-close{
  position:absolute; top:0; right:0;
  appearance:none; background:none; border:none;
  color:var(--faint);
  font-size:1.25rem; line-height:1;
  min-width:44px; min-height:44px;
  padding:8px 10px;
  cursor:pointer;
}
.card:focus-visible{ outline:2px solid var(--verdis); outline-offset:-2px; }
.card-close:hover{ color:var(--bone); }
.card-close:focus-visible{ outline:2px solid var(--verdis); outline-offset:1px; }
.card-logo{
  display:block;
  width:34px; height:34px;
  margin:0 0 12px;
  border:1px solid var(--line);
  background:var(--panel);
  object-fit:contain;
  padding:3px;
}
.card-family{
  margin:0 0 6px;
  font-family:var(--mono);
  font-size:.68rem;
  letter-spacing:.22em;
  color:var(--faint);
  text-transform:lowercase;
}
.card-name{
  margin:0 0 10px;
  font-weight:350;
  font-size:1.35rem;
  letter-spacing:.02em;
}
.card-desc{
  margin:0 0 10px;
  color:var(--muted);
  font-size:.9rem;
  line-height:1.55;
}
.card-rel{
  margin:0 0 14px;
  color:var(--faint);
  font-size:.78rem;
  line-height:1.5;
  font-family:var(--mono);
}
.card-rel a{ color:var(--muted); text-decoration:none; border-bottom:1px solid var(--line); cursor:pointer; }
.card-rel a:hover{ color:var(--verdis); border-color:var(--verdis); }
.card-actions{ margin:0; }
.card-visit{
  display:inline-block;
  font-family:var(--mono);
  font-size:.82rem;
  letter-spacing:.08em;
  color:var(--bone);
  text-decoration:none;
  border:1px solid var(--faint);
  padding:9px 16px;
  transition:border-color .2s ease, color .2s ease;
}
.card-visit:hover{ border-color:var(--ember); color:#fff; }
.card-visit:focus-visible{ outline:2px solid var(--verdis); outline-offset:2px; }
.card-soon{
  font-family:var(--mono);
  font-size:.82rem;
  letter-spacing:.14em;
  color:var(--faint);
}

/* ==========================================================================
   SEARCH RESULTS
   ========================================================================== */
.search{ position:relative; }
.search-pop{
  position:absolute; top:calc(100% + 6px); right:0;
  width:max(100%, 250px);
  background:var(--panel);
  border:1px solid var(--line);
  z-index:7;
  max-height:min(50vh, 380px);
  overflow:auto;
}
.search-pop button{
  display:block; width:100%;
  appearance:none; background:none; border:none;
  text-align:left;
  font-family:var(--mono);
  font-size:.8rem;
  color:var(--muted);
  padding:9px 14px;
  cursor:pointer;
}
.search-pop button:hover, .search-pop button.is-hot{ color:var(--bone); background:#161b18; }
.search-pop button:focus-visible{ outline:2px solid var(--verdis); outline-offset:-2px; }
.search-pop .sp-soon{ color:var(--faint); }
.search-pop .sp-none{ padding:10px 14px; color:var(--faint); font-family:var(--mono); font-size:.78rem; margin:0; }

/* ==========================================================================
   LEDGER — the celestial catalogue
   ========================================================================== */
.ledger{
  max-width:820px;
  margin:0 auto;
  padding:96px clamp(18px,4vw,40px) 80px;
}
.lg-title{
  margin:0 0 14px;
  font-weight:300;
  font-size:clamp(2rem, 5vw, 3rem);
  letter-spacing:.03em;
  color:var(--bone);
}
.lg-logo{
  width:20px; height:20px;
  object-fit:contain;
  vertical-align:-4px;
  margin-right:10px;
  background:var(--panel);
  border:1px solid var(--line);
  padding:2px;
}
.lg-lede{
  color:var(--muted);
  line-height:1.65;
  max-width:56ch;
  margin:0 0 30px;
}
.lg-hall{
  margin:44px 0 0;
  border-top:1px solid var(--line);
  padding-top:26px;
}
.lg-hall h2{
  font-family:var(--mono);
  font-weight:400;
  font-size:.85rem;
  letter-spacing:.26em;
  color:var(--muted);
  margin:0 0 8px;
}
.lg-hallnote{
  color:var(--faint);
  font-size:.88rem;
  line-height:1.6;
  max-width:58ch;
  margin:0 0 18px;
}
.lg-item{
  display:grid;
  grid-template-columns:200px 1fr;
  gap:4px 22px;
  padding:13px 0;
  border-top:1px dashed var(--line);
  align-items:baseline;
}
.lg-item h3{
  margin:0;
  font-weight:400;
  font-size:1rem;
  letter-spacing:.02em;
  cursor:pointer;
}
.lg-item[data-status="live"] h3::before{
  content:"";
  display:inline-block;
  width:.45em; height:.45em;
  border-radius:50%;
  margin-right:.6em;
  background:var(--ember);
}
.lg-item[data-status="soon"] h3{ color:var(--faint); }
.lg-item[data-status="soon"] h3::after{
  content:"soon";
  font-family:var(--mono);
  font-size:.68rem;
  letter-spacing:.18em;
  color:var(--faint);
  margin-left:1em;
  border:1px solid var(--line);
  padding:2px 8px;
  vertical-align:middle;
}
.lg-url{ margin:4px 0 0; grid-column:2; font-family:var(--mono); font-size:.76rem; }
.lg-url a{
  display:inline-block;
  color:var(--muted);
  text-decoration:none;
  letter-spacing:.08em;
  border:1px solid var(--line);
  padding:5px 12px;
  transition:color .2s ease, border-color .2s ease;
}
.lg-url a:hover{ color:var(--bone); border-color:var(--ember); }
.lg-url a:focus-visible{ outline:2px solid var(--verdis); outline-offset:2px; }
.lg-desc{ margin:2px 0 0; grid-column:2; color:var(--muted); font-size:.9rem; line-height:1.55; }
.lg-relnote{ margin:4px 0 0; grid-column:2; color:var(--faint); font-size:.78rem; font-family:var(--mono); }
.lg-builder p{ color:var(--muted); line-height:1.7; max-width:56ch; }
.lg-contact a{
  color:var(--bone);
  font-family:var(--mono);
  text-decoration:none;
  border-bottom:1px solid var(--faint);
}
.lg-contact a:hover{ border-color:var(--ember); }
.lg-contact a:focus-visible{ outline:2px solid var(--verdis); outline-offset:3px; }

/* catalogue footer — matches the root page's legal bar */
.lg-foot{
  margin:56px 0 0;
  border-top:1px solid var(--line);
  padding-top:22px;
  display:flex;
  justify-content:space-between;
  gap:10px 24px;
  flex-wrap:wrap;
  font-family:var(--mono);
  font-size:.74rem;
  letter-spacing:.08em;
  color:var(--faint);
}
.lg-foot p{ margin:0; }
.lg-foot a{
  color:var(--muted);
  text-decoration:none;
  border-bottom:1px solid var(--line);
  transition:color .2s ease, border-color .2s ease;
}
.lg-foot a:hover{ color:var(--bone); border-color:var(--ember); }
.lg-foot a:focus-visible{ outline:2px solid var(--verdis); outline-offset:2px; }

.noscript-note{
  max-width:820px;
  margin:0 auto;
  padding:0 clamp(18px,4vw,40px) 60px;
  color:var(--faint);
  font-family:var(--mono);
  font-size:.8rem;
}

.visually-hidden{
  position:absolute;
  width:1px; height:1px;
  margin:-1px; padding:0;
  overflow:hidden;
  clip:rect(0 0 0 0);
  white-space:nowrap;
  border:0;
}

/* ==========================================================================
   SMALL SCREENS — authored: rail scrolls, card is a sheet, steppers walk
   ========================================================================== */
.stepper{
  position:fixed;
  z-index:6;
  top:50%;
  transform:translateY(-50%);
  appearance:none;
  background:rgba(6,8,7,.74);
  border:1px solid var(--line);
  color:var(--muted);
  font-size:1.1rem;
  width:42px; height:56px;
  cursor:pointer;
  display:none;
}
.stepper:focus-visible{ outline:2px solid var(--verdis); outline-offset:2px; }
.stepper-prev{ left:8px; }
.stepper-next{ right:8px; }

/* ==========================================================================
   SMALL SCREENS — authored mobile, its own product.
   One top row: brand + search. One bottom dock at the thumb:
   home · sites · tour · map · pause — five fixed cells, no scrolling
   chrome anywhere. Constellation jumps live in the map, where they are
   spatial and tappable, not in a 13-chip rail.
   ========================================================================== */
@media (max-width: 820px), (pointer:coarse) and (max-width:1024px){
  .top{
    gap:10px;
    padding:calc(10px + env(safe-area-inset-top,0px)) 12px 58px;
    pointer-events:none;
    background:linear-gradient(to bottom,
      rgba(6,8,7,.96) 0%, rgba(6,8,7,.9) 45%, rgba(6,8,7,0) 100%);
  }
  .top > *{ pointer-events:auto; }
  .top-title, .top-hall, .chip-sep{ display:none; }
  .brand{ font-size:1rem; }
  .top-tools{ flex:1; min-width:0; gap:0; }
  .search{ flex:1; min-width:0; }
  .search input{ width:100%; min-width:0; font-size:16px; padding:9px 12px; } /* 16px: no ios focus-zoom */
  .search input::placeholder{ font-size:.72rem; letter-spacing:.06em; }       /* quiet, uncramped */

  /* identity + compass live inside the header scrim */
  .counts{
    top:calc(58px + env(safe-area-inset-top,0px)); left:12px; right:12px;
    font-size:.64rem; letter-spacing:.08em;
    background:none; padding:0;
  }
  .compass{ top:calc(80px + env(safe-area-inset-top,0px)); width:88vw; }

  /* THE DOCK: the modes cluster leaves the header and fixes to the thumb */
  .modes{
    position:fixed;
    left:0; right:0; bottom:0;
    z-index:5;
    display:flex;
    gap:6px;
    padding:10px 10px calc(10px + env(safe-area-inset-bottom,0px));
    background:linear-gradient(to top, rgba(6,8,7,.96) 72%, rgba(6,8,7,0) 100%);
  }
  .dock-home{ display:block; color:var(--bone); border-color:var(--faint); }
  .modes .chip{
    flex:1;
    padding:13px 0;
    min-height:48px;
    text-align:center;
    font-size:.74rem;
    letter-spacing:.1em;
  }

  /* the rail is a desktop instrument; the map is the jump surface here */
  .halls{ display:none; }

  /* steppers are a card-walking control, not idle furniture */
  .stepper{ display:none; }
  body.card-open .stepper{ display:block; }
  body.pre-gl .stepper, body.ledger-open .stepper{ display:none; }

  /* hint: one quiet line above the dock */
  .hint{
    font-size:.7rem; letter-spacing:.1em;
    max-width:none; white-space:nowrap; padding:8px 12px;
    bottom:calc(78px + env(safe-area-inset-bottom,0px));
  }
  .hint strong{ display:none; }
  .hint span{ display:inline; }

  .card{
    right:0; left:0; top:auto; bottom:0;
    transform:none;
    width:100%;
    z-index:6;
    background:rgba(10,13,11,.98);      /* a sheet, not a pane of glass */
    border-left:none; border-right:none; border-bottom:none;
    padding-top:26px;
    padding-bottom:calc(20px + env(safe-area-inset-bottom,0px));
  }
  /* nothing interactive lives underneath an open sheet */
  body.card-open .modes{ display:none; }
  .card::before{                          /* sheet handle */
    content:"";
    position:absolute;
    top:10px; left:50%;
    transform:translateX(-50%);
    width:36px; height:3px;
    background:var(--line);
    border-radius:2px;
  }
  .tour-cap{ bottom:calc(84px + env(safe-area-inset-bottom,0px)); }
  body.card-open .tour-cap{ bottom:calc(260px + env(safe-area-inset-bottom,0px)); }

  /* the open catalogue keeps the dock (it is how you close it) */
  body.ledger-open .modes{ z-index:9; }
  body.ledger-open .ledger{ padding-bottom:120px; }

  .lg-item{ grid-template-columns:1fr; }
  .lg-url, .lg-desc, .lg-relnote{ grid-column:1; }
}

@media (prefers-contrast: more){
  :root{ --muted:var(--bone); --faint:#8b958e; --line:#39413b; }
}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{ transition:none !important; animation:none !important; }
  /* the boot veil must still lift for no-JS visitors: a motionless jump cut */
  .boot{ animation:boot-linger 0s linear 7s forwards !important; }
}
