/* =============================================================================
   The 1,667 — Conservation Imperatives
   Landseed immersive design language. Tokens and card grammar match the vista
   engine (virunga / chitwan / etosha); the type scale and gbar come from
   Landseed-site-v2. Dark is the brand, so there is no light theme.
   ========================================================================== */
:root{
  --sat:env(safe-area-inset-top,0px); --sab:env(safe-area-inset-bottom,0px);
  --sal:env(safe-area-inset-left,0px); --sar:env(safe-area-inset-right,0px);
  --appvh:100vh}

/* ==========================================================================
   The type scale.

   Ten sizes replace 28, five trackings replace 28, five leadings replace 19,
   four radii replace 14, and ten ink steps replace 38 hand-written alphas.
   Every fold moves a value by at most 1px and almost all by 0.5px or less, so
   the page is meant to look identical — verified against 8,308 element boxes
   rather than by eye. Nobody could tell 12.8px from 13.2px; the cost of both
   existing was that the same element got styled two ways in two places.
   Each step is the value that minimises how far real elements move, measured
   over 8,308 rendered boxes — not the value that happened to be written most
   often. Picking by declaration count put the base at 12.5px and pushed 1,319
   table cells up half a pixel, which is a 4% swell on the densest surface here.
   ========================================================================== */
:root{
  --fs-micro:8.5px;
  --fs-tiny:9.5px;
  --fs-xs:10px;
  --fs-sm:11.5px;
  --fs-base:12px;
  --fs-md:13px;
  --fs-lg:15px;
  --fs-xl:17px;
  --fs-2xl:20px;
  --fs-3xl:22px;
  /* Fluid display sizes. Both were declared twice with different numbers —
     24/3vw/32 then 25/2.8vw/32, and 21/2.4vw/27 then 22/2.5vw/29 — so the
     later silently won and the earlier was dead. One definition each. */
  --fs-head:clamp(25px,2.8vw,32px);
  --fs-figure:clamp(22px,2.5vw,29px);
  /* Near-white tinted toward the accent, for text sitting on green or over the
     globe. There were four of these — var(--ink-on-green), var(--ink-on-green), var(--ink-on-green), var(--ink-on-green) —
     doing one job at four values nobody could tell apart. */
  --ink-on-green:#e4f4ea;
  --ls-display:-.03em;
  --ls-tight:-.015em;
  --ls-wide:.05em;
  --ls-caps:.15em;
  --ls-caps-x:.18em;
  --ls-nudge:.015em;
  /* Four weights, not five. 400 had a single use and read as a mistake beside
     500; the rest are kept because 600 and 800 do distinct jobs here — 600 for
     emphasis inside running text, 800 for standalone display figures. */
  --fw-normal:500;
  --fw-med:600;
  --fw-bold:700;
  --fw-display:800;
  --lh-flat:1;
  --lh-snug:1.25;
  --lh-body:1.45;
  --lh-loose:1.55;
  --lh-airy:1.62;
  --r-hair:3px;
  --r-ctl:9px;
  --r-card:14px;
  --r-pill:999px;
  --ink-muted:rgba(240,240,234,.62);
  --ink-dim:rgba(240,240,234,.75);
  --ink-soft:rgba(240,240,234,.85);
  --ink-near:rgba(240,240,234,.9);
  --ink-faint:rgba(240,240,234,.45);
  --sf-line:rgba(240,240,234,.1);
  --sf-edge:rgba(240,240,234,.2);
  --sf-tint:rgba(240,240,234,.07);
  --sf-wash:rgba(240,240,234,.05);
  --sf-hair:rgba(240,240,234,.32)}

@supports (height:100svh){ :root{ --appvh:100svh} }
:root{
  --deep:#070F07; --forest:#0D1F0D; --green:#2D5A27; --accent:#00BE5A; --alive:#00FF64;
  --text:#F0F0EA; --dim:var(--ink-soft); --muted:var(--ink-muted);
  --aqua:#32C8FF; --gold:#FFC800; --warm:#FF8C42;
  --line:var(--sf-line);
  --sans:"Hanken Grotesk",-apple-system,BlinkMacSystemFont,system-ui,sans-serif;
  --serif:"Fraunces",Georgia,serif}
*{box-sizing:border-box;margin:0;padding:0}
html,html[data-theme]{background:#040A04;color-scheme:dark}
body{background:#040A04;color:var(--text);font-family:var(--sans);
  -webkit-font-smoothing:antialiased;overflow:hidden;height:var(--appvh);
  overscroll-behavior:none}
#scene{position:fixed;inset:0;width:100vw;height:var(--appvh);display:block;
  cursor:grab;touch-action:none}
#scene:active{cursor:grabbing}
#scene.pick{cursor:pointer}
::selection{background:var(--accent);color:var(--deep)}
button{font-family:inherit}
:focus-visible{outline:2px solid var(--alive);outline-offset:3px;border-radius:var(--r-hair)}

/* ---------------------------------------------------------------- vignette */
#vig{position:fixed;inset:0;z-index:2;pointer-events:none;
  background:radial-gradient(ellipse at 50% 46%,transparent 34%,rgba(2,6,3,.42) 78%,rgba(2,6,3,.8) 100%)}

/* ------------------------------------------------------------------ loader */
#loader{position:fixed;inset:0;z-index:80;display:grid;place-items:center;gap:0;
  background:#040A04;transition:opacity .9s ease,visibility .9s}
#loader.gone{opacity:0;visibility:hidden;pointer-events:none}
@keyframes spin{to{transform:rotate(360deg)}}
#loader span{font-size:var(--fs-base);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--dim)}
#ldbar{width:184px;height:2px;background:var(--sf-line);border-radius:var(--r-hair);overflow:hidden}
#ldfill{height:100%;width:0;background:var(--accent);transition:width .35s ease}

/* -------------------------------------------------------------------- labels */
/* Projected each frame from lat/lon. Screen-space text stays crisp at any zoom,
   which a sprite atlas cannot, and it inherits the page's own font.
   ⭐ 2026-09-28: a label is a NAME PLATE in the landscape's own hue — small, sans, upright, with
   the index in a pill and a hairline leader to the anchor dot (the SVG below). The italic serif
   at --fs-lg was a headline standing on the terrain; seven of them made the globe a poster. */
#labels{position:fixed;inset:0;z-index:8;pointer-events:none;
  contain:layout style;will-change:contents}
#labels .leaders{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
#labels .leaders line{stroke-width:1;shape-rendering:geometricPrecision}
.mlabel{position:absolute;top:0;left:0;white-space:nowrap;opacity:0;--c:var(--alive);
  transition:opacity .28s ease;display:inline-flex;align-items:center;gap:6px;
  padding:3px 4px 3px 8px;border-radius:var(--r-pill);
  background:rgba(6,12,9,.72);border:1px solid color-mix(in srgb,var(--c) 38%,transparent);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px)}
.mlabel.on{opacity:1}
.mlabel.hot{border-color:color-mix(in srgb,var(--c) 75%,transparent);background:rgba(6,12,9,.86)}
.mlabel .ml-n{font-family:var(--sans);font-weight:var(--fw-med);font-size:var(--fs-sm);
  color:var(--ink-on-green);letter-spacing:var(--ls-nudge);line-height:1.2}
.mlabel .ml-v{font-size:var(--fs-tiny);font-weight:var(--fw-bold);color:#0b1410;line-height:1.3;
  font-variant-numeric:tabular-nums;padding:1px 6px;border-radius:var(--r-pill);background:var(--c)}

/* ----------------------------------------------------------------- masthead */
#top{position:fixed;top:0;left:0;right:0;z-index:30;display:flex;align-items:flex-start;
  justify-content:space-between;gap:24px;
  padding:calc(20px + var(--sat)) calc(24px + var(--sar)) 0 calc(24px + var(--sal));
  pointer-events:none;opacity:0;transition:opacity 1s ease .15s}
body.ready #top{opacity:1}
#brand{display:flex;align-items:center;gap:13px;text-decoration:none;pointer-events:auto;flex:none}
#brand img{height:18px;width:auto;display:block;opacity:.94}
#brand .bsep{width:1px;height:16px;background:var(--sf-edge)}
#brand .btag{font-size:var(--fs-tiny);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps-x);text-transform:uppercase;
  color:var(--muted);white-space:nowrap}
#brand:hover img{opacity:1}
#brand:hover .btag{color:var(--dim)}

/* global figures, always on: the landing page should already tell you something */
#gstats{display:flex;gap:0;pointer-events:auto;justify-content:flex-end;align-items:stretch}
#gstats div{padding:1px 0 1px 18px;margin-left:18px;
  border-left:1px solid var(--sf-edge);display:flex;flex-direction:column;
  justify-content:center;min-width:104px}
#gstats div:first-child{border-left:0;margin-left:0;padding-left:0}
#gstats b{font-size:var(--fs-2xl);font-weight:var(--fw-display);letter-spacing:var(--ls-display);line-height:var(--lh-flat);color:var(--text);
  font-variant-numeric:tabular-nums;text-shadow:0 1px 10px rgba(0,0,0,.85)}
#gstats span{font-size:var(--fs-micro);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);text-transform:uppercase;
  color:var(--muted);margin-top:7px;white-space:nowrap}

/* ------------------------------------------------------- global summary panel */
/* The instrument panel: map key, then the figures, then the two distributions.
   Every block is titled — this is a reference surface, not decoration. */
#summary{position:fixed;right:calc(20px + var(--sar));top:calc(84px + var(--sat));
  z-index:24;width:262px;max-height:calc(var(--appvh) - 104px - var(--sab));
  overflow-y:auto;overscroll-behavior:contain;padding:2px 0;
  border-radius:var(--r-card);
  background:linear-gradient(180deg,rgba(7,15,8,.72),rgba(4,10,5,.86));
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border:1px solid var(--line);box-shadow:0 18px 50px rgba(0,0,0,.5);
  opacity:0;transition:opacity .6s ease .35s}
body.ready #summary{opacity:1}
.sm-sec{padding:13px 16px 14px;border-bottom:1px solid var(--sf-tint)}
.sm-sec:last-of-type{border-bottom:0}
.sm-sec h3{font-size:var(--fs-micro);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps-x);text-transform:uppercase;
  color:var(--accent);margin-bottom:12px}

/* ------------------------------------------------------------ detail panel */
#detail{position:fixed;left:calc(20px + var(--sal));top:calc(74px + var(--sat));
  z-index:34;width:min(462px,calc(100vw - 40px));
  max-height:calc(var(--appvh) - 168px - var(--sab));display:flex;flex-direction:column;
  border-radius:var(--r-card);
  background:linear-gradient(180deg,rgba(7,15,8,.94),rgba(4,10,5,.985));
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  border:1px solid var(--line);box-shadow:0 26px 70px rgba(0,0,0,.6);
  opacity:0;transform:translateX(-14px);pointer-events:none;
  transition:opacity .32s ease,transform .42s cubic-bezier(.22,.92,.2,1)}
#detail.open{opacity:1;transform:none;pointer-events:auto}
.dt-top{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;
  padding:16px 18px 14px;border-bottom:1px solid var(--sf-line);flex:none}
.dt-k{font-size:var(--fs-tiny);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps-x);text-transform:uppercase;
  color:var(--accent);margin-bottom:8px}
#dtName{font-family:var(--serif);font-size:var(--fs-3xl);font-weight:var(--fw-normal);letter-spacing:var(--ls-tight);
  line-height:var(--lh-flat);color:var(--text)}
.dt-sub{font-size:var(--fs-xs);letter-spacing:var(--ls-wide);color:var(--muted);margin-top:5px;line-height:var(--lh-body)}
/* The name a species' Red List category is assessed under, shown where that name differs from the
   accepted binomial. Muted and smaller: it qualifies the category, it is not a second name for the
   animal. Both hooks are written by assessedAs() in src/main.js and the species sub-line in
   src/site.js, and appear only when the two names differ. */
.sp-assessed,.dt-assessed{color:var(--muted);font-size:var(--fs-tiny);letter-spacing:var(--ls-wide)}
.sp-assessed i,.dt-assessed i{opacity:.8}
.dt-body{overflow-y:auto;overscroll-behavior:contain;padding:16px 18px 20px;flex:1;min-height:0}
.dt-grid{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--sf-line);
  border:1px solid var(--sf-line);border-radius:var(--r-ctl);overflow:hidden}
.dt-grid div{background:#080f09;padding:12px 13px}
.dt-grid dt{font-size:var(--fs-micro);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--muted);
  margin-bottom:5px}
.dt-grid dd{font-size:var(--fs-xl);font-weight:var(--fw-bold);letter-spacing:var(--ls-tight);color:var(--text);
  font-variant-numeric:tabular-nums;line-height:var(--lh-flat)}
.dt-grid dd em{font-style:normal;font-size:var(--fs-tiny);font-weight:var(--fw-normal);letter-spacing:var(--ls-wide);
  color:var(--muted);display:block;margin-top:5px;line-height:var(--lh-body)}
.dt-block{margin-top:20px}
.dt-block h4{font-size:var(--fs-tiny);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);text-transform:uppercase;
  color:var(--muted);margin-bottom:11px}
.dt-more{font-size:var(--fs-xs);color:var(--muted);margin-top:9px;line-height:var(--lh-loose)}

/* ---------------------------------------------------------------------- dock */
/* One bar. Two hover menus and the ask field, which is the primary action —
   the old row of nine chips was most of the interface competing with the globe. */
#dock{position:fixed;left:50%;bottom:calc(20px + var(--sab));transform:translateX(-50%);
  z-index:52;display:flex;align-items:center;gap:6px;padding:6px;border-radius:var(--r-pill);
  width:min(760px,calc(100vw - 32px));
  background:rgba(7,15,7,.66);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);
  border:1px solid var(--line);box-shadow:0 20px 52px rgba(0,0,0,.55);
  opacity:0;transition:opacity .7s ease}
body.ready #dock{opacity:1}
.dock-sep{width:1px;height:20px;background:var(--sf-line);flex:none}
.dock-menu{position:relative;flex:none}
.dm-btn{display:inline-flex;align-items:center;gap:7px;background:none;border:0;
  color:var(--dim);font-family:var(--sans);font-size:var(--fs-base);font-weight:var(--fw-med);
  padding:9px 13px;border-radius:var(--r-pill);cursor:pointer;white-space:nowrap;transition:.18s}
.dm-btn:hover,.dock-menu.open .dm-btn{color:var(--text);background:var(--sf-tint)}
.dm-btn svg{opacity:.8;flex:none}
.dm-caret{font-size:var(--fs-micro);opacity:.5;transition:transform .2s}
.dock-menu.open .dm-caret{transform:rotate(180deg)}
.dm-btn.plain{padding:9px 14px}

/* pop-up menus rise out of the dock */
.pop{position:absolute;bottom:calc(100% + 12px);left:0;min-width:290px;
  padding:8px;border-radius:var(--r-card);
  background:linear-gradient(180deg,rgba(8,16,9,.97),rgba(5,11,6,.99));
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  border:1px solid var(--line);box-shadow:0 24px 60px rgba(0,0,0,.6);
  opacity:0;visibility:hidden;transform:translateY(8px) scale(.98);transform-origin:bottom left;
  transition:opacity .22s ease,transform .22s cubic-bezier(.22,.92,.2,1),visibility .22s}
.dock-menu.open .pop{opacity:1;visibility:visible;transform:none}

/* ⛔ BOTH MENUS SHIPPED AS RAW OS BUTTONS, and no gate could see it. The stylesheet styled
 * `.pop-i`/`.pi-n`/`.pi-s` and `.find-i`/`.find-h`/`.find-f` — the dashboard's class names — while
 * main.js writes `<button><i style=background>Name<em>141.0</em></button>` into both #popData and
 * #find. Not one of those selectors matched anything, so the Landscapes menu and the search
 * results rendered in Chrome's default button chrome: grey #6b6b6b on the dark page, 13.33px
 * system text, no padding, the colour dot invisible at zero size, name and index run together.
 * Measured, then looked at: the coverage gate never types into the field and the prose linter
 * renders site.js, so both instruments were blind to the one control a reader reaches first.
 * Styled by what the markup IS, not by a class it never had. */
#popData button,#find button{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:10px;
  align-items:center;width:100%;text-align:left;background:none;border:0;color:var(--text);
  font-family:var(--sans);font-size:var(--fs-md);font-weight:var(--fw-med);letter-spacing:var(--ls-tight);
  padding:9px 11px;border-radius:var(--r-ctl);cursor:pointer;transition:background .15s}
#popData button:hover,#popData button:focus-visible,
#find button:hover,#find button:focus-visible{background:rgba(0,190,90,.13);outline:none}
#popData button i,#find button i{width:9px;height:9px;border-radius:50%;flex:none;align-self:center}
#popData button em,#find button em{font-style:normal;font-size:var(--fs-sm);font-weight:var(--fw-normal);
  color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
/* The name is a bare text node between the dot and the figure, so it is an anonymous grid item:
 * it WRAPS rather than ellipsising, which is what G244 requires of every name on this page.
 * "All the data" is inserted afterbegin, so its rule separates it from what follows, not above. */
#popData button[data-all]{color:var(--muted);font-size:var(--fs-sm);font-weight:var(--fw-normal);
  border-bottom:1px solid var(--line);border-radius:var(--r-ctl) var(--r-ctl) 0 0;margin-bottom:4px;padding-bottom:11px}

/* ask field */
#chatform{display:flex;align-items:center;gap:8px;flex:1;min-width:0;position:relative}
#chatq{flex:1;min-width:0;background:var(--sf-tint);border:1px solid transparent;
  border-radius:var(--r-pill);padding:10px 16px;color:var(--text);font-family:var(--sans);
  font-size:var(--fs-md);outline:none;transition:border-color .2s,background .2s}
#chatq:focus{border-color:rgba(0,190,90,.55);background:var(--sf-tint)}
#chatq::placeholder{color:var(--ink-faint)}
#chatsend{flex:none;width:36px;height:36px;border-radius:50%;border:0;cursor:pointer;
  background:var(--accent);color:var(--deep);display:grid;place-items:center;transition:.2s}
#chatsend:hover{background:#00d066}
#chatsend:disabled{opacity:.42;cursor:default}

/* -------------------------------------------------------------- transcript */
#chat{position:fixed;left:50%;bottom:calc(80px + var(--sab));transform:translateX(-50%) translateY(10px);
  z-index:51;width:min(760px,calc(100vw - 32px));
  max-height:min(58vh,520px);display:flex;flex-direction:column;border-radius:var(--r-card);
  background:linear-gradient(180deg,rgba(7,15,8,.95),rgba(4,10,5,.985));
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  border:1px solid var(--line);box-shadow:0 26px 70px rgba(0,0,0,.6);
  opacity:0;pointer-events:none;
  transition:opacity .3s ease,transform .38s cubic-bezier(.22,.92,.2,1)}
#chat.open{opacity:1;pointer-events:auto;transform:translateX(-50%)}
.chat-top{display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:12px 16px 11px;border-bottom:1px solid var(--sf-line);flex:none}
.chat-top .pk{font-size:var(--fs-tiny);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);text-transform:uppercase;
  color:var(--muted)}
#chatlog{overflow-y:auto;overscroll-behavior:contain;padding:15px 16px 16px;
  display:flex;flex-direction:column;gap:11px}
@keyframes blink{0%,60%,100%{opacity:.25}30%{opacity:1}}

/* -------------------------------------------------------------------- sheets */
.sheet{position:fixed;z-index:45;background:linear-gradient(180deg,rgba(6,13,7,.96),rgba(4,9,5,.985));
  backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
  border:1px solid var(--line);box-shadow:0 30px 90px rgba(0,0,0,.62);
  display:flex;flex-direction:column;opacity:0;pointer-events:none;
  transition:transform .48s cubic-bezier(.22,.92,.2,1),opacity .34s ease}
.sheet.open{opacity:1;pointer-events:auto;transform:none!important}
.sheet-top{display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:15px 20px 13px;border-bottom:1px solid var(--sf-line);flex:none}
.sheet-top .pk{font-size:var(--fs-tiny);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps-x);text-transform:uppercase;
  color:var(--accent)}
.sheet-body{overflow-y:auto;overscroll-behavior:contain;flex:1;min-height:0}
.xbtn{background:none;border:1px solid var(--line);color:var(--dim);width:28px;height:28px;
  border-radius:50%;cursor:pointer;font-size:var(--fs-lg);line-height:var(--lh-flat);display:grid;place-items:center;
  transition:.2s;flex:none}
.xbtn:hover{border-color:var(--accent);color:var(--accent)}

