@font-face{font-family:'TreeSapMono';src:url('font/TreeSapMonoRegular.ttf') format('truetype');font-weight:700}

/* ─── BASE ─────────────────────────────────────────────── */
*,*::before,*::after{
 margin:0;padding:0;box-sizing:border-box;
 font-family:'TreeSapMono',monospace;
 font-size:13px;
 font-weight:700;
 font-style:normal;
 line-height:1.65;
 letter-spacing:0;
 text-transform:none;
 color:rgba(255,192,44,0.70);
}

/* ─── VARIABLES ─────────────────────────────────────── */
:root{
 --yellow: #FFC02C;
 --red: #B60C0C;
 --green: #4B9B2B;
 --blue: #1E40AF;

 /* legacy aliases used in JS/inline */
 --amber: #FFC02C;
 --orange: #B60C0C;
 --cyan: #4B9B2B;
 --gold: #FFC02C;

 --bg: #000;
 --panel: #0C0C0C;

 --text: rgba(255,192,44,0.70);
 --text-hi:#FFC02C;
 --dim: rgba(255,192,44,0.38);
 --border: rgba(255,192,44,0.14);
}

html,body{
 width:100%;height:100%;
 background:var(--bg);
 overflow:hidden;
 -webkit-font-smoothing:antialiased;
}

/* ─── LANGUAGE TOGGLE ──────────────────────────────────── */
#lang-toggle{
 display:flex;gap:6px;align-items:center;justify-content:flex-end;
 pointer-events:auto;
}
.lang-btn{
 width:32px;height:22px;cursor:pointer;
 border:2px solid transparent;
 border-radius:2px;
 opacity:0.45;
 transition:opacity 0.15s,border-color 0.15s,transform 0.1s;
 padding:0;background:none;
 overflow:hidden;display:flex;align-items:center;justify-content:center;
}
.lang-btn svg{width:100%;height:100%;display:block}
.lang-btn:hover{opacity:0.85;transform:scale(1.08)}
.lang-btn.active{opacity:1;border-color:#FFC02C;}
/* ─── SÁMI LANGUAGE POPDOWN ──────────────────────────
   Sits to the LEFT of the Sámi flag button, growing
   upward from its bottom edge. Anchored to the
   #sami-lang-wrap container so it positions next to the
   flag rather than the document. Hidden by default; the
   toggleSamiLangPopdown() helper flips the .show class. */
#sami-lang-wrap{position:relative;display:inline-flex}
#sami-lang-popdown{
 display:none;
 position:absolute;bottom:0;right:calc(100% + 6px);
 background:rgba(8,8,8,0.96);border:1px solid #FFC02C;
 padding:4px;z-index:100;min-width:120px;
 box-shadow:0 6px 14px rgba(0,0,0,0.55);
 font-family:'TreeSapMono',monospace;
}
#sami-lang-popdown.show{display:flex;flex-direction:column-reverse;gap:2px}
#sami-lang-popdown button{
 background:none;border:0;color:#FFC02C;cursor:pointer;
 padding:7px 10px;text-align:left;
 font:inherit;font-size:11px;letter-spacing:0.04em;
 display:flex;flex-direction:column;gap:1px;
}
#sami-lang-popdown button:hover{background:rgba(255,192,44,0.12)}
#sami-lang-popdown .lang-name{font-weight:bold}
#sami-lang-popdown .lang-sub{
 font-size:9px;opacity:0.62;letter-spacing:0.06em;
}
/* Tiny pointer arrow on the right edge of the popdown so it
   visually "hangs" off the flag button to its right. */
#sami-lang-popdown::before{
 content:'';position:absolute;right:-6px;bottom:10px;
 width:0;height:0;
 border-top:6px solid transparent;border-bottom:6px solid transparent;
 border-left:6px solid #FFC02C;
}
::selection{background:#FFC02C;color:#000}

/* ─── LAYOUT ─────────────────────────────────────── */
#app{display:flex;width:100vw;height:100vh;position:relative}
.panel{height:100%;background:var(--panel);display:flex;flex-direction:column;position:relative;overflow:hidden;flex-shrink:0}
#left-panel{width:240px;border-right:1px solid var(--border);display:none}
#right-panel{width:340px;border-left:1px solid var(--border)}

/* ─── PANEL HEADER ─────────────────────────────────── */
.ph{color:var(--text-hi);padding:16px 20px;border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center;flex-shrink:0}
#panel-collapse-btn{
 background:transparent;border:1px solid var(--border);color:#FFC02C;
 font-family:'TreeSapMono',monospace;font-size:14px;
 width:28px;height:28px;cursor:pointer;
 display:flex;align-items:center;justify-content:center;
 transition:background 0.15s, transform 0.25s;
 padding:0;line-height:1;
}
#panel-collapse-btn:hover{background:rgba(255,192,44,0.15)}
#app.right-collapsed #panel-collapse-btn{transform:rotate(180deg)}

/* ─── CENTER VIEWPORT ───────────────────────────────── */
#vp{flex:1;position:relative;overflow:hidden;background:#000;min-width:0}
.crn{display:none}

#hud-top{
 position:absolute;top:0;left:0;right:0;
 display:flex;align-items:center;
 padding:8px 24px;pointer-events:none;z-index:20;
 border-bottom:1px solid var(--border);
 background:rgba(0,0,0,0.80);
}
.ht{color:var(--text-hi)}
.hs{color:var(--green)}

/* ─── MODE TOGGLE ───────────────────────────────────── */
#mode-toggle{display:flex;gap:0;border-bottom:1px solid var(--border);flex-shrink:0}
.mode-btn{
 flex:1;background:transparent;border:none;
 border-left:1px solid var(--border);
 color:var(--dim);padding:12px 20px;cursor:pointer;
 transition:color 0.12s,background 0.12s;
}
.mode-btn:first-child{border-left:none}
.mode-btn:hover{color:var(--text-hi)}
.mode-btn.active{color:#000;background:#FFC02C}

/* ─── SCALE / FRAME ─────────────────────────────────── */
#scale-ind{position:absolute;bottom:20px;left:24px;z-index:20;pointer-events:none;color:var(--dim)}
.scale-bar{width:56px;height:1px;background:rgba(255,192,44,0.40);margin-top:6px;position:relative}
.scale-bar::before,.scale-bar::after{content:'';position:absolute;top:-3px;width:1px;height:7px;background:rgba(255,192,44,0.40)}
.scale-bar::before{left:0}.scale-bar::after{right:0}
#frame-ind{position:absolute;bottom:20px;right:24px;z-index:20;pointer-events:none;color:var(--dim)}
#coords{position:absolute;top:50px;left:24px;color:var(--green);pointer-events:none;z-index:20;line-height:1.8}

/* ─── MAP STAGE ─────────────────────────────────────── */
#map-stage{position:absolute;inset:46px 0 0 0;display:flex;align-items:center;justify-content:center;z-index:5}
#map-2d{position:relative;width:96%;max-width:1400px;aspect-ratio:1700/760;display:block;will-change:transform}
#map-2d.hidden{display:none}
.layer-svg-wrap{position:absolute;inset:0;pointer-events:none}
.layer-svg-wrap svg,.layer-svg-wrap img{width:100%;height:100%;display:block}
.layer-svg-wrap.eo img{position:absolute;left:0;top:0;width:100%;height:100%;mix-blend-mode:normal}
.layer-svg-wrap.eo.tinted img{filter:contrast(1.05) saturate(1.15)}
.layer-svg-wrap.eo.tinted-warm img{filter:hue-rotate(-12deg) saturate(1.2) contrast(1.05)}

/* ─── GEOSPATIAL BASEMAP (MAPLIBRE GL) ──────────────────
 Sits BEHIND the hand-drawn strata. Off by default
 (--geo-opacity:0); the GEO button fades it in as a real
 coordinate ground truth and renders the Ran sameby
 polygon in its native lat/lng. Strata remain on top so
 the atlas's hand-drawn character is preserved. */
#geo-basemap{
 /* MapLibre fills the ENTIRE viewport area (from the top HUD bar
 down to the bottom). It used to be cropped to the SVG strata's
 1700:760 rectangle inside #map-2d, which is why zooming felt
 "weirdly cropped". Now it's a sibling of #map-2d, sized to the
 whole #map-stage. The SVG strata still draw on top in their
 own centred rectangle. */
 position:absolute;inset:0;
 z-index:0;
 opacity:1;
 background:#000;
}
/* #map-2d stays positioned over the basemap; pointer-events:none
 so the user's drag/scroll lands on MapLibre, not the strata DIV. */
