/* TNG50 explorer page styles (Phase 3). Look: mockup B (dark-first glass console, light theme of equal quality) with
   mockup A's grafts (labelled control groups, labelled ion chips, switch toggles, a single-column mobile layout with a
   controls drawer). pick.md is binding on look, design §6 on ids and semantics. */
:root{--scheme:dark;--bg:#07090f;--bg2:#0d1220;--glow1:rgba(84,64,200,.22);--glow2:rgba(230,110,60,.10);--glass:rgba(22,27,42,.62);--glass2:rgba(30,36,56,.94);
  --gline:rgba(160,175,220,.15);--ink:#eef0f7;--muted:#a0a8c0;--faint:#8b93ad;--strip:#131827;--swoff:rgba(127,127,160,.36);--grid:rgba(150,165,210,.11);--panel:rgba(14,18,30,.55);--data:#c4cadb;--fit:#ffffff;
  --accent:#8fa8ff;--hl:rgba(143,168,255,.16);--good:#4ade80;--warn:#f5b84b;--bad:#ff8a8a;--shadow:0 18px 50px rgba(0,0,0,.55);
  --sans:"Space Grotesk",system-ui,sans-serif;--mono:"JetBrains Mono",ui-monospace,Menlo,monospace;--body:var(--sans);--rule:var(--gline);--ink2:var(--muted);color-scheme:dark}
@media (prefers-color-scheme:light){:root:not([data-theme="dark"]){--scheme:light;--bg:#eef0f6;--bg2:#e3e7f2;--glow1:rgba(110,90,230,.14);--glow2:rgba(240,140,80,.10);
  --glass:rgba(255,255,255,.66);--glass2:rgba(255,255,255,.97);--gline:rgba(40,50,90,.13);--ink:#121628;--muted:#525a78;--faint:#5f6783;--strip:#f5f6fa;--swoff:rgba(60,70,110,.64);--grid:rgba(40,50,90,.08);
  --panel:rgba(255,255,255,.6);--data:#363c52;--fit:#0b0e1a;--accent:#3a55d8;--hl:rgba(58,85,216,.10);--good:#15803d;--warn:#a16207;--bad:#b91c1c;
  --shadow:0 18px 50px rgba(30,40,90,.16);color-scheme:light}}
:root[data-theme="light"]{--scheme:light;--bg:#eef0f6;--bg2:#e3e7f2;--glow1:rgba(110,90,230,.14);--glow2:rgba(240,140,80,.10);
  --glass:rgba(255,255,255,.66);--glass2:rgba(255,255,255,.97);--gline:rgba(40,50,90,.13);--ink:#121628;--muted:#525a78;--faint:#5f6783;--strip:#f5f6fa;--swoff:rgba(60,70,110,.64);--grid:rgba(40,50,90,.08);
  --panel:rgba(255,255,255,.6);--data:#363c52;--fit:#0b0e1a;--accent:#3a55d8;--hl:rgba(58,85,216,.10);--good:#15803d;--warn:#a16207;--bad:#b91c1c;
  --shadow:0 18px 50px rgba(30,40,90,.16);color-scheme:light}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{display:flow-root}   /* B_fix F6: #top's margin no longer collapses through body (the page was 10 px taller than the viewport) */
body{color:var(--ink);font:13px/1.4 var(--sans);overflow:hidden;background:var(--bg);
  background-image:radial-gradient(1200px 700px at 12% -10%,var(--glow1),transparent 60%),radial-gradient(900px 600px at 105% 110%,var(--glow2),transparent 60%),linear-gradient(180deg,var(--bg),var(--bg2));-webkit-font-smoothing:antialiased}