#data{left:50%;top:calc(26px + var(--sat));
  width:min(1180px,calc(100vw - 52px));height:calc(var(--appvh) - 118px - var(--sab));
  border-radius:var(--r-card);transform:translateX(-50%) translateY(-10px) scale(.985)}
#data.open{transform:translateX(-50%)!important}

#databody{padding:26px clamp(20px,2.2vw,34px) 44px}

#panel{right:0;top:0;height:var(--appvh);width:min(500px,100vw);border-radius:0;
  border-right:0;border-top:0;border-bottom:0;transform:translateX(100%)}
.pbody{padding:22px 26px 60px}
.pbody h3{font-family:var(--serif);font-size:var(--fs-3xl);font-weight:var(--fw-normal);letter-spacing:var(--ls-tight);
  line-height:var(--lh-flat);color:var(--text);margin-bottom:12px}
.pbody h4{font-size:var(--fs-tiny);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps-x);text-transform:uppercase;
  color:var(--accent);margin:28px 0 12px}
.pbody p{font-size:var(--fs-md);line-height:var(--lh-airy);color:var(--dim)}
.pbody p+p{margin-top:11px}
.pstep{display:flex;gap:14px;align-items:flex-start;margin-top:15px}
.pstep b{flex:none;width:25px;height:25px;border-radius:50%;display:grid;place-items:center;
  border:1px solid rgba(0,190,90,.34);color:var(--accent);font-size:var(--fs-sm);font-weight:var(--fw-display);
  font-variant-numeric:tabular-nums;margin-top:1px}
.pstep div{font-size:var(--fs-base);line-height:var(--lh-loose);color:var(--dim)}
.pstep strong{color:var(--text);font-weight:var(--fw-med);display:block;margin-bottom:3px;font-size:var(--fs-md)}

.sheet-body h4.sh{font-size:var(--fs-tiny);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);
  text-transform:uppercase;color:var(--muted);margin-bottom:16px}

/* --------------------------------------------------------------- responsive */
/* Narrow: the single-row bar squeezed the chips down to two characters. Stack
   it — chips get the full width to scroll, controls sit underneath. */
@media (max-width:760px){
  #bar{flex-wrap:wrap;justify-content:center;border-radius:var(--r-card);gap:5px;
    left:calc(10px + var(--sal));right:calc(10px + var(--sar));transform:none;
    max-width:none;width:auto;padding:7px 8px}
  .mode{padding:7px 11px;font-size:var(--fs-xs)}
  .act{padding:7px 11px;font-size:var(--fs-base)}
}
/* Narrow: the five-figure strip wrapped over the wordmark. Stack the masthead,
   keep the two figures that matter, and give the detail panel the screen. */
@media (max-width:760px){
  #top{flex-direction:column;align-items:flex-start;gap:10px;padding-bottom:2px}
  #gstats{justify-content:flex-start;gap:0}
  #gstats div{padding:0 12px;text-align:left}
  #gstats div:first-child{padding-left:0}
  #gstats div:nth-child(n+4){display:none}
  #gstats b{font-size:var(--fs-lg)}
  #gstats span{font-size:var(--fs-micro);letter-spacing:var(--ls-caps);margin-top:4px}
  #detail{left:0;right:0;bottom:0;top:auto;width:auto;
    max-height:min(72vh,calc(var(--appvh) - 150px));
    border-radius:var(--r-card) 16px 0 0;border-left:0;border-right:0;border-bottom:0;
    transform:translateY(20px)}
  #detail.open{transform:none}
  #hint{display:none}
  #dock{bottom:calc(12px + var(--sab))}
}
@media (max-width:860px){
  #cap{left:calc(16px + var(--sal));right:calc(16px + var(--sar));width:auto;
    bottom:calc(88px + var(--sab));padding:16px 17px 14px;max-height:42vh;overflow-y:auto}
  #cap h2{font-size:var(--fs-2xl)}
  #cap p{font-size:var(--fs-base)}
  #hint{display:none}
  #chat{bottom:calc(140px + var(--sab));max-height:min(560px,calc(var(--appvh) - 190px))}
  #brand img{height:16px}
  #brand .btag{display:none}
  #brand .bsep{display:none}
}
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001ms!important;transition-duration:.01ms!important}
}

/* ------------------------------------------------------------------ intro */
/* Under the wordmark: what this is, in the paper's own words, with the DOI. */
#intro{position:fixed;z-index:29;top:calc(76px + var(--sat));left:calc(24px + var(--sal));
  width:min(322px,calc(100vw - 48px));padding:0;border-radius:var(--r-card);overflow:hidden;
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border:1px solid var(--line);box-shadow:0 16px 44px rgba(0,0,0,.46);
  opacity:0;transform:translateY(-6px);
  transition:opacity .7s ease .3s,transform .7s ease .3s,visibility .4s}
body.ready #intro{opacity:1;transform:none}
body.detail-open #intro{opacity:0;visibility:hidden;pointer-events:none;transition-delay:0s}
.in-cite{display:block;padding:9px 17px 14px;background:rgba(0,190,90,.045);
  font-size:var(--fs-tiny);letter-spacing:var(--ls-wide);line-height:var(--lh-loose);color:var(--muted);
  text-decoration:none;transition:color .18s}
.in-cite:hover{color:var(--accent)}
.in-cite i{font-style:italic}

/* ----------------------------------------------------------------- finder */
#find{position:absolute;left:0;right:0;bottom:calc(100% + 10px);
  padding:7px;border-radius:var(--r-card);
  background:linear-gradient(180deg,rgba(8,16,9,.97),rgba(5,11,6,.99));
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  border:1px solid var(--line);box-shadow:0 22px 56px rgba(0,0,0,.6);
  opacity:0;visibility:hidden;transform:translateY(6px);
  transition:opacity .18s ease,transform .18s ease,visibility .18s}
#find.on{opacity:1;visibility:visible;transform:none}

.sv-q{font-size:var(--fs-base);line-height:var(--lh-airy);;margin-bottom:16px}
.sv-q b{color:var(--text);font-weight:var(--fw-med)}

@media (max-width:860px){
  #data{top:auto;bottom:0;transform:translateY(24px);
    height:calc(var(--appvh) - 96px);border-radius:var(--r-card) 16px 0 0}
  #data.open{transform:none!important}
  #databody{padding:22px 18px 40px}
}

#data{background:linear-gradient(180deg,#0a1410 0%,#070f0b 46%,#050b07 100%)}
#data.open{box-shadow:0 0 0 100vmax rgba(2,6,4,.94),0 40px 120px rgba(0,0,0,.7)}
#data{left:50%;top:calc(20px + var(--sat));
  width:min(1420px,calc(100vw - 40px));height:calc(var(--appvh) - 104px - var(--sab))}

.sheet-top{align-items:flex-start;padding:20px 26px 16px}
.dsh-k{font-size:var(--fs-micro);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps-x);text-transform:uppercase;
  color:var(--accent);display:block;margin-bottom:7px}
.dsh h2{font-family:var(--serif);font-size:var(--fs-3xl);font-weight:var(--fw-normal);letter-spacing:var(--ls-tight);
  color:var(--text);line-height:var(--lh-flat)}

/* contents rail — the index answers "what is here" and "where am I" at once,
   which a row of five tabs never did */
.data-cols{display:grid;grid-template-columns:216px minmax(0,1fr);flex:1;min-height:0}
#datanav{border-right:1px solid var(--sf-line);padding:20px 12px 24px;
  overflow-y:auto;display:flex;flex-direction:column;gap:2px}
.sv-q{color:var(--ink-soft)}
#intro{background:linear-gradient(180deg,rgba(9,18,11,.84),rgba(6,13,8,.9))}
#dock{background:rgba(9,18,11,.76)}

/* intro, rewritten */
.in-lede{font-size:var(--fs-md);line-height:var(--lh-airy);color:var(--ink-soft);padding:14px 18px 0}
.in-lede + .in-lede{padding-top:9px}
.in-lede b{color:#fff;font-weight:var(--fw-bold);font-variant-numeric:tabular-nums}
.in-key{display:flex;flex-wrap:wrap;align-items:center;gap:7px 14px;
  padding:13px 18px 15px;margin-top:12px;font-size:var(--fs-xs);color:var(--muted);
  border-top:1px solid var(--sf-line)}
.in-key i{width:15px;height:0;display:inline-block;flex:none}
.in-cite{padding-bottom:15px}

/* globe / map toggle */
#viewBtn.on{background:rgba(0,190,90,.18);color:var(--accent)}

@media (max-width:1080px){
  .data-cols{grid-template-columns:1fr}
  #datanav{flex-direction:row;overflow-x:auto;border-right:0;
    border-bottom:1px solid var(--sf-line);padding:10px 12px;gap:4px}
}
@media (max-width:860px){
  #data{width:auto;left:0;right:0}
  .dsh h2{font-size:var(--fs-xl)}
}

body.flat #intro{transition:opacity .5s ease,visibility .5s}

/* ==========================================================================
   v9 — the right column rebuilt
   Five identically-weighted blocks of small text read as one endless list.
   Give it a control, a figure grid, a key and two composition bars; nine
   separate magnitude bars become two stacked ones that show share at a glance.
   ========================================================================== */
#summary{overflow:hidden;padding:0;
  top:calc(80px + var(--sat));
  display:flex;flex-direction:column;
  background:linear-gradient(180deg,rgba(11,21,14,.9),rgba(7,14,9,.94))}
.sm-sec{padding:13px 16px 14px;border-bottom:1px solid var(--sf-line)}
.sm-sec:last-child{border-bottom:0}
.sm-sec h3{font-size:var(--fs-micro);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps-x);text-transform:uppercase;
  color:var(--accent);margin-bottom:11px}

/* figure grid — four numbers, not nine label:value rows */
.sm-fig{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--sf-line);
  border:1px solid var(--sf-line);border-radius:var(--r-ctl);overflow:hidden}
.sm-fig div{background:#0b1510}
.sm-fig b{display:block;font-weight:var(--fw-display);letter-spacing:var(--ls-display);line-height:var(--lh-flat);
  color:var(--text);font-variant-numeric:tabular-nums}
.sm-fig span{display:block;font-size:var(--fs-tiny);color:var(--ink-dim);line-height:var(--lh-snug)}
.sm-fig em{display:block;font-style:normal;;line-height:var(--lh-snug)}

/* composition bars */
.sm-stack{display:flex;height:13px;border-radius:var(--r-hair);overflow:hidden;gap:1.5px;
  background:var(--sf-tint)}
.sm-stack i{display:block;height:100%;min-width:2px}
.sm-leg{display:flex;flex-wrap:wrap;gap:5px 12px;margin-top:10px}
.sm-leg span{display:inline-flex;align-items:baseline;gap:6px;font-size:var(--fs-xs);
  color:var(--ink-dim);line-height:var(--lh-snug)}
.sm-leg i{width:8px;height:8px;border-radius:var(--r-hair);flex:none;transform:translateY(1px)}
.sm-leg b{color:var(--text);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums}
.sm-leg em{font-style:normal;font-variant-numeric:tabular-nums}

/* ==========================================================================
   v10 — nominal breakdowns become bars; the panel widens
   Realm and country are not ordered, so a stacked bar was making colour carry
   an identity it cannot carry: the validator put adjacent greens 7.9 dE apart
   in normal vision, under the 15 floor. Bars on a shared baseline need no
   colour encoding at all, and let you compare lengths directly. Only predicted
   pressure — which really is an ordered scale — keeps the stacked form.
   ========================================================================== */
#summary{width:352px}

.sm-sec h3{display:flex;align-items:baseline;justify-content:space-between;gap:8px}
.sm-sec h3 em{font-style:normal;font-weight:var(--fw-med);letter-spacing:var(--ls-wide);text-transform:none;
  font-size:var(--fs-tiny);color:var(--ink-faint);font-variant-numeric:tabular-nums}

/* "How each one is counted": one row per landscape, the paper's own opening clause
   in full. A dt/dd pair rather than a bar, because the seven methods are seven of
   seven and a bar of equal length next to six others says nothing. The clause
   WRAPS — it is the paper's words and must never be cut to fit a column. */
.sm-meth{margin:0;display:flex;flex-direction:column;gap:7px}
.sm-meth > div{display:grid;grid-template-columns:86px minmax(0,1fr);gap:2px 10px;align-items:baseline}
.sm-meth dt{font-size:var(--fs-xs);font-weight:var(--fw-med);color:var(--ink-near);
  line-height:var(--lh-snug);border-left:2px solid var(--c,var(--accent));padding-left:7px}
.sm-meth dd{margin:0;font-size:var(--fs-xs);color:var(--ink-soft);line-height:var(--lh-snug)}
@media (max-width:760px){
  .sm-meth > div{grid-template-columns:minmax(0,1fr)}
  .sm-meth dd{padding-left:9px}
}

.sm-bars{display:flex;flex-direction:column;gap:5px}
.sm-bar{display:grid;grid-template-columns:82px 1fr 30px 26px;align-items:center;gap:8px}
/* ⛔ NO ELLIPSIS HERE. These keys are Red List categories, landscape names and
   unit names — claims, not decoration. At 82px "Critically Endangered" was cut to
   "Critically Endan…" at EVERY width, 1180 included, and a title attribute does not
   reach a touch reader. They wrap instead; the row grows by one line and says the
   whole thing. */
.sm-bar-k{font-size:var(--fs-xs);color:var(--ink-soft);line-height:var(--lh-snug);
  overflow-wrap:anywhere;hyphens:none}
.sm-bar-t{display:block;height:7px;border-radius:var(--r-hair);background:var(--sf-tint)}
.sm-bar-t i{display:block;height:100%;min-width:2px;border-radius:var(--r-hair);
  background:linear-gradient(90deg,#12A25E,#4FE09A)}
.sm-bar b{font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--text);text-align:right;
  font-variant-numeric:tabular-nums}
.sm-bar em{font-style:normal;text-align:right;font-variant-numeric:tabular-nums}

/* On the flat map the description steps aside entirely and the plate takes the
   whole column left of the summary panel. The card is a globe aid — it explains
   an object you are turning; the world map explains itself. */
body.flat #intro{opacity:0;visibility:hidden;pointer-events:none}

@media (max-height:780px){
  .sm-sec{padding:10px 16px 11px}
  .sm-fig div{padding:8px 10px}
  .sm-fig b{font-size:var(--fs-xl)}
  #intro .in-lede{font-size:var(--fs-base)}
}

/* ==========================================================================
   v11 — the panel has to fit without scrolling
   Six sections of real content in an 800px column at 1600x900, and seven realm
   bars in importance mode rather than five. Everything below is density, not
   redesign: the type sizes and the information are unchanged.
   ========================================================================== */
@media (max-height:1000px){
  .sm-sec{padding:9px 15px 10px}
  .sm-sec h3{margin-bottom:8px}
  .sm-fig div{padding:8px 10px}
  .sm-fig b{font-size:var(--fs-xl)}
  .sm-fig span{margin-top:4px}
  .sm-fig em{margin-top:2px}
  .sm-bars{gap:4px}
  .sm-leg{margin-top:8px;gap:4px 12px}
}
@media (max-height:840px){
  .sm-sec{padding:7px 15px 8px}
  .sm-sec h3{margin-bottom:6px}
  .sm-fig b{font-size:var(--fs-xl)}
  .sm-bars{gap:3px}
  .sm-bar-t{height:6px}
}
@media (max-height:845px){
  .sm-sec{padding:6px 14px 7px}
  .sm-sec h3{margin-bottom:5px}
  .sm-fig b{font-size:var(--fs-lg)}
  .sm-fig div{padding:6px 9px}
  .sm-bars{gap:2px}
  .sm-bar-t{height:5px}
  .sm-leg{margin-top:6px;gap:3px 10px}
}

/* ==========================================================================
   v12 — one ranking, and a panel that earns its column
   The pressure-weighted / importance-only toggle is gone: it made every figure
   on the page conditional and asked for a methodological distinction before the
   reader had seen a number. The column it freed goes to habitat type, the
   concentration reading and what the land actually costs.
   ========================================================================== */
#summary{overflow-y:auto;overscroll-behavior:contain}
#summary::-webkit-scrollbar{width:7px}
#summary::-webkit-scrollbar-track{background:transparent}
#summary::-webkit-scrollbar-thumb{background:var(--sf-edge);border-radius:var(--r-hair)}
#summary::-webkit-scrollbar-thumb:hover{background:var(--sf-edge)}
#summary{scrollbar-width:thin;scrollbar-color:var(--sf-edge) transparent}

.vh{position:absolute!important;width:1px;height:1px;margin:-1px;padding:0;border:0;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}

:where(a,button,input,[tabindex]):focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-hair)}
#chatq:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

/* ---- phone ---------------------------------------------------------------
   Three things made this close to unusable below 760px: the ask field, which is
   the only route to a region without a pointer, collapsed to a 34px stub; the
   summary panel covered two thirds of the screen so almost nothing hit-tested
   to the globe; and the description card — which carries the map key, the one
   thing that says what the green outlines mean — was display:none.
   ------------------------------------------------------------------------- */
@media (max-width:760px){
  /* the dock wraps so the field gets a row of its own */
  #dock{flex-wrap:wrap;gap:7px;left:calc(9px + var(--sal));right:calc(9px + var(--sar));
    width:auto;max-width:none;transform:none;padding:8px 9px;border-radius:var(--r-card)}
  /* flex:1 on #chatform sets flex-basis:0, so width:100% alone did not give it a
     row of its own and the field collapsed to a 28px stub. */
  #chatform{order:-1;flex:1 1 100%;width:100%;display:flex;gap:7px}
  #chatq{flex:1 1 auto;min-width:0;width:auto;font-size:var(--fs-xl);padding:11px 13px}
  /* one row of controls under the field: tighter buttons and no separators, so "Method" does not
     wrap onto a third row at 390 px */
  #dock .dm-btn,#dock #viewBtn,#dock #methodBtn{font-size:var(--fs-sm);padding:8px 8px}
  #dock .dock-sep{display:none}
  #dock #spinBtn{margin-left:auto}
  #find{bottom:calc(100% + 8px)}

  /* the description card comes back, compact: lede + map key + citation */
  #intro{display:block;position:fixed;top:calc(96px + var(--sat));
    left:calc(10px + var(--sal));right:calc(10px + var(--sar));width:auto;overflow-y:auto;overscroll-behavior:contain;z-index:22}
  #intro .in-lede{font-size:var(--fs-base)}          /* the citation link below it stays */
  body.flat #intro{display:none}  /* the flat map needs the whole screen */

  /* the summary becomes a bottom sheet, so the globe keeps the middle */
  #summary{top:auto;bottom:calc(104px + var(--sab));
    left:calc(10px + var(--sal));right:calc(10px + var(--sar));width:auto;overflow-y:auto}
  /* seven sections in a 300px sheet is all scrollbar; keep the four that answer
     "what am I looking at", "where", "how bad" and drop the rest to the Data view */
  .sm-bar{grid-template-columns:88px 1fr 34px 30px}
}

/* Very short or very small: the panel yields further rather than clipping. */
@media (max-height:480px){
  #intro{display:none}
  #summary{max-height:44vh}
}

/* Three headline figures overflow a 390px masthead and cut mid-word. Two fit.
   ⚠ The dropped one is the stated index span, and it is NOT a restatement of
   anything else in the masthead — so buildIntro() states the span in the scope
   sentence, which is in the card and survives every width. Check that prose before
   dropping another figure here. */
@media (max-width:430px){
  #gstats div:nth-child(n+3){display:none}
  #gstats b{font-size:var(--fs-xl)}
}
.sm-leg em,.sm-bar em{font-size:var(--fs-xs);color:var(--ink-muted)}
.sm-fig em{font-size:var(--fs-tiny);color:var(--ink-muted)}

/* The masthead figures are composited straight onto a rotating photograph: over
   ocean they read at about 7:1, over the Sahara they drop under 2:1. A scrim
   costs nothing and makes them legible over every frame. */
#top::before{content:"";position:absolute;inset:0;pointer-events:none;z-index:-1;
  background:linear-gradient(180deg,rgba(4,10,5,.78),rgba(4,10,5,.42) 62%,transparent)}
#top{position:fixed;isolation:isolate}
#gstats span{color:var(--ink-dim)}

/* One meaning per colour. #FF8A3D was simultaneously the "Moderate high"
   pressure class, the chat error, a negative delta and the boot-failure
   message — and in the record panel the delta sat 40px from the pressure
   swatch wearing the identical hue. Status gets its own token, well clear of
   the pressure ramp, and never travels without a word beside it. */