#map-stage > #map-2d{pointer-events:none;z-index:2}
#map-stage > #map-2d .layer-svg-wrap{pointer-events:none}
#geo-basemap .maplibregl-canvas{filter:saturate(0.85) brightness(0.92)}
#geo-basemap .maplibregl-ctrl-attrib{
 background:rgba(0,0,0,0.65);color:rgba(255,192,44,0.6);
 font-size:9px;font-family:'TreeSapMono',monospace;
}
#geo-basemap .maplibregl-ctrl-attrib a{color:rgba(255,192,44,0.85)}
/* Position the geo controls relative to #vp (the center viewport,
   not the whole screen) so they don't overlap the right-panel on
   desktop and automatically reposition when the panel collapses. */
/* TIDSSTYRD button lives at the BOTTOM next to where the time
 slider appears, since that's what it actually controls. */
#geo-toggle{
 position:absolute;bottom:14px;left:50%;transform:translateX(-50%);
 z-index:55;
 background:rgba(0,0,0,0.85);border:1px solid #FFC02C;
 color:#FFC02C;padding:6px 12px;cursor:pointer;
 font-family:'TreeSapMono',monospace;font-size:10px;font-weight:bold;
 letter-spacing:0.08em;
}
#geo-toggle:hover{background:rgba(255,192,44,0.15)}
#geo-toggle.on{background:#FFC02C;color:#000}
/* Ran (mask) + NAMN (labels) toggles live in the top HUD bar's
   right corner, sitting on the same line as the language flags so
   the whole top edge reads as one row of pill-buttons. Height + box
   styling match .lang-btn (22px tall) so they visually belong with
   the flags; width is auto to accommodate the text label. */
#hud-top-right{
 margin-left:auto;
 display:flex;gap:6px;align-items:center;
 pointer-events:auto;
}
#mask-toggle,#labels-toggle,#videos-toggle,#bg-toggle,#notes-toggle,#key-toggle{
 height:22px;padding:0 8px;cursor:pointer;
 background:rgba(0,0,0,0.85);border:2px solid transparent;
 border-radius:2px;
 color:#FFC02C;
 font-family:'TreeSapMono',monospace;font-size:10px;font-weight:bold;
 letter-spacing:0.06em;line-height:1;
 display:inline-flex;align-items:center;justify-content:center;
 transition:opacity 0.15s,border-color 0.15s,transform 0.1s,background 0.15s;
 opacity:0.85;
}
#mask-toggle:hover,#labels-toggle:hover,#videos-toggle:hover,
#bg-toggle:hover,#notes-toggle:hover,#key-toggle:hover{opacity:1;transform:scale(1.05)}
#mask-toggle.on,#labels-toggle.on,#videos-toggle.on,
#bg-toggle.on,#notes-toggle.on,#key-toggle.on{
 opacity:1;border-color:#FFC02C;background:#FFC02C;color:#000;
}
/* The "?" key button is a square so it reads as help, not a toggle. */
#key-toggle{width:22px;padding:0;border-radius:50%}

/* Videos toggle hides the entire star-marker stack — plus marks,
   connector lines, and the expanded video panels — in one swoop. */
body.star-markers-hidden #star-layer,
body.star-markers-hidden #star-lines-svg{
 display:none;
}
/* Hidden by request — the RAN SAMEBY ≈ km² / vertices / lat-lon box
 cluttered the corner. The data is still available via the layer
 panel's chevron-expanded details. */
#geo-info{display:none !important}
#geo-toggle.on ~ #geo-info{display:none !important}

/* ─── DATA OVERLAY PANEL ────────────────────────────────
 Floats over the viewport (not constrained to #map-2d) so
 it remains readable even on tiny mobile preview frames.
 The panel is scrollable internally with a sticky header
 + a collapse button so it can be tucked away. */
#geo-overlay-panel{
 position:absolute;top:62px;left:8px;z-index:60;
 background:rgba(0,0,0,0.95);border:1px solid var(--border);
 color:var(--text);font-size:11px;line-height:1.5;
 width:min(260px, calc(100% - 16px));
 max-height:calc(100% - 80px);
 display:none;flex-direction:column;
}
#geo-toggle.on ~ #geo-overlay-panel{display:flex}
#geo-overlay-panel.collapsed{
 max-height:42px;overflow:hidden;
}
#geo-overlay-panel .panel-head{
 display:flex;align-items:center;justify-content:space-between;
 padding:10px 12px;border-bottom:1px solid var(--border);
 background:rgba(255,192,44,0.06);cursor:pointer;flex-shrink:0;
 user-select:none;-webkit-user-select:none;
}
#geo-overlay-panel .panel-head h4{
 color:#FFC02C;font-size:11px;margin:0;
 letter-spacing:0.06em;font-weight:bold;
}
#geo-overlay-panel .panel-head .collapse-icon{
 color:#FFC02C;font-size:14px;transition:transform 0.2s;
}
#geo-overlay-panel.collapsed .panel-head .collapse-icon{
 transform:rotate(-90deg);
}
#geo-overlay-list{
 padding:8px 12px 14px;
 overflow-y:auto;-webkit-overflow-scrolling:touch;
 flex:1;
}
#geo-overlay-panel .grp{margin-top:10px}
#geo-overlay-panel .grp:first-child{margin-top:2px}
#geo-overlay-panel .grp-h{
 color:#FFC02C;font-size:9px;margin-bottom:5px;
 letter-spacing:0.08em;opacity:0.7;font-weight:bold;
}
#geo-overlay-panel label{
 display:flex;align-items:flex-start;gap:8px;cursor:pointer;
 padding:4px 0;color:var(--text);transition:color 0.1s;
}
#geo-overlay-panel label:hover{color:var(--text-hi)}
#geo-overlay-panel input[type="checkbox"]{
 appearance:none;-webkit-appearance:none;
 width:14px;height:14px;border:1.5px solid var(--border);
 background:transparent;cursor:pointer;flex-shrink:0;margin-top:1px;
 position:relative;border-radius:2px;
}
#geo-overlay-panel input[type="checkbox"]:checked{
 background:#FFC02C;border-color:#FFC02C;
}
#geo-overlay-panel input[type="checkbox"]:checked::after{
 content:'✓';position:absolute;color:#000;font-size:11px;font-weight:bold;
 line-height:11px;left:1px;top:0;
}
.lbl-txt{flex:1;font-size:11px}
.lbl-sub{color:var(--dim);font-size:9px;display:block;line-height:1.4;margin-top:1px}
.lbl-loading{color:var(--green);font-size:10px;margin-left:4px}
.lbl-error{color:var(--red);font-size:10px;margin-left:4px}

/* ─── TIME SLIDER ───────────────────────────────────────
 Pinned to viewport bottom while GEO is on. Drives Hansen
 forest-loss year filtering, the TIME parameter of GIBS
 time-versioned layers, and the lynx chart marker. */
#geo-time-bar{
 position:absolute;bottom:54px;left:8px;right:8px;z-index:55;
 max-width:760px;margin:0 auto;
 background:rgba(0,0,0,0.92);border:1px solid #FFC02C;
 color:var(--text);padding:8px 14px;display:none;
 grid-template-columns:auto auto 1fr auto;gap:12px;align-items:center;
}
#geo-toggle.on ~ #geo-time-bar{display:grid}
#geo-time-play{
 width:34px;height:34px;flex-shrink:0;
 background:rgba(255,192,44,0.08);border:1px solid #FFC02C;color:#FFC02C;
 font-size:13px;line-height:1;cursor:pointer;padding:0;
 display:flex;align-items:center;justify-content:center;
 font-family:'TreeSapMono',monospace;transition:background .15s,color .15s;
}
#geo-time-play:hover{background:rgba(255,192,44,0.2)}
#geo-time-play.playing{background:#FFC02C;color:#000}
#geo-time-year{
 color:var(--text-hi);font-size:22px;line-height:1;
 min-width:70px;letter-spacing:0.04em;
}
#geo-time-year .geo-yr-sub{
 display:block;color:var(--dim);font-size:9px;line-height:1.4;
 letter-spacing:0.06em;margin-top:2px;
}
#geo-time-year.ft-mode{
 min-width:120px; /* dates need more room than 4-digit years */
}
#geo-time-year .ft-date{
 font-size:15px;color:#ff7a3c;letter-spacing:0.05em;
 font-variant-numeric:tabular-nums;line-height:1;display:block;
}
#geo-time-year.ft-mode .geo-yr-sub{color:#ff7a3c;opacity:0.75}
#geo-time-slider{
 -webkit-appearance:none;appearance:none;
 width:100%;height:2px;background:var(--border);outline:none;
 cursor:pointer;margin:0;
}
#geo-time-slider::-webkit-slider-thumb{
 -webkit-appearance:none;appearance:none;
 width:14px;height:14px;background:#FFC02C;cursor:pointer;
 border:0;border-radius:0;
}
#geo-time-slider::-moz-range-thumb{
 width:14px;height:14px;background:#FFC02C;cursor:pointer;
 border:0;border-radius:0;
}
#geo-time-marks{
 font-size:9px;color:var(--dim);display:flex;justify-content:space-between;
 margin-top:4px;letter-spacing:0.06em;
}
#geo-time-meta{color:var(--dim);font-size:9px;text-align:right;min-width:70px}