button,input,select{font:inherit;color:inherit}
a{color:var(--accent)}
[hidden]{display:none!important}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.glass{background:var(--glass);border:1px solid var(--gline);backdrop-filter:blur(18px) saturate(1.3);-webkit-backdrop-filter:blur(18px) saturate(1.3);border-radius:14px}
sub{font-size:.75em}
/* ---- top bar ---- */
#top{height:48px;display:flex;align-items:center;gap:10px;padding:0 10px 0 16px;margin:10px 12px 0;position:relative;z-index:30}
#title{font:600 12.5px var(--sans);letter-spacing:.01em;margin:0;white-space:nowrap;color:var(--ink)}
#tabs{display:flex;gap:2px;padding:3px;border-radius:10px;background:rgba(127,127,160,.10)}
#tabs [role=tab]{border:0;background:none;padding:5px 12px;border-radius:7px;color:var(--muted);cursor:pointer;font-weight:500}
#tabs [role=tab][aria-selected=true]{background:var(--glass2);color:var(--ink);box-shadow:0 1px 0 var(--gline) inset,0 2px 8px rgba(0,0,0,.16)}
.sep{width:1px;height:22px;background:var(--gline);flex:none}
.sp{flex:1}
.grp{display:flex;align-items:center;gap:5px;min-width:0}
.gl{font:500 10px var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-right:2px;white-space:nowrap}
.pbtn{display:inline-flex;align-items:center;gap:7px;height:32px;padding:0 11px;border:1px solid var(--gline);background:rgba(127,127,160,.08);border-radius:9px;cursor:pointer;white-space:nowrap;color:var(--ink)}
.pbtn:hover,.pbtn[aria-expanded=true]{background:var(--hl);border-color:var(--accent)}
.pbtn:disabled{opacity:.5;cursor:not-allowed}
.pbtn svg{width:14px;height:14px;color:var(--muted);flex:none}
/* ux4 B: the sightline button shows clean parameters (glyph, orientation, b, Φ) and a chevron; the id is in its tip */
#gal-open{gap:6px}
#gal-open .slab{display:inline-flex;align-items:center;gap:8px;white-space:nowrap;font:500 12px var(--sans)}
#gal-open .slab .og{width:15px;height:15px;color:var(--accent)}
#gal-open .pv{font:500 11.5px var(--mono)}
#gal-open .chev{width:11px;height:11px;color:var(--muted)}
.pv i{font:italic 500 12px var(--sans);color:var(--muted);margin-right:3px}
@media (max-width:1180px){#top #gal-open .ow{display:none}}
.pbtn.sq{width:32px;padding:0;justify-content:center}
.ib{width:32px;height:32px;border-radius:9px;border:1px solid transparent;background:none;display:inline-grid;place-items:center;cursor:pointer;color:var(--muted);flex:none}
.ib:hover,.ib[aria-expanded=true],.ib[aria-pressed=true]{background:var(--hl);color:var(--ink)}
.ib svg{width:16px;height:16px}
.icons{display:flex;gap:0;align-items:center}
#pill{font:500 10.5px var(--mono);color:var(--muted);display:flex;align-items:center;gap:6px;white-space:nowrap}
#pill::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--faint)}
#pill[data-state=offline]::before{background:#f97316;box-shadow:0 0 10px #f97316}
#pill[data-state=warming]::before{background:var(--warn);box-shadow:0 0 10px var(--warn)}
#pill[data-state=live]::before{background:var(--good);box-shadow:0 0 10px var(--good)}
.banner{margin:8px 12px 0;padding:7px 12px;border:1px solid var(--warn);border-radius:10px;display:flex;gap:10px;align-items:center;flex-wrap:wrap;font-size:12px;background:var(--glass2)}
.banner b{font:500 11.5px var(--mono)}
/* ---- shell ---- */
#shell{display:grid;grid-template-columns:minmax(0,1fr) clamp(236px,calc(20 * var(--vw, 1vw)),300px);gap:12px;padding:12px;height:calc(100% - 58px);min-height:0}
body.has-banner #shell{height:calc(100% - 58px - 46px)}
body.side-off #shell{grid-template-columns:minmax(0,1fr)}
body.side-off #side{display:none}
#panel-spectra{display:flex;flex-direction:column;min-height:0;min-width:0;padding:8px 10px 4px 4px}
/* tune1 F5: Layout floats right on the first row and the chips flow round it, then under it at full width, so the bar
   takes one row of chips more only when they need it (it was up to three rows plus a stranded Layout at 1024) */
#plotbar{display:flow-root;min-height:34px;padding:0 4px 4px 10px}
#plotbar #grp-layout{float:right;margin:0 0 2px 14px}
#plotbar #grp-lines{display:block;line-height:32px}
#plotbar #grp-lines>.gl,#plotbar #ion-open{vertical-align:middle;margin-right:6px}
#plotbar #ion-chips{display:inline}
#plotbar .chip{margin:2px 4px 2px 0;vertical-align:middle;line-height:normal}
#ion-chips{display:flex;gap:4px;align-items:center;flex-wrap:wrap;min-width:0}
.chip{display:inline-flex;align-items:center;gap:6px;height:24px;padding:0 6px 0 8px;border-radius:99px;border:1px solid var(--gline);background:rgba(127,127,160,.07);font:500 11.5px var(--sans);cursor:pointer;white-space:nowrap;color:var(--ink)}
.chip:hover{border-color:var(--ic)}
.chip .x{color:var(--muted);font-size:12px;line-height:1;margin-left:1px}
.chip:hover .x{color:var(--ink)}
.sw{width:8px;height:8px;border-radius:50%;background:var(--ic);box-shadow:0 0 7px var(--ic);flex:none;display:inline-block}
#ion-open .n{font:500 11px var(--mono);color:var(--accent)}
.seg{display:inline-grid;grid-auto-flow:column;grid-auto-columns:1fr;padding:3px;border-radius:10px;background:rgba(127,127,160,.10);gap:2px}
.seg label{position:relative;cursor:pointer}
.seg input{position:absolute;opacity:0;inset:0;margin:0;cursor:pointer}
.seg span{display:flex;align-items:center;justify-content:center;height:26px;padding:0 9px;font:500 11px var(--mono);color:var(--muted);border-radius:7px;white-space:nowrap}
.seg input:checked+span{background:var(--hl);color:var(--ink);box-shadow:inset 0 0 0 1px var(--accent),0 2px 8px rgba(0,0,0,.14)}
.seg input:focus-visible+span{outline:2px solid var(--accent)}
.seg input:disabled+span{opacity:.4;cursor:not-allowed}
#spectra{position:relative;flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;outline:none;cursor:grab;scrollbar-width:thin;touch-action:pan-y}
#spectra:focus-visible{outline:2px solid var(--accent);outline-offset:-2px;border-radius:4px}   /* B_fix F1: the same 2 px accent ring as every control */
#spectra.dragging{cursor:grabbing}
#cv{display:block}
#hitboxes{position:absolute;inset:0;pointer-events:none}
#hitboxes .panel{position:absolute}
/* tune1 F3, B_tune2 M3: the velocity-axis strip under the stage when the rows overflow; it takes its own height (the
   stage above ends at a row boundary) and holds the lines-below pill, right-aligned under the ticks */
#vaxis{flex:none;box-sizing:border-box;height:48px;display:flex;flex-direction:column;align-items:stretch;gap:4px;padding:3px 0 0;border-top:1px solid var(--grid);background:var(--strip)}
#vaxis[hidden]{display:none}
#vaxis-cv{display:block}
#more-below{align-self:flex-end;display:inline-flex;align-items:center;gap:5px;height:20px;padding:0 9px;margin-right:6px;border-radius:99px;border:1px solid var(--gline);background:var(--glass2);color:var(--ink);font:500 11px var(--sans);cursor:pointer}
#more-below[hidden]{display:none}
#more-below:hover{border-color:var(--accent)}#more-below svg{width:11px;height:11px;color:var(--accent)}
#bar{display:flex;align-items:center;gap:14px;height:24px;font:10.5px var(--mono);color:var(--muted);padding:0 4px 0 24px;min-width:0}
#statusline,#readouts{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#statusline b{font-weight:500;color:var(--ink)}
#statusline .sid{font:11px var(--mono);opacity:.7}
#note{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:40%}
#note.bad{color:var(--bad)}#note.good{color:var(--good)}
#fitstatus{white-space:nowrap}
#fitstatus[data-state=running]{color:var(--accent)}#fitstatus[data-state=error]{color:var(--bad)}#fitstatus[data-state=budget]{color:var(--warn)}
/* ---- side column ---- */
#side{display:flex;flex-direction:column;gap:12px;min-height:0;overflow:auto;scrollbar-width:none}
#mobslot{display:none}
#side-head{display:none}
#v3d-mini{position:relative;display:block;width:100%;aspect-ratio:1/1;border-radius:14px;overflow:hidden;border:1px solid var(--gline);background:#05070b;flex:none;padding:0;cursor:pointer}
#v3d-mini:hover{border-color:var(--accent)}
#v3d-mini:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
#v3d-mini-host{position:absolute;inset:0}
#v3d-mini.live .mini-art{display:none}
.mini-art{position:absolute;inset:0;background:radial-gradient(circle at 50% 52%,rgba(255,196,120,.55),rgba(214,90,140,.35) 18%,rgba(80,40,150,.28) 42%,transparent 70%),#0b0718}
.card{padding:12px 12px 10px;display:flex;flex-direction:column;gap:9px}
.card h2{margin:0 0 1px;font:500 10px var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
/* tune1 F15: a card header can carry a small text action (Velocity: Reset view) */
.card .hd{display:flex;align-items:center;justify-content:space-between;gap:8px}.card .hd h2{margin:0}
.lk{border:0;background:none;padding:2px 0;font:500 11.5px var(--sans);color:var(--accent);cursor:pointer}.lk:hover{text-decoration:underline}
.ctl{display:grid;grid-template-columns:62px 1fr 54px;align-items:center;gap:8px}
.ctl .k{font:500 11px var(--mono);color:var(--muted);white-space:nowrap}
.ctl .k em{font-style:normal;color:var(--faint);font-size:10px;margin-left:2px}
.ctl output{font:500 11.5px var(--mono);text-align:right;white-space:nowrap}
#rsliders{display:flex;flex-direction:column;gap:9px}
input[type=range]{-webkit-appearance:none;appearance:none;width:100%;height:18px;background:transparent;margin:0;cursor:pointer;--pc:50%}
input[type=range]::-webkit-slider-runnable-track{height:4px;border-radius:2px;background:linear-gradient(to right,var(--accent) var(--pc),rgba(127,127,160,.24) var(--pc))}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:14px;height:14px;border-radius:50%;background:var(--ink);margin-top:-5px;box-shadow:0 0 0 3px rgba(143,168,255,.25)}
input[type=range]::-moz-range-track{height:4px;border-radius:2px;background:rgba(127,127,160,.24)}
input[type=range]::-moz-range-progress{height:4px;border-radius:2px;background:var(--accent)}
input[type=range]::-moz-range-thumb{width:14px;height:14px;border:0;border-radius:50%;background:var(--ink)}
input[type=range]:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
.tg{display:flex;align-items:center;justify-content:space-between;cursor:pointer;min-height:26px;font-size:12.5px;gap:10px}
.tg input{appearance:none;-webkit-appearance:none;width:30px;height:17px;border-radius:99px;background:var(--swoff);position:relative;cursor:pointer;margin:0;transition:background .15s;flex:none}
.tg input::after{content:"";position:absolute;top:2px;left:2px;width:13px;height:13px;border-radius:50%;background:#fff;transition:left .15s;box-shadow:0 1px 2px rgba(0,0,0,.3)}
.tg input:checked{background:var(--accent)}.tg input:checked::after{left:15px}
.row{display:flex;gap:6px}
.row .pbtn{flex:1;justify-content:center;height:30px;color:var(--muted)}
.row .pbtn.sq{flex:none}
/* ---- popovers ---- */
.pop{position:fixed;z-index:50;background:var(--glass2);border:1px solid var(--gline);backdrop-filter:blur(24px) saturate(1.4);-webkit-backdrop-filter:blur(24px) saturate(1.4);border-radius:14px;box-shadow:var(--shadow);padding:14px;max-width:min(400px,calc(calc(100 * var(--vw, 1vw)) - 24px));max-height:calc(calc(100 * var(--vh, 1vh)) - 80px);overflow:auto}
.pop h3{margin:0 0 8px;font:600 12.5px var(--sans)}
.pop p,.pop li{margin:0 0 6px;color:var(--muted);font-size:12.5px;line-height:1.55}
.pop ul{margin:0;padding-left:16px}
.pop ul.plain{list-style:none;padding:0}.pop ul.plain li{margin-bottom:9px}.pop ul.plain li:last-child{margin-bottom:0}
.pop strong{color:var(--ink);font-weight:500}
.pop.sheet{left:10px!important;right:10px;top:auto!important;bottom:10px;width:auto!important;max-width:none;max-height:calc(74 * var(--vh, 1vh))}
#gal-pop{width:440px;padding:10px}
.galcur{display:flex;align-items:center;gap:6px;margin:0 0 8px;padding:0 2px 8px;border-bottom:1px solid var(--mat-edge-c,var(--gline))}
#gal-id{flex:1;min-width:0;display:flex;align-items:center;gap:8px;font:500 12px var(--sans);overflow:hidden;white-space:nowrap}
#gal-id .og{width:15px;height:15px;color:var(--accent);flex:none}
#gal-id .pv{font:500 11.5px var(--mono)}
#gal-copy{width:28px;height:28px}
#gal-copy[data-state=done]{color:var(--accent);border-color:var(--accent)}
#gal-copy[data-state=fail]{color:var(--bad,#d55)}
#gal-pop .fl{display:flex;gap:6px;margin-bottom:8px}
#gal-search,#filter,.pop input[type=number],.pop input[type=url]{height:32px;border:1px solid var(--gline);border-radius:9px;background:rgba(127,127,160,.08);padding:0 10px;font:12px var(--mono);min-width:0}
#gal-search{flex:1}
#gal-list{list-style:none;margin:0;padding:0;max-height:320px;overflow:auto;position:relative}
#gal-list li{display:grid;grid-template-columns:auto minmax(0,1fr) 26px;gap:10px;align-items:center;padding:6px 9px;border-radius:8px;cursor:pointer;font:500 12px var(--sans)}
#gal-list li:hover{background:rgba(127,127,160,.09)}
#gal-list li.hl{background:var(--hl);box-shadow:inset 0 0 0 1px var(--accent)}   /* B_fix F11: the keyboard highlight differs from the mouse hover */
#gal-list .gp{display:grid;grid-template-columns:16px 54px 72px 64px;gap:8px;align-items:center;white-space:nowrap}
#gal-list .og{width:15px;height:15px;color:var(--muted)}
#gal-list .pv{font:500 11.5px var(--mono)}
#gal-list .gid{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:right;font:10px var(--mono);color:var(--muted);opacity:.8}
#gal-list li[aria-selected=true] .og,#gal-list li[aria-selected=true] .ow,#gal-list li[aria-selected=true] .gid{color:var(--accent);opacity:1}
#gal-list .gn,#gal-list .tag{justify-self:end}
.gn{display:inline-grid;place-items:center;min-width:18px;height:18px;padding:0 5px;border-radius:9px;font:500 10px var(--mono);color:var(--accent);background:var(--hl)}
#gal-list li.empty{display:flex;justify-content:center;gap:8px;cursor:default;padding:16px 9px;color:var(--muted)}
#gal-list li.empty:hover{background:none}
@media (max-width:480px){#gal-list .gid{display:none}#gal-list li{grid-template-columns:auto minmax(0,1fr)}}
.tag{font:500 9.5px var(--mono);color:var(--accent);border:1px solid currentColor;border-radius:4px;padding:0 4px}
.galf{display:flex;justify-content:space-between;align-items:center;margin-top:8px;font:11px var(--mono);color:var(--muted)}
.galf label{display:flex;gap:5px;align-items:center;cursor:pointer}
#ion-pop{width:320px;padding:8px}
.ion-row{display:grid;grid-template-columns:18px 12px 1fr auto;align-items:center;gap:8px;padding:6px 8px;border-radius:8px;cursor:pointer}
.ion-row:hover{background:var(--hl)}
.ion-row input{margin:0;accent-color:var(--accent)}
.ion-row .nm{font-weight:500}
.ion-row .bd{font:10px var(--mono);color:var(--faint)}
.ion-row.absent .nm{color:var(--faint)}
.pbtns{display:flex;gap:6px;margin-top:6px;padding-top:8px;border-top:1px solid var(--gline)}
.pbtns button{flex:1;height:28px;border:1px solid var(--gline);background:none;border-radius:8px;cursor:pointer;font-size:11.5px;color:var(--muted)}
.pbtns button:hover{background:var(--hl);color:var(--ink)}
#dl-menu{padding:6px;display:flex;flex-direction:column;min-width:170px}
#dl-menu button{text-align:left;border:0;background:none;padding:8px 10px;border-radius:8px;cursor:pointer}
#dl-menu button:hover{background:var(--hl)}#dl-menu button:disabled{opacity:.4}
#geo-pop{width:330px}
#geo-pop fieldset{border:0;margin:0 0 8px;padding:0}
#geo-pop legend{font:500 9.5px var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--faint);margin-bottom:5px}
.radios{display:flex;gap:12px;font-size:12.5px}
.radios label{display:flex;gap:5px;align-items:center;cursor:pointer}
.field{display:grid;grid-template-columns:70px 1fr;gap:8px;align-items:center;margin:6px 0;font-size:12.5px}
.field label{color:var(--muted)}
.go{margin-top:8px;width:100%;height:32px;border-radius:9px;border:1px solid var(--accent);background:var(--accent);color:var(--bg);cursor:pointer;font-weight:500}
.go:disabled{opacity:.45;cursor:not-allowed}
.prog{display:flex;flex-direction:column;gap:5px;margin-top:8px}
.stagebar{display:grid;grid-template-columns:repeat(6,1fr);gap:3px}
.stagebar span{height:5px;border-radius:3px;background:rgba(127,127,160,.22);position:relative;overflow:hidden}
.stagebar span i{position:absolute;inset:0 auto 0 0;background:var(--accent);width:0}
.stagebar span.done i{width:100%}
.stagenames{display:grid;grid-template-columns:repeat(6,1fr);gap:3px;font:10px var(--mono);color:var(--faint)}
.stagenames span.on{color:var(--ink)}
.msg{font-size:11.5px;color:var(--muted);overflow-wrap:anywhere;margin:8px 0 0}
.msg.bad{color:var(--bad)}.msg.good{color:var(--good)}
#geo-pop details{margin-top:8px;font-size:12px}
#geo-pop summary{cursor:pointer;color:var(--muted)}
.backends{font:11px var(--mono);color:var(--muted);display:flex;flex-direction:column;gap:2px;margin-top:6px;overflow-wrap:anywhere}
#find-pop{width:440px}
#find-pop .msg{margin:0 0 6px}
/* tune1 F7: the Find form on one grid: a fixed label column, equal min and max boxes, buttons in the page style */
#find-form .field{grid-template-columns:118px minmax(0,1fr);margin:5px 0}
#find-form .field>label,#find-form .field>.lab{color:var(--muted);white-space:nowrap;font-size:12px}
#find-form .field>.row{display:grid!important;grid-template-columns:1fr 1fr;gap:6px!important}
#find-body select,#find-body input{height:30px;width:100%;border:1px solid var(--gline);background:rgba(127,127,160,.08);border-radius:8px;padding:0 8px;min-width:0;font:12px var(--mono)}
#find-form>.row{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:10px!important}
#find-form>.row button{height:32px;border-radius:9px;border:1px solid var(--gline);background:rgba(127,127,160,.08);color:var(--ink);cursor:pointer;font:500 12.5px var(--sans)}
#find-form>.row button:hover{background:var(--hl);border-color:var(--accent)}
#find-form>.row button.primary{background:var(--accent);border-color:var(--accent);color:var(--bg)}#find-form>.row button.primary:hover{filter:brightness(1.08)}
#find-body .findres button{border:1px solid var(--gline);background:rgba(127,127,160,.08);border-radius:8px;padding:5px 9px;cursor:pointer;color:var(--ink)}
#find-body .findres button:hover{background:var(--hl)}
#find-body .findres{list-style:none;margin:6px 0 0;padding:0;display:flex;flex-direction:column;gap:4px;max-height:300px;overflow:auto}
#find-body .findres button{width:100%;text-align:left;font:11.5px/1.4 var(--mono);white-space:normal}
#find-body .findres button[aria-current=true]{border-color:var(--accent)}
#find-body .hint{font-size:11.5px;color:var(--muted)}
/* ---- 3D tab ---- */
#panel-3d{grid-column:1/-1;display:flex;justify-content:center;align-items:flex-start;gap:16px;min-height:0;overflow:auto}
#v3d-stage{position:relative;aspect-ratio:1/1;width:min(calc(60 * var(--vw, 1vw)),calc(calc(100 * var(--vh, 1vh)) - 58px - 32px),900px);flex:none;border-radius:16px;overflow:hidden;background:#05070b;border:1px solid var(--gline);box-shadow:var(--shadow)}
#v3d-root{position:absolute;inset:0}
#v3d-root>p{margin:0;padding:14px;color:#b3bdc9;font-size:12.5px}
#v3d-controls{width:300px;flex:none;display:flex;flex-direction:column;gap:12px;padding-bottom:12px}
/* tune1 F14: from 1300 px the control cards flow into two balanced columns beside the stage, so Pick ray ends near the
   stage bottom instead of 450 px below the fold (one column of 300 px was 1264 px tall next to an 810 px stage) */
@media (min-width:1300px){#v3d-controls{width:560px}#v3d-stage{width:min(calc(calc(100 * var(--vw, 1vw)) - 24px - 16px - 560px - 8px),calc(calc(100 * var(--vh, 1vh)) - 58px - 32px),900px)}
  #v3d-controls .v3c{display:block;columns:2;column-gap:12px}#v3d-controls .v3c>*{break-inside:avoid;margin:0 0 12px}#v3d-controls .v3c>.v3c-lod{margin:0}
  #v3d-controls .v3c-btns{grid-template-columns:repeat(2,minmax(0,1fr))}}
.grp-k{font:500 9.5px var(--mono);color:var(--faint);letter-spacing:.08em;text-transform:uppercase}
#v3d-status{font:11px var(--mono);color:var(--muted);overflow-wrap:anywhere}
#v3d-wait{margin:0;padding:12px;border:1px solid var(--gline);border-radius:14px;background:var(--glass);font:11px var(--mono);color:var(--muted)}
#v3d-wait.bad{color:var(--bad)}
#picker-root{font-size:12px}
#picker-root .btn,#picker-root button{border:1px solid var(--gline);background:rgba(127,127,160,.08);border-radius:8px;padding:4px 9px;cursor:pointer;color:var(--ink)}
#picker-root input{border:1px solid var(--gline);background:rgba(127,127,160,.08);border-radius:7px;padding:3px 5px;min-width:0;width:100%}
#picker-root .pk,#picker-root .pk-xyz{display:grid;gap:6px}
#picker-root .pk-xyz{grid-template-columns:repeat(3,minmax(0,1fr))}
#picker-root .readouts{display:flex;flex-direction:column;gap:2px;font:11px var(--mono);color:var(--muted);border:0;padding:0}
#picker-root .msg{margin:4px 0 0}
#controls-open{display:none}
body[data-tab="3d"] #panel-spectra,body[data-tab="3d"] #side{display:none}
body[data-tab="3d"] #shell{grid-template-columns:minmax(0,1fr)}
@media (max-width:1180px){#find-toggle .lbl{display:none}
  #plotbar .chip{gap:5px;padding:0 5px 0 7px;font-size:11px;margin-right:3px}#plotbar .chip .sw{width:7px;height:7px}#plotbar #grp-layout{margin-left:10px}#plotbar .seg span{padding:0 7px}}
/* B_fix F7: from 1024 px the stage stays put and only the control column scrolls (Pick ray needs clicks on the stage) */
@media (min-width:1024px){#panel-3d{overflow:hidden}#v3d-controls{align-self:stretch;min-height:0;overflow-y:auto;scrollbar-width:thin;padding-right:4px}}
/* B_fix F8: the 3D LOD and download line is a debug aid, shown with ?debug */
#v3-lod{display:none}body.debug #v3-lod:not(:empty){display:block}
@media (max-width:1023px){#panel-3d{flex-direction:column;align-items:center}#v3d-stage{width:min(100%,calc(calc(100 * var(--vh, 1vh)) - 140px),900px)}#v3d-controls{width:min(100%,560px)}}
/* ---- phone and narrow tablet: one column, controls in a drawer (mockup A) ---- */
@media (max-width:820px){
  body{overflow:auto}
  #top{margin:8px 8px 0;padding:0 6px 0 12px;gap:6px;height:46px}
  .hide-m{display:none!important}
  #controls-open{display:inline-grid}
  #shell{display:block;padding:10px 16px;height:calc(100dvh - 54px)}
  body.side-off #side{display:flex}
  #panel-spectra{height:100%;padding:6px 2px 4px}
  #plotbar{display:none}
  /* tune1 F12: the drawer is a bottom sheet over the lower part of the stage (the top rows of spectra stay in view while a
     slider moves), with a Done button in its sticky header */
  #side{position:fixed;z-index:40;left:0;right:0;top:auto;bottom:0;max-height:min(66dvh,600px);padding:0 16px 24px;transform:translateY(110%);transition:transform .22s;
    background:var(--glass2);border-top:1px solid var(--gline);border-radius:18px 18px 0 0;backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);box-shadow:0 -12px 40px rgba(0,0,0,.35);overflow:auto;visibility:hidden}
  #side-head{display:grid;grid-template-columns:1fr auto;align-items:center;position:sticky;top:0;z-index:1;margin:0 -16px;padding:14px 16px 10px;background:var(--glass2);border-bottom:1px solid var(--gline)}
  #side-head .grab{position:absolute;left:50%;top:5px;width:36px;height:4px;margin-left:-18px;border-radius:2px;background:var(--gline)}
  #side-head #side-done{height:30px;padding:0 14px;color:var(--accent);font-weight:600}
  body.ctl-open #side{transform:none;visibility:visible}
  #v3d-mini{display:none}
  #mobslot{display:flex;flex-direction:column;gap:12px}
  #mobslot .grp{flex-direction:column;align-items:stretch;gap:8px;padding:12px;border:1px solid var(--gline);border-radius:14px;background:var(--glass)}
  #mobslot .gl{display:block;font-size:9.5px;margin:0}
  #mobslot #grp-sight{display:grid;grid-template-columns:32px minmax(0,1fr) 32px;align-items:center}
  #mobslot #grp-sight .gl,#mobslot #grp-sight #geo-open{grid-column:1/-1}
  #mobslot #grp-sight #geo-open{justify-content:center}
  #mobslot #gal-open{justify-content:center}
  #mobslot #ion-chips{gap:5px}
  #mobslot .seg{display:grid;grid-template-columns:repeat(4,1fr)}
  #mobslot #find-toggle .lbl{display:inline}#mobslot #grp-tools .row .pbtn{color:var(--ink)}
  #bar{padding-left:20px}
  #note{display:none}
  #v3d-stage{width:100%}
  #panel-3d{padding-bottom:16px}
}
@media (max-width:480px){#top{gap:4px;padding:0 4px 0 10px}#title{font-size:11.5px}#tabs [role=tab]{padding:4px 8px}
  .ib{width:28px;height:28px}.ib svg{width:15px;height:15px}#pill{display:none}}
/* ---- button visibility (2026-11): every control has a visible edge and full-contrast label ---- */
:root{--bline:rgba(175,190,235,.30);--btnbg:rgba(150,165,215,.13);--accent-ink:#0a0d18}
@media (prefers-color-scheme:light){:root:not([data-theme="dark"]){--bline:rgba(40,50,90,.26);--btnbg:rgba(255,255,255,.88);--accent-ink:#fff}}
:root[data-theme="light"]{--bline:rgba(40,50,90,.26);--btnbg:rgba(255,255,255,.88);--accent-ink:#fff}
.pbtn{border-color:var(--bline);background:var(--btnbg);font-weight:500;box-shadow:0 1px 2px rgba(0,0,0,.10)}
.pbtn svg{color:var(--ink)}
.pbtn.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:600}
.pbtn.primary svg{color:var(--accent-ink)}
.pbtn.primary:hover,.pbtn.primary[aria-expanded=true]{background:var(--accent);border-color:var(--accent);filter:brightness(1.1)}
.ib{border-color:var(--bline);background:var(--btnbg);color:var(--ink)}
.ib:hover,.ib[aria-expanded=true],.ib[aria-pressed=true]{border-color:var(--accent)}
.icons{gap:4px}
#tabs,.seg{box-shadow:inset 0 0 0 1px var(--bline)}
#tabs [role=tab]:hover{color:var(--ink);background:var(--hl)}
.seg span{color:var(--ink);opacity:.8}.seg input:checked+span{opacity:1}
.seg label:hover span{background:var(--hl)}
.chip{border-color:var(--bline)}
.row .pbtn,.pbtns button{color:var(--ink)}
.pbtns button{border-color:var(--bline);background:var(--btnbg)}
#chat-open.fab{position:fixed;right:14px;bottom:calc(14px + env(safe-area-inset-bottom,0px));z-index:45;height:46px;padding:0 18px 0 15px;border-radius:23px;font-size:14px;box-shadow:0 10px 28px rgba(0,0,0,.32)}
#chat-open.fab svg{width:17px;height:17px}
body.chat-on #chat-open.fab{display:none}
@media (max-width:480px){.icons{gap:1px}}
@media (prefers-reduced-motion:reduce){*{transition:none!important}}
/* ---- material system (2026-11 glass): Apple-style layered materials, defined once here; chat.js, viewer3d.js,
   picker.js and gallery.js reuse the same names. Roles: thin = buttons, chips, cards inside a panel; regular = top bar,
   side cards, spectra frame, floating controls; thick = popovers, menus, sheets, drawers. Only top-level surfaces blur;
   glass nested in glass takes --mat-tint and an edge, never a second backdrop-filter. *-o are the near-opaque fallbacks. ---- */
:root{--mat-thin:rgba(40,47,72,.40);--mat-regular:rgba(17,21,35,.56);--mat-thick:rgba(20,24,40,.80);
  --mat-thin-o:rgba(34,40,62,.95);--mat-regular-o:rgba(17,21,35,.96);--mat-thick-o:rgba(22,27,44,.98);
  --mat-blur-thin:blur(14px) saturate(1.7);--mat-blur-regular:blur(24px) saturate(1.8);--mat-blur-thick:blur(40px) saturate(1.9);
  --mat-edge-c:rgba(190,205,255,.14);--mat-edge-hc:rgba(220,228,255,.55);--mat-edge:1px solid var(--mat-edge-c);
  --mat-highlight:inset 0 1px 0 rgba(255,255,255,.10);
  --mat-shadow:0 1px 2px rgba(0,0,0,.30),0 22px 56px -14px rgba(0,0,0,.62);
  --mat-shadow-s:0 1px 2px rgba(0,0,0,.34);
  --mat-shadow-m:0 1px 2px rgba(0,0,0,.30),0 10px 28px -12px rgba(0,0,0,.55);
  --mat-fill:linear-gradient(180deg,rgba(255,255,255,.11),rgba(255,255,255,.035));
  --mat-fill-hover:linear-gradient(180deg,rgba(255,255,255,.18),rgba(255,255,255,.07));
  --mat-press:linear-gradient(180deg,rgba(0,0,0,.26),rgba(0,0,0,.16));
  --mat-raised:rgba(255,255,255,.13);--mat-well:rgba(0,0,0,.26);--mat-tint:rgba(255,255,255,.045);
  --mat-gloss:linear-gradient(180deg,rgba(255,255,255,.30),rgba(255,255,255,.08) 55%,rgba(255,255,255,0));
  --accent-ring:rgba(143,168,255,.55);--accent-glow:rgba(110,140,255,.45);--bline-hc:rgba(205,215,250,.62);
  --r-s:10px;--r-m:16px;--r-l:22px;
  --glow1:rgba(96,72,222,.40);--glow2:rgba(236,112,60,.20);--glow3:rgba(36,160,210,.18);
  --mat-rim:linear-gradient(180deg,rgba(255,255,255,.26),rgba(255,255,255,.04) 38%,rgba(255,255,255,0) 70%,rgba(255,255,255,.06));
  --panel:rgba(11,14,24,.94)}
@media (prefers-color-scheme:light){:root:not([data-theme="dark"]){--mat-thin:rgba(255,255,255,.46);--mat-regular:rgba(255,255,255,.58);--mat-thick:rgba(250,251,255,.90);--mat-blur-thick:blur(40px) saturate(1.9) brightness(1.1);--swoff:rgba(30,40,90,.16);
  --mat-thin-o:rgba(255,255,255,.96);--mat-regular-o:rgba(250,251,255,.97);--mat-thick-o:rgba(252,252,255,.99);
  --mat-edge-c:rgba(30,40,90,.13);--mat-edge-hc:rgba(20,25,60,.55);
  --mat-highlight:inset 0 1px 0 rgba(255,255,255,.90);
  --mat-shadow:0 1px 2px rgba(30,40,90,.08),0 22px 56px -16px rgba(30,40,90,.24);
  --mat-shadow-s:0 1px 2px rgba(30,40,90,.12);
  --mat-shadow-m:0 1px 2px rgba(30,40,90,.08),0 10px 28px -12px rgba(30,40,90,.22);
  --mat-fill:linear-gradient(180deg,rgba(255,255,255,.96),rgba(255,255,255,.66));
  --mat-fill-hover:linear-gradient(180deg,#fff,rgba(255,255,255,.86));
  --mat-press:linear-gradient(180deg,rgba(30,40,90,.10),rgba(30,40,90,.06));
  --mat-raised:#fff;--mat-well:rgba(30,40,90,.07);--mat-tint:rgba(255,255,255,.50);
  --mat-gloss:linear-gradient(180deg,rgba(255,255,255,.26),rgba(255,255,255,.06) 55%,rgba(255,255,255,0));
  --accent-ring:rgba(58,85,216,.42);--accent-glow:rgba(58,85,216,.34);--bline-hc:rgba(20,25,60,.62);
  --glow1:rgba(112,88,236,.28);--glow2:rgba(248,140,76,.22);--glow3:rgba(40,170,225,.22);
  --mat-rim:linear-gradient(180deg,#fff,rgba(255,255,255,.5) 40%,rgba(255,255,255,.15) 80%,rgba(255,255,255,.4));
  --panel:rgba(255,255,255,.93)}}
:root[data-theme="light"]{--mat-thin:rgba(255,255,255,.46);--mat-regular:rgba(255,255,255,.58);--mat-thick:rgba(250,251,255,.90);--mat-blur-thick:blur(40px) saturate(1.9) brightness(1.1);--swoff:rgba(30,40,90,.16);
  --mat-thin-o:rgba(255,255,255,.96);--mat-regular-o:rgba(250,251,255,.97);--mat-thick-o:rgba(252,252,255,.99);
  --mat-edge-c:rgba(30,40,90,.13);--mat-edge-hc:rgba(20,25,60,.55);
  --mat-highlight:inset 0 1px 0 rgba(255,255,255,.90);
  --mat-shadow:0 1px 2px rgba(30,40,90,.08),0 22px 56px -16px rgba(30,40,90,.24);
  --mat-shadow-s:0 1px 2px rgba(30,40,90,.12);
  --mat-shadow-m:0 1px 2px rgba(30,40,90,.08),0 10px 28px -12px rgba(30,40,90,.22);
  --mat-fill:linear-gradient(180deg,rgba(255,255,255,.96),rgba(255,255,255,.66));
  --mat-fill-hover:linear-gradient(180deg,#fff,rgba(255,255,255,.86));
  --mat-press:linear-gradient(180deg,rgba(30,40,90,.10),rgba(30,40,90,.06));
  --mat-raised:#fff;--mat-well:rgba(30,40,90,.07);--mat-tint:rgba(255,255,255,.50);
  --mat-gloss:linear-gradient(180deg,rgba(255,255,255,.26),rgba(255,255,255,.06) 55%,rgba(255,255,255,0));
  --accent-ring:rgba(58,85,216,.42);--accent-glow:rgba(58,85,216,.34);--bline-hc:rgba(20,25,60,.62);
  --glow1:rgba(112,88,236,.28);--glow2:rgba(248,140,76,.22);--glow3:rgba(40,170,225,.22);
  --mat-rim:linear-gradient(180deg,#fff,rgba(255,255,255,.5) 40%,rgba(255,255,255,.15) 80%,rgba(255,255,255,.4));
  --panel:rgba(255,255,255,.93)}
/* background: static colour glows for the glass to refract (no motion) */
body{background-image:radial-gradient(1200px 760px at 10% -12%,var(--glow1),transparent 62%),radial-gradient(900px 640px at 104% 108%,var(--glow2),transparent 62%),
  radial-gradient(760px 560px at 88% -6%,var(--glow3),transparent 64%),radial-gradient(700px 520px at -6% 96%,var(--glow3),transparent 66%),linear-gradient(180deg,var(--bg),var(--bg2))}
/* regular: top bar, spectra frame, side cards */
.glass{background:var(--mat-regular);border:var(--mat-edge);border-radius:var(--r-m);backdrop-filter:var(--mat-blur-regular);-webkit-backdrop-filter:var(--mat-blur-regular);box-shadow:var(--mat-highlight),var(--mat-shadow)}
#top{border-radius:var(--r-m)}
/* the specular rim: a 1 px edge that is bright at the top and fades down (a masked gradient over the border) */
.glass{position:relative}   /* not on .pop or the phone sheet: they scroll, and a scroller clips its border */
.glass::before{content:"";position:absolute;inset:-1px;border-radius:inherit;padding:1px;background:var(--mat-rim);pointer-events:none;
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box exclude,linear-gradient(#000 0 0)}
#panel-spectra,#side .glass{box-shadow:var(--mat-highlight),var(--mat-shadow-m)}
/* #side scrolls (overflow:auto): give the card shadows 12 px of room inside the scroller, taken from the grid gap and the shell padding, so they are not cut into a slab */
@media (min-width:821px){#side{margin:0 -12px -12px;padding:0 12px 24px}}
/* thick: popovers and menus */
.pop{background:var(--mat-thick);border:var(--mat-edge);border-radius:var(--r-m);backdrop-filter:var(--mat-blur-thick);-webkit-backdrop-filter:var(--mat-blur-thick);box-shadow:var(--mat-highlight),var(--mat-shadow)}
.pop.sheet{border-radius:var(--r-l)}
.banner{background:var(--mat-thick);backdrop-filter:var(--mat-blur-regular);-webkit-backdrop-filter:var(--mat-blur-regular);border-radius:var(--r-s);box-shadow:var(--mat-highlight),var(--mat-shadow-s)}
/* tabs and segmented controls: a recessed well with a raised pill */
#tabs,.seg{background:var(--mat-well);box-shadow:inset 0 0 0 1px var(--mat-edge-c),inset 0 1px 2px rgba(0,0,0,.12)}
#tabs [role=tab]{border-radius:8px}
#tabs [role=tab][aria-selected=true]{background:var(--mat-raised);color:var(--ink);box-shadow:var(--mat-highlight),0 0 0 1px var(--mat-edge-c),0 2px 8px rgba(0,0,0,.18)}
.seg span{border-radius:8px}
.seg input:checked+span{background:var(--mat-raised);color:var(--ink);box-shadow:var(--mat-highlight),inset 0 0 0 1px var(--accent),0 2px 8px rgba(0,0,0,.16)}
.seg label:hover input:not(:checked)+span,#tabs [role=tab][aria-selected=false]:hover{background:var(--mat-tint)}
/* thin: buttons (sheen + highlight; hover brightens; pressed darkens and drops the highlight) */
.pbtn,.ib,.pbtns button,#find-form>.row button,#find-body .findres button,#more-below{background:var(--mat-fill),var(--mat-thin);border-color:var(--bline);box-shadow:var(--mat-highlight),var(--mat-shadow-s);transition:background-color .12s,border-color .12s,filter .12s}
.pbtn,.ib{border-radius:var(--r-s)}
.pbtn:hover,.ib:hover,.pbtns button:hover,#find-form>.row button:hover,#find-body .findres button:hover,#more-below:hover{background:var(--mat-fill-hover),var(--mat-thin);border-color:var(--bline)}
.pbtn[aria-expanded=true],.ib[aria-expanded=true],.ib[aria-pressed=true]{background:linear-gradient(var(--hl),var(--hl)),var(--mat-fill),var(--mat-thin);border-color:var(--accent)}
.pbtn:active:not(:disabled),.ib:active,.pbtns button:active,#find-form>.row button:active,#find-body .findres button:active,#more-below:active{background:var(--mat-press),var(--mat-thin);box-shadow:inset 0 1px 2px rgba(0,0,0,.22)}
/* primary: solid accent with a glossy highlight */
.pbtn.primary,.go,#find-form>.row button.primary{background:var(--mat-gloss),var(--accent);border-color:var(--accent);color:var(--accent-ink);box-shadow:inset 0 1px 0 rgba(255,255,255,.35),0 4px 14px -4px var(--accent-glow)}
.pbtn.primary:hover,.pbtn.primary[aria-expanded=true],.go:hover:not(:disabled),#find-form>.row button.primary:hover{background:var(--mat-gloss),var(--accent);border-color:var(--accent);filter:brightness(1.08)}
.pbtn.primary:active,.go:active:not(:disabled),#find-form>.row button.primary:active{background:var(--accent);filter:brightness(.92);box-shadow:inset 0 1px 3px rgba(0,0,0,.25)}
.go{border-radius:var(--r-s)}
#chat-open.fab{box-shadow:inset 0 1px 0 rgba(255,255,255,.35),0 12px 32px -6px var(--accent-glow),0 4px 12px rgba(0,0,0,.25)}
/* chips: thin tint and edge, no blur */
.chip{background:var(--mat-fill);box-shadow:var(--mat-highlight)}
.chip:hover{background:var(--mat-fill-hover)}
/* fields: recessed wells */
#gal-search,#filter,.pop input[type=number],.pop input[type=url],#find-body select,#find-body input{background:var(--mat-well);border-color:var(--mat-edge-c);border-radius:var(--r-s);box-shadow:inset 0 1px 2px rgba(0,0,0,.10)}
/* list rows inside thick surfaces: tint only */
.pop input:disabled{opacity:.55;cursor:not-allowed}
#gal-list li,.ion-row,#dl-menu button{border-radius:var(--r-s)}
#gal-list li:hover,#dl-menu button:hover,.ion-row:hover{background:var(--mat-tint)}
#gal-list li.hl{background:var(--hl)}
.pbtns{border-top-color:var(--mat-edge-c)}
.stagebar span{background:var(--mat-well)}
/* data surfaces: framed by glass, plotted on an opaque ground */
#v3d-mini{border-radius:var(--r-m);border:var(--mat-edge);box-shadow:var(--mat-highlight),var(--mat-shadow-s)}
#v3d-stage{border:var(--mat-edge);box-shadow:var(--mat-highlight),var(--mat-shadow-s)}   /* small: #panel-3d is overflow:hidden from 1024 px */
#vaxis{border-top-color:var(--mat-edge-c)}
#v3d-wait{background:var(--mat-regular);border:var(--mat-edge);border-radius:var(--r-m);backdrop-filter:var(--mat-blur-regular);-webkit-backdrop-filter:var(--mat-blur-regular);box-shadow:var(--mat-highlight)}
/* phone: the controls sheet is thick glass; cards and groups inside it are tint + edge only */
@media (max-width:820px){
  #side{background:var(--mat-thick);border-top:var(--mat-edge);border-radius:var(--r-l) var(--r-l) 0 0;backdrop-filter:var(--mat-blur-thick);-webkit-backdrop-filter:var(--mat-blur-thick);
    box-shadow:var(--mat-highlight),0 -18px 50px -10px rgba(0,0,0,.40)}
  #side-head{background:var(--mat-thick-o);border-bottom-color:var(--mat-edge-c);border-radius:var(--r-l) var(--r-l) 0 0}
  #side-head .grab{background:var(--muted);opacity:.45}
  #side .card,#mobslot .grp{background:var(--mat-tint);border:var(--mat-edge);border-radius:var(--r-m);backdrop-filter:none;-webkit-backdrop-filter:none;box-shadow:var(--mat-highlight)}
  #side-done.pbtn{background:none;border-color:transparent;box-shadow:none}
  /* the floating Ask button sits over the sheet: let the sheet scroll its last row clear of it */
  body:has(>#chat-open.fab:not([hidden])) #side{padding-bottom:calc(84px + env(safe-area-inset-bottom,0px))}
  /* ... and keep the status bar (fit status, story hint) clear of it on its right */
  body:has(>#chat-open.fab:not([hidden])) #bar{padding-right:calc(118px + env(safe-area-inset-right,0px))}
}
/* sliders and switches: white knob with a hairline edge and a soft shadow, accent fill; the switch off track is a light well */
input[type=range]::-webkit-slider-thumb{background:#fff;box-shadow:0 0 0 .5px rgba(0,0,0,.28),0 1px 3px rgba(0,0,0,.30)}
input[type=range]::-moz-range-thumb{background:#fff;box-shadow:0 0 0 .5px rgba(0,0,0,.28),0 1px 3px rgba(0,0,0,.30)}
.tg input{box-shadow:inset 0 0 0 1px var(--bline)}
.tg input:checked{box-shadow:inset 0 0 0 1px var(--accent)}
.tg input::after{box-shadow:0 0 0 .5px rgba(0,0,0,.12),0 1px 3px rgba(0,0,0,.30)}
#find-body input::placeholder{color:var(--muted);opacity:1}
/* fallbacks: no backdrop-filter or reduced transparency take near-opaque fills; more contrast strengthens edges */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  :root:not(#_){--mat-thin:var(--mat-thin-o);--mat-regular:var(--mat-regular-o);--mat-thick:var(--mat-thick-o)}}
@media (prefers-reduced-transparency:reduce){
  :root:not(#_){--mat-thin:var(--mat-thin-o);--mat-regular:var(--mat-regular-o);--mat-thick:var(--mat-thick-o);--mat-blur-thin:none;--mat-blur-regular:none;--mat-blur-thick:none}}
@media (prefers-contrast:more){
  :root:not(#_){--mat-thin:var(--mat-thin-o);--mat-regular:var(--mat-regular-o);--mat-thick:var(--mat-thick-o);--mat-edge-c:var(--mat-edge-hc);--bline:var(--bline-hc)}}
/* tf3d: Transfer function card (3D volume mode; tfeditor.js): the plot is a well in the glass card, the colour swatch
   a small raised control */
#v3d-controls .v3tf-plot canvas{background:var(--mat-well);box-shadow:inset 0 0 0 1px var(--mat-edge-c),inset 0 1px 2px rgba(0,0,0,.18);border-radius:var(--r-s)}
#v3d-controls .v3tf-bands input[type=color]{background:var(--mat-fill),var(--mat-thin);border:1px solid var(--mat-edge-c);box-shadow:var(--mat-highlight);border-radius:var(--r-s)}
#v3d-controls .v3tf-bands input[type=color]::-webkit-color-swatch-wrapper{padding:2px}
#v3d-controls .v3tf-bands input[type=color]::-webkit-color-swatch{border:0;border-radius:6px}
#v3d-controls .v3tf-bands input[type=color]::-moz-color-swatch{border:0;border-radius:6px}
/* tips: the one-line help of every control (js/tips.js; data-tip on the control): one glass tooltip, thick material,
   never takes the pointer; near-opaque under the reduced-transparency and no-backdrop fallbacks above */
.tip{position:fixed;z-index:2000;left:0;top:0;max-width:min(280px,calc(calc(100 * var(--vw, 1vw)) - 16px));padding:6px 10px;border-radius:var(--r-s,10px);
  background:var(--mat-thick);border:var(--mat-edge);backdrop-filter:var(--mat-blur-thick);-webkit-backdrop-filter:var(--mat-blur-thick);
  box-shadow:var(--mat-highlight),var(--mat-shadow-m);color:var(--ink);font:500 12px/1.35 var(--sans);letter-spacing:.01em;text-wrap:pretty;
  pointer-events:none;opacity:0;transform:translateY(2px);transition:opacity .12s ease-out,transform .12s ease-out}
.tip[data-side=bottom]{transform:translateY(-2px)}
.tip.on{opacity:1;transform:none}
/* touch: a long press on a tipped control shows its tip, so it must not start a text selection or the iOS callout */
@media (hover:none){[data-tip]:not(input[type=text],input[type=number],input[type=search],input[type=url],textarea),
  label:has(> [data-tip]){-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}}
/* ==== ux4 features (js/features.js): share, keys overlay, random, undo, CSV items, loading bar. Own block, start ==== */
#share.done{color:var(--good);border-color:var(--good)}
.card .hd .undo{display:inline-flex;gap:4px}
.ib.sm{width:24px;height:24px;border-radius:8px}.ib.sm svg{width:13px;height:13px}
.ib:disabled{opacity:.35;cursor:default}
#keys-pop{width:340px}
#keys-pop .kgrp{display:grid;grid-template-columns:1fr;gap:4px;padding:6px 0;border-top:1px solid var(--mat-edge-c)}
#keys-pop .kgrp:first-of-type{border-top:0;padding-top:0}
#keys-pop .kg{font:500 9.5px var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
#keys-pop dl{display:grid;grid-template-columns:auto 1fr;gap:5px 12px;margin:0;align-items:center}
#keys-pop dt{display:flex;gap:3px;justify-content:flex-end}
#keys-pop dd{margin:0;font-size:12px;color:var(--muted)}
#keys-pop kbd{font:500 10.5px var(--mono);min-width:18px;text-align:center;padding:1px 5px;border-radius:6px;color:var(--ink);
  background:var(--mat-fill),var(--mat-thin);border:1px solid var(--mat-edge-c);box-shadow:var(--mat-highlight),0 1px 0 var(--mat-edge-c)}
#spectra[data-busy]::before{content:"";position:sticky;top:0;display:block;height:2px;margin-bottom:-2px;z-index:3;pointer-events:none;
  background:linear-gradient(90deg,transparent,var(--accent) 40%,var(--accent) 60%,transparent) 0 0/40% 100% no-repeat;animation:ux4-run 1.1s linear infinite}
@keyframes ux4-run{from{background-position:-40% 0}to{background-position:140% 0}}
@media (prefers-reduced-motion:reduce){#spectra[data-busy]::before{animation:none;background:var(--accent);opacity:.5}}
/* integrate: the top bar keeps its square buttons whole; below 1280 px share and keys leave it ("Copy link" moves into
   the Save menu, keys l and ? still work), below 1100 px New ray and the server pill shrink to an icon and a dot */
#top .pbtn.sq{flex:none}
@media (min-width:1281px){#dllink{display:none}}
@media (max-width:1280px){#top #share,#top #keys-open{display:none}}
@media (max-width:1100px){#top #geo-open{font-size:0;gap:0;width:32px;padding:0;justify-content:center}#top #pill{font-size:0;gap:0}}
@media (max-width:960px){#top #grp-sight .gl,#top .sep{display:none}#top{gap:6px}}
@media (max-width:880px){#top #gal-open .chev,#top #chat-open .lbl{display:none}#top #chat-open{gap:0}#top #gal-open .slab{gap:6px}#top{gap:4px}#top #grp-sight{gap:4px}}
@media (max-width:820px){#mobslot #grp-sight{grid-template-columns:32px minmax(0,1fr) 32px 32px}}   /* prev, picker, next, random on one row in the phone drawer */
/* ==== ux4 features: end ==== */
/* ---- ux4 pivot: stage "re-centre" chip (viewer3d.js #v3-pivot), shown while the orbit centre is off the galaxy;
   top right of the 3D stage (the message sits top left; in fullscreen it drops under the Controls/Exit pair), glass like
   the stage overlays (.v3d tokens), hidden in the Spectra-tab thumbnail ---- */
.v3d-pv{position:absolute;top:10px;right:10px;z-index:3;display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 11px 0 9px;
  border:1px solid var(--s-edge,rgba(200,215,240,.16));border-radius:999px;cursor:pointer;color:var(--s-ink,#e9eef4);font:500 12px var(--sans,system-ui,sans-serif);
  background:linear-gradient(180deg,rgba(255,255,255,.12),rgba(255,255,255,0) 70%),var(--s-mat,rgba(12,16,22,.74));
  box-shadow:var(--s-hi,inset 0 1px 0 rgba(255,255,255,.10)),0 4px 14px rgba(0,0,0,.30);backdrop-filter:var(--s-blur,blur(24px) saturate(1.5));-webkit-backdrop-filter:var(--s-blur,blur(24px) saturate(1.5));
  animation:v3d-pv-in .18s ease-out}
.v3d-pv[hidden],.v3d-thumb .v3d-pv{display:none}
.v3d.v3d-fs .v3d-pv,.v3d:fullscreen .v3d-pv{top:48px}
.v3d-pv svg{width:14px;height:14px;flex:none;color:var(--s-accent,#7db2f0)}
.v3d-pv:hover{background:linear-gradient(180deg,rgba(255,255,255,.18),rgba(255,255,255,.05)),var(--s-mat,rgba(12,16,22,.74))}
.v3d-pv:active{box-shadow:inset 0 1px 2px rgba(0,0,0,.35)}
.v3d-pv:focus-visible{outline:2px solid var(--s-accent,#7db2f0);outline-offset:2px}
@keyframes v3d-pv-in{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.v3d-pv{animation:none}}
/* ---- default scale (2026-11): on large screens the page renders at 112 %, what the owner preferred with browser zoom.
   Phones and narrow windows keep 100 %. Browser zoom still works on top of it. ---- */
:root{--uiz:1;--vh:1vh;--vw:1vw}
/* viewport units do not follow CSS zoom, so every vh/vw size in the page reads var(--vh)/var(--vw), divided by the zoom:
   the 3D stage and the drawers then still fit the window exactly */
@media (min-width:1400px){:root{--uiz:1.12;--vh:calc(1vh / 1.12);--vw:calc(1vw / 1.12)}html{zoom:var(--uiz)}}
/* at 125 % a 1400 to 1900 px screen lays out like 1120 to 1520 px: keep the top bar on one line by showing the status as a
   dot only and Find and New ray as icons (their tips still name them) */
@media (min-width:1400px) and (max-width:1900px){
  #pill{font-size:0;gap:0}
  #find-toggle .lbl{display:none}
  #geo-open{font-size:0;gap:0;width:32px;padding:0;justify-content:center}
  #geo-open svg{width:14px;height:14px}
  #title{font-size:12px}
}

/* 3D orbit button: top-right of the full stage (the scale bar owns bottom-centre); the re-centre chip sits below it */
.v3d-orb{position:absolute;top:10px;right:10px;z-index:3;display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 12px 0 10px;
  border:1px solid var(--s-edge,rgba(200,215,240,.16));border-radius:999px;cursor:pointer;color:var(--s-ink,#e9eef4);font:500 12px var(--sans,system-ui,sans-serif);
  background:linear-gradient(180deg,rgba(255,255,255,.12),rgba(255,255,255,0) 70%),var(--s-mat,rgba(12,16,22,.74));
  box-shadow:var(--s-hi,inset 0 1px 0 rgba(255,255,255,.10)),0 4px 14px rgba(0,0,0,.30);backdrop-filter:var(--s-blur,blur(24px) saturate(1.5));-webkit-backdrop-filter:var(--s-blur,blur(24px) saturate(1.5))}
.v3d-orb svg{width:14px;height:14px;flex:none}
.v3d-orb[aria-pressed=true]{border-color:var(--s-accent,#7db2f0)}
.v3d-orb[aria-pressed=true] svg{color:var(--s-accent,#7db2f0)}
.v3d-orb:focus-visible{outline:2px solid var(--s-accent,#7db2f0);outline-offset:2px}
.v3d-thumb .v3d-orb{display:none}

.v3d-pv{top:46px}
.v3d.v3d-fs .v3d-orb,.v3d:fullscreen .v3d-orb{top:48px}
.v3d.v3d-fs .v3d-pv,.v3d:fullscreen .v3d-pv{top:84px}

/* ==== galaxy picker (galaxy-sample web contract; js/galaxies.js) BEGIN ==== */
#grp-gal[hidden]{display:none}
#gxy-open{gap:6px}
#gxy-open .gxg{width:15px;height:15px;color:var(--accent)}
#gxy-open .glab{font:500 12px var(--mono)}
#gxy-open .chev{width:11px;height:11px;color:var(--muted)}
#gxy-open[data-state=loading]{opacity:.65;cursor:progress}
#gxy-open[data-state=loading] .gxg{animation:gxy-spin 1.1s linear infinite}
@keyframes gxy-spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){#gxy-open[data-state=loading] .gxg{animation:none}}
#gxy-pop{width:500px;max-width:min(500px,calc(calc(100 * var(--vw, 1vw)) - 24px));padding:10px}
.gxycur{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 12px;margin:0 0 8px;padding:2px 2px 9px;border-bottom:1px solid var(--mat-edge-c,var(--gline))}
.gxycur .gxid{font:600 14px var(--mono);color:var(--ink)}
.gxycur .gxk{font:500 11px var(--sans);color:var(--muted)}
.gxycur .pv{font:500 11.5px var(--mono);color:var(--ink);white-space:nowrap}
.gxycur .pv i{font-style:normal;color:var(--muted);margin-right:5px;font-family:var(--sans);font-size:11px}
#gxy-pop .fl{display:flex;gap:6px;margin-bottom:6px}
#gxy-search,#gxy-filter{height:32px;border:1px solid var(--gline);border-radius:9px;background:rgba(127,127,160,.08);padding:0 10px;font:12px var(--mono);min-width:0;color:inherit}
#gxy-search{flex:1}
.gxyhead,#gxy-list li{display:grid;grid-template-columns:70px repeat(3,minmax(0,1fr)) 124px;gap:6px;align-items:center}
.gxyhead{padding:0 9px 4px;border-bottom:1px solid var(--mat-edge-c,var(--gline));margin-bottom:4px}
.gxs{border:0;background:none;padding:3px 0;font:500 10.5px var(--sans);color:var(--muted);cursor:pointer;text-align:right;display:flex;justify-content:flex-end;gap:3px;border-radius:6px}
.gxs:first-child{justify-content:flex-start;text-align:left}
.gxs:hover,.gxs[aria-sort=ascending],.gxs[aria-sort=descending]{color:var(--ink)}
.gxs:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.gxs b{font-weight:500;color:var(--accent);min-width:8px}
#gxy-list{list-style:none;margin:0;padding:0;max-height:340px;overflow:auto;position:relative}
#gxy-list li{padding:6px 9px;border-radius:8px;cursor:pointer;font:500 12px var(--mono)}
#gxy-list li:hover{background:rgba(127,127,160,.09)}
#gxy-list li.hl{background:var(--hl);box-shadow:inset 0 0 0 1px var(--accent)}
#gxy-list li[aria-selected=true] .gxid{color:var(--accent)}
#gxy-list .num{text-align:right;font:11.5px var(--mono);color:var(--ink)}
#gxy-list .gxt{display:flex;justify-content:flex-end;gap:4px;white-space:nowrap}
.gxs{white-space:nowrap}
#gxy-list .tag.dim{color:var(--muted)}
#gxy-list li.empty{display:flex;justify-content:center;gap:8px;cursor:default;padding:16px 9px;color:var(--muted);font-family:var(--sans)}
#gxy-list li.empty:hover{background:none}
#gxy-pop .galf .msg{font:10.5px var(--sans);color:var(--muted);margin:0}
@media (max-width:480px){.gxyhead,#gxy-list li{grid-template-columns:62px repeat(3,minmax(0,1fr)) 40px}#gxy-list .tag.dim{display:none}}
/* ==== galaxy picker END ==== */
/* ---- top bar never overlaps at any width or browser zoom (owner 2026-11-13). Groups keep their content width; only the
   sightline label shrinks (ellipsis); text labels collapse to icons step by step as the bar narrows ---- */
#top>*{flex-shrink:0}
#top .grp{min-width:auto}
#top #grp-sight{min-width:0;flex-shrink:1}
#top #gal-open{min-width:48px;flex-shrink:1;overflow:hidden}
#top #gal-open .slab{min-width:0;overflow:hidden;text-overflow:ellipsis}
#top .sp{min-width:4px;flex:1 1 4px}
@media (max-width:1650px){#top .gl{display:none}}
@media (max-width:1240px){#top #geo-open{font-size:0;gap:0;width:32px;padding:0;justify-content:center}#top #pill{font-size:0;gap:0}#find-toggle .lbl{display:none}}
@media (max-width:1100px){#top #gal-open .pv,#top #gal-open .chev{display:none}#top .sep{display:none}}
@media (max-width:980px){#top #title{display:none}#top #chat-open .lbl{display:none}}

/* ---- Data and credits (2026-11): the #pop-licence dialog (Simulation, Spectra, Code and data) at a readable size, and its
   footer at the bottom of the side column (the phone Controls drawer below 821 px) ---- */
#pop-licence{width:480px;max-width:min(480px,calc(calc(100 * var(--vw, 1vw)) - 24px));padding:16px 18px}
#pop-licence h3{font:600 15px var(--sans);color:var(--ink);margin:0 0 4px}
#pop-licence h4{margin:12px 0 4px;font:600 13px var(--sans);letter-spacing:.02em;color:var(--ink)}
#pop-licence p{font-size:14px;line-height:1.55;margin:0 0 7px}
#pop-licence p.ack{font-size:12.5px;line-height:1.5}
#pop-licence a{color:var(--accent);overflow-wrap:anywhere}
#pop-licence .cur-l{color:var(--ink);font-weight:600}
#credits-foot{margin-top:auto;display:flex;flex-direction:column;align-items:flex-start;gap:2px;padding:4px 6px 0;font:12px/1.4 var(--sans);color:var(--muted)}
#credits-foot .lk{font-size:13px;padding:2px 0}
#credits-foot .lk:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