:root{--warn:#FFB03A;--bad:#FF6B6B}

/* Five different right edges down one column — 1475 for tiles and tables, 1131
   for charts, 1101 for bars, 957 for the question line, 856 for notes, 827 for
   the lede — none of them chosen, all of them the residue of separate
   max-widths. Prose genuinely should be narrower than a table; that is one
   decision, not four. Three widths, on purpose:
     data   — tiles and tables, the full content column
     figure — every chart, one width so they stack flush
     prose  — one measure for lede, question and note */
:root{--figure-w:840px;--measure:68ch}
.sv-q{max-width:var(--measure)}
/* the whole-source download, offered where the table it completes sits */
.dl{display:inline-block;margin-top:8px;color:var(--accent);text-decoration:none;
  border-bottom:1px solid rgba(0,190,90,.4);padding-bottom:1px}
.dl:hover{border-bottom-color:var(--accent)}
/* The loading line names what is being drawn rather than the planet it sits on.
   It is longer than "Assembling the Earth" was, and 12px uppercase at .14em
   tracking runs past a 390px screen, so give it a measure and let it wrap. */
#loader span{max-width:min(30ch,calc(100vw - 48px));text-align:center;
  line-height:var(--lh-airy);text-wrap:balance}


/* ==========================================================================
   v15 — the column stops above the dock, and you can work in it
   ========================================================================== */

/* The panel ran to 20px off the viewport floor, which put its last 53px behind
   the dock. Stop above it with a real gap. */
#summary{max-height:calc(var(--appvh) - 172px - var(--sab))}

/* Long lists scroll inside their own block rather than being truncated to
   whatever the viewport happened to allow. All 71 countries and all 12 habitat
   types are here now; the section keeps its size either way. */
.sm-bars{overflow-y:auto;overscroll-behavior:contain;
  padding-right:4px;scrollbar-width:thin;
  scrollbar-color:var(--sf-edge) transparent}
.sm-bars::-webkit-scrollbar{width:6px}
.sm-bars::-webkit-scrollbar-thumb{background:var(--sf-edge);border-radius:var(--r-hair)}   /* five rows; nothing to scroll */

/* A row that flies the globe should look like it does something. */
.sm-bar.act{cursor:pointer;border-radius:var(--r-hair);margin:0 -5px;padding:1px 5px;
  transition:background .12s ease}
.sm-bar.act:hover,.sm-bar.act:focus-visible{background:rgba(0,190,90,.13)}
.sm-bar.act:hover .sm-bar-k,.sm-bar.act:focus-visible .sm-bar-k{color:var(--text)}
.sm-bar.act:hover .sm-bar-t i{filter:brightness(1.18)}
.sm-stack i{cursor:default}
.sm-stack i:hover,.sm-stack i:focus-visible{filter:brightness(1.22)}

/* the section heading's count doubles as the scroll affordance */
.sm-sec h3 em{white-space:nowrap}

@media (max-height:845px){ .sm-bars{} }
/* On a phone the lists are now long enough to fill whatever cap they are given,
   where before they were six rows and the sheet sat well under it. Left at 42vh
   the panel grew upward into the globe — 27% of the screen hit-tested to the
   canvas, then 9%. Size the sheet for content that always fills it. */
@media (max-width:760px){
  #intro{max-height:27vh}
  #summary{max-height:31vh}
  .sm-bars{max-height:96px}
}
@media (max-width:760px) and (max-height:700px){
  #intro{max-height:23vh}
  #summary{max-height:29vh}
  .sm-bars{max-height:84px}
}


/* ==========================================================================
   v16 — density: the column's space belongs to the data
   Measured at 1600x900: 726px of panel showing 1,178px of content, of which the
   two scrollers — the actual data — held 344px and the four-figure grid and the
   map key together held 292px for eight numbers and a legend. Tightening the
   chrome moves roughly 80px into the lists without touching a type size.
   ========================================================================== */
.sm-fig div{padding:7px 10px 8px}
.sm-fig b{font-size:var(--fs-xl)}
.sm-fig span{margin-top:3px}
.sm-fig em{margin-top:1px}

/* what the chrome gave up, the lists take */
.sm-bars{max-height:218px}
@media (max-height:845px){ .sm-bars{max-height:168px} }

/* The column shows 726px of 1,245px, so roughly two screens of scrolling. Pin
   each section's heading while its block is on screen: the count beside it is
   also the scroll affordance ("all 71 · scroll"), and losing that off the top
   is how you end up reading a list of numbers without knowing what they count. */
.sm-sec h3{position:sticky;top:0;z-index:3;margin:-9px -15px 8px;padding:9px 15px 6px;
  background:linear-gradient(180deg,rgba(10,20,13,.97) 72%,rgba(10,20,13,0))}
@media (max-height:1000px){.sm-sec h3{margin:-9px -15px 6px}}
@media (max-height:845px){.sm-sec h3{margin:-7px -15px 5px}}
body.flat #spinBtn,body.flat #spinBtn + .dock-sep{display:none}
@media (max-width:760px){#spinLbl{display:none}#spinBtn{padding:8px 9px}}
/* ⛔ .in-arg was deleted 2026-09-29: 14 rules for a quantity-versus-quality block
   that no source file has produced for some time. A controlled sweep of every
   selector in this file against index.html and all four src/*.js found it
   unreferenced; the sweep's controls (.mlabel, #detail, .dt-body live; a planted
   absent selector dead) passed. 122 other selectors here are unreferenced too —
   see the gap register. */

/* ==========================================================================
   Findings, in the card
   Three headline rows that expand where they sit. They were a modal; a thing
   you dismiss to reach the map is a toll gate, and once dismissed the argument
   was gone. Here it is permanent and costs nothing to skip.
   ========================================================================== */
.in-find{margin-top:12px;border-top:1px solid var(--sf-line);background:rgba(0,190,90,.045)}
.in-find-h{padding:11px 18px 2px;font-size:var(--fs-micro);font-weight:var(--fw-bold);
  letter-spacing:var(--ls-caps-x);text-transform:uppercase;color:var(--accent)}
.fnd{border-top:1px solid var(--sf-line)}
.fnd:first-of-type{border-top:0}
.fnd-h{display:grid;grid-template-columns:1fr 10px;align-items:center;gap:9px;
  width:100%;padding:9px 18px 5px;background:none;border:0;cursor:pointer;text-align:left;
  font-family:var(--sans);transition:color .14s ease}
.fnd-h:hover .fnd-t{color:var(--text)}
.fnd-t{font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--ink-soft);
  line-height:var(--lh-snug);letter-spacing:var(--ls-nudge)}

/* The figures that make the point, visible without asking. Same figure/label
   grid as the summary panel so the two columns read as one system. */
.fnd-f{margin:0;padding:0 18px 10px;display:flex;flex-direction:column;gap:2px}
.fnd-f div{display:grid;grid-template-columns:64px 1fr;gap:9px;align-items:baseline}
.fnd-f dt{font-size:var(--fs-xs);font-weight:var(--fw-display);color:var(--accent);
  text-align:right;letter-spacing:var(--ls-tight);font-variant-numeric:tabular-nums}
.fnd-f dd{margin:0;font-size:var(--fs-tiny);line-height:var(--lh-snug);color:var(--ink-muted)}
.fnd.on .fnd-f dd{color:var(--ink-dim)}
.fnd-x{color:var(--ink-muted);transition:transform .18s ease;flex:none}
.fnd.on .fnd-x{transform:rotate(180deg)}
.fnd.on .fnd-t{color:var(--text)}
.fnd-b{padding:2px 18px 12px;border-top:1px solid var(--sf-line);margin:0 18px 0;
  padding-left:0;padding-right:0}
.fnd-b p{margin:0;font-size:var(--fs-tiny);line-height:var(--lh-loose);color:var(--ink-dim)}
.fnd-b b{color:var(--text);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums}
.fnd-b em{font-style:italic;color:var(--ink-soft)}
.fnd-cap{display:block;margin-top:6px;font-size:var(--fs-micro);color:var(--ink-muted);
  letter-spacing:var(--ls-wide);text-transform:uppercase}

/* The card can now grow when a finding opens, so it gets the same treatment the
   summary panel has: stop above the dock and scroll rather than run under it. */
/* Scoped above the phone breakpoint on purpose. Unscoped, this sat later in the
   file than the phone rules and silently replaced them, and the card grew until
   it overlapped the summary sheet — 27% of a 375px screen reaching the globe
   became 9%. */
@media (min-width:761px){
  #intro{max-height:calc(var(--appvh) - 190px - var(--sab))}
}
#intro{overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;
  scrollbar-color:var(--sf-edge) transparent}
#intro::-webkit-scrollbar{width:7px}
#intro::-webkit-scrollbar-thumb{background:var(--sf-edge);border-radius:var(--r-hair)}
@media (max-width:760px){
  /* No max-height here: the phone values are tuned further up against how much
     of the screen still hit-tests to the globe, and re-stating it taller undid
     that — 27% reachable became 13%. */
  .fnd-h{padding:7px 14px 4px}
  .fnd-t{font-size:var(--fs-tiny)}
  .fnd-f{padding:0 14px 8px}
  .fnd-f div{grid-template-columns:52px 1fr;gap:7px}
  .fnd-b{margin:0 14px}
  .in-find-h{padding:9px 14px 2px}
  .fnd-b{padding:0 14px 10px}
}

/* ═══════════════════════════════════════════════════════════════════════ PSI
   Everything above is conservation-imperatives', unchanged. Everything below is
   the PSI-only vocabulary, written in the same idiom and on the same tokens — no
   raw font sizes, no new colour system, no second set of spacing rules.

   ⛔ COLOUR CARRIES A CLAIM HERE. Increase is the brand green; decrease is a warm
   amber and deliberately NOT red, because the one landscape below baseline has no
   statistically significant trend and red would assert something the paper does not. */

:root { --psi-up:#00be5a; --psi-down:#d98032; --psi-none:#8a9a86; }

/* the summary rail's landscape rows */
#smList{display:flex;flex-direction:column;gap:2px}
.lsrow{display:grid;grid-template-columns:1fr auto;grid-template-areas:"n v" "c v" "b b";
  gap:0 8px;width:100%;text-align:left;background:none;border:0;border-left:2px solid var(--c);
  padding:5px 6px 6px 8px;cursor:pointer;color:inherit;font:inherit;transition:background .14s ease}
.lsrow:hover{background:rgba(255,255,255,.05)}
.lsr-n{grid-area:n;font-size:var(--fs-sm)}
.lsr-c{grid-area:c;font-size:var(--fs-tiny);opacity:.6}
.lsr-v{grid-area:v;align-self:center;font-size:var(--fs-lg);color:var(--c);font-variant-numeric:tabular-nums}


/* a withheld note — the most important recurring element on this page */
.wh{border-left:2px solid var(--psi-down);padding:1px 0 1px 9px;margin:7px 0;
  font-size:var(--fs-sm);opacity:.85}
.wh b{display:block;opacity:1;margin-bottom:1px}
.cap{font-size:var(--fs-tiny);opacity:.55;margin:4px 0 0;max-width:62ch}

/* the detail record */
.dt-big{font-size:var(--fs-figure);line-height:1;margin:2px 0 10px;font-variant-numeric:tabular-nums}
.dt-big em{display:block;font-style:normal;font-size:var(--fs-tiny);opacity:.6;margin-top:5px;
  color:var(--ink,inherit)}
.trend{width:100%;height:auto;display:block;margin:2px 0 6px}
.tr-grid{stroke:rgba(255,255,255,.07)}
.tr-base{stroke:rgba(255,255,255,.3);stroke-dasharray:3 4}
.tr-ax{fill:currentColor;opacity:.45;font-size:9px}

/* tables — one style for every table on the page, scrolling in its own box */
.tw{overflow-x:auto;margin:4px 0 2px}
table.sp{width:100%;border-collapse:collapse;font-size:var(--fs-sm)}
table.sp th,table.sp td{text-align:left;padding:4px 8px 4px 0;border-bottom:1px solid rgba(255,255,255,.07);
  white-space:nowrap}
table.sp th{font-size:var(--fs-tiny);text-transform:uppercase;letter-spacing:.08em;opacity:.5;font-weight:400}
table.sp td.c,table.sp th.c{text-align:center;font-variant-numeric:tabular-nums}
table.sp tr.out td{opacity:.45}
table.sp i{opacity:.65}
table.sp code{font-size:var(--fs-tiny);opacity:.7}
table.sp button{background:none;border:0;padding:0;color:inherit;font:inherit;cursor:pointer;
  text-decoration:underline;text-decoration-color:rgba(255,255,255,.25);text-underline-offset:3px}
table.sp button:hover{text-decoration-color:var(--psi-up)}

.kv{display:grid;grid-template-columns:auto 1fr;gap:2px 14px;font-size:var(--fs-sm);margin:4px 0}
.kv dt{opacity:.55}
.kv dd{margin:0}

/* a Red List badge. CR and EN take the warm accent; nothing here is red. */
.rl{font-size:var(--fs-micro);letter-spacing:.04em;border:1px solid rgba(255,255,255,.22);
  border-radius:2px;padding:0 4px;white-space:nowrap}
.rl[data-c="CR"],.rl[data-c="EN"]{color:var(--psi-down);border-color:var(--psi-down)}

.golink{display:inline-block;margin-top:14px;background:var(--psi-up);color:#07090a;
  padding:7px 14px;border-radius:3px;text-decoration:none;font-size:var(--fs-sm);font-weight:600}
.golink.off{background:none;color:inherit;opacity:.5;border:1px solid rgba(255,255,255,.2)}

.pform{font-family:ui-monospace,'JetBrains Mono',SFMono-Regular,Menlo,monospace;
  font-size:var(--fs-sm);color:var(--psi-up);background:rgba(255,255,255,.04);
  border:1px solid rgba(255,255,255,.08);padding:9px 11px;margin:8px 0;line-height:1.9}

/* the assistant's transcript */
.cq{font-size:var(--fs-sm);opacity:.6;margin:10px 0 3px}
.cq::before{content:"› "}
.ca{font-size:var(--fs-sm);border-left:2px solid var(--psi-up);padding-left:9px;margin:0 0 4px;
  white-space:pre-wrap}

/* ⛔ THREE COLLISIONS WITH THE ADOPTED SHEET, all found by LOOKING at the render.
   · #hint is display:none in the imperatives sheet and was resurfacing unpositioned at the top-left,
     on top of the masthead. It belongs above the dock, where its own copy tells you what to do next.
   · #scale (the direction key) is GONE, 2026-09-28: four inherited rules fought over it and the
     9px-high one clipped the key under the next heading (seen in a screenshot). Colour is identity
     now, one hue per landscape, and direction is the ▲/▼ on each row — a key had nothing to say.
   · .sm-fig is a two-column grid and three figures leave a visible hole in the fourth cell. */
#hint{display:block;position:fixed;left:50%;transform:translateX(-50%);
  bottom:calc(84px + var(--sab,0px));z-index:40;font-size:var(--fs-tiny);opacity:.42;
  pointer-events:none;white-space:nowrap}