/* ─── LYNX CHART PANEL ──────────────────────────────────
 Floats above the time bar when "Lodjur" is toggled. Pinned
 to viewport so it's accessible at any map size. */
#lynx-chart-panel{
 position:absolute;bottom:80px;left:8px;z-index:54;
 background:rgba(0,0,0,0.95);border:1px solid #FFC02C;
 color:var(--text);padding:10px 14px;
 width:min(380px, calc(100% - 16px));display:none;
 font-family:'TreeSapMono',monospace;
}
#geo-toggle.on ~ #lynx-chart-panel.visible{display:block}
#lynx-chart-panel h4{
 color:#FFC02C;font-size:11px;margin-bottom:4px;
 letter-spacing:0.05em;
}
#lynx-chart-panel .sub{
 color:var(--dim);font-size:9px;margin-bottom:8px;line-height:1.5;
}
#lynx-chart-svg{display:block;width:100%;height:140px;margin-bottom:6px}
#lynx-chart-legend{
 display:flex;gap:14px;font-size:9px;color:var(--text);
 padding-top:6px;border-top:1px solid var(--border);
}
#lynx-chart-legend .sw{display:inline-block;width:10px;height:2px;margin-right:5px;vertical-align:middle}
#lynx-chart-readout{
 margin-top:4px;font-size:10px;color:var(--text-hi);line-height:1.4;
}
#lynx-chart-readout .num{color:#FFC02C}
#lynx-chart-source{
 margin-top:6px;font-size:8px;color:var(--dim);line-height:1.4;
}

#eo-attrib{
 position:absolute;bottom:48px;right:24px;z-index:20;pointer-events:none;
 color:var(--dim);background:rgba(0,0,0,0.85);padding:6px 10px;
 border:1px solid var(--border);max-width:40%;line-height:1.5;text-align:right;display:none;
}
#eo-attrib.show{display:block}

#map-3d{position:absolute;inset:0;display:none;z-index:5}
#map-3d.active{display:block}
#map-3d canvas{display:block;width:100%;height:100%}

/* ─── LOADING SCREEN ────────────────────────────────── */
#loading{
 position:absolute;inset:0;display:flex;flex-direction:column;
 align-items:center;justify-content:center;
 background:#000;z-index:200;gap:20px;transition:opacity 0.8s;
}
.ld-title{
 color:var(--text-hi);
 font-size:14px;letter-spacing:0.10em;
 min-height:1.2em;text-align:center;font-weight:normal;
 transition:opacity 0.4s ease;
}
.ld-title.swap{opacity:0}

/* Circular progress ring */
.ld-ring{width:80px;height:80px;position:relative}
.ld-ring svg{width:80px;height:80px;display:block}

/* hidden log kept for JS but not visible */
#ld-list{display:none}

/* Intro GIF — hidden until the ring finishes; revealed once, plays once,
   then the whole loading screen fades out. */
#ld-intro-gif{
 display:none;
 width:240px;height:240px;object-fit:contain;
 opacity:0;transition:opacity 0.4s ease;
}
#ld-intro-gif.show{display:block;opacity:1}
#loading.intro-gif-mode .ld-ring,
#loading.intro-gif-mode .ld-title{display:none}

/* Onne logo at the left of the top HUD, with breathing room before flags. */
#onne-logo{
 height:42px;width:auto;display:block;
 margin-right:28px;pointer-events:auto;
 image-rendering:auto;
}

/* ─── RIGHT-PANEL INTRO SLIDE-IN ──────────────────────
   At boot the right panel is collapsed to zero width AND translated
   off-screen, so #vp expands to fill the whole viewport and the
   loader sits in the true centre of the page. When JS removes
   .intro-hidden (and adds .intro-show), width animates back to its
   media-query default in parallel with the transform — the growing
   panel visually pushes the loader to its final off-centre position
   just as the loader fades away. Scoped to desktop so it doesn't
   fight the tablet/phone drawer rules below (≤1024). */
@media(min-width:1025px){
 #right-panel.intro-hidden,
 #right-panel.intro-show{
 transition:width 0.8s cubic-bezier(0.22,0.61,0.36,1),
 transform 0.8s cubic-bezier(0.22,0.61,0.36,1);
 }
 #right-panel.intro-hidden{
 width:0;
 border-left-width:0;
 overflow:hidden;
 transform:translateX(100%);
 }
}

