*{box-sizing:border-box;}
html,body{margin:0;height:100%;background:var(--bg);color:var(--text);
  font-family:'Inter','Segoe UI',ui-sans-serif,system-ui,sans-serif;overflow:hidden;}
::-webkit-scrollbar{width:9px;height:9px;}
::-webkit-scrollbar-track{background:var(--panel);}
::-webkit-scrollbar-thumb{background:var(--surface-hover);border-radius:6px;}
::-webkit-scrollbar-thumb:hover{background:var(--accent);}
*{scrollbar-width:thin;scrollbar-color:var(--surface-hover) var(--panel);}
/* A2/A3: hidden until storage/vault.js's openVault()/createVault() shows it — the launcher
   (ui/launcher.js, ui/styles/launcher.css) is what's visible before then. Same .show convention as
   every overlay in this app, just inverted (this one starts hidden, not the other way round). */
#app{position:relative;width:100vw;height:100vh;display:none;}
#app.show{display:block;}
svg#stage{width:100%;height:100%;display:block;background:
  radial-gradient(ellipse at 30% 20%, #10162a 0%, var(--bg) 55%),
  radial-gradient(ellipse at 80% 80%, #1a1030 0%, transparent 60%);cursor:grab;}
svg#stage.panning{cursor:grabbing;}
svg#stage.linking, svg#stage.unlinking{cursor:crosshair;}
/* z-index:25, not 10: #topbar and #panelLeft/#panel never overlap in normal flow (topbar is 0-52px
   tall, the side panels start exactly at 52px), so this only matters for a descendant that spills
   past that boundary — #titleMenu (ui/title-menu.js), whose own z-index:70 (overlays.css) is
   otherwise trapped inside #topbar's stacking context and loses to a side panel's z-index:20
   regardless. 25 clears both panels (20) while staying below every actual overlay tier (60+). */
#topbar{position:absolute;top:0;left:0;right:0;height:52px;display:flex;align-items:center;gap:8px;
  padding:0 14px;background:linear-gradient(180deg,#05060a 0%, rgba(5,6,10,0) 100%);z-index:25;pointer-events:none;}
#topbar > *{pointer-events:auto;}
#topbar .title{font-weight:700;letter-spacing:.5px;margin-right:6px;font-size:15px;position:relative;}
#titleBtn{display:flex;align-items:center;gap:7px;cursor:pointer;user-select:none;}
.pill{display:flex;align-items:center;gap:6px;background:rgba(24,22,29,.85);border:1px solid var(--line);
  border-radius:20px;padding:6px 12px;font-size:12px;cursor:pointer;color:var(--text);
  backdrop-filter:blur(6px);user-select:none;transition:.15s;}
.pill:hover{border-color:var(--accent);color:var(--accent);}
.pill.round{width:30px;height:30px;padding:0;justify-content:center;border-radius:50%;font-weight:700;}
.pill.round.active{border-color:var(--accent);color:var(--accent);background:rgba(255,62,119,.15);}
.dot{width:9px;height:9px;border-radius:50%;display:inline-block;flex-shrink:0;}
.dot.nebulosa{background:var(--nebulosa-fill);} .dot.sol{background:var(--sol-fill);}
.dot.planeta{background:var(--planeta-fill);} .dot.luna{background:var(--luna-fill);} .dot.idea{background:var(--idea-fill);}
#modeIndicator{display:none;}
#saveToast{position:absolute;top:60px;right:16px;font-size:11px;color:var(--dim);
  background:rgba(24,22,29,.85);border:1px solid var(--line);border-radius:8px;padding:5px 10px;
  opacity:0;transition:opacity .4s;z-index:9;pointer-events:none;}
#saveToast.show{opacity:1;}
/* Background split-migration sweep (storage/vault.js's runMigrationSweep, shown via app.js) —
   offset below #saveToast so the two can be visible at once without overlapping. Reuses
   ui/styles/overlays.css's sync-spin keyframe (same stylesheet-load, no need to redefine it). */
#migrationSweepIndicator{position:absolute;top:90px;right:16px;font-size:11px;color:var(--dim);
  background:rgba(24,22,29,.85);border:1px solid var(--line);border-radius:8px;padding:5px 10px;
  display:none;align-items:center;gap:7px;z-index:9;pointer-events:none;}
#migrationSweepIndicator.show{display:flex;}
#migrationSweepIndicator .spinner{width:10px;height:10px;border-radius:50%;flex-shrink:0;
  border:2px solid var(--line);border-top-color:var(--accent);animation:sync-spin .8s linear infinite;}
#zoom{display:flex;gap:6px;margin-left:auto;}
#zoom .pill{padding:6px 10px;}