body:not(.ready) #hint{display:none}
@media (max-width:900px){#hint{display:none}}


/* the "show me" affordance inside a finding — it is what makes the abstract interactive */
.fnd-go{display:inline-block;margin:6px 0 2px;background:none;border:1px solid rgba(255,255,255,.22);
  border-radius:99px;padding:3px 10px;color:var(--alive);font:inherit;font-size:var(--fs-tiny);cursor:pointer}
.fnd-go:hover{border-color:var(--alive);background:rgba(0,255,100,.08)}

/* the measurement type, above the figure it qualifies */
/* ⭐ 2026-09-28: it was a five-line paragraph SET IN CAPS in brand green, above the figure, and it
   read as a headline shouting the method (G234). The kicker carries the caps; the sentence is set
   as a sentence, muted, so the figure below it is still the loudest thing on the record. */
.dt-meas{font-size:var(--fs-sm);color:var(--muted);line-height:var(--lh-body);margin:0 0 8px;max-width:52ch}
.dt-meas-k{display:block;font-size:var(--fs-tiny);text-transform:uppercase;letter-spacing:.08em;
  color:var(--alive);margin-bottom:2px}
.dt-meas.none{color:var(--psi-down)}
.dt-meas.none .dt-meas-k{color:var(--psi-down)}
/* the direction line replaced a bar that put seven incomparable indices on one axis */
.lsr-d{grid-area:b;font-size:var(--fs-micro);opacity:.5;margin-top:2px}

/* leave-one-out, as deviation bars against the landscape's own recomputed baseline */
.loo{display:grid;grid-template-columns:1fr 84px auto;gap:0 8px;align-items:center;padding:2px 0;font-size:var(--fs-sm)}
.loo-n{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.loo-t{height:5px;background:rgba(255,255,255,.08);border-radius:3px;overflow:hidden}
.loo-t i{display:block;height:100%}
.loo b{font-variant-numeric:tabular-nums;font-size:var(--fs-tiny);opacity:.8}

/* ⛔ THE DETAIL RECORD IS READING MATTER, NOT RAIL FURNITURE. It inherited --fs-sm (11.5px) from
   the imperatives rail tokens, which are sized for a dense column of counts you scan — not for a
   1,500-character landscape description and a nine-column species table you actually read. The rail
   keeps its own scale; only the record moves up. */
#detail .dt-body{font-size:var(--fs-md)}
#detail .dt-body p{font-size:var(--fs-md);line-height:1.62;max-width:56ch}
#detail table.sp{font-size:var(--fs-base)}
#detail table.sp th{font-size:var(--fs-xs)}
#detail .cap{font-size:var(--fs-xs);line-height:1.5}
#detail .wh{font-size:var(--fs-base)}
#detail .kv{font-size:var(--fs-base)}
#detail h4{font-size:var(--fs-sm);letter-spacing:.09em}
#detail .loo{font-size:var(--fs-base)}
#detail .dt-meas{font-size:var(--fs-xs)}

/* the method panel and data sheet are reading matter too */
.pbody p,.pbody .pstep div{font-size:var(--fs-md);line-height:1.6}
#databody p{font-size:var(--fs-md);line-height:1.6;max-width:70ch}
#databody table.sp{font-size:var(--fs-base)}
/* whose figure this is — stated by the paper, or recomputed here. Never left to inference. */
.dt-src{font-size:var(--fs-xs);opacity:.6;margin:4px 0 0}
.dt-src.calc{color:var(--psi-down);opacity:.85}
/* a label near the right-hand rail draws leftward so its name is never cut by opaque furniture */
/* ⛔ `margin-left:-100%` resolves against the CONTAINING BLOCK, not the element, so a flipped label
   jumped a screen-width rather than its own width. `translateX(-100%)` composes with the inline
   transform the projection writes, which is what actually needs to happen. */
.mlabel{transform:translate(0,0)}

/* ── the globe's labels ───────────────────────────────────────────────────────
   The imperatives sheet gives these their serif italic and their fade. What it
   does not give them is a ground: over a Blue Marble texture a light serif sits
   on sand, ice and ocean in the same sentence, and it disappears over two of the
   three. A plate, a hairline leader and a tabular badge fix that without making
   them shout — and the badge is the only element on the globe carrying colour,
   so the reader learns the colour means direction before reading the key. */
.mlabel{
  display:flex;align-items:center;gap:7px;padding:3px 9px 3px 8px;
  background:rgba(4,10,4,.62);border:1px solid rgba(159,216,255,.16);
  border-radius:99px;backdrop-filter:blur(7px);
  transform-origin:left center;pointer-events:none;
  box-shadow:0 1px 14px rgba(0,0,0,.45)
}
.mlabel .ml-n{font-size:var(--fs-sm);letter-spacing:.005em}
.mlabel .ml-v{
  font-size:var(--fs-tiny);font-variant-numeric:tabular-nums;
  border:1px solid currentColor;border-radius:99px;padding:0 5px;opacity:.9
}
.mlabel.hot{border-color:rgba(0,255,100,.55);background:rgba(4,10,4,.82)}
.mlabel.hot .ml-n{color:#fff}
@media (prefers-reduced-motion:no-preference){
  .mlabel{transition:opacity .28s ease,border-color .2s ease,background .2s ease}
}

/* ═══════════════════════════════════════════════════════════════ the site view
   Level 0 on both rails, Levels 1–4 in the left rail (src/site.js; spec in
   docs/PSI-INTERACTION-SPEC.md). The right rail reuses #summary's shell exactly,
   so the two rails a reader sees are the same object in two states. */
#place{position:fixed;right:calc(20px + var(--sar));top:calc(80px + var(--sat));
  z-index:24;width:352px;max-height:calc(var(--appvh) - 172px - var(--sab));
  overflow-y:auto;overscroll-behavior:contain;padding:0;
  display:flex;flex-direction:column;
  border-radius:var(--r-card);
  background:linear-gradient(180deg,rgba(11,21,14,.9),rgba(7,14,9,.94));
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border:1px solid var(--line);box-shadow:0 18px 50px rgba(0,0,0,.5);
  opacity:0;transform:translateX(14px);pointer-events:none;
  transition:opacity .32s ease,transform .42s cubic-bezier(.22,.92,.2,1)}
body.detail-open #place:not([hidden]){opacity:1;transform:none;pointer-events:auto}
body.detail-open #summary{opacity:0;visibility:hidden;pointer-events:none;transition-delay:0s}
#place .sm-sec h3{color:var(--accent)}
#place .sm-bars{display:block}
#place .sm-fig b small{font-size:var(--fs-xs);font-weight:var(--fw-normal);opacity:.6;letter-spacing:0}
.sv-q{font-size:var(--fs-xs);color:var(--ink-dim);line-height:var(--lh-body);margin:-6px 0 10px}
#detail .sv-q{font-size:var(--fs-sm)}

/* the breadcrumb of a deeper level */
.crumb{background:none;border:0;padding:0;margin:0 10px 0 0;color:var(--ink-dim);font:inherit;font-size:var(--fs-tiny);
  letter-spacing:var(--ls-caps);text-transform:uppercase;cursor:pointer}
.crumb:hover,.crumb:focus-visible{color:var(--alive);outline:none}
.crumb-k{color:inherit}
.tr-pt{cursor:pointer}
.tr-pt:hover,.tr-pt:focus{r:5;outline:none;filter:brightness(1.3)}
.tr-hint{margin-top:-2px}

/* small multiples — the sparkline is the button */
.spk-list{display:block}
.spk{display:grid;grid-template-columns:minmax(0,1.15fr) 118px auto auto;gap:4px 10px;align-items:center;
  width:100%;padding:7px 4px;margin:0;background:none;border:0;border-bottom:1px solid var(--sf-line);
  color:inherit;font:inherit;text-align:left;cursor:pointer;border-radius:var(--r-hair)}
.spk:hover,.spk:focus-visible{background:rgba(0,190,90,.13);outline:none}
.spk.static{cursor:default}.spk.static:hover{background:none}
.spk-n{font-size:var(--fs-base);line-height:var(--lh-snug);overflow:hidden}
/* the binomial wraps rather than truncating — at 390px seven of them were cut,
   "Ailuropoda melanoleuca" among them, and half a scientific name names nothing */
.spk-n i{display:block;font-size:var(--fs-xs);opacity:.6;line-height:var(--lh-snug);overflow-wrap:anywhere}
.spk-g{display:block;height:34px}
.spk-svg{width:100%;height:100%;display:block}
.spk-base{stroke:rgba(255,255,255,.28);stroke-dasharray:2 3}
.spk-none{font-size:var(--fs-micro);opacity:.45}
.spk-v{font-variant-numeric:tabular-nums;font-size:var(--fs-sm);text-align:right;min-width:44px}
.spk-rl{justify-self:end}
.spk-u{grid-column:1 / -1;font-style:normal;font-size:var(--fs-micro);opacity:.5}
.spk-all{grid-column:1 / -1;display:flex;flex-wrap:wrap;gap:2px 10px;font-size:var(--fs-micro);font-variant-numeric:tabular-nums;opacity:.7}
.spk-all b{font-weight:400;opacity:.6;margin-right:3px}.spk-all em{font-style:normal}
.spk-out{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.spk-o{display:inline-flex;align-items:center;gap:7px;background:none;border:1px solid var(--sf-line);border-radius:var(--r-pill);
  padding:4px 10px;color:inherit;font:inherit;font-size:var(--fs-xs);opacity:.62;cursor:pointer}
.spk-o em{font-style:normal;opacity:.6}
.spk-o:hover,.spk-o:focus-visible{opacity:1;border-color:var(--accent);outline:none}
#detail .loo{width:100%;background:none;border:0;color:inherit;font:inherit;text-align:left;cursor:pointer;
  border-radius:var(--r-hair);padding:3px 4px}
#detail .loo:hover,#detail .loo:focus-visible{background:rgba(0,190,90,.13);outline:none}
#detail .loo.static{cursor:default}
.loo-n em{font-style:normal;opacity:.55;font-size:var(--fs-xs)}
.dt-more{margin-top:18px;border-top:1px solid var(--sf-line);padding-top:10px}
.dt-more summary{cursor:pointer;font-size:var(--fs-sm);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--muted)}
.dt-more[open] summary{color:var(--alive)}
.dt-grid.crit dd{font-size:var(--fs-base)}
.pl-loo{font-size:var(--fs-md);line-height:var(--lh-body)}
.pl-loo b{font-variant-numeric:tabular-nums}
.pl-int{font-size:var(--fs-md);line-height:var(--lh-body)}
.pl-link{display:grid;grid-template-columns:1fr auto;gap:10px;align-items:baseline;width:100%;text-align:left;
  background:none;border:0;border-bottom:1px solid var(--sf-line);padding:8px 4px;color:inherit;font:inherit;
  font-size:var(--fs-base);cursor:pointer;border-radius:var(--r-hair)}
.pl-link em{font-style:normal;font-size:var(--fs-xs);opacity:.6;white-space:nowrap}
.pl-link:hover,.pl-link:focus-visible{background:rgba(0,190,90,.13);outline:none}

/* the place rail's own rows */
.pl-row{display:grid;grid-template-columns:minmax(0,1fr) auto auto auto;gap:8px;align-items:baseline;padding:5px 0;
  border-bottom:1px solid var(--sf-line);font-size:var(--fs-sm)}
.pl-n{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pl-row code{font-size:var(--fs-micro);opacity:.55}
.pl-row b{font-variant-numeric:tabular-nums}
#place .sm-bar{width:100%;background:none;border:0;color:inherit;font:inherit;text-align:left}
.pl-pair{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.pl-pair span{display:block;font-size:var(--fs-xs);opacity:.75;margin-top:3px}
.pl-pair b{font-variant-numeric:tabular-nums}
.pl-pair .spk-all{display:flex;margin-top:4px}.pl-pair .spk-all span{display:inline;margin:0;font-size:var(--fs-micro)}
.pl-stand{margin-bottom:8px}
.pl-stand b{display:block;font-size:var(--fs-sm);line-height:var(--lh-snug)}
.pl-stand span{display:block;font-size:var(--fs-xs);opacity:.6;margin-top:4px}
.pl-more summary{font-size:var(--fs-xs);color:var(--ink-dim);cursor:pointer;line-height:var(--lh-body)}
.pl-more[open] summary{color:var(--alive)}
.pl-more p{font-size:var(--fs-xs);line-height:var(--lh-body);opacity:.85;margin:8px 0 0}

/* the timeline — index span as a bar, interventions as markers on it */
.tl{position:relative;height:46px;margin:6px 6px 8px}
.tl::before{content:"";position:absolute;left:0;right:0;top:22px;height:1px;background:var(--sf-edge)}
.tl-span{position:absolute;top:20px;height:5px;border-radius:3px;background:var(--accent);opacity:.55}
.tl-m{position:absolute;top:8px;transform:translateX(-50%);background:none;border:0;padding:0;cursor:pointer;color:inherit;font:inherit}
.tl-m b{display:block;width:10px;height:10px;border-radius:50%;background:var(--gold);border:2px solid #0b1510;
  text-indent:-999px;overflow:hidden;box-shadow:0 0 0 1px var(--gold)}
.tl-m:hover b,.tl-m:focus-visible b{background:#fff;outline:none}
.tl-a,.tl-b{position:absolute;top:30px;font-size:var(--fs-micro);opacity:.5}
.tl-a{left:0}.tl-b{right:0}
.tl-row{display:grid;grid-template-columns:34px 1fr;gap:8px;width:100%;text-align:left;background:none;border:0;
  border-top:1px solid var(--sf-line);padding:6px 2px;color:inherit;font:inherit;font-size:var(--fs-xs);cursor:pointer;line-height:var(--lh-body)}
.tl-row b{color:var(--gold);font-variant-numeric:tabular-nums}
.tl-row:hover,.tl-row:focus-visible{background:rgba(0,190,90,.13);outline:none}
.tl-bands{margin-top:8px}
.sm-stack i span{display:none}

/* narrow: the place folds under the index */
.dt-place{margin-top:22px;border-top:1px solid var(--sf-edge);padding-top:8px}
.dt-place-h{font-size:var(--fs-tiny);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--accent);margin:8px 0 2px}
.dt-place .sm-sec{padding:12px 0 14px}
@media (max-width:1080px){#place{display:none}}
.pl-years{display:flex;flex-wrap:wrap;gap:6px}
.pl-year{background:none;border:1px solid var(--sf-line);border-radius:var(--r-ctl);padding:5px 9px;color:inherit;font:inherit;cursor:pointer;text-align:left;min-width:56px}
.pl-year b{display:block;font-size:var(--fs-sm);font-variant-numeric:tabular-nums}
.pl-year em{display:block;font-style:normal;font-size:var(--fs-micro);opacity:.6;font-variant-numeric:tabular-nums}
.pl-year .pl-est{display:block;font-style:normal;font-size:var(--fs-micro);opacity:.75;font-variant-numeric:tabular-nums}
.pl-year .pl-est small{display:block;font-size:inherit;opacity:.7}
.pl-year:hover,.pl-year:focus-visible{border-color:var(--accent);background:rgba(0,190,90,.13);outline:none}
.golink.vista{margin-top:4px}
.sm-bar.cur .sm-bar-k,.tl-row.cur,.tl-m.cur{color:var(--accent)}
.sm-bar.cur{background:rgba(0,190,90,.10)}

/* ── the globe's second state and its seated labels ──────────────────────────
   A label is seated right, left, above or below its anchor — whichever is clear of
   the other labels and of the rails — on one of two rings. ⛔ 2026-09-28: the CSS
   tails that used to stand in for a leader are GONE. They were nine fixed pixels of
   pale blue on one edge of the pill, so on a second-ring seat they pointed at empty
   space, and on any seat they were the wrong colour now that a landscape owns a hue.
   The leader is an SVG line from the anchor dot to the pill (world.js placeLabels),
   which is the only one of the two that knows where the anchor actually is.
   `.dim` is the other six while one landscape is picked. */
.mlabel{transform-origin:left center}
/* ⛔ `.mlabel.dim` alone out-specifies `.mlabel{opacity:0}`, so a dimmed label that had been
   seated off stayed on screen at 42% — the six ghosts. Dim applies only to a seated label. */
.mlabel.on.dim{opacity:.42}
.mlabel.on.dim.hot{opacity:1}
/* ⛔⛔ NO `transform` IN THIS TRANSITION, AND IT IS NOT A STYLE PREFERENCE. placeLabels() rewrites
 * every label's transform EVERY FRAME from the projection, so the motion is already smooth; a
 * 180 ms ease on top of it does not smooth anything, it makes the PAINTED position permanently
 * trail the position the seating logic tested. The seat loop rejects any seat that hits a rail —
 * and it was right every time: all seven seats matched the transform written, to half a pixel.
 * The label was simply somewhere else on screen. Measured on the home view, 2026-09-29:
 *     with `transform .18s ease`   worst lag 172.9 px, 3 of 7 labels painted over a rail
 *     with it removed              worst lag 0 px,     0 of 7
 * The 180 ms is at its worst exactly when it is most visible: a seat hop moves a label 400 px,
 * so the name SLIDES ACROSS THE READER'S TEXT on its way to a seat that was checked and clear.
 * An instant hop is the cheaper of the two. Gated by tools/check_frame_transitions.mjs. */
@media (prefers-reduced-motion:no-preference){.mlabel{transition:opacity .28s ease,border-color .2s ease,background .2s ease}}
/* the hover tip — the imperatives sheet keeps this below its divider, so the hub carries its own */
#tip{position:fixed;left:0;top:0;z-index:31;pointer-events:none;opacity:0;
  display:flex;flex-direction:column;gap:1px;padding:6px 10px;
  background:rgba(4,10,4,.86);border:1px solid rgba(159,216,255,.18);border-radius:var(--r-ctl);
  backdrop-filter:blur(8px);box-shadow:0 2px 16px rgba(0,0,0,.5);
  font-size:var(--fs-xs);color:var(--text);white-space:nowrap;transition:opacity .15s ease}
#tip.on{opacity:1}
#tip b{font-family:var(--serif);font-style:italic;font-weight:var(--fw-normal);font-size:var(--fs-sm)}
#tip span{opacity:.7;font-variant-numeric:tabular-nums}
@media (max-width:760px){
  /* the sheet ends above the dock, not under it: the last block of a level must be reachable */
  #detail .dt-body{padding-bottom:calc(132px + var(--sab))}
}
/* inside the stacked sheet the section heads scroll with their sections — a sticky head here
   floats over the block above it */
#dtPlace .sm-sec h3{position:static;margin:0 0 8px}
.pl-go{color:inherit;text-decoration:none;border-bottom:1px dotted rgba(0,190,90,.5)}
.pl-go:hover{color:var(--accent)}
.pl-row[data-osm]:hover{background:rgba(0,190,90,.07);margin:0 -6px;padding-left:6px;padding-right:6px;border-radius:4px}
.pl-globe{appearance:none;border:1px solid rgba(0,190,90,.45);background:transparent;color:var(--accent);border-radius:50%;width:20px;height:20px;line-height:1;font-size:var(--fs-micro);cursor:pointer;padding:0}
.pl-globe:hover,.pl-globe:focus-visible{background:rgba(0,190,90,.18);outline:none}
/* seated labels are controls: clickable, hoverable, and in the tab order (world.js sets tabIndex) */
.mlabel.on{pointer-events:auto;cursor:pointer}
.mlabel:focus-visible{outline:2px solid var(--alive);outline-offset:4px;border-radius:4px}

/* ⛔ NO-GLOBE MODE — main.js sets this when WebGL cannot start. The canvas and its labels go, the
 * two globe controls read as disabled, and every rail, sheet and level works exactly as before.
 * The CI coverage gate runs the page in this mode (a GPU-less runner) and says so in its output. */
body.no-globe #scene,body.no-globe #labels,body.no-globe #tip{display:none}
body.no-globe #spinBtn,body.no-globe #viewBtn{opacity:.38;cursor:default}
#noglobe{display:none}
/* ⛔ 2026-09-28: it was prepended to #main, which starts UNDER the fixed masthead — so the one
   sentence explaining the empty screen was drawn behind the logo and clipped. A reader without
   WebGL saw a blank middle and half a sentence. It belongs where the globe would have been. */
body.no-globe #noglobe{display:block;position:fixed;left:50%;top:50%;z-index:6;
  transform:translate(-50%,-50%);max-width:min(430px,calc(100vw - 48px));margin:0;
  padding:14px 16px;border:1px solid var(--line);border-radius:8px;
  background:var(--sf-wash);color:var(--muted);font-size:var(--fs-sm);line-height:var(--lh-body)}
@media (max-width:1080px){body.no-globe #noglobe{top:30%}}

/* boundaries listed beside units; framework totals named */
.pl-ways{font-size:var(--fs-micro);color:var(--muted);margin-left:auto;padding-right:8px}
.rf-tot span em{color:var(--muted);font-style:normal;margin:0 3px}
.pl-vals{margin-top:8px}
.pl-host{display:block;margin-top:4px;opacity:.7;word-break:break-all}

/* ------------------------------------------------- a scroll region that says it scrolls
 * ⛔ MEASURED 2026-09-29, AND IT IS A TRUNCATION, NOT A FLOURISH. Six regions on this page
 * scroll: #intro, #summary, #place, .sheet-body, .dt-body and .sm-bars. Three of them reported
 * a scrollbar 0 px wide (macOS overlay scrollbars, invisible until something moves) and NONE
 * carried a fade. On the Terai Arc recovery-framework criterion the score list was cut through
 * the middle of "Gharial · Nepal · 15" at the panel edge with nothing to say the list went on —
 * 319 px of the 780 px body was below the fold, and 2,022 px of the place rail. A reader who
 * cannot tell a cut row from the last row reads a shorter paper than the one we published.
 * ⭐ TWO SIGNALS, BECAUSE THEY ANSWER DIFFERENT QUESTIONS. The thin bar says THIS SCROLLS; the
 * fade says THERE IS MORE, RIGHT HERE — and it is removed at the end, so its absence is also a
 * statement. The fade is a sticky ::after rather than a mask on the element because #intro,
 * #summary and #place ARE the cards: a mask fades their 1px border and 14px corner with the
 * text, and the frame of the card is not the thing that continues.
 * ⚠ --sf-to must track the BOTTOM stop of each card's own gradient; a wrong value reads as a
 * faint band above the last line rather than as an edge. */
.sfade{--sf-h:34px;--sf-to:#060d08}
/* ⛔ `flex:none` IS LOAD-BEARING, NOT TIDINESS. #intro, #summary and #place are column flex
 * containers, so this ::after is a FLEX ITEM: with the default flex-shrink it computed to
 * height 0 and the right rail's boundary list went on being sliced while .dt-body — a plain
 * block — faded correctly. Two containers fading and one not is the hardest version of this
 * bug to see, because the mechanism looks proven. Measured 2026-09-29. */
.sfade.more-b::after{content:'';display:block;position:sticky;bottom:0;z-index:2;flex:none;
  height:var(--sf-h);margin-top:calc(var(--sf-h) * -1);pointer-events:none;
  background:linear-gradient(to bottom,transparent,var(--sf-to))}
#detail .sfade{--sf-to:#040a05}
.sheet .sfade{--sf-to:#070f0b}
.sm-bars.sfade{--sf-h:22px}
.sfade::-webkit-scrollbar{width:7px}
.sfade::-webkit-scrollbar-track{background:transparent}
.sfade::-webkit-scrollbar-thumb{background:var(--sf-edge);border-radius:var(--r-hair)}
.sfade{scrollbar-width:thin;scrollbar-color:var(--sf-edge) transparent}
/* ⛔ THE BOTTOM PADDING IS WHY THE FIRST VERSION OF THIS FADE STOPPED 20 px SHORT, AND IT LOOKED
 * LIKE A WORKING FADE. A sticky box cannot leave its containing block, and for a ::after that is
 * the scroller's CONTENT box — so on a scroller with padding-bottom the fade pins ABOVE the
 * padding, the row sitting in that gap stays fully sharp underneath it, and the panel reads as
 * "the faded row is the second to last" instead of "the list continues". A negative margin-bottom
 * does not escape the clamp either; both were measured on the Terai Arc criterion, 2026-09-29.
 * ⭐ So the end-of-scroll breathing room moves OFF the scroller and ONTO its last child, where it
 * is inside the content box and the fade can reach the true edge. Only these two scrollers have
 * bottom padding; the other four are already flush. */
.dt-body.sfade{padding-bottom:0}
.dt-body.sfade > :last-child{margin-bottom:20px}
.sheet-body.sfade{padding-bottom:0}
.sheet-body.sfade > :last-child{margin-bottom:44px}
/* ⭐ FOUND BY check_scroll_edges, NOT BY EYE: #summary carries `padding:2px 0` in one media state,
 * so its fade clamped 2 px above the edge too. Two pixels is invisible in a screenshot and is the
 * same mechanism as the 20 px one — which is the argument for the gate's threshold being ANY
 * non-zero bottom padding rather than a number somebody judged small enough. */
#summary.sfade{padding-bottom:0}
#summary.sfade > :last-child{margin-bottom:2px}

/* ===== facelift: landscape =====
   Level 1 — the landscape record (#detail) and the place rail (#place). Cosmetic only: no text,
   no data, no door mechanics change. The landscape's own hue arrives as --c on both rails (set in
   openDetail); every tint below reads it, so the record is coloured by the place it describes.
   ⛔ Nothing in a SCROLLER moves on hover — a transform on a 100%-wide row inside overflow:auto is
   2px of horizontal scroll. Rows lift with a swatch and a chevron instead. */
#detail,#place{--c:var(--accent)}

/* ── arrival ── keyframes, not transitions: the panel is display:none between opens, and a
   transition from display:none has no start state, so the second open POPPED while the first
   slid. An animation starts whenever the element is rendered with the class on. */
@keyframes fl-panel{from{opacity:0;transform:translateX(-18px) scale(.985)}to{opacity:1;transform:none}}
@keyframes fl-sheet{from{opacity:0;transform:translateY(28px)}to{opacity:1;transform:none}}
@keyframes fl-place{from{opacity:0;transform:translateX(18px)}to{opacity:1;transform:none}}
@keyframes fl-rise{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}
#detail{transition:opacity .16s ease,transform .2s ease}
#detail.open{animation:fl-panel .5s cubic-bezier(.22,.92,.2,1) both}
/* staggered children: kicker → name → measurement → figure → chart → the rail's blocks */
#detail.open .dt-k,#detail.open #dtName,#detail.open .dt-sub,
#detail.open #dtFig .dt-meas,#detail.open #dtFig .dt-big,#detail.open #dtFig .dt-src,
#detail.open #dtTrend,#detail.open #dtBody > *{animation:fl-rise .42s cubic-bezier(.22,.92,.2,1) both}
#detail.open .dt-k{animation-delay:.06s}
#detail.open #dtName{animation-delay:.12s}
#detail.open .dt-sub{animation-delay:.18s}
#detail.open #dtFig .dt-meas{animation-delay:.2s}
#detail.open #dtFig .dt-big{animation-delay:.26s}
#detail.open #dtFig .dt-src{animation-delay:.32s}
#detail.open #dtTrend{animation-delay:.34s}
#detail.open #dtBody > *{animation-delay:.52s}
#detail.open #dtBody > :nth-child(1){animation-delay:.4s}
#detail.open #dtBody > :nth-child(2){animation-delay:.46s}
body.detail-open #place:not([hidden]){animation:fl-place .5s cubic-bezier(.22,.92,.2,1) both}
#place > .sm-sec{animation:fl-rise .42s cubic-bezier(.22,.92,.2,1) both;animation-delay:.42s}
#place > .sm-sec:nth-child(1){animation-delay:.16s}
#place > .sm-sec:nth-child(2){animation-delay:.22s}
#place > .sm-sec:nth-child(3){animation-delay:.28s}
#place > .sm-sec:nth-child(4){animation-delay:.34s}
@media (max-width:760px){#detail.open{animation-name:fl-sheet}}
@media (prefers-reduced-motion:reduce){
  #detail.open,#detail.open .dt-k,#detail.open #dtName,#detail.open .dt-sub,
  #detail.open #dtFig .dt-meas,#detail.open #dtFig .dt-big,#detail.open #dtFig .dt-src,
  #detail.open #dtTrend,#detail.open #dtBody > *,
  body.detail-open #place:not([hidden]),#place > .sm-sec{animation:none!important}
  #dtClose:hover{transform:none}
  #place .golink:hover,#dtPlace .golink:hover{transform:none}
}

/* ── the two surfaces ── a 1px inner light at the top in the landscape's hue */
#detail{box-shadow:0 26px 70px rgba(0,0,0,.6),inset 0 1px 0 0 color-mix(in srgb,var(--c) 55%,transparent)}
#place{box-shadow:0 18px 50px rgba(0,0,0,.5),inset 0 1px 0 0 color-mix(in srgb,var(--c) 55%,transparent)}

/* ── the head ── */
.dt-top{padding:18px 20px 16px;
  background:linear-gradient(180deg,color-mix(in srgb,var(--c) 7%,transparent),transparent)}
.dt-k{display:flex;flex-wrap:wrap;align-items:center;gap:6px 9px;font-size:var(--fs-micro);
  letter-spacing:var(--ls-caps-x);margin-bottom:10px}
.dt-k::before{content:'';width:14px;height:2px;border-radius:1px;background:currentColor;flex:none}
#dtName{font-size:var(--fs-head);line-height:var(--lh-snug);letter-spacing:var(--ls-tight);text-wrap:balance}
.dt-sub{margin-top:7px;font-size:var(--fs-xs);letter-spacing:var(--ls-wide);color:var(--ink-dim);
  font-variant-numeric:tabular-nums}
#dtClose{width:30px;height:30px;transition:border-color .2s,color .2s,transform .25s cubic-bezier(.22,.92,.2,1)}
#dtClose:hover{transform:rotate(90deg)}

/* ── the readout ── measurement, then the figure, as one instrument */
#dtFig.dt-block{margin-top:2px;padding:14px 16px 13px;position:relative;
  border:1px solid var(--sf-line);border-radius:var(--r-ctl);
  background:linear-gradient(135deg,color-mix(in srgb,var(--c) 9%,transparent),transparent 62%),#080f09}
#detail .dt-body p.dt-meas{font-size:var(--fs-sm);color:var(--ink-dim);line-height:var(--lh-body);
  margin:0 0 12px;padding-bottom:12px;border-bottom:1px solid var(--sf-line);max-width:none}
#detail .dt-meas-k{font-size:var(--fs-micro);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps-x);
  color:var(--c);margin-bottom:4px}
#detail .dt-meas.none{color:var(--psi-down)}
#detail .dt-meas.none .dt-meas-k{color:var(--psi-down)}
.dt-big{font-size:calc(var(--fs-figure) * 1.7);font-weight:var(--fw-display);letter-spacing:var(--ls-display);
  line-height:var(--lh-flat);margin:0;display:flex;flex-direction:column;gap:8px;
  text-shadow:0 0 28px color-mix(in srgb,currentColor 35%,transparent)}
.dt-big em{font-size:var(--fs-micro);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);text-transform:uppercase;
  color:var(--ink-muted);opacity:1;margin:0;line-height:var(--lh-body);text-shadow:none}
#detail .dt-body p.dt-src{margin:11px 0 0;font-size:var(--fs-xs);line-height:var(--lh-body);color:var(--ink-muted);
  opacity:1;display:flex;gap:8px;align-items:baseline}
.dt-src::before{content:'';width:5px;height:5px;border-radius:50%;background:var(--accent);flex:none;transform:translateY(-1px)}
#detail .dt-body p.dt-src.calc{color:var(--psi-down)}
.dt-src.calc::before{background:var(--psi-down)}
#dtTrend.dt-block{margin-top:18px}

/* ── tiles ── */
.dt-grid{border-radius:var(--r-ctl)}
.dt-grid div{background:#0a120b;padding:13px 14px 12px}
.dt-grid dt{font-size:var(--fs-micro);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);color:var(--ink-muted);margin-bottom:7px}
.dt-grid dd{font-size:var(--fs-2xl);font-weight:var(--fw-display);letter-spacing:var(--ls-display)}
.dt-grid dd small{font-size:var(--fs-sm);font-weight:var(--fw-normal);letter-spacing:0;color:var(--ink-muted)}
.dt-grid dd em{margin-top:6px;color:var(--ink-muted)}
.dt-grid.crit dd{font-size:var(--fs-base);font-weight:var(--fw-med);letter-spacing:var(--ls-tight)}

/* ── block rhythm ── a heading is a caps label with a rule running to the edge */
.dt-block{margin-top:26px}
#detail .dt-block h4{display:flex;align-items:center;gap:10px;font-size:var(--fs-xs);font-weight:var(--fw-bold);
  letter-spacing:var(--ls-caps);color:var(--ink-dim);margin-bottom:10px}
#detail .dt-block h4::after{content:'';flex:1 1 24px;height:1px;background:var(--sf-line)}
#detail .sv-q{margin:-4px 0 12px;color:var(--ink-dim)}
.dt-more{margin-top:22px;padding-top:12px}
.dt-more summary{font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--ink-dim)}
.dt-more summary::marker{color:var(--c)}
#detail .kv{gap:5px 16px}
#detail .kv dt{font-size:var(--fs-micro);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);text-transform:uppercase;
  color:var(--ink-muted);opacity:1;padding-top:2px}