/* ─── REVEAL CURTAIN ────────────────────────────────── */
#reveal-curtain{
 position:absolute;top:0;left:0;right:0;display:none;z-index:90;
 background:rgba(0,0,0,0.97);border-bottom:1px solid var(--border);
 flex-direction:row;align-items:center;gap:20px;padding:12px 24px;
}
#reveal-curtain.show{display:flex}
.rc-eyebrow{color:var(--red);flex-shrink:0}
.rc-percent{color:var(--text-hi);flex-shrink:0;border-left:1px solid var(--border);padding-left:20px}
.rc-label{color:#FFC02C;flex-shrink:0;border-left:1px solid var(--border);padding-left:20px}
.rc-body{color:rgba(255,192,44,0.62);flex:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.rc-body em{color:#FFC02C}
.rc-close{
 flex-shrink:0;margin-left:auto;background:none;border:1px solid var(--border);
 color:var(--dim);padding:8px 16px;cursor:pointer;
 transition:background 0.12s,color 0.12s;
}
.rc-close:hover{background:#FFC02C;color:#000;border-color:#FFC02C}

/* genomgång button*/
/* Default state (remove red background from here) */
#btn-reveal {
  /* your default styles */
}

/* Active state (add red background here) */
#btn-reveal.active {
  background-color: red;
  color: black;
}



/* ─── RIGHT PANEL CONTROLS ──────────────────────────── */
#right-controls{display:flex;gap:0;border-bottom:1px solid var(--border);flex-shrink:0}
#right-controls .mode-btn{color:var(--red);border-color:rgba(182,12,12,0.35)}
#right-controls .mode-btn:hover{color:#ff2222;border-color:var(--red);background:rgba(182,12,12,0.08)}
#right-controls .mode-btn.active{color:#000;background:var(--red);border-color:var(--red)}
.btn{
 flex:1;background:transparent;border:1px solid var(--border);
 color:var(--dim);padding:10px;cursor:pointer;
 transition:color 0.12s,background 0.12s,border-color 0.12s;white-space:nowrap;
}
.btn:hover{color:var(--text-hi);border-color:#FFC02C}
.btn.primary{color:#000;background:#FFC02C;border-color:#FFC02C}
.btn.primary:hover{background:var(--text-hi);border-color:var(--text-hi)}

/* ─── LAYER LIST ─────────────────────────────────────── */
#layer-list{flex:1;overflow-y:auto;overflow-x:hidden;padding:0}
#layer-list::-webkit-scrollbar{width:2px}
#layer-list::-webkit-scrollbar-thumb{background:var(--border)}

.lr{
 padding:12px 20px;border-bottom:1px solid var(--border);
 cursor:pointer;position:relative;transition:background 0.1s;
}
.lr:hover{background:rgba(255,192,44,0.04)}
.lr.active{background:rgba(255,192,44,0.07)}
.lr.active::before{content:'';position:absolute;left:0;top:0;bottom:0;width:2px;background:currentColor}
.lr.disabled{opacity:0.28;cursor:not-allowed}
.lr .lr-head{display:flex;align-items:center;gap:10px}
.lr .lr-num{color:var(--dim);width:20px;flex-shrink:0}
.lr .lr-dot{width:8px;height:8px;border:1px solid currentColor;flex-shrink:0;transition:background 0.12s}
.lr.active .lr-dot{background:currentColor}
.lr .lr-name{flex:1;line-height:1.3}
.lr .lr-badge{padding:2px 8px;border:1px solid currentColor;flex-shrink:0}
.lr.locked .lr-badge{color:var(--green);border-color:var(--green)}
.lr .lr-desc{color:rgba(255,192,44,0.42);margin:8px 0 6px 30px;font-size:10px;line-height:1.5}
.lr .lr-meta{display:flex;gap:16px;margin-left:30px;color:var(--dim)}
.lr.active .lr-meta{color:rgba(255,192,44,0.55)}

/* Details collapsed by default; click the chevron to expand. Keeps
 the panel clean — the small "NASA GIBS MODIS tidsstyrd" style
 context hides until the user wants it. */
.lr .lr-desc, .lr .lr-meta{display:none}
.lr.expanded .lr-desc{display:block}
.lr.expanded .lr-meta{display:flex}
.lr .lr-expand{
 cursor:pointer;padding:2px 6px;color:var(--dim);
 font-size:10px;line-height:1;transition:transform 0.15s,color 0.15s;
 flex-shrink:0;user-select:none;
}
.lr .lr-expand:hover{color:currentColor}
.lr.expanded .lr-expand{transform:rotate(180deg);color:currentColor}

/* Kind color coding */
.lr.kind-ally{color:var(--green)}
.lr.kind-base{color:rgba(255,192,44,0.42)}
.lr.kind-encroach{color:var(--red)}
.lr.kind-eo{color:rgba(255,192,44,0.55)}
/* Overlay-registry categories: harm = red, good = green, neutral = yellow */
.lr.kind-harm{color:var(--red)}
.lr.kind-good{color:var(--green)}
.lr.kind-neutral{color:rgba(255,192,44,0.7)}

/* Group headers tinted to match the bucket below them. */
.lr-group.lr-group-harm{color:var(--red);border-bottom-color:var(--red)}
.lr-group.lr-group-good{color:var(--green);border-bottom-color:var(--green)}
.lr-group.lr-group-neutral{color:rgba(255,192,44,0.85)}

/* ── LOADING-BAR INVERT EFFECT ────────────────────────────────
 On click, a pseudo-element grows across the row in the row's
 accent colour (red for harm, green for good, yellow for
 neutral). The growth is INDETERMINATE: it eases toward ~92%
 over ~6s, holding short of completion until MapLibre signals
 the data source has actually loaded — at which point JS
 swaps .loading → .active and the row snaps to a flat 100%
 invert. The text uses mix-blend-mode:difference so it reads
 black wherever the same-colour fill has reached.
 The bar's colour is explicit per category (red/green/yellow)
 instead of currentColor so it always matches the harm/good
 signal even if a parent style overrides currentColor. */
.lr{overflow:hidden}
.lr .lr-fill{
 position:absolute;left:0;top:0;bottom:0;width:0;
 pointer-events:none;z-index:0;
}
.lr.kind-harm .lr-fill,
.lr.kind-encroach .lr-fill{ background:var(--red) }
.lr.kind-good .lr-fill,
.lr.kind-ally .lr-fill{ background:var(--green) }
.lr.kind-neutral .lr-fill,
.lr.kind-base .lr-fill,
.lr.kind-eo .lr-fill,
.lr.kind-ref .lr-fill{ background:#FFC02C }

.lr.loading .lr-fill{
 animation: lrFillIn 6s cubic-bezier(0.15,0.7,0.3,0.95) forwards;
}
.lr.loading .lr-head,
.lr.loading .lr-desc,
.lr.loading .lr-meta{
 position:relative;z-index:1;mix-blend-mode:difference;
}
@keyframes lrFillIn{
 0% { width:0 }
 100% { width:92% } /* asymptote — never reach 100% while waiting */
}

/* Progressive overlays drive the fill width by real chunk progress.
 Override the CSS animation so the inline width set via the
 --lr-prog custom property is what actually renders. */
.lr.loading.progressive .lr-fill{
 animation: none !important;
 width: var(--lr-prog, 0%) !important;
 transition: width 0.4s ease;
}

/* Once the row is active, drop the dynamic fill and paint the
 entire row in its accent so every child reads as black. */
.lr.active.kind-harm,
.lr.active.kind-encroach{ background:var(--red) }
.lr.active.kind-good,
.lr.active.kind-ally{ background:var(--green) }
.lr.active.kind-neutral,
.lr.active.kind-base,
.lr.active.kind-eo,
.lr.active.kind-ref{ background:#FFC02C }

.lr.active,
.lr.active .lr-head,
.lr.active .lr-desc,
.lr.active .lr-meta,
.lr.active .lr-num,
.lr.active .lr-name,
.lr.active .lr-badge,
.lr.active .lr-expand,
.lr.active .lr-meta strong,
.lr.active .lm-impact,
.lr.active .lm-status,
.lr.active .lbl-sub,
.lr.active .lbl-loading,
.lr.active .lbl-error{
 color:#000 !important;
}
.lr.active .lr-head,
.lr.active .lr-desc,
.lr.active .lr-meta{ position:relative;z-index:1 }
.lr.active .lr-dot{ background:#000;border-color:#000 }
.lr.active .lr-badge{ border-color:#000 }
.lr.active::before{ display:none } /* hide the side-stripe; whole row is the accent */

.lr-group{
 padding:10px 20px;color:#FFC02C;
 border-top:1px solid var(--border);border-bottom:1px solid var(--border);
 background:rgba(255,192,44,0.03);
 display:flex;justify-content:space-between;align-items:center;
}

/* ─── RIGHT FOOTER METRICS ────────────────────────── */
#right-footer{padding:16px 20px;border-top:1px solid var(--border);background:rgba(0,0,0,0.4);flex-shrink:0}
.metric-row{
 display:flex;justify-content:space-between;align-items:baseline;
 margin-bottom:8px;color:var(--dim);
}
.metric-row .val-claim{color:var(--green)}
.metric-row .val-impact{color:var(--red)}
.metric-row .val-remain{color:#FFC02C}

#bar-stack{margin-top:8px;height:2px;background:rgba(255,192,44,0.08);display:flex;overflow:hidden}
#bar-amber{background:#FFC02C;transition:width 0.4s ease}
#bar-red{background:var(--red);transition:width 0.4s ease}

#bar-meta{display:flex;justify-content:space-between;color:var(--dim);margin-top:8px}
#bar-meta .right{color:var(--red)}

/* ─── TIME SCRUBBER ─────────────────────────────────── */
#time-scrubber{
 background:rgba(0,0,0,0.97);border-top:1px solid var(--border);
 pointer-events:auto;display:none;flex-shrink:0;
}
#time-scrubber.show{display:block}
.ts-row{display:flex;align-items:center;gap:14px;padding:10px 20px;border-bottom:1px solid rgba(255,192,44,0.07)}
.ts-row:last-child{border-bottom:none}
.ts-label{color:var(--dim);white-space:nowrap;width:100px;flex-shrink:0}
.ts-year{color:#FFC02C;width:40px;flex-shrink:0;text-align:center}
.ts-range{
 flex:1;-webkit-appearance:none;appearance:none;height:1px;
 background:rgba(255,192,44,0.18);border-radius:0;outline:none;cursor:pointer;
}
.ts-range::-webkit-slider-thumb{-webkit-appearance:none;width:10px;height:10px;border-radius:0;background:#FFC02C;cursor:pointer}
.ts-range::-moz-range-thumb{width:10px;height:10px;border-radius:0;background:#FFC02C;border:none;cursor:pointer}
.ts-range::-webkit-slider-runnable-track{height:1px;background:linear-gradient(90deg,#FFC02C var(--pct,0%),rgba(255,192,44,0.18) var(--pct,0%))}
.ts-date{color:var(--green);white-space:nowrap;width:70px;flex-shrink:0;text-align:right}
.ts-status{white-space:nowrap;width:50px;flex-shrink:0;text-align:right}
.ts-status.live{color:var(--green)}
.ts-status.loading{color:#FFC02C}
.ts-status.err{color:var(--red)}

/* ─── COLD OPEN ──────────────────────────────────────── */
#cold-open{
 position:absolute;inset:0;display:none;flex-direction:column;
 align-items:flex-start;justify-content:center;
 background:rgba(0,0,0,0.98);z-index:180;
 padding:60px 80px;gap:20px;
}
#cold-open.show{display:flex}
#cold-open .co-accent{display:none}
#cold-open .co-eyebrow{color:var(--red)}
#cold-open .co-quote{color:var(--text-hi);max-width:820px}
#cold-open .co-quote em{color:var(--red)}
#cold-open .co-attrib{color:var(--dim)}
#cold-open .co-sami-voice{
 color:rgba(255,192,44,0.72);max-width:580px;
 border-left:2px solid var(--green);padding:12px 0 12px 20px;
}
#cold-open .co-sami-voice .voice-attrib{display:block;margin-top:10px;color:rgba(255,192,44,0.32)}
#cold-open .co-thesis{
 color:rgba(255,192,44,0.58);max-width:680px;
 border-top:1px solid var(--border);padding-top:20px;
}
#cold-open .co-controls{display:flex;gap:10px;align-items:center;padding-top:4px}
#cold-open .co-btn{
 background:#FFC02C;color:#000;border:none;
 padding:12px 28px;cursor:pointer;transition:background 0.12s;
}
#cold-open .co-btn:hover{background:#E0AC22}
#cold-open .co-btn.ghost{
 background:transparent;color:var(--dim);
 border:1px solid var(--border);
}
#cold-open .co-btn.ghost:hover{color:var(--text-hi);border-color:#FFC02C}
#cold-open .co-meta{display:none}
#cold-open .co-swatches{display:flex;width:200px;height:3px;gap:0;flex-shrink:0}
#cold-open .co-swatches span{flex:1}
.co-decor{display:none}

/* ─── CHAPTER DOCK ─────────────────────────────────────
 The dock lives INSIDE the right-panel, between the
 GENOMGÅNG/ÅTERSTÄLL buttons and the layer list. When the
 walkthrough runs the dock takes over the layer-list slot;
 when the user leaves the walkthrough the layer list returns.
 Position is static (not absolute) so the panel scrolls
 naturally. */
#chapter-dock{
 display:none;flex-direction:column;
 background:transparent;border:none;
 border-top:1px solid var(--border);
 border-bottom:1px solid var(--border);
 pointer-events:auto;
 width:100%;
 /* Fill the remaining panel height so cd-foot can sit at the
   bottom regardless of how long or short the prose is. */
 flex:1 1 auto;min-height:0;
}
/* Show ONLY when the briefing is active. The legacy .show
 class is kept for backwards compatibility but body class
 is now the source of truth so we never get a floating dock
 plus a hidden layer list. */
body.briefing-active #chapter-dock{display:flex}
body:not(.briefing-active) #chapter-dock{display:none !important}
/* Hide the rest of the panel content (layer list, time slider,
 footer metrics) while the walkthrough is running so the dock
 has the whole panel column to itself. */
body.briefing-active #right-panel #layer-list,
body.briefing-active #right-panel #time-scrubber,
body.briefing-active #right-panel #right-footer{display:none}
body.briefing-active #scale-ind,
body.briefing-active #frame-ind,
body.briefing-active #eo-attrib{opacity:0.2;pointer-events:none}

#chapter-dock .cd-strip{
 display:flex;align-items:center;gap:8px;padding:10px 14px;
 border-bottom:1px solid var(--border);flex-wrap:wrap;
}
#chapter-dock .cd-strip .cd-eye{color:var(--green);transition:color 0.2s ease}
#chapter-dock .cd-strip .cd-counter{color:var(--green);transition:color 0.2s ease}
/* Flips to red as soon as the active chapter activates a
   "harmful for the Sámi" overlay or stratum. See tintCounter()
   inside applyChapter() — it toggles the .harm class per step. */
#chapter-dock .cd-strip .cd-counter.harm,
#chapter-dock .cd-strip .cd-eye.harm{color:var(--red)}
#chapter-dock .cd-strip .cd-tag{display:none}
#chapter-dock .cd-strip .cd-skip{
 background:none;border:1px solid var(--border);color:var(--dim);
 padding:5px 12px;cursor:pointer;transition:color 0.1s,border-color 0.1s;
 /* The strip-level skip button is hidden  the bottom "Explore
   layers on your own" button (rendered in summary mode) is the
   single, prominent way out of the walkthrough now. */
 display:none;
}
#chapter-dock .cd-strip .cd-skip:hover{color:var(--text-hi);border-color:#FFC02C}

#chapter-dock .cd-body{
 padding:14px 14px 12px;transition:opacity 0.22s;
 /* Take all remaining vertical space and scroll internally so
   the foot stays pinned at the bottom of the dock. */
 flex:1 1 auto;overflow-y:auto;min-height:0;
}
#chapter-dock .cd-title{color:var(--text-hi);margin-bottom:10px}
#chapter-dock .cd-title .cd-num{display:none}
#chapter-dock .cd-prose{color:rgba(255,192,44,0.70)}
#chapter-dock .cd-prose em{color:var(--green)}
#chapter-dock.harm .cd-prose em{color:var(--red)}
#chapter-dock .cd-stats{display:none}

#chapter-dock .cd-foot{
 display:flex;align-items:center;gap:6px;padding:10px 14px;
 border-top:1px solid var(--border);flex-wrap:wrap;
 flex-shrink:0; /* never collapse — always anchored at the bottom */
}
/* The summary "Explore layers on your own" exit button is wider and
 visually distinct from the prev/next nav buttons. */
#chapter-dock .cd-exit{
 width:100%;background:#FFC02C;color:#000;border:none;
 padding:12px 14px;cursor:pointer;font-weight:bold;letter-spacing:0.04em;
 transition:filter 0.1s;
}
#chapter-dock .cd-exit:hover{filter:brightness(1.15)}
#chapter-dock .cd-dots{display:flex;gap:3px;flex:1 1 0;min-width:0}
/* Each dot scales down to share the available row instead of
   overflowing the panel when the chapter count is high. The
   max-width caps them at the original 18px on wide layouts. */
#chapter-dock .cd-dot{flex:1 1 0;min-width:4px;max-width:18px;height:2px;background:rgba(255,192,44,0.15);cursor:pointer;transition:background 0.15s}
#chapter-dock .cd-dot:hover{background:rgba(255,192,44,0.35)}
#chapter-dock .cd-dot.done{background:rgba(255,192,44,0.40)}
#chapter-dock .cd-dot.active{background:#FFC02C}
#chapter-dock .cd-nav{
 background:none;border:1px solid var(--border);color:#FFC02C;
 padding:7px 12px;cursor:pointer;transition:background 0.1s,color 0.1s;white-space:nowrap;
 font-size:11px;
}
#chapter-dock .cd-nav:hover{background:#FFC02C;color:#000}
#chapter-dock .cd-nav:disabled{opacity:0.18;cursor:not-allowed;background:none;color:var(--dim)}
#chapter-dock .cd-nav.primary{background:rgba(255,192,44,0.07)}
#chapter-dock .cd-nav.primary:hover{background:#FFC02C;color:#000}
#chapter-dock.transitioning .cd-body{opacity:0.3}

/* ─── BRIEFING LOCK ────────────────────────────────────
 The right-panel is no longer dimmed while the briefing is
 active because the panel itself now hosts the dock. Header
 buttons (GENOMGÅNG / ÅTERSTÄLL / collapse) must stay
 clickable so the user can leave the walkthrough. Keep the
 class for backwards compatibility but make it a no-op. */
#right-panel.brief-locked{opacity:1;pointer-events:auto}

/* ─── PLACE LABELS ─────────────────────────────────────
 Labels are positioned by REAL lat/lng (converted to %
 against RAN_VIEW_BBOX), not arbitrary SVG coordinates.
 Each label shows Swedish + Sámi name where the Sámi
 name is attested. Different kinds get different visual
 weights: settlements > mountains > water > context. */
/* SVG place-label overlay is hidden — labels are now rendered by
 MapLibre's `ran-places-symbols` symbol layer so they stay locked to
 their real lat/lng coordinates while the map pans and zooms. The
 old % positioned overlay drifted because it was anchored to a
 static bbox rather than the live map projection. */
#place-labels{display:none}
#place-labels.hidden{display:none}
.place-mark{position:absolute;transform:translate(-50%,-50%);pointer-events:none}
.place-mark .pm-dot{width:5px;height:5px;background:#FFC02C;margin:0 auto;border-radius:50%}
.place-mark .pm-name{
 color:#FFC02C;margin-top:4px;white-space:nowrap;
 font-family:'TreeSapMono',monospace;text-align:center;
}
.place-mark .pm-sv{display:block;font-size:11px;letter-spacing:0.04em}
.place-mark .pm-sami{
 display:block;font-size:9px;color:#FFC02C;opacity:0.75;
 font-style:italic;letter-spacing:0.02em;margin-top:1px;
}
/* Settlements: bright yellow */
.place-mark.village .pm-dot{background:#FFC02C;width:5px;height:5px}
.place-mark.village .pm-sv{color:#FFC02C}
.place-mark.village.tier-1 .pm-sv{font-size:12px;font-weight:bold}
.place-mark.village.tier-1 .pm-dot{width:7px;height:7px}
.place-mark.village.tier-2 .pm-sv{font-size:10px}
.place-mark.village.tier-3 .pm-sv{font-size:9px;opacity:0.8}
.place-mark.village.tier-3 .pm-dot{width:3px;height:3px;opacity:0.7}
/* Mountains: green, italic */
.place-mark.mountain .pm-dot{width:0;height:0;
 border-left:5px solid transparent;border-right:5px solid transparent;
 border-bottom:7px solid #4B9B2B;background:transparent;border-radius:0}
.place-mark.mountain .pm-sv{color:#4B9B2B;font-style:italic;font-size:10px}
.place-mark.mountain .pm-sami{color:#4B9B2B}
/* Water (lake/river): blue */
.place-mark.water .pm-dot{background:#7BA7D4;width:4px;height:4px}
.place-mark.water .pm-sv{color:#7BA7D4;font-style:italic;font-size:10px}
.place-mark.water .pm-sami{color:#7BA7D4}
/* River: no dot, just text along an imaginary line */
.place-mark.river .pm-dot{display:none}
.place-mark.river .pm-sv{color:#7BA7D4;font-style:italic;font-size:10px}
.place-mark.river .pm-sami{color:#7BA7D4}
/* Context (places OUTSIDE Ran that the narrative still references) */
.place-mark.context .pm-dot{background:var(--red);width:4px;height:4px;opacity:0.7}
.place-mark.context .pm-sv{color:var(--red);font-size:9px;opacity:0.75}
.place-mark.context .pm-sami{color:var(--red);opacity:0.7}
/* Reserve: large area label */
.place-mark.reserve .pm-dot{display:none}
.place-mark.reserve .pm-sv{
 color:#4B9B2B;font-size:10px;letter-spacing:0.15em;
 font-weight:bold;opacity:0.85;
}
.place-mark.reserve .pm-sami{color:#4B9B2B;opacity:0.8;letter-spacing:0.05em}
/* States */
.place-mark.faint{opacity:0.38}
.place-mark.hilite .pm-dot{outline:1px solid currentColor}
.place-mark.hilite .pm-sv{font-weight:bold}
.focus-ring{position:absolute;border:1px dashed #FFC02C;border-radius:50%;transform:translate(-50%,-50%);pointer-events:none;z-index:13}

/* ─── PLACE VIDEO MARKERS ────────────────────────────── */
/* Small yellow-bordered black square at the place coordinates.
 Click toggles its larger video box and the connecting line. */
.place-video-dot{
 width:14px;height:14px;
 background:#000;
 border:2px solid #FFC02C;
 cursor:pointer;
 pointer-events:auto;
 box-sizing:border-box;
 transition:transform 0.15s ease, box-shadow 0.15s ease;
}
.place-video-dot:hover{
 transform:scale(1.25);
 box-shadow:0 0 0 2px rgba(255,192,44,0.35);
}
.place-video-dot.open{
 background:#FFC02C;
 box-shadow:0 0 0 2px rgba(255,192,44,0.55);
}
/* Larger square video box, anchored by its top-left corner to
 the user-supplied lon/lat. Yellow outline, black interior so
 letterboxing stays consistent with the rest of the atlas. */
.place-video-box{
 border:2px solid #FFC02C;
 background:#000;
 pointer-events:auto;
 overflow:hidden;
 box-sizing:content-box;
 box-shadow:0 0 0 1px #000, 0 6px 24px rgba(0,0,0,0.6);
}
.place-video-box video{
 width:100%;height:100%;display:block;object-fit:cover;background:#000;
}
/* SVG overlay that hosts the connector lines. Pinned to the
 map container, never intercepts pointer events. */
#place-video-svg{
 position:absolute;inset:0;width:100%;height:100%;
 pointer-events:none;z-index:5;
}
#place-video-svg line{
 stroke:#FFC02C;stroke-width:1.2;
 vector-effect:non-scaling-stroke;
}

/* ─── FINAL READOUT ──────────────────────────────────── */
#final-readout{
 position:absolute;inset:0;display:none;z-index:170;flex-direction:column;
 align-items:flex-start;justify-content:center;
 background:rgba(0,0,0,0.97);
 padding:60px 80px;gap:16px;
}
#final-readout.show{display:flex}
#final-readout .fr-eyebrow{color:var(--red)}
#final-readout .fr-pre{color:rgba(255,192,44,0.50);max-width:580px}
#final-readout .fr-num{color:#FFC02C}
#final-readout .fr-num sup{color:var(--red)}
#final-readout .fr-label{color:var(--text-hi);max-width:580px}
#final-readout .fr-label em{color:var(--red)}
#final-readout .fr-prose{color:rgba(255,192,44,0.68);max-width:580px}
#final-readout .fr-prose em{color:var(--green)}
#final-readout .fr-controls{display:flex;gap:8px;margin-top:8px;flex-wrap:wrap}
#final-readout .fr-btn{
 background:transparent;border:1px solid var(--border);color:var(--dim);
 padding:10px 18px;cursor:pointer;transition:border-color 0.1s,color 0.1s;
}
#final-readout .fr-btn:hover{border-color:#FFC02C;color:var(--text-hi)}
#final-readout .fr-btn.primary{background:#FFC02C;color:#000;border-color:#FFC02C}
#final-readout .fr-btn.primary:hover{background:#E0AC22;border-color:#E0AC22}
#final-readout .fr-citations{
 color:rgba(255,192,44,0.28);max-width:720px;
 margin-top:4px;border-top:1px solid var(--border);padding-top:14px;
}
#final-readout .fr-swatches{display:flex;width:180px;height:3px;gap:0}
#final-readout .fr-swatches span{flex:1}

#fr-human{max-width:640px;border-top:1px solid rgba(255,192,44,0.12);padding-top:20px;margin-top:4px}

/* ─── BRIEF RESUME ──────────────────────────────────── */
#brief-resume{
 display:none;width:100%;
 background:rgba(255,192,44,0.04);border:none;border-bottom:1px solid var(--border);
 color:#FFC02C;padding:12px 20px;cursor:pointer;
 transition:background 0.12s,color 0.12s;flex-shrink:0;text-align:left;
}
#brief-resume.show{display:block}
#brief-resume:hover{background:#FFC02C;color:#000}

/* ─── LEFT PANEL ────────────────────────────────────── */
#telem-meta{padding:16px 20px;border-bottom:1px solid var(--border);flex-shrink:0}
.tm-row{display:flex;justify-content:space-between;line-height:2.2}
.tm-key{color:var(--dim)}
.tm-val{color:var(--text-hi)}
.tm-val.green{color:var(--green)}
.tm-val.yellow{color:#FFC02C}
.tm-val.red{color:var(--red)}
#data-scroll{flex:1;overflow:hidden;position:relative}
#data-content{position:absolute;bottom:0;left:0;right:0;padding:12px 20px}
.dl{line-height:1.8;white-space:nowrap;overflow:hidden;color:var(--dim)}
.dl.g{color:var(--green)}.dl.y{color:#FFC02C}.dl.r{color:var(--red)}
#left-status{padding:12px 20px;color:var(--dim);border-top:1px solid var(--border);flex-shrink:0}

/* ─── SWATCH STRIP ──────────────────────────────────── */
.swatch-col{display:flex;flex-direction:column;width:4px;flex-shrink:0}
.swatch-col>div{flex:1}

/* ═══════════════════════════════════════════════════════════
 STAR MARKERS — lon/lat–anchored diamonds + corner video panels
 ═══════════════════════════════════════════════════════════
 Layout hierarchy (all absolute, all inside #vp):
   #star-lines-svg   SVG overlay — holds the white connector lines
   #star-layer       container for .star-marker and .star-square divs

 Coordinate note: geoMap.project() is relative to #geo-basemap,
 which is inside #map-stage (inset: 46px 0 0 0 from #vp). JS adds
 _mapOffset() to every projected point so markers land on the exact
 geographic coordinate.

 Animation sequence (expand):
   1. Line draws from marker → square's transform-origin point (~380 ms)
   2. Square scales from 0 → 1 at that same fixed origin point

 Animation sequence (collapse):
   1. Square scales back to 0
   2. Line retracts toward marker
 ═══════════════════════════════════════════════════════════ */

/* Full-viewport SVG for connector lines. Never steals pointer events. */
#star-lines-svg {
 position: absolute;
 inset: 0;
 overflow: visible;
 pointer-events: none;
 /* Sits BEHIND #star-layer (31) so the connector line passes
    underneath the expanded video panel rather than over it. */
 z-index: 28;
}

/* Marker + square container. Children are individually interactive. */
#star-layer {
 position: absolute;
 inset: 0;
 pointer-events: none;
 z-index: 31;
}

/* ── Diamond marker ──────────────────────────────────────── */
.star-marker {
 position: absolute;
 width: 14px;
 height: 14px;
 pointer-events: auto;
 cursor: pointer;
 /* JS drives position via transform: translate(x,y) translate(-50%,-50%) */
 will-change: transform;
 transition: opacity 0.18s ease;
 /* No glow — clean white diamond on the dark map */
}
.star-marker svg {
 width: 100%;
 height: 100%;
 display: block;
}

/* ── Video square panel ──────────────────────────────────── */
/* Always at its final layout size; hidden via transform:scale(0).
   CSS transform does not affect layout, so getBoundingClientRect()
   returns the correct position even when visually collapsed — but
   we use the analytical _starOriginPx() helper instead to avoid
   any timing ambiguity. */
.star-square {
 position: absolute;
 /* Size: responsive square, same formula as _starOriginPx() in JS */
 width:  clamp(160px, 20vw, 260px);
 height: clamp(160px, 20vw, 260px);
 overflow: hidden;
 background: #000;
 border: 1px solid rgba(255, 255, 255, 0.80);
 box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.9), 0 8px 28px rgba(0, 0, 0, 0.7);
 pointer-events: none;
 z-index: 29;
 /* Start collapsed at the inner corner (transform-origin set per-corner below) */
 transform: scale(0);
 transition: transform 0.36s cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* Corner anchors — PAD/TOP/BOT mirror the JS constants */
.star-square.corner-tl { top: 56px;    left:  20px; transform-origin: bottom right; }
.star-square.corner-tr { top: 56px;    right: 20px; transform-origin: bottom left;  }
.star-square.corner-bl { bottom: 50px; left:  20px; transform-origin: top    right; }
.star-square.corner-br { bottom: 50px; right: 20px; transform-origin: top    left;  }

/* Expanded state */
.star-square.expanded {
 transform: scale(1);
 pointer-events: auto;
 cursor: pointer;
}

/* Hover ring signals the panel is clickable to collapse */
.star-square.expanded::after {
 content: '';
 position: absolute;
 inset: 0;
 border: 1px solid rgba(255, 255, 255, 0);
 transition: border-color 0.20s ease;
 pointer-events: none;
 z-index: 1;
}
.star-square.expanded:hover::after {
 border-color: rgba(255, 255, 255, 0.40);
}

/* Video fills its container, square crop */
.star-square video {
 width: 100%;
 height: 100%;
 display: block;
 object-fit: cover;
 background: #000;
}

/* ═══════════════════════════════════════════════════════════
 RESPONSIVE LAYOUT
 ═══════════════════════════════════════════════════════════
 Four breakpoint tiers:
   desktop (≥1280px)     — full layout, all panels visible, optional collapse
   small-desktop (1025-1279) — narrower right panel, slightly compressed
   tablet (641-1024)     — right panel becomes a slide-out drawer
   phone (≤640)          — drawer + full-width map + compact UI

 The right LAGER panel is ALWAYS collapsible (#right-panel.collapsed)
 even on full desktop, via a chevron in its header. When collapsed it
 slides off to the right and a small re-open tab appears at the edge.
 ═══════════════════════════════════════════════════════════ */

/* Small desktop: narrower right panel, no left */
@media(max-width:1279px){
 #left-panel{display:none}
 #right-panel{width:300px}
}

/* Tablet (641-1024): right panel becomes a slide-out drawer (closed by default
   so the map gets full viewport width). The user opens it via the persistent
   drawer tab on the right edge. Same mechanism as phone, just slightly bigger. */
@media(max-width:1024px){
 #right-panel{
 position:fixed;right:0;top:0;bottom:0;
 width:min(320px, 80vw);z-index:80;
 transform:translateX(100%);transition:transform 0.25s ease;
 border-left:1px solid var(--border);
 }
 #right-panel.mobile-open{transform:translateX(0)}
 #vp{width:100vw}
}

/* Phone (≤640): compact UI, bigger touch targets, GEO controls pinned
   to viewport corners (not inside transformed #map-2d). */
@media(max-width:640px){
 /* Overlay panel — anchor top-left, room for header at top */
 #geo-overlay-panel{
 left:8px;top:56px;
 width:min(280px, calc(100vw - 16px));
 max-height:calc(100vh - 160px); /* leaves room for time-bar */
 }
 /* Bigger touch targets */
 #geo-overlay-panel input[type="checkbox"]{ width:18px;height:18px }
 #geo-overlay-panel input[type="checkbox"]:checked::after{
 font-size:14px;left:2px;
 }
 #geo-overlay-panel label{padding:6px 0}
 /* GEO toggle near top-right, smaller. The base rule pins the
    button via left/bottom + transform: without resetting those
    here, top/right would just add a second pair of anchors and
    the element would stretch to fill almost the whole viewport
    (top:8 → bottom:14, left:50% → right:8 with a translateX). */
 #geo-toggle{
 top:8px;right:8px;
 left:auto;bottom:auto;transform:none;
 font-size:11px;padding:6px 10px;
 }
 /* Hide the info-readout on phones, it overlaps everything */
 #geo-info{display:none !important}
 #geo-toggle.on ~ #geo-info{display:none !important}
 /* Compact time bar */
 #geo-time-bar{
 padding:6px 10px;gap:8px;
 left:4px;right:4px;bottom:4px;
 }
 #geo-time-year{font-size:18px;min-width:54px}
 #geo-time-meta{display:none}
 /* Cold-open: scale text down so it doesn't overflow */
 #cold-open .co-quote{font-size:22px;line-height:1.3}
 #cold-open .co-sami-voice{font-size:13px}
 #cold-open .co-thesis{font-size:13px}
 #cold-open{padding:24px 16px;overflow-y:auto}
}

/* Mobile/tablet drawer-tab visibility + position. Shown only when
   right-panel is in drawer mode (≤1024). */
#mobile-lager-tab{
 display:none;
 position:fixed;top:50%;right:0;z-index:75;
 transform:translateY(-50%);
 background:rgba(0,0,0,0.85);border:1px solid var(--border);
 border-right:0;color:#FFC02C;
 padding:14px 8px;font-family:'TreeSapMono',monospace;
 font-size:10px;writing-mode:vertical-rl;
 letter-spacing:0.12em;cursor:pointer;
}
#mobile-lager-tab:hover{background:rgba(255,192,44,0.15)}
@media(max-width:1024px){
 #mobile-lager-tab{display:block}
}

/* Desktop collapse tab — sits at the left edge of #right-panel when
   the panel is in normal (non-drawer) mode. Click to slide the right
   panel away and reclaim the full map width. */
#right-panel{
 transition:transform 0.25s ease, width 0.25s ease;
}
#right-panel.collapsed{
 transform:translateX(100%);
}
/* When the panel collapses on DESKTOP (>1024) we need to let the
   center viewport expand to fill the freed space. Since right-panel
   is part of the flex layout there, we'd need flex-basis:0 to fully
   remove it. We do this via JS toggling a class on #app. */
@media(min-width:1025px){
 #app.right-collapsed #right-panel{
 width:0;border-left:0;overflow:hidden;
 }
}