/* ── doors ── every row that opens a level: swatch on the left, chevron on the right, tint on hover,
   a ring on focus. The earlier rules set outline:none on focus; these put a visible ring back. */
.spk{position:relative;grid-template-columns:minmax(0,1.15fr) 112px auto auto;padding:9px 24px 9px 12px;
  border-radius:var(--r-ctl);transition:background .18s ease}
.spk::before{content:'';position:absolute;left:0;top:11px;bottom:11px;width:3px;border-radius:2px;background:var(--c);
  opacity:.5;transition:opacity .18s,top .18s,bottom .18s}
.spk::after{content:'';position:absolute;right:10px;top:50%;width:7px;height:7px;
  border-top:1.5px solid var(--ink-faint);border-right:1.5px solid var(--ink-faint);
  transform:translateY(-50%) rotate(45deg);transition:border-color .18s,right .18s}
.spk:hover,.spk:focus-visible{background:color-mix(in srgb,var(--c) 11%,transparent)}
.spk:hover::before,.spk:focus-visible::before{opacity:1;top:6px;bottom:6px}
.spk:hover::after,.spk:focus-visible::after{border-color:var(--c);right:7px}
.spk:focus-visible{outline:2px solid var(--alive);outline-offset:-2px}
.spk.static::before,.spk.static::after{display:none}
.spk-n{font-weight:var(--fw-med)}
.spk-n i{opacity:.55;transition:opacity .18s}
.spk:hover .spk-n i{opacity:.85}
.spk-v{font-weight:var(--fw-bold);font-size:var(--fs-base)}
/* a guild row is a line, not a species: dashed swatch and a small gold tag where the binomial sits */
.spk.spk-guild::before{background:repeating-linear-gradient(180deg,var(--c) 0 4px,transparent 4px 7px)}
.spk.spk-guild .spk-n i{font-style:normal;font-size:var(--fs-micro);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);
  text-transform:uppercase;color:var(--gold);opacity:.85}

/* the candidates: in-a-line rows at full strength, the unselected greyed and still legible */
.spk-out{gap:6px;margin-top:12px}
.spk-o{position:relative;padding:5px 22px 5px 10px;opacity:1;color:var(--ink-dim);border-color:var(--sf-line);
  transition:border-color .18s,background .18s,color .18s}
.spk-o::after{content:'';position:absolute;right:9px;top:50%;width:5px;height:5px;
  border-top:1.5px solid var(--ink-faint);border-right:1.5px solid var(--ink-faint);
  transform:translateY(-50%) rotate(45deg);transition:border-color .18s}
.spk-o em{color:var(--ink-faint);opacity:1}
.spk-o.spk-o-via{color:var(--ink-soft);border-color:color-mix(in srgb,var(--c) 40%,transparent)}
.spk-o.spk-o-out{color:var(--ink-muted);background:var(--sf-wash)}
.spk-o.spk-o-out .rl{opacity:.7}
.spk-o:hover,.spk-o:focus-visible{opacity:1;color:var(--text);border-color:var(--c);background:color-mix(in srgb,var(--c) 10%,transparent)}
.spk-o:hover .rl,.spk-o:focus-visible .rl{opacity:1}
.spk-o:hover::after,.spk-o:focus-visible::after{border-color:var(--c)}
.spk-o:focus-visible{outline:2px solid var(--alive);outline-offset:2px}

/* leave-one-out: the bar is the door */
#detail .loo{position:relative;grid-template-columns:1fr 96px auto;padding:6px 22px 6px 10px;
  border-bottom:1px solid var(--sf-line);border-radius:var(--r-ctl);transition:background .18s ease}
#detail .loo::after{content:'';position:absolute;right:9px;top:50%;width:6px;height:6px;
  border-top:1.5px solid var(--ink-faint);border-right:1.5px solid var(--ink-faint);
  transform:translateY(-50%) rotate(45deg);transition:border-color .18s}
#detail .loo:hover,#detail .loo:focus-visible{background:color-mix(in srgb,var(--c) 11%,transparent)}
#detail .loo:hover::after,#detail .loo:focus-visible::after{border-color:var(--c)}
#detail .loo:focus-visible{outline:2px solid var(--alive);outline-offset:-2px}
#detail .loo.static::after{display:none}
.loo-t{height:6px;background:var(--sf-tint)}
#detail .loo b{font-size:var(--fs-xs);font-weight:var(--fw-bold);opacity:1;color:var(--ink-soft)}

/* ── the place rail ── */
#place .sm-sec,#dtPlace .sm-sec{border-bottom:1px solid var(--sf-line)}
#place .sm-sec h3,#dtPlace .sm-sec h3{justify-content:flex-start;gap:8px;color:var(--accent)}
#place .sm-sec h3::before,#dtPlace .sm-sec h3::before{content:'';width:10px;height:2px;border-radius:1px;background:var(--c);flex:none}
#place .sm-fig div,#dtPlace .sm-fig div{background:#0a120b;padding:10px 12px 11px}
#place .sm-fig b,#dtPlace .sm-fig b{font-size:var(--fs-2xl)}
@media (max-height:845px){#place .sm-fig b{font-size:var(--fs-xl)}}
#place .sm-fig span,#dtPlace .sm-fig span{margin-top:5px;font-size:var(--fs-micro);font-weight:var(--fw-bold);
  letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--ink-muted)}
#place .sm-fig em,#dtPlace .sm-fig em{margin-top:3px;color:var(--ink-muted)}
#place .sv-q,#dtPlace .sv-q{margin:-2px 0 10px}

/* units and criteria: the bar is the door, and it wears the landscape's hue */
#place .sm-bars,#dtPlace .sm-bars{gap:2px}
.sm-bar.act{position:relative;padding:3px 18px 3px 7px;margin:0 -5px;border-radius:var(--r-ctl);transition:background .16s ease}
.sm-bar.act::after{content:'';position:absolute;right:7px;top:50%;width:5px;height:5px;
  border-top:1.5px solid var(--ink-faint);border-right:1.5px solid var(--ink-faint);
  transform:translateY(-50%) rotate(45deg);transition:border-color .16s}
.sm-bar.act:hover,.sm-bar.act:focus-visible{background:color-mix(in srgb,var(--c) 11%,transparent)}
.sm-bar.act:hover::after,.sm-bar.act:focus-visible::after{border-color:var(--c)}
.sm-bar.act:focus-visible{outline:2px solid var(--alive);outline-offset:-2px}
#place .sm-bar-t,#dtPlace .sm-bar-t{background:var(--sf-tint)}
#place .sm-bar-t i,#dtPlace .sm-bar-t i{background:linear-gradient(90deg,color-mix(in srgb,var(--c) 55%,#0b1510),var(--c))}
.sm-bar.cur{background:color-mix(in srgb,var(--c) 14%,transparent)}
.sm-bar.cur .sm-bar-k{color:var(--text)}
.sm-bar.cur::after{border-color:var(--c)}

/* boundaries: the ◎ flies the globe; the row lights the outline */
.pl-row{padding:6px 0}
.pl-row[data-osm]:hover{background:color-mix(in srgb,var(--c) 8%,transparent)}
.pl-globe{border-color:color-mix(in srgb,var(--c) 50%,transparent);color:var(--c);
  transition:background .16s,border-color .16s,box-shadow .16s}
.pl-globe:hover,.pl-globe:focus-visible{background:color-mix(in srgb,var(--c) 22%,transparent);border-color:var(--c);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--c) 18%,transparent)}
.pl-globe:focus-visible{outline:2px solid var(--alive);outline-offset:2px}
.pl-go{border-bottom-color:color-mix(in srgb,var(--c) 50%,transparent)}
.pl-go:hover{color:var(--c)}

/* the protection pair as two cards */
.pl-pair > div{padding:8px 9px 9px;border:1px solid var(--sf-line);border-radius:var(--r-ctl);background:var(--sf-wash)}

/* the timeline: the index span glows in the landscape's hue; a marker is a ring on a tick */
.tl{height:50px;margin:8px 8px 10px}
.tl::before{top:24px;background:var(--sf-edge)}
.tl-span{top:22px;height:5px;opacity:.85;
  background:linear-gradient(90deg,color-mix(in srgb,var(--c) 55%,transparent),var(--c));
  box-shadow:0 0 12px color-mix(in srgb,var(--c) 40%,transparent)}
.tl-m{top:8px;height:12px}
.tl-m::after{content:'';position:absolute;left:50%;top:12px;width:1px;height:4px;background:var(--gold);opacity:.6;transform:translateX(-50%)}
.tl-m b{width:12px;height:12px;background:#0b1510;border:2px solid var(--gold);
  box-shadow:0 0 0 3px rgba(255,200,0,.14);transition:background .16s,box-shadow .16s}
.tl-m:hover b,.tl-m:focus-visible b{background:var(--gold);box-shadow:0 0 0 4px rgba(255,200,0,.28)}
.tl-m:focus-visible{outline:2px solid var(--alive);outline-offset:4px;border-radius:var(--r-hair)}
.tl-m.cur b{background:var(--gold)}
.tl-a,.tl-b{top:34px;letter-spacing:var(--ls-wide);color:var(--ink-muted);opacity:1;font-variant-numeric:tabular-nums}
.tl-row{position:relative;grid-template-columns:38px 1fr;padding:7px 20px 7px 6px;border-radius:var(--r-ctl);
  transition:background .16s ease}
.tl-row b{font-weight:var(--fw-bold)}
.tl-row::after{content:'';position:absolute;right:8px;top:50%;width:5px;height:5px;
  border-top:1.5px solid var(--ink-faint);border-right:1.5px solid var(--ink-faint);
  transform:translateY(-50%) rotate(45deg);transition:border-color .16s}
.tl-row:hover,.tl-row:focus-visible{background:color-mix(in srgb,var(--c) 10%,transparent)}
.tl-row:hover::after,.tl-row:focus-visible::after{border-color:var(--c)}
.tl-row:focus-visible{outline:2px solid var(--alive);outline-offset:-2px}

/* the Recovery Framework bands — the colours are the markup's own, inline on each swatch */
.tl-bands{gap:6px;margin-top:10px}
.tl-bands span{align-items:center;gap:7px;padding:4px 10px 4px 7px;border:1px solid var(--sf-line);
  border-radius:var(--r-pill);background:var(--sf-wash);font-variant-numeric:tabular-nums}
.tl-bands i{width:9px;height:9px;border-radius:50%;transform:none}
.rf-tot{gap:4px 6px;margin-top:8px}
.rf-tot span{padding:3px 8px;border:1px solid var(--sf-line);border-radius:var(--r-hair);background:var(--sf-wash);font-size:var(--fs-xs)}

/* who counts, and on what standing */
.pl-stand{padding:6px 0 6px 10px;border-left:2px solid var(--c);margin-bottom:10px}
.pl-stand b{font-size:var(--fs-base);color:var(--text)}
.pl-stand span{margin-top:5px;font-size:var(--fs-xs);color:var(--ink-muted);opacity:1}
.pl-more summary::marker{color:var(--c)}

/* the Vista door */
#place .golink,#dtPlace .golink{display:inline-flex;align-items:center;gap:8px;border-radius:var(--r-ctl);padding:9px 16px;
  font-weight:var(--fw-med);letter-spacing:var(--ls-nudge);box-shadow:0 6px 18px rgba(0,190,90,.18);
  transition:transform .18s cubic-bezier(.22,.92,.2,1),box-shadow .18s,filter .18s}
#place .golink:hover,#dtPlace .golink:hover{transform:translateY(-1px);filter:brightness(1.06);box-shadow:0 10px 24px rgba(0,190,90,.26)}
#place .golink.off,#dtPlace .golink.off{box-shadow:none}
#place .golink.off:hover,#dtPlace .golink.off:hover{transform:none;filter:none}
#place .pl-link,#dtPlace .pl-link{position:relative;padding:9px 20px 9px 6px;border-radius:var(--r-ctl);transition:background .16s ease}
#place .pl-link::after,#dtPlace .pl-link::after{content:'';position:absolute;right:8px;top:50%;width:5px;height:5px;
  border-top:1.5px solid var(--ink-faint);border-right:1.5px solid var(--ink-faint);transform:translateY(-50%) rotate(45deg)}
#place .pl-link:hover,#dtPlace .pl-link:hover{background:color-mix(in srgb,var(--c) 10%,transparent)}
#place .pl-link:focus-visible,#dtPlace .pl-link:focus-visible{outline:2px solid var(--alive);outline-offset:-2px}

/* narrow: the place folds under the index with the same rhythm */
.dt-place{margin-top:30px;padding-top:10px}
.dt-place-h{display:flex;align-items:center;gap:10px;font-size:var(--fs-xs);font-weight:var(--fw-bold);color:var(--ink-dim);margin:8px 0 4px}
.dt-place-h::after{content:'';flex:1 1 24px;height:1px;background:var(--sf-line)}
#dtPlace .sm-sec{padding:14px 0 16px}
/* narrow: four columns left the name 32px wide at 390px and the binomial broke letter by letter.
   The row becomes two lines — the name across the top, then sparkline · change · badge. */
@media (max-width:760px){
  .spk{grid-template-columns:minmax(0,1fr) auto auto;gap:4px 10px;padding:9px 24px 9px 12px}
  .spk-n{grid-column:1 / -1}
  .spk-n i{display:inline;margin-left:6px;overflow-wrap:normal}
  .spk-g{grid-column:1;height:30px;max-width:150px}
  .spk-v{min-width:0}
}
#place a.pl-link,#dtPlace a.pl-link{text-decoration:none;color:inherit}
/* ===== facelift: levels =====
   Levels 1–4 — what opens when a species, a unit, a survey point, a marker or a criterion is
   picked. State: `#detail.lv` while a level is open, `data-level` names which, `--lvc` is the
   landscape's hue (main.js openLevel). Rules are scoped to #dtKick / #dtSub / #dtBody under .lv so
   the landscape record and the folded place rail (#dtPlace) keep their own agents' styling.
   Every text node here is site.js's own; this block only places and colours it. */