/* Desktop reopen tab visible only when right-panel is collapsed */
#desktop-reopen-tab{
 position:fixed;top:50%;right:0;z-index:75;
 transform:translateY(-50%) translateX(100%);
 background:rgba(0,0,0,0.85);border:1px solid var(--border);
 border-right:0;color:#FFC02C;
 padding:14px 8px;font-family:'TreeSapMono',monospace;
 font-size:10px;writing-mode:vertical-rl;
 letter-spacing:0.12em;cursor:pointer;
 transition:transform 0.25s ease;
}
#app.right-collapsed #desktop-reopen-tab{
 transform:translateY(-50%) translateX(0);
}
@media(max-width:1024px){
 #desktop-reopen-tab{display:none !important}
}

/* ═══════════════════════════════════════════════════════════════
   FEEDBACK ADDITIONS — key popover, why-chip, 3D explainer,
   voice notes, clickable-feature popups
   ═══════════════════════════════════════════════════════════════ */

/* ─── "?" KEY POPOVER ───────────────────────────────────────── */
#hud-key-pop{
 position:absolute;top:50px;right:16px;z-index:80;
 width:min(360px,calc(100vw - 32px));
 max-height:calc(100% - 110px);overflow-y:auto;
 background:rgba(0,0,0,0.94);border:1px solid #FFC02C;
 padding:14px 16px;display:none;
 font-family:'TreeSapMono',monospace;font-size:11px;line-height:1.55;
 color:rgba(255,192,44,0.85);
 box-shadow:0 8px 30px rgba(0,0,0,0.6);
}
#hud-key-pop.show{display:block}
#hud-key-pop .hk-title{
 color:#FFC02C;font-weight:bold;font-size:12px;
 letter-spacing:0.08em;margin-bottom:10px;
 border-bottom:1px solid rgba(255,192,44,0.25);padding-bottom:6px;
}
#hud-key-pop .hk-row{margin-bottom:9px}
#hud-key-pop .hk-term{
 display:block;color:#FFC02C;font-weight:bold;letter-spacing:0.06em;
 font-size:11px;
}
#hud-key-pop .hk-def{display:block;color:rgba(255,192,44,0.7);font-size:11px}
#hud-key-pop .hk-leg{font-size:10.5px}
#hud-key-pop .hk-leg-title{
 color:#FF6A6A;font-weight:bold;font-size:11px;letter-spacing:0.06em;
 margin:12px 0 6px;border-top:1px solid rgba(255,192,44,0.2);padding-top:10px;
}
#hud-key-pop .hk-legend{display:flex;flex-wrap:wrap;gap:4px 12px}
#hud-key-pop .hk-leg{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}
#hud-key-pop .hk-leg-dot{
 width:8px;height:8px;border-radius:1px;flex-shrink:0;display:inline-block;
}
#hud-key-pop .hk-leg-foot{margin-top:8px;color:rgba(255,192,44,0.55);font-size:10px}

/* ─── "WHY THIS MAP?" CHIP + POPOVER ────────────────────────── */
#why-chip{
 position:absolute;top:56px;left:24px;z-index:30;
 display:inline-flex;align-items:center;gap:7px;
 background:rgba(0,0,0,0.85);border:1px solid rgba(255,192,44,0.5);
 color:#FFC02C;padding:5px 10px;cursor:pointer;
 font-family:'TreeSapMono',monospace;font-size:10px;font-weight:bold;
 letter-spacing:0.06em;border-radius:2px;
 transition:border-color 0.15s,background 0.15s;
}
#why-chip:hover{border-color:#FFC02C;background:rgba(255,192,44,0.12)}
#why-chip.on{background:#FFC02C;color:#000}
/* The global `*` rule pins span colour/size — restore inheritance so
   the chip text flips to black when the chip is in its .on state. */
#why-chip span{color:inherit;font-size:10px;line-height:1.2}
#why-chip .why-dot{
 width:7px;height:7px;border-radius:50%;background:#FFC02C;flex-shrink:0;
 animation:whyPulse 2.2s ease-in-out infinite;
}
#why-chip.on .why-dot{background:#000;animation:none}
@keyframes whyPulse{
 0%,100%{opacity:1;transform:scale(1)}
 50%{opacity:0.35;transform:scale(0.75)}
}
#why-pop{
 position:absolute;top:92px;left:24px;z-index:80;
 width:min(420px,calc(100vw - 48px));display:none;
 background:rgba(0,0,0,0.95);border:1px solid #FFC02C;
 padding:16px 18px;
 font-family:'TreeSapMono',monospace;font-size:11px;line-height:1.65;
 color:rgba(255,192,44,0.8);
 box-shadow:0 8px 30px rgba(0,0,0,0.65);
}
#why-pop.show{display:block}
#why-pop .why-title{
 color:#FFC02C;font-weight:bold;font-size:13px;letter-spacing:0.05em;
 margin-bottom:10px;
}
#why-pop .why-body strong{color:#FFC02C}
#why-pop .why-body em{color:#4B9B2B;font-style:normal}
#why-pop .why-close{
 margin-top:12px;background:transparent;border:1px solid rgba(255,192,44,0.5);
 color:#FFC02C;padding:5px 14px;cursor:pointer;
 font-family:'TreeSapMono',monospace;font-size:10px;letter-spacing:0.08em;
}
#why-pop .why-close:hover{background:rgba(255,192,44,0.15)}