/* the descent and the return — one animation each, re-armed per level (main.js reflows between) */
@keyframes lv-descend{from{opacity:0;transform:translateY(16px) scale(.988)}to{opacity:1;transform:none}}
@keyframes lv-ascend{from{opacity:0;transform:translateY(-12px)}to{opacity:1;transform:none}}
@keyframes lv-head{from{opacity:0;transform:translateX(-8px)}to{opacity:1;transform:none}}
#detail.lv-in .dt-body{animation:lv-descend .46s cubic-bezier(.22,.92,.2,1) both}
#detail.lv-in .dt-top > div{animation:lv-head .4s cubic-bezier(.22,.92,.2,1) both}
#detail.lv-up .dt-body{animation:lv-ascend .38s cubic-bezier(.22,.92,.2,1) both}
#detail.lv-up .dt-top > div{animation:lv-ascend .34s cubic-bezier(.22,.92,.2,1) both}
@media (prefers-reduced-motion:reduce){
  #detail.lv-in .dt-body,#detail.lv-in .dt-top > div,#detail.lv-up .dt-body,#detail.lv-up .dt-top > div{animation:none}
}

/* the header of a level: a wash of the landscape's hue, the breadcrumb, the name a size up */
#detail.lv .dt-top{padding:16px 18px 16px;
  background:linear-gradient(180deg,color-mix(in srgb,var(--lvc,var(--accent)) 10%,transparent),transparent 92%);
  box-shadow:inset 0 1px 0 color-mix(in srgb,var(--lvc,var(--accent)) 35%,transparent)}
#detail.lv .dt-k{display:flex;flex-wrap:wrap;align-items:center;gap:6px 0;margin-bottom:12px}
#detail.lv .crumb{display:inline-flex;align-items:center;margin:0;padding:4px 10px 4px 8px;
  border:1px solid var(--sf-edge);border-radius:var(--r-pill);background:var(--sf-wash);
  color:var(--ink-dim);letter-spacing:var(--ls-caps);line-height:var(--lh-snug);
  transition:color .16s ease,border-color .16s ease,background .16s ease,transform .2s ease}
#detail.lv .crumb:hover,#detail.lv .crumb:focus-visible{color:var(--alive);border-color:var(--alive);
  background:rgba(0,190,90,.12);transform:translateX(-2px)}
#detail.lv .crumb:focus-visible{outline:2px solid var(--alive);outline-offset:2px}
/* the level's kicker follows the crumb: Landscape › Species — the › is a separator, the words are the markup's */
#detail.lv .crumb-k{display:inline-flex;align-items:center;font-weight:var(--fw-bold)}
#detail.lv .crumb-k::before{content:"›";margin:0 9px;color:var(--ink-faint);font-weight:var(--fw-normal);letter-spacing:0}
#detail[data-level="species"] #dtName,#detail[data-level="unit"] #dtName,
#detail[data-level="point"] #dtName,#detail[data-level="step"] #dtName{font-size:var(--fs-head)}
#detail.lv #dtName{line-height:1.08;text-wrap:balance}
#detail.lv #dtName:focus:not(:focus-visible){outline:none}
#detail.lv #dtName:focus-visible{outline:1px solid color-mix(in srgb,var(--alive) 70%,transparent);outline-offset:6px;border-radius:var(--r-ctl)}
/* the sub line: chips — the binomial, the Red List category, CITES, the unit's facts */
#detail.lv .dt-sub{display:flex;flex-wrap:wrap;align-items:center;gap:5px 7px;margin-top:9px;
  font-size:var(--fs-xs);letter-spacing:var(--ls-nudge);color:var(--ink-faint)}
#detail.lv .dt-sub i{font-style:italic;font-size:var(--fs-sm);color:var(--ink-soft);letter-spacing:0}
#detail.lv .dt-sub .dt-fact,#detail.lv .dt-sub .dt-cites{display:inline-flex;align-items:center;
  font-size:var(--fs-tiny);letter-spacing:var(--ls-wide);color:var(--ink-dim);
  font-variant-numeric:tabular-nums;line-height:var(--lh-snug)}
#detail.lv .dt-sub .dt-cites{padding:2px 8px;border:1px solid var(--sf-edge);border-radius:var(--r-pill);
  text-transform:uppercase;letter-spacing:var(--ls-caps)}
#detail.lv .dt-sub .dt-fact{padding:2px 0}

/* Red List chips on a level: the page's own category palette (the one the place rail's stacked bar
   already uses — CR is the warm accent, never red; see the badge rule above) */
#detail.lv #dtSub .rl,#detail.lv #dtBody .rl{--rc:var(--psi-none);
  display:inline-flex;align-items:center;padding:2px 8px;border-radius:var(--r-pill);
  font-size:var(--fs-tiny);font-weight:var(--fw-med);letter-spacing:var(--ls-wide);line-height:var(--lh-snug);
  color:var(--rc);border:1px solid color-mix(in srgb,var(--rc) 55%,transparent);
  background:color-mix(in srgb,var(--rc) 13%,transparent)}
#detail.lv #dtSub .rl[data-c="CR"],#detail.lv #dtBody .rl[data-c="CR"]{--rc:var(--psi-down)}
#detail.lv #dtSub .rl[data-c="EN"],#detail.lv #dtBody .rl[data-c="EN"]{--rc:#e89a5a}
#detail.lv #dtSub .rl[data-c="VU"],#detail.lv #dtBody .rl[data-c="VU"]{--rc:#e0c341}
#detail.lv #dtSub .rl[data-c="NT"],#detail.lv #dtBody .rl[data-c="NT"]{--rc:#9bd17a}
#detail.lv #dtSub .rl[data-c="LC"],#detail.lv #dtBody .rl[data-c="LC"]{--rc:var(--alive)}

/* the body of a level: blocks read as chapters */
#detail.lv #dtBody > .dt-block{margin-top:24px}
#detail.lv #dtBody > .dt-block:first-child{margin-top:4px}
#detail.lv #dtBody h4{color:var(--ink-soft)}
#detail.lv #dtBody h4::before{content:"";display:inline-block;width:14px;height:1px;margin-right:8px;
  vertical-align:middle;background:var(--lvc,var(--accent))}
#detail.lv #dtBody .sv-q{margin-bottom:12px}

/* the leave-one-out sentence as the centrepiece: lead, then the two figures either side of "to" */
#detail.lv #dtBody .loo-hero{display:grid;grid-template-columns:auto auto minmax(0,1fr);
  grid-template-areas:"lead lead lead" "a to b";align-items:baseline;column-gap:12px;row-gap:8px;
  margin:0;padding:14px 16px 13px;max-width:none;border:1px solid var(--sf-line);border-radius:var(--r-ctl);
  background:linear-gradient(180deg,var(--sf-wash),transparent);line-height:var(--lh-body)}
#detail.lv #dtBody .loo-lead{grid-area:lead;font-size:var(--fs-sm);color:var(--ink-dim);line-height:var(--lh-body)}
#detail.lv #dtBody .loo-a{grid-area:a;font-size:var(--fs-figure);font-weight:var(--fw-display);
  letter-spacing:var(--ls-display);line-height:var(--lh-flat);color:var(--ink-soft);font-variant-numeric:tabular-nums}
#detail.lv #dtBody .loo-to{grid-area:to;display:inline-flex;align-items:center;gap:5px;align-self:center;
  font-size:var(--fs-micro);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--ink-faint)}
#detail.lv #dtBody .loo-to::after{content:"→";font-size:var(--fs-lg);font-weight:var(--fw-normal);letter-spacing:0;
  color:var(--ink-muted);transform:translateY(-1px)}
#detail.lv #dtBody .loo-res{grid-area:b;display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 4px;min-width:0}
#detail.lv #dtBody .loo-b{font-size:var(--fs-figure);font-weight:var(--fw-display);letter-spacing:var(--ls-display);
  line-height:var(--lh-flat);font-variant-numeric:tabular-nums;
  text-shadow:0 0 22px color-mix(in srgb,currentColor 40%,transparent)}
#detail.lv #dtBody .loo-tail{font-size:var(--fs-sm);color:var(--ink-dim);white-space:nowrap}

/* the nine criteria: one judgement per row, its state a pill */
#detail.lv #dtBody .dt-grid.crit{grid-template-columns:1fr;gap:0;background:none;border:0;border-radius:0;overflow:visible}
#detail.lv #dtBody .dt-grid.crit div{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:10px;
  padding:7px 2px;background:none;border-bottom:1px solid var(--sf-line)}
#detail.lv #dtBody .dt-grid.crit div:last-child{border-bottom:0}
#detail.lv #dtBody .dt-grid.crit dt{margin:0;font-size:var(--fs-sm);letter-spacing:0;text-transform:none;color:var(--ink-soft);line-height:var(--lh-snug)}
#detail.lv #dtBody .dt-grid.crit dd{font-size:var(--fs-tiny);font-weight:var(--fw-med);letter-spacing:var(--ls-wide);
  text-transform:uppercase;line-height:var(--lh-snug);padding:3px 9px;min-width:58px;text-align:center;
  border-radius:var(--r-pill);border:1px solid var(--sf-edge);color:var(--ink-dim)}
#detail.lv #dtBody .dt-grid.crit div[data-v="yes"] dd,#detail.lv #dtBody .dt-grid.crit div[data-v="high"] dd{
  color:var(--alive);border-color:color-mix(in srgb,var(--alive) 55%,transparent);background:rgba(0,190,90,.13)}
#detail.lv #dtBody .dt-grid.crit div[data-v="medium"] dd{
  color:var(--gold);border-color:color-mix(in srgb,var(--gold) 50%,transparent);background:rgba(255,200,0,.09)}
#detail.lv #dtBody .dt-grid.crit div[data-v="low"] dd,#detail.lv #dtBody .dt-grid.crit div[data-v="no"] dd{
  color:var(--ink-muted);border-style:dashed}
#detail.lv #dtBody .dt-grid.crit div[data-v="none"] dd{color:var(--ink-faint);border-color:var(--sf-line)}

/* the series under the line: a tiled table — year small above the value, the estimate beneath */
/* per-cell hairlines rather than a filled grid: a short last row leaves no grey hole beside it */
#detail.lv #dtBody .pl-years.pl-vals{display:grid;grid-template-columns:repeat(auto-fill,minmax(84px,1fr));gap:2px;margin-top:10px}
#detail.lv #dtBody .pl-vals .pl-year{border:1px solid var(--sf-line);border-radius:var(--r-hair);background:#080f09;padding:8px 10px 9px;min-width:0}
#detail.lv #dtBody .pl-vals .pl-year b{font-size:var(--fs-micro);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps);
  color:var(--ink-muted);line-height:var(--lh-snug)}
#detail.lv #dtBody .pl-vals .pl-year em{font-size:var(--fs-md);font-weight:var(--fw-bold);letter-spacing:var(--ls-tight);
  color:var(--text);opacity:1;margin-top:3px;line-height:var(--lh-flat)}
#detail.lv #dtBody .pl-vals .pl-est{margin-top:6px;font-size:var(--fs-micro);color:var(--ink-dim);opacity:1;line-height:var(--lh-snug)}
#detail.lv #dtBody .pl-vals .pl-est small{color:var(--ink-muted);opacity:1;margin-top:1px}

/* the survey-year doors on a species (the landscape index it feeds): the same tiles, live */
#detail.lv #dtBody .pl-years:not(.pl-vals){gap:5px}
#detail.lv #dtBody .pl-years:not(.pl-vals) .pl-year{border-color:var(--sf-edge);background:var(--sf-wash);
  transition:border-color .16s ease,background .16s ease,transform .18s ease}
#detail.lv #dtBody .pl-years:not(.pl-vals) .pl-year:hover,#detail.lv #dtBody .pl-years:not(.pl-vals) .pl-year:focus-visible{
  border-color:var(--alive);background:rgba(0,190,90,.13);transform:translateY(-1px)}
#detail.lv #dtBody .pl-years:not(.pl-vals) .pl-year:focus-visible{outline:2px solid var(--alive);outline-offset:2px}

/* every count in a unit, as a small table under its sparkline */
#detail.lv #dtBody .spk{padding:10px 6px;gap:5px 10px}
#detail.lv #dtBody .spk-u{margin-top:2px;letter-spacing:var(--ls-wide);opacity:.6}
#detail.lv #dtBody .spk-all{display:grid;grid-template-columns:repeat(auto-fill,minmax(62px,1fr));gap:2px;margin-top:6px;opacity:1}
#detail.lv #dtBody .spk-all > span{display:flex;flex-direction:column;gap:2px;padding:5px 8px 6px;background:#080f09;
  border:1px solid var(--sf-line);border-radius:var(--r-hair)}
#detail.lv #dtBody .spk-all b{margin:0;font-size:var(--fs-micro);letter-spacing:var(--ls-caps);color:var(--ink-muted);opacity:1;line-height:var(--lh-snug)}
#detail.lv #dtBody .spk-all em{font-size:var(--fs-sm);font-weight:var(--fw-bold);color:var(--text);line-height:var(--lh-flat)}
#detail.lv #dtBody .spk-v{font-weight:var(--fw-med);color:var(--ink-near)}

/* doors to the next level: a row with an arrow, lit on hover — never a dead end */
#detail.lv #dtBody .pl-link{grid-template-columns:minmax(0,1fr) auto auto;align-items:center;padding:9px 8px 9px 10px;
  border-left:2px solid transparent;border-radius:0 var(--r-hair) var(--r-hair) 0;
  transition:background .14s ease,border-color .14s ease}
#detail.lv #dtBody .pl-link::after{content:"→";color:var(--ink-faint);font-size:var(--fs-sm);
  transition:transform .18s ease,color .18s ease}
#detail.lv #dtBody .pl-link:hover,#detail.lv #dtBody .pl-link:focus-visible{border-left-color:var(--alive)}
#detail.lv #dtBody .pl-link:hover::after,#detail.lv #dtBody .pl-link:focus-visible::after{transform:translateX(3px);color:var(--alive)}
#detail.lv #dtBody .pl-link:focus-visible{outline:2px solid var(--alive);outline-offset:-2px}
#detail.lv #dtBody .pl-link em{opacity:.75}

/* the survey point: its four figures, and how sure it is — a stated interval as figures, no
   interval as a deliberate empty state (dashed, quiet), not as a warning */
#detail.lv #dtBody .pt-ci{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 8px;margin:0;padding:12px 16px;
  border:1px solid var(--sf-line);border-radius:var(--r-ctl);background:linear-gradient(180deg,var(--sf-wash),transparent);
  font-size:var(--fs-sm);color:var(--ink-dim)}
#detail.lv #dtBody .pt-ci b{font-size:var(--fs-2xl);font-weight:var(--fw-display);letter-spacing:var(--ls-display);
  line-height:var(--lh-flat);color:var(--text)}
#detail.lv #dtBody .pt-empty{border-left:1px dashed var(--sf-edge);opacity:1;margin:0;padding:11px 14px 12px;
  border-radius:0 var(--r-ctl) var(--r-ctl) 0;background:var(--sf-wash);color:var(--ink-dim);font-size:var(--fs-sm);line-height:var(--lh-loose)}
#detail.lv #dtBody .pt-empty b{color:var(--ink-near);font-weight:var(--fw-med);margin-bottom:4px}
#detail.lv #dtBody .dt-grid{background:var(--sf-line)}
#detail.lv #dtBody .dt-grid dd{color:var(--text)}
#detail.lv #dtBody .dt-grid dd em{color:var(--ink-muted)}

/* the intervention: the paper's line as the lede, in the timeline's own gold; the caveat stays a caveat */
#detail.lv #dtBody .pl-int{font-size:var(--fs-lg);line-height:var(--lh-loose);color:var(--text);
  border-left:2px solid var(--gold);padding-left:14px;margin:2px 0 16px;max-width:none}
#detail.lv #dtBody .wh:not(.pt-empty){opacity:1;color:var(--ink-dim);padding:2px 0 2px 12px;line-height:var(--lh-loose)}
#detail.lv #dtBody .wh:not(.pt-empty) b{color:var(--ink-near)}

/* the criterion: its weight as a bar under the definition, the bands as a four-cell strip */
#detail.lv #dtBody .wt-bar{height:5px;margin:2px 0 16px;border-radius:var(--r-hair);background:var(--sf-tint);overflow:hidden}
#detail.lv #dtBody .wt-bar i{display:block;height:100%;border-radius:var(--r-hair);
  background:linear-gradient(90deg,var(--green),var(--accent));box-shadow:0 0 12px rgba(0,190,90,.35)}
#detail.lv #dtBody .loo{padding:5px 6px;gap:0 10px}
#detail.lv #dtBody .loo-t{height:6px;background:var(--sf-tint)}
#detail.lv #dtBody .loo-t i{border-radius:var(--r-hair)}
#detail.lv #dtBody .loo b{opacity:1;color:var(--ink-near);font-size:var(--fs-sm)}
#detail.lv #dtBody .tl-bands{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:5px;margin-top:4px}
#detail.lv #dtBody .tl-bands span{display:flex;flex-direction:column;align-items:stretch;gap:7px;
  font-size:var(--fs-tiny);line-height:var(--lh-snug);color:var(--ink-dim)}
#detail.lv #dtBody .tl-bands i{width:auto;height:4px;border-radius:var(--r-hair);transform:none}

/* the way out: the Vista door closes every level */
#detail.lv #dtBody > .dt-block:last-child:not(:first-child){border-top:1px solid var(--sf-line);padding-top:8px}
#detail.lv #dtBody .golink.vista{transition:background .16s ease,transform .18s ease}
#detail.lv #dtBody .golink.vista:hover{background:var(--alive);transform:translateX(2px)}