/* ─── 3D FIRST-ENTRY EXPLAINER ──────────────────────────────── */
#mode3d-explainer{
 position:absolute;inset:0;z-index:90;display:none;
 align-items:center;justify-content:center;
 background:rgba(0,0,0,0.55);
}
#mode3d-explainer.show{display:flex}
#mode3d-explainer .m3d-card{
 width:min(460px,calc(100vw - 48px));
 background:rgba(0,0,0,0.96);border:1px solid #FFC02C;
 padding:22px 24px;
 font-family:'TreeSapMono',monospace;font-size:11px;line-height:1.65;
 color:rgba(255,192,44,0.8);
 box-shadow:0 12px 40px rgba(0,0,0,0.7);
}
#mode3d-explainer .m3d-eyebrow{
 color:#FF6A6A;font-size:10px;letter-spacing:0.18em;margin-bottom:8px;
}
#mode3d-explainer .m3d-title{
 color:#FFC02C;font-weight:bold;font-size:15px;letter-spacing:0.04em;
 margin-bottom:10px;
}
#mode3d-explainer .m3d-body strong{color:#FFC02C}
#mode3d-explainer .m3d-ok{
 margin-top:16px;background:#FFC02C;border:none;color:#000;
 padding:8px 20px;cursor:pointer;font-weight:bold;
 font-family:'TreeSapMono',monospace;font-size:11px;letter-spacing:0.08em;
}
#mode3d-explainer .m3d-ok:hover{background:#FFD566}

/* ─── VOICE NOTES (RÖSTER) ──────────────────────────────────── */
/* Reuses the video-marker animation: a dot, a connector line that
   draws out, and a corner card (.star-square) that unfolds. The
   line SVG + dot/card container mirror #star-lines-svg / #star-layer. */
#voice-lines-svg{
 position:absolute;inset:0;overflow:visible;pointer-events:none;z-index:28;
}
#voice-layer{
 position:absolute;inset:0;pointer-events:none;z-index:31;
}
body.voice-notes-hidden #voice-layer,
body.voice-notes-hidden #voice-lines-svg{display:none !important}

/* Dot marker — positioned by JS transform like .star-marker. */
.voice-marker{
 position:absolute;
 width:18px;height:18px;border-radius:50%;
 background:rgba(0,0,0,0.88);border:1.5px solid #FEC20E;
 display:flex;align-items:center;justify-content:center;
 font-family:'TreeSapMono',monospace;font-size:11px;font-weight:bold;
 cursor:pointer;line-height:1;pointer-events:auto;
 will-change:transform;
 transition:opacity 0.18s ease;
}
.voice-marker:hover{filter:brightness(1.3)}

/* Text card — inherits .star-square geometry/animation; only the
   content styling differs from the video square. */
.voice-square{
 background:rgba(0,0,0,0.92);
 overflow:auto;
 padding:14px 16px;
 display:flex;flex-direction:column;gap:8px;
}
.voice-square .vp-type{
 display:inline-block;font-size:9px;font-weight:bold;
 letter-spacing:0.16em;text-transform:uppercase;flex-shrink:0;
}
.voice-square .vp-text{
 color:#fff;
 font-family:'TreeSapMono',monospace;font-size:12px;line-height:1.55;
}

/* ─── PLACE-NAME CARD ───────────────────────────────────────── */
/* Same draw-on line + unfold as the voice/video cards, but anchored
   right next to the clicked name (short connector). */
#place-card-svg{
 position:absolute;inset:0;overflow:visible;pointer-events:none;z-index:32;
}
#place-card-layer{
 position:absolute;inset:0;pointer-events:none;z-index:33;
}
.place-card{
 position:absolute;
 width:240px;max-width:62vw;
 background:rgba(0,0,0,0.93);
 border:1px solid #FFC02C;
 box-shadow:0 6px 24px rgba(0,0,0,0.6);
 pointer-events:none;
 transform:scale(0);
 transition:transform 0.28s cubic-bezier(0.22,0.61,0.36,1);
}
.place-card.open{transform:scale(1);pointer-events:auto;cursor:pointer}
.place-card .gfp{max-width:none}

/* ─── CLICKABLE-FEATURE POPUPS ──────────────────────────────── */
.geo-feature-popup .maplibregl-popup-content{
 background:rgba(0,0,0,0.93);border:1px solid rgba(255,192,44,0.55);
 border-radius:0;padding:0;box-shadow:0 6px 24px rgba(0,0,0,0.6);
}
.geo-feature-popup .maplibregl-popup-tip{border-top-color:rgba(0,0,0,0.93)}
.geo-feature-popup .maplibregl-popup-close-button{
 color:#FFC02C;font-size:14px;right:4px;top:2px;
}
.gfp{
 padding:11px 13px;max-width:280px;
 font-family:'TreeSapMono',monospace;font-size:10.5px;line-height:1.55;
}
.gfp-title{font-weight:bold;font-size:12px;letter-spacing:0.04em;margin-bottom:5px}
.gfp-title .gfp-sami{color:rgba(255,255,255,0.85);font-weight:normal;font-style:italic}
.gfp-line{color:rgba(255,192,44,0.75);margin-bottom:2px;font-size:10.5px}
.gfp-tag{color:rgba(255,255,255,0.85);margin-bottom:2px;font-size:10.5px}
.gfp-tag span{color:rgba(255,192,44,0.55);margin-right:6px}
.gfp-sub{
 color:rgba(255,192,44,0.55);font-size:9.5px;margin-top:7px;
 border-top:1px solid rgba(255,192,44,0.18);padding-top:6px;
}

/* Mobile: keep the chip clear of the HUD buttons row. */
@media(max-width:760px){
 #why-chip{top:52px;left:12px}
 #why-pop{top:86px;left:12px}
 #hud-key-pop{right:8px}
}