/* the rails behind: the open item stays lit while the reader is down a level */
.sm-bar.cur{background:rgba(0,190,90,.12);box-shadow:inset 2px 0 0 var(--alive)}
.sm-bar.cur .sm-bar-t i{filter:brightness(1.18)}
.tl-row.cur{background:rgba(255,200,0,.07);box-shadow:inset 2px 0 0 var(--gold)}
.tl-row.cur span{color:var(--text)}
.tl-m.cur b{background:#fff;box-shadow:0 0 0 2px var(--gold),0 0 14px rgba(255,200,0,.55)}

@media (max-width:760px){
  #detail.lv .dt-top{padding:14px 16px 14px}
  #detail[data-level="species"] #dtName,#detail[data-level="unit"] #dtName,
  #detail[data-level="point"] #dtName,#detail[data-level="step"] #dtName{font-size:var(--fs-3xl)}
  #detail.lv #dtBody .loo-hero{padding:12px 13px 11px;column-gap:9px}
  #detail.lv #dtBody .loo-a,#detail.lv #dtBody .loo-b{font-size:var(--fs-2xl)}
  #detail.lv #dtBody .pl-years.pl-vals{grid-template-columns:repeat(auto-fill,minmax(72px,1fr))}
  #detail.lv #dtBody .tl-bands{grid-template-columns:1fr 1fr}
}
/* ===== facelift: graphics =====
   2026-09-29, presentation only: the index chart, the sparklines, the summary rail's bars and
   figures, and the masthead numerals. Every number, label and data-* attribute the SVGs emit is
   as before; this block adds gradients, guides, halos, one draw-in and the hover states.
   Scoped to #summary where the same classes also build the place rail and the level panels,
   which another block owns. Every animation is cancelled under prefers-reduced-motion. */

/* ── the index line (trend(), src/main.js) ─────────────────────────────────── */
.trend{overflow:visible;--c:var(--accent)}
.trend text{font-family:var(--sans);font-variant-numeric:tabular-nums}
.tr-ax{font-size:var(--fs-tiny);opacity:.5;letter-spacing:var(--ls-nudge)}
.tr-yr{font-size:var(--fs-xs);opacity:.72;font-weight:var(--fw-med)}
.tr-grid{stroke:rgba(240,240,234,.05)}
.tr-base{stroke:rgba(240,240,234,.42);stroke-dasharray:2 4}
.tr-area{pointer-events:none;opacity:0;animation:tr-fade .9s ease .55s forwards}
.tr-line{transition:stroke-width .2s ease}
/* the draw-in: pathLength="1" on a solid line, so one dash the length of the path is pulled in */
.tr-solid{stroke-dasharray:1;stroke-dashoffset:1;animation:tr-draw 1.15s cubic-bezier(.4,0,.2,1) .12s forwards}
.tr-line:not(.tr-solid){opacity:0;animation:tr-fade .7s ease .15s forwards}
@keyframes tr-draw{to{stroke-dashoffset:0}}
@keyframes tr-fade{to{opacity:1}}
/* each survey point fades in after the line reaches it — staggered by its index, --i */
.tr-p{opacity:0;animation:tr-fade .38s ease forwards;animation-delay:calc(.35s + var(--i,0) * .09s)}
.tr-guide{stroke-width:1;stroke-opacity:0;stroke-dasharray:2 3;pointer-events:none;transition:stroke-opacity .18s ease}
.tr-p:hover .tr-guide,.tr-p:focus-within .tr-guide{stroke-opacity:.55}
.tr-pt{transition:r .18s ease,filter .18s ease}
.tr-p:hover .tr-pt,.tr-pt:focus,.tr-pt:focus-visible{r:5.2;filter:drop-shadow(0 0 5px var(--c)) brightness(1.2);outline:none}
.tr-halo{pointer-events:none;fill-opacity:.09;stroke-opacity:.28;stroke-width:1;opacity:0;animation:tr-fade .8s ease 1.2s forwards}
.tr-halo-end{fill-opacity:.14;stroke-opacity:.5}
/* a perception series is points, not a trajectory: ringed points, a quieter line, no wash */
.tr-perc .tr-pt{r:4.4;stroke-width:1.6;fill-opacity:.85}
.tr-perc .tr-p:hover .tr-pt,.tr-perc .tr-pt:focus{r:6}
.tr-perc .tr-halo{display:none}

/* ── the sparklines (spark(), src/site.js) ────────────────────────────────── */
.spk-svg{overflow:visible}
.spk-area{pointer-events:none;transition:opacity .2s ease}
.spk-base{stroke:rgba(240,240,234,.26);stroke-dasharray:2 3}
.spk-tick{stroke:rgba(240,240,234,.6);stroke-width:1.2}
.spk-line{transition:stroke-width .18s ease}
.spk-pt{opacity:.72}
.spk-end{opacity:1}
.spk:hover .spk-line,.spk:focus-visible .spk-line{stroke-width:2.1}
.spk:hover .spk-pt,.spk:focus-visible .spk-pt{opacity:1}
.spk:hover .spk-end,.spk:focus-visible .spk-end{filter:drop-shadow(0 0 4px currentColor)}
.spk-g{height:36px}

/* ── the summary rail's instrument: figures and the two bar charts ─────────── */
#summary .sm-fig div{position:relative;padding-top:10px}
#summary .sm-fig div::before{content:"";position:absolute;left:10px;top:0;width:22px;height:2px;border-radius:0 0 2px 2px;
  background:linear-gradient(90deg,var(--accent),transparent)}
#summary .sm-fig b{font-size:var(--fs-2xl);font-weight:var(--fw-display);letter-spacing:var(--ls-display);
  font-variant-numeric:tabular-nums;font-feature-settings:"tnum";color:var(--text)}
#summary .sm-fig span{margin-top:5px;font-size:var(--fs-micro);letter-spacing:var(--ls-caps);text-transform:uppercase;
  font-weight:var(--fw-bold);color:var(--ink-dim)}
#summary .sm-fig em{margin-top:3px;line-height:var(--lh-body)}
@media (max-height:845px){ #summary .sm-fig b{font-size:var(--fs-xl)} }

/* the bars take the row's own colour — the Red List category or the landscape hue that bars()
   already writes as --c — instead of the one green every row used to wear */
#summary .sm-bars{gap:6px}
#summary .sm-bar{grid-template-columns:82px 1fr 30px 28px;gap:9px}
#summary .sm-bar-t{height:8px;border-radius:var(--r-pill);background:var(--sf-wash);
  box-shadow:inset 0 0 0 1px var(--sf-tint);overflow:hidden}
#summary .sm-bar-t i{border-radius:var(--r-pill);min-width:4px;
  background:linear-gradient(90deg,color-mix(in srgb,var(--c,#2fbf7a) 58%,#0b1510),var(--c,#2fbf7a));
  box-shadow:0 0 8px color-mix(in srgb,var(--c,#2fbf7a) 35%,transparent);
  transform-origin:left center;animation:bar-grow .8s cubic-bezier(.22,.92,.2,1) both;animation-delay:.2s}
@keyframes bar-grow{from{transform:scaleX(0)}to{transform:scaleX(1)}}
#summary .sm-bar b{font-size:var(--fs-sm);font-weight:var(--fw-display);letter-spacing:var(--ls-tight);
  font-variant-numeric:tabular-nums;color:var(--text)}
#summary .sm-bar em{font-size:var(--fs-tiny);color:var(--ink-faint);letter-spacing:var(--ls-nudge)}
#summary .sm-bar-k{color:var(--ink-dim)}
#summary .sm-bar.act:hover .sm-bar-t i,#summary .sm-bar.act:focus-visible .sm-bar-t i{filter:brightness(1.25);
  box-shadow:0 0 12px color-mix(in srgb,var(--c,#2fbf7a) 60%,transparent)}
#summary .sm-bar.act:hover em,#summary .sm-bar.act:focus-visible em{color:var(--ink-dim)}
@media (max-width:760px){ #summary .sm-bar{grid-template-columns:88px 1fr 34px 30px} }

/* ── the masthead's headline figures ──────────────────────────────────────── */
#gstats div{border-left:0;padding-left:18px;
  background:linear-gradient(180deg,var(--sf-edge),transparent 92%) left top/1px 100% no-repeat}
#gstats div:first-child{background:none;padding-left:0}
#gstats b{font-size:var(--fs-3xl);font-feature-settings:"tnum";letter-spacing:var(--ls-display);
  text-shadow:0 1px 10px rgba(0,0,0,.85),0 0 24px rgba(0,190,90,.18)}
#gstats span{display:inline-flex;align-items:center;gap:7px;margin-top:8px}
#gstats span::before{content:"";width:5px;height:5px;border-radius:50%;background:var(--accent);flex:none;
  box-shadow:0 0 6px rgba(0,190,90,.6)}
@media (max-width:760px){
  #gstats div{background:none}
  #gstats b{font-size:var(--fs-xl)}
  #gstats span{margin-top:4px;gap:5px}
}
@media (max-width:430px){ #gstats b{font-size:var(--fs-xl)} }

/* every animation in this block, off */
@media (prefers-reduced-motion:reduce){
  .tr-area,.tr-line,.tr-line:not(.tr-solid),.tr-p,.tr-halo{animation:none;opacity:1}
  .tr-solid{animation:none;stroke-dasharray:none;stroke-dashoffset:0}
  #summary .sm-bar-t i{animation:none;transform:none}
  .tr-pt,.tr-guide,.tr-line,.spk-line,.spk-area{transition:none}
}
/* ===== end facelift: graphics ===== */
/* ===== facelift: entry =====
   Level 0, cosmetic only — the first frame and the globe. Nothing here changes a figure, a word or
   a control's semantics; every rule is additive and later in the cascade than what it refines.
   Motion is one-shot on `body.ready`, eased, and switched off under prefers-reduced-motion. */

/* ── the loader: a brand mark, a sweeping bar, a clean dissolve ─────────────────────────────── */
#loader{background:radial-gradient(ellipse at 50% 58%,rgba(13,31,13,.55),rgba(4,10,4,0) 62%),#040A04}
#loader>div{display:grid;justify-items:center;gap:18px;transition:opacity .45s ease,transform .9s cubic-bezier(.2,.7,.2,1)}
#loader.gone>div{opacity:0;transform:translateY(-8px)}
/* the same wordmark file the masthead requests — one URL, one fetch */
#loader>div::before{content:"";width:150px;height:18px;opacity:.72;
  background:url(../public/landseed-wordmark.svg) no-repeat center/contain;
  animation:fl-breathe 2.4s ease-in-out infinite}
#ldmsg:empty{display:none}
#ldmsg{max-width:min(30ch,calc(100vw - 48px));text-align:center;font-size:var(--fs-xs);
  letter-spacing:var(--ls-caps);text-transform:uppercase;color:var(--ink-dim);line-height:var(--lh-airy)}
#ldbar{width:184px;height:2px;background:var(--sf-line);overflow:hidden;position:relative}
#ldfill{width:38%;transition:none;
  background:linear-gradient(90deg,transparent,var(--accent) 35%,var(--alive) 65%,transparent);
  box-shadow:0 0 12px rgba(0,190,90,.55);
  animation:fl-sweep 1.5s cubic-bezier(.45,0,.2,1) infinite}
@keyframes fl-sweep{from{transform:translateX(-110%)}to{transform:translateX(290%)}}
@keyframes fl-breathe{0%,100%{opacity:.58}50%{opacity:.86}}

/* ── the entrance: masthead, then the two rails, each child a beat after the last ───────────── */
@keyframes fl-rise{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes fl-drift{from{opacity:0;transform:translateX(-6px)}to{opacity:1;transform:none}}
body.ready #brand{animation:fl-drift .8s cubic-bezier(.2,.7,.2,1) .2s both}
body.ready #gstats>div{animation:fl-rise .7s cubic-bezier(.2,.7,.2,1) both}
body.ready #gstats>div:nth-child(1){animation-delay:.42s}
body.ready #gstats>div:nth-child(2){animation-delay:.52s}
body.ready #gstats>div:nth-child(3){animation-delay:.62s}
body.ready #intro>*{animation:fl-rise .75s cubic-bezier(.2,.7,.2,1) both}
body.ready #intro>:nth-child(1){animation-delay:.48s}
body.ready #intro>:nth-child(2){animation-delay:.56s}
body.ready #intro>:nth-child(3){animation-delay:.64s}
body.ready #intro>:nth-child(4){animation-delay:.72s}
body.ready #intro>:nth-child(5){animation-delay:.78s}
body.ready #summary>.sm-sec{animation:fl-rise .7s cubic-bezier(.2,.7,.2,1) both}
body.ready #summary>.sm-sec:nth-child(1){animation-delay:.55s}
body.ready #summary>.sm-sec:nth-child(2){animation-delay:.62s}
body.ready #summary>.sm-sec:nth-child(3){animation-delay:.70s}
body.ready #summary>.sm-sec:nth-child(n+4){animation-delay:.78s}
body.ready #smList .lsrow{animation:fl-rise .6s cubic-bezier(.2,.7,.2,1) both}
body.ready #smList .lsrow:nth-child(1){animation-delay:.72s}
body.ready #smList .lsrow:nth-child(2){animation-delay:.77s}
body.ready #smList .lsrow:nth-child(3){animation-delay:.82s}
body.ready #smList .lsrow:nth-child(4){animation-delay:.87s}
body.ready #smList .lsrow:nth-child(5){animation-delay:.92s}
body.ready #smList .lsrow:nth-child(6){animation-delay:.97s}
body.ready #smList .lsrow:nth-child(n+7){animation-delay:1.02s}
body.ready #hint{animation:fl-rise 1s ease 1.5s both}

/* ── the headline figures read as instruments: a gauge rule over each, tabular, settled ─────── */
#gstats>div{position:relative;padding-top:5px}
#gstats>div::before{content:"";position:absolute;top:0;left:18px;right:0;height:1px;
  background:linear-gradient(90deg,rgba(0,190,90,.75),rgba(0,190,90,0) 85%)}
#gstats>div:first-child::before{left:0}
#gstats b{text-shadow:0 1px 10px rgba(0,0,0,.85),0 0 24px rgba(0,190,90,.18)}
#gstats span{color:var(--ink-muted)}
@media (max-width:760px){#gstats>div::before{left:12px}#gstats>div:first-child::before{left:0}}

/* ── the intro: labelled clauses, findings that open like a drawer ──────────────────────────── */
.in-lede b{color:var(--text)}                     /* body text is #F0F0EA here, never pure white */
.in-lede .in-k{color:var(--accent);font-weight:var(--fw-bold);letter-spacing:var(--ls-nudge)}
.in-key{color:var(--ink-dim)}
.fnd{position:relative;transition:background .2s ease}
.fnd::before{content:"";position:absolute;left:0;top:0;bottom:0;width:2px;background:var(--accent);
  transform:scaleY(0);transform-origin:center;transition:transform .28s cubic-bezier(.2,.8,.2,1);
  border-radius:var(--r-hair)}
.fnd:hover,.fnd:has(.fnd-h:focus-visible){background:rgba(0,190,90,.045)}
.fnd:hover::before,.fnd:has(.fnd-h:focus-visible)::before,.fnd.on::before{transform:scaleY(1)}
.fnd-h{transition:color .14s ease,background .2s ease}
.fnd-h:focus-visible{outline:2px solid var(--alive);outline-offset:-4px;border-radius:var(--r-ctl)}
.fnd-x{transition:transform .32s cubic-bezier(.2,.8,.2,1),color .2s ease}
.fnd.on .fnd-x,.fnd-h:hover .fnd-x{color:var(--alive)}
.fnd-f dt{transition:color .2s ease}
.fnd.on .fnd-f dt{color:var(--alive)}
/* the body collapses by height rather than blinking: a grid track from 0fr to 1fr, the inner
   wrapper (.fnd-bi, main.js) clipping. `hidden` stays on the element for the a11y tree, so the
   closed state is also visibility:hidden and its button leaves the tab order. */
.fnd-b{display:grid;grid-template-rows:0fr;opacity:0;visibility:hidden;
  padding:0;border-top-color:transparent;
  transition:grid-template-rows .42s cubic-bezier(.2,.8,.2,1),opacity .26s ease,
    padding .42s cubic-bezier(.2,.8,.2,1),border-color .3s ease,visibility 0s linear .42s}
.fnd-b:not([hidden]){grid-template-rows:1fr;opacity:1;visibility:visible;padding:2px 0 12px;
  border-top-color:var(--sf-line);transition-delay:0s,.08s,0s,0s,0s}
/* the clip stays on while the track grows — a 4px bleed keeps the go button's focus ring whole */
.fnd-bi{min-height:0;overflow:hidden;margin:0 -4px;padding:0 4px}
@media (max-width:760px){.fnd-b:not([hidden]){padding:0 0 10px}}
.fnd-go{transition:border-color .18s ease,background .18s ease,transform .18s ease}
.fnd-go:hover,.fnd-go:focus-visible{transform:translateX(2px)}
.fnd-go:focus-visible{outline-offset:1px}

/* ── the rail: seven tiles, each carrying its landscape's hue, lit from the globe and lighting it ─ */
#smList{gap:4px}
.lsrow{position:relative;border:1px solid var(--sf-line);border-left:2px solid var(--c);
  border-radius:var(--r-ctl);padding:7px 9px 8px 10px;
  background:linear-gradient(90deg,color-mix(in srgb,var(--c) 9%,transparent),transparent 58%),var(--sf-wash);
  transition:background .18s ease,border-color .18s ease,transform .22s cubic-bezier(.2,.8,.2,1),box-shadow .22s ease}
.lsr-n{color:var(--ink-near);transition:color .18s ease}
.lsr-c{opacity:1;color:var(--ink-muted)}
.lsr-d{opacity:1;color:var(--ink-faint);letter-spacing:var(--ls-nudge)}
.lsr-v{font-weight:var(--fw-med);transition:text-shadow .22s ease,color .18s ease}
.lsrow:hover,.lsrow.hot,.lsrow:focus-visible{
  background:linear-gradient(90deg,color-mix(in srgb,var(--c) 18%,transparent),transparent 62%),var(--sf-tint);
  border-color:color-mix(in srgb,var(--c) 42%,transparent);border-left-color:var(--c);
  transform:translateY(-1px);box-shadow:0 6px 18px rgba(0,0,0,.35),0 0 0 1px color-mix(in srgb,var(--c) 14%,transparent)}
.lsrow:hover .lsr-n,.lsrow.hot .lsr-n,.lsrow:focus-visible .lsr-n{color:var(--text)}
.lsrow:hover .lsr-v,.lsrow.hot .lsr-v{text-shadow:0 0 14px color-mix(in srgb,var(--c) 60%,transparent)}
.lsrow:active{transform:translateY(0) scale(.992);transition-duration:.08s}
.lsrow:focus-visible{outline:2px solid var(--alive);outline-offset:1px}
/* the row a record was last opened from stays marked when the reader comes back to the rail */
.lsrow.cur{border-color:color-mix(in srgb,var(--c) 34%,transparent);
  background:linear-gradient(90deg,color-mix(in srgb,var(--c) 14%,transparent),transparent 62%),var(--sf-tint)}
.lsrow.cur .lsr-n{color:var(--text)}
.lsrow.cur{border-left-width:3px;padding-left:9px;
  box-shadow:inset 6px 0 14px -8px var(--c),0 0 0 1px color-mix(in srgb,var(--c) 10%,transparent)}

/* ── the globe's furniture: lit labels glow in their hue, the tip takes it too, the hint is a pill ─ */
.mlabel{transition:opacity .28s ease,border-color .2s ease,background .2s ease,box-shadow .28s ease}
.mlabel.hot .ml-n{color:var(--text)}
.mlabel.on.hot{box-shadow:0 0 0 1px color-mix(in srgb,var(--c) 55%,transparent),
  0 0 22px color-mix(in srgb,var(--c) 30%,transparent),0 1px 14px rgba(0,0,0,.45)}
.mlabel.on.hot .ml-v{box-shadow:0 0 10px color-mix(in srgb,var(--c) 65%,transparent)}
#tip{--c:var(--accent);border-color:color-mix(in srgb,var(--c) 40%,transparent);
  border-left:2px solid var(--c);padding:7px 11px 7px 10px;transform:translateY(3px);
  box-shadow:0 2px 16px rgba(0,0,0,.5),0 0 18px color-mix(in srgb,var(--c) 14%,transparent);
  transition:opacity .15s ease,transform .18s cubic-bezier(.2,.8,.2,1)}
#tip.on{transform:none}
#tip span{color:var(--c);opacity:.95}
#hint{opacity:.72;color:var(--ink-muted);padding:6px 13px;border-radius:var(--r-pill);
  border:1px solid var(--sf-line);background:rgba(4,10,4,.5);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  transition:opacity .4s ease,visibility .4s}
body.detail-open #hint,body.flat #hint{opacity:0;visibility:hidden}
#vig{background:radial-gradient(ellipse at 50% 46%,transparent 30%,rgba(3,9,4,.46) 74%,rgba(2,7,3,.88) 100%)}

/* ── reduced motion: no sweep, no stagger, nothing waits on a delay ─────────────────────────── */
@media (prefers-reduced-motion:reduce){
  #ldfill{animation:none;transform:none;width:42%;margin-left:29%}
  #loader>div::before{animation:none;opacity:.72}
  body.ready #brand,body.ready #gstats>div,body.ready #intro>*,body.ready #summary>.sm-sec,
  body.ready #smList .lsrow,body.ready #hint{animation:none;animation-delay:0s}
  .fnd-b,.fnd-b:not([hidden]),.lsrow,.mlabel,#tip,.fnd::before,.fnd-x{transition-delay:0s}
  .lsrow:hover,.lsrow.hot,.lsrow:focus-visible,.lsrow:active,.fnd-go:hover{transform:none}
}
/* ===== facelift: motion+chrome =====
   The chrome and the small screen: sheets, dock, chat, the text alternative, and the phone layout.
   One easing set and three durations, declared once here and used by everything below. Every rule
   is additive; the two in-place edits this pass made are named in the commit. */
:root{--ease-out:cubic-bezier(.22,.92,.2,1);--ease-in:cubic-bezier(.4,0,.7,.2);
  --ease-inout:cubic-bezier(.65,0,.35,1);--dur-fast:.16s;--dur-base:.28s;--dur-slow:.48s;
  --dock-clear:136px}
@keyframes fl-rise{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes fl-fade{from{opacity:0}to{opacity:1}}

/* ---- sheets: enter with scale+fade under a dim, exit the same way back ------------------------ */
.sheet{transition:transform var(--dur-slow) var(--ease-out),opacity var(--dur-base) ease,
  box-shadow var(--dur-slow) ease}
#data{transform:translateX(-50%) translateY(14px) scale(.975);transform-origin:50% 100%}
#panel.open{box-shadow:0 0 0 100vmax rgba(2,6,4,.58),0 30px 90px rgba(0,0,0,.62)}
.sheet.open .sheet-top{animation:fl-rise var(--dur-base) var(--ease-out) both}
.sheet.open .sheet-body,.sheet.open .data-cols{animation:fl-fade var(--dur-slow) ease both;animation-delay:60ms}

/* the header: kicker with a hairline dash, a serif title, a soft green wash that says "a page" */
.sheet-top{padding:22px 28px 18px;
  background:linear-gradient(180deg,rgba(0,190,90,.07),rgba(0,190,90,0));
  border-bottom:1px solid var(--sf-line)}
.dsh-k,.sheet-top .pk{display:inline-flex;align-items:center;gap:9px}
.dsh-k::before,.sheet-top .pk::before{content:"";width:14px;height:1px;background:var(--accent);opacity:.8}
.sheet-top .pk{font-size:var(--fs-micro);line-height:1;padding:7px 0}
.dsh h2{font-size:clamp(20px,2vw,26px)}
.xbtn{width:32px;height:32px;border-color:var(--sf-edge);color:var(--ink-dim);
  background:rgba(240,240,234,.03);
  transition:transform var(--dur-base) var(--ease-out),border-color var(--dur-fast) ease,
    color var(--dur-fast) ease,background var(--dur-fast) ease}
.xbtn:hover{transform:rotate(90deg);border-color:var(--accent);color:var(--accent);background:rgba(0,190,90,.1)}
.xbtn:active{transform:rotate(90deg) scale(.92)}
.xbtn:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:50%}

/* ---- the Data sheet's contents rail: a spine, a dot per chapter, the current one lit ---------- */
#datanav{position:relative;padding:22px 14px 24px 16px;gap:2px}
/* the spine is drawn per chapter, from each dot to the next, so it ends where the contents end */
#datanav button::after{content:"";position:absolute;left:8px;top:50%;bottom:-50%;width:1px;
  background:var(--sf-line);pointer-events:none}
#datanav button:last-child::after{display:none}
#datanav button{position:relative;display:block;width:100%;text-align:left;
  background:none;border:0;padding:9px 10px 9px 26px;border-radius:var(--r-ctl);
  color:var(--ink-muted);font-family:var(--sans);font-size:var(--fs-base);font-weight:var(--fw-med);
  letter-spacing:var(--ls-nudge);line-height:var(--lh-snug);cursor:pointer;
  transition:color var(--dur-fast) ease,background var(--dur-fast) ease}
#datanav button::before{content:"";position:absolute;left:5px;top:50%;width:7px;height:7px;
  margin-top:-3.5px;border-radius:50%;background:#040A04;border:1px solid var(--sf-edge);
  transition:transform var(--dur-base) var(--ease-out),border-color var(--dur-fast) ease,
    background var(--dur-fast) ease,box-shadow var(--dur-base) ease}
#datanav button:hover{color:var(--text);background:var(--sf-wash)}
#datanav button:hover::before{border-color:var(--ink-soft)}
#datanav button[aria-current="true"]{color:var(--text);background:rgba(0,190,90,.09)}
#datanav button[aria-current="true"]::before{background:var(--accent);border-color:var(--accent);
  transform:scale(1.25);box-shadow:0 0 0 3px rgba(0,190,90,.18),0 0 12px rgba(0,190,90,.45)}
#datanav button:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
@media (max-width:1080px){
  #datanav{padding:10px 14px;gap:6px;scrollbar-width:none}
  #datanav::-webkit-scrollbar{display:none}
  /* the grid stretched its two auto rows to fill the sheet, so on a short chapter the row of
     chapter pills grew to 140px tall; the nav row takes its content height, the body the rest */
  .data-cols{grid-template-rows:auto minmax(0,1fr)}
  #datanav button{width:auto;flex:none;padding:8px 13px;border-radius:var(--r-pill);
    border:1px solid var(--sf-line);white-space:nowrap;font-size:var(--fs-sm);min-height:40px}
  #datanav button::before,#datanav button::after{display:none}
  #datanav button[aria-current="true"]{border-color:rgba(0,190,90,.5)}
}

/* ---- Method: the steps read as one numbered sequence, joined by a spine -------------------- */
.pstep{position:relative;gap:16px;margin-top:18px;padding-bottom:4px}
.pstep::before{content:"";position:absolute;left:13px;top:30px;bottom:-16px;width:1px;
  background:linear-gradient(180deg,rgba(0,190,90,.35),rgba(0,190,90,.08))}
.pstep:last-of-type::before{display:none}
.pstep b{width:27px;height:27px;background:rgba(0,190,90,.1);border-color:rgba(0,190,90,.45);
  box-shadow:0 0 0 4px #060d08;position:relative;z-index:1}
.pstep strong{margin-bottom:4px}
.pbody .pform{border-radius:var(--r-ctl);border-color:rgba(0,190,90,.18);
  background:linear-gradient(180deg,rgba(0,190,90,.06),rgba(0,190,90,.02))}
.pbody h4{display:flex;align-items:center;gap:10px}
.pbody h4::after{content:"";flex:1;height:1px;background:var(--sf-line)}

/* ---- the dock: one bar, every control answering the pointer ------------------------------- */
#dock{transition:opacity .7s ease,bottom var(--dur-base) var(--ease-out);
  background:linear-gradient(180deg,rgba(12,22,14,.8),rgba(7,15,9,.8));
  box-shadow:0 20px 52px rgba(0,0,0,.55),inset 0 1px 0 rgba(240,240,234,.06)}
.dm-btn{transition:color var(--dur-fast) ease,background var(--dur-fast) ease,
  transform var(--dur-fast) var(--ease-out)}
.dm-btn:active{transform:scale(.96)}
.dm-btn svg{transition:opacity var(--dur-fast) ease,transform var(--dur-base) var(--ease-out)}
.dm-btn:hover svg{opacity:1}
.dock-menu.open .dm-btn{color:var(--accent);background:rgba(0,190,90,.12)}
.dm-caret{transition:transform var(--dur-base) var(--ease-out),opacity var(--dur-fast) ease}
.dm-btn:hover .dm-caret{opacity:.9}
#spinBtn[aria-pressed="true"] svg{animation:spin 6s linear infinite}
#viewBtn[aria-pressed="true"]{background:rgba(0,190,90,.14);color:var(--accent)}
#methodBtn:hover{color:var(--accent)}
#dock :focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-pill)}

/* the popovers rise out of the bar, each row a beat behind the last */
.pop,#find{transition:opacity var(--dur-base) ease,transform var(--dur-base) var(--ease-out),
  visibility var(--dur-base);box-shadow:0 24px 60px rgba(0,0,0,.6),inset 0 1px 0 rgba(240,240,234,.05)}
.pop{transform:translateY(10px) scale(.97);min-width:324px}
.dock-menu.open .pop button,#find.on button{animation:fl-rise var(--dur-base) var(--ease-out) both}
.dock-menu.open .pop button:nth-child(2),#find.on button:nth-child(2){animation-delay:25ms}
.dock-menu.open .pop button:nth-child(3),#find.on button:nth-child(3){animation-delay:50ms}
.dock-menu.open .pop button:nth-child(4),#find.on button:nth-child(4){animation-delay:75ms}
.dock-menu.open .pop button:nth-child(5),#find.on button:nth-child(5){animation-delay:100ms}
.dock-menu.open .pop button:nth-child(6),#find.on button:nth-child(6){animation-delay:125ms}
.dock-menu.open .pop button:nth-child(7){animation-delay:150ms}
.dock-menu.open .pop button:nth-child(8){animation-delay:175ms}
#popData button,#find button{transition:background var(--dur-fast) ease,color var(--dur-fast) ease}
#popData button:hover,#popData button:focus-visible,#find button:hover,#find button:focus-visible{color:#fff}
/* the landscape's colour dot, ringed so it reads on the dark; the value as a tabular pill */
#popData button i,#find button i{width:10px;height:10px;
  box-shadow:0 0 0 2px rgba(240,240,234,.07),0 0 10px -2px rgba(240,240,234,.35);
  transition:transform var(--dur-base) var(--ease-out),box-shadow var(--dur-base) ease}
#popData button:hover i,#find button:hover i,#popData button:focus-visible i,#find button:focus-visible i{
  transform:scale(1.25);box-shadow:0 0 0 3px rgba(240,240,234,.12),0 0 14px -1px rgba(240,240,234,.5)}
#popData button em,#find button em{padding:2px 8px;border-radius:var(--r-pill);
  background:var(--sf-tint);color:var(--ink-dim);font-size:var(--fs-xs);font-weight:var(--fw-med);
  transition:background var(--dur-fast) ease,color var(--dur-fast) ease}
#popData button:hover em,#find button:hover em{background:rgba(0,190,90,.16);color:var(--text)}
#popData button[data-all]{margin-bottom:6px;padding-bottom:12px}
#popData button[data-all] em{background:none;color:var(--ink-faint);font-weight:var(--fw-normal)}
#popData button[data-all]:hover{color:var(--text)}

/* the ask field: a brand ring, not the browser's */
#chatq{transition:border-color var(--dur-fast) ease,background var(--dur-fast) ease,
  box-shadow var(--dur-base) ease}
#chatq:focus{border-color:rgba(0,190,90,.6);box-shadow:0 0 0 3px rgba(0,190,90,.16)}
#chatq:focus-visible{outline:none}
#chatsend{transition:background var(--dur-fast) ease,transform var(--dur-fast) var(--ease-out),
  box-shadow var(--dur-base) ease;box-shadow:0 0 0 0 rgba(0,190,90,0)}
#chatsend:hover{transform:scale(1.06);box-shadow:0 0 18px rgba(0,190,90,.35)}
#chatsend:active{transform:scale(.94)}
#chatsend:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:50%}
#chatsend svg{transition:transform var(--dur-base) var(--ease-out)}
#chatsend:hover svg{transform:translateX(1px)}

/* ---- the transcript: rises with the dock's rhythm, each answer arriving in a beat ---------- */
#chat{transition:opacity var(--dur-base) ease,transform var(--dur-slow) var(--ease-out);
  box-shadow:0 26px 70px rgba(0,0,0,.6),inset 0 1px 0 rgba(240,240,234,.05)}
.chat-top{padding:13px 18px 12px;
  background:linear-gradient(180deg,rgba(0,190,90,.06),rgba(0,190,90,0))}
.chat-top .pk{display:inline-flex;align-items:center;gap:9px;color:var(--ink-dim)}
.chat-top .pk::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 8px rgba(0,190,90,.6);flex:none}
#chatlog{padding:16px 18px 18px}
.cq{animation:fl-rise var(--dur-base) var(--ease-out) both;color:var(--ink-dim);opacity:1}
.cq::before{color:var(--accent)}
.ca{animation:fl-rise var(--dur-slow) var(--ease-out) both;border-left-width:2px;padding-left:12px;
  line-height:var(--lh-loose)}

/* ---- the text alternative: hidden by policy, laid out as a page the moment it is not ------- */
body:has(#alt:not(.vh)){overflow:auto;height:auto}
#alt:not(.vh){position:relative;z-index:81;min-height:var(--appvh);background:#040A04;
  padding:calc(24px + var(--sat)) calc(20px + var(--sar)) calc(40px + var(--sab)) calc(20px + var(--sal));
  color:var(--text);font-size:var(--fs-md);line-height:var(--lh-airy)}
/* a px column, not ch: ch scales with each child's own font, so the serif title computed 1511px and
   sat at the left edge while the 13px body got 524px */
#alt:not(.vh) > *{max-width:600px;margin-left:auto;margin-right:auto}
#alt:not(.vh) h2{font-family:var(--serif);font-size:var(--fs-head);font-weight:var(--fw-normal);
  letter-spacing:var(--ls-tight);margin:0 auto 20px}
#alt:not(.vh) article{padding:16px 0 18px;border-top:1px solid var(--sf-line)}
#alt:not(.vh) article h3{font-family:var(--serif);font-size:var(--fs-2xl);font-weight:var(--fw-normal);
  letter-spacing:var(--ls-tight);margin-bottom:8px}
#alt:not(.vh) article p{color:var(--ink-soft);margin-top:6px}
#alt:not(.vh) #vistanav{margin-top:26px;padding-top:18px;border-top:1px solid var(--sf-edge)}
#alt:not(.vh) #vistanav h3{font-size:var(--fs-tiny);font-weight:var(--fw-bold);letter-spacing:var(--ls-caps-x);
  text-transform:uppercase;color:var(--accent);margin-bottom:12px}
#alt:not(.vh) #vistanav ul{list-style:none;display:flex;flex-direction:column;gap:6px}
#alt:not(.vh) #vistanav a{display:block;padding:11px 14px;border:1px solid var(--sf-line);
  border-radius:var(--r-ctl);color:var(--text);text-decoration:none;
  transition:border-color var(--dur-fast) ease,background var(--dur-fast) ease}
#alt:not(.vh) #vistanav a:hover,#alt:not(.vh) #vistanav a:focus-visible{border-color:var(--accent);
  background:rgba(0,190,90,.08)}

/* ---- the phone: sheets end above the dock, nothing sits under it, thumbs get 44px ---------- */
@media (hover:none) and (pointer:coarse){#hint{display:none}}
@media (max-width:760px){
  /* the dock: full-width card with its bottom in the safe area */
  #dock{padding:8px 9px calc(8px + var(--sab));bottom:0;left:0;right:0;border-radius:var(--r-card) var(--r-card) 0 0;
    border-bottom:0;gap:6px 4px}
  #chatq{min-height:44px;font-size:16px}
  #chatsend{width:44px;height:44px}
  #dock .dm-btn,#dock #viewBtn,#dock #methodBtn,#dock #spinBtn{min-height:44px;padding:8px 10px;
    font-size:var(--fs-sm)}
  #dock .dm-btn svg{width:15px;height:15px}
  #dock #spinBtn{min-width:44px;justify-content:center}
  #find,.pop{bottom:calc(100% + 10px)}
  .pop{max-width:calc(100vw - 36px);min-width:min(290px,calc(100vw - 36px))}
  #popData button,#find button{min-height:46px}
  /* a popover can never be taller than the room above the dock; it scrolls instead */
  .pop,#find{max-height:calc(var(--appvh) - var(--dock-clear) - 24px - var(--sab));overflow-y:auto;
    overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--sf-edge) transparent}
  /* the seven-landscape rail, the record, and both sheets stop above the dock, with a gap */
  #summary{bottom:calc(var(--dock-clear) + var(--sab))}
  #detail{bottom:calc(var(--dock-clear) - 12px + var(--sab));
    max-height:calc(var(--appvh) - 120px - var(--dock-clear) - var(--sab));
    border-radius:var(--r-card) var(--r-card) 0 0;border-bottom:1px solid var(--line);
    transition:opacity var(--dur-base) ease,transform var(--dur-slow) var(--ease-out)}
  #detail .dt-body.sfade{padding-bottom:0}
  #detail .dt-body.sfade > :last-child{margin-bottom:24px}
  #data,#panel{left:0;right:0;width:auto;top:calc(56px + var(--sat));bottom:calc(var(--dock-clear) - 12px + var(--sab));
    height:auto;border-radius:var(--r-card) var(--r-card) 0 0;border:1px solid var(--line);border-bottom:0;
    transform:translateY(28px);transform-origin:50% 100%}
  #data.open{box-shadow:0 0 0 100vmax rgba(2,6,4,.7),0 -20px 60px rgba(0,0,0,.5)}
  #panel.open{box-shadow:0 0 0 100vmax rgba(2,6,4,.7),0 -20px 60px rgba(0,0,0,.5)}
  /* a handle on every bottom sheet: the affordance a thumb expects */
  #detail::before,#data::before,#panel::before{content:"";flex:none;width:36px;height:4px;margin:8px auto -4px;
    border-radius:2px;background:var(--sf-edge)}
  .sheet-top{padding:14px 18px 14px 18px}
  .dsh h2{font-size:var(--fs-xl)}
  .pbody{padding:18px 18px 40px}
  #chat{left:0;right:0;width:auto;transform:none;bottom:calc(var(--dock-clear) - 4px + var(--sab));
    max-height:min(52vh,calc(var(--appvh) - 190px));border-radius:var(--r-card) var(--r-card) 0 0}
  #chat.open{transform:none}
}
@media (max-width:430px){
  #dock .dm-btn,#dock #viewBtn,#dock #methodBtn{padding:8px 8px}
  .sheet-top{padding:12px 16px}
  #databody{padding:18px 14px 40px}
}
/* a phone held sideways: the dock keeps one row so the globe keeps the middle */
@media (max-width:760px) and (max-height:480px){
  #dock{flex-wrap:nowrap;padding:6px 8px calc(6px + var(--sab))}
  #chatform{order:0;flex:1 1 auto;width:auto}
  #chatq{min-height:40px;font-size:16px;padding:8px 13px}
  #chatsend{width:40px;height:40px}
  #dock .dm-btn,#dock #viewBtn,#dock #methodBtn,#dock #spinBtn{min-height:40px;padding:6px 9px}
  .pop,#find{max-height:calc(var(--appvh) - 72px - var(--sab))}
  #popData button,#find button{min-height:38px;padding-top:6px;padding-bottom:6px}
  #summary{bottom:calc(66px + var(--sab));max-height:calc(var(--appvh) - 144px)}
  #detail,#data,#panel{bottom:calc(60px + var(--sab));top:auto}
  #detail{max-height:calc(var(--appvh) - 118px)}
  #data,#panel{top:calc(8px + var(--sat))}
  #chat{bottom:calc(66px + var(--sab))}
}

/* ---- motion off when asked: every duration this block declared collapses to nothing -------- */
@media (prefers-reduced-motion:reduce){
  :root{--dur-fast:0s;--dur-base:0s;--dur-slow:0s}
  .sheet.open .sheet-top,.sheet.open .sheet-body,.sheet.open .data-cols,.dock-menu.open .pop button,
  #find.on button,.cq,.ca{animation:none}
  #spinBtn[aria-pressed="true"] svg{animation:none}
  .xbtn:hover,.xbtn:active,.dm-btn:active,#chatsend:hover,#chatsend:active,#chatsend:hover svg,
  #popData button:hover i,#find button:hover i,#datanav button[aria-current="true"]::before{transform:none}
}

/* ── THE LANDSCAPES: A LIST, NOT A STACK OF CARDS (Alex, 2026-09-30) ─────────────────────────────
   The rail read as seven boxed tiles, each with a border, a radius, a gradient and a lift on hover —
   the generic card. It is a ranked-looking list of places, so it is set as one: hairline rules
   between rows, the landscape's hue as a small mark beside its name, the name in the serif, the
   index figure right-aligned in its hue. Hover and the current row are said in type and rule,
   not in a box that rises. */
#smList{gap:0;border-top:1px solid var(--sf-line)}
.lsrow{border:0;border-bottom:1px solid var(--sf-line);border-radius:0;background:none;box-shadow:none;
  padding:10px 4px 10px 18px;transform:none}
.lsrow::before{content:"";position:absolute;left:4px;top:15px;width:6px;height:6px;border-radius:50%;
  background:var(--c)}
.lsr-n{font-family:var(--serif);font-size:var(--fs-md);font-weight:var(--fw-normal);letter-spacing:var(--ls-tight)}
.lsr-v{font-family:var(--serif);font-weight:var(--fw-normal)}
.lsrow:hover,.lsrow.hot,.lsrow:focus-visible{background:none;border-color:var(--sf-line);
  border-bottom-color:color-mix(in srgb,var(--c) 55%,transparent);transform:none;box-shadow:none}
.lsrow:hover .lsr-v,.lsrow.hot .lsr-v{text-shadow:none}
.lsrow:active{transform:none}
.lsrow.cur{border-left-width:0;padding-left:18px;background:none;box-shadow:none;
  border-color:var(--sf-line);border-bottom-color:var(--c)}
.lsrow.cur::before{box-shadow:0 0 0 3px color-mix(in srgb,var(--c) 30%,transparent)}

/* ── THE FIGURES, OPEN ON THE PAGE, NOT IN A GRID OF BOXES (Alex, 2026-09-30) ─────────────────────
   "Same way": the seven-at-a-glance tiles and each place's figure grid lose the boxed cells (outer
   border, radius, cell fills, 1px grid lines). Each figure stands on a hairline rule, the number in
   the serif, its label in small caps below — the way the landscapes list below it now reads. */
.sm-fig{background:none;border:0;border-radius:0;overflow:visible;gap:14px 20px}
.sm-fig div,#place .sm-fig div,#dtPlace .sm-fig div{background:none;padding:9px 0 0;border-top:1px solid var(--sf-line);position:relative}
#summary .sm-fig div::before{left:0;top:-1px;width:28px;height:1px;border-radius:0;background:var(--accent)}
.sm-fig b,#summary .sm-fig b,#place .sm-fig b,#dtPlace .sm-fig b{font-family:var(--serif);font-weight:var(--fw-normal);
  letter-spacing:var(--ls-tight)}
