/* ====================================================================
   weltgraph-rpg — v2 layout, v3 "Champagne" editorial design system.
   ONE place to retune everything: the tokens below. Everything uses
   var(--…). Swap the [PEWTER] values for the cool variant.
   ==================================================================== */
:root{
  /* spacing (4px base) */
  --sp1:4px; --sp2:8px; --sp3:12px; --sp4:16px; --sp5:24px; --sp6:32px; --sp7:48px; --sp8:64px;

  /* LAYERS — one scale for desktop AND mobile. Never write a raw z-index:
     the order below IS the design. Read it top-down = back to front. */
  --z-nav:10;        /* mobile bottom navigation (app chrome)      */
  --z-dock:20;       /* dock / character bottom sheet              */
  --z-journal:40;    /* full-screen journal overlay                */
  --z-hover:50;      /* hover card — floats above panels it points at */
  --z-home:60;       /* start hub — a screen of its own, covers the game */
  --z-palette:70;    /* command palette (Ctrl+K)                   */
  --z-modal:80;      /* dialogs                                    */
  --z-toast:90;      /* transient messages                         */
  --z-login:100;     /* auth gate — above everything               */

  /* INK — near-black, faintly cool (never #000) */
  --ink9:#0F1216;  /* page ground            [PEWTER #0D1014] */
  --ink85:#12161B; /* bars                   [PEWTER #10141B] */
  --ink8:#161A20;  /* cards / panels         [PEWTER #141821] */
  --ink7:#1F242C;  /* hover / inputs / tracks[PEWTER #1D2230] */
  --ink65:#262D37; /* selection */
  --line:#2C333D;  /* hairlines              [PEWTER #2B3140] */
  --line-soft:#222932;

  /* TEXT — off-white (never #fff) */
  --t1:#ECEAE4; --t2:#CBC6BA; --t3:#8B8574; --t4:#6B6555;

  /* ACCENT — ONE accent, ≤8% of the screen */
  --accent:#C9B489;      /* champagne              [PEWTER #AEBBCC] */
  --accent-hi:#DBC79E;   /*                        [PEWTER #C4CFDD] */
  --accent-dim:#7E6E45;  /* ticks / quiet accent   [PEWTER #5C6675] */
  --accent-tint:rgba(201,180,137,.12); /*          [PEWTER rgba(174,187,204,.12)] */
  --on-accent:#14171B;

  /* SEMANTIC — desaturated */
  --ok:#7FB58C; --bad:#D98C82;
  --c-char:#8AA6C2; --c-loc:#93A98A; --c-fac:#C08C6B; --c-item:#B8A98A;

  /* type — premium editorial (no Inter/Roboto) */
  --ui:"Instrument Sans",system-ui,sans-serif;
  --serif:"Newsreader",Georgia,serif;
  --display:"Fraunces",Georgia,serif;
  --mono:"IBM Plex Mono",ui-monospace,monospace;
  --spring:cubic-bezier(.32,.72,0,1);

  /* legacy aliases so dev.html / dev.js keep resolving old var names */
  --ink-900:var(--ink9); --ink-850:var(--ink85); --ink-800:var(--ink8);
  --ink-700:var(--ink7); --ink-650:var(--ink65);
  --bg:var(--ink9); --bg2:var(--ink8); --bg3:var(--ink7); --border:var(--line);
  --fg:var(--t2); --muted:var(--t3); --warn:var(--accent);
  --accent2:var(--ok); --info:var(--c-char); --brass:var(--accent); --brass-dim:var(--accent-dim);
  --steel:var(--c-char); --moss:var(--c-loc); --rust:var(--c-fac);
  --entity-character:var(--c-char); --entity-location:var(--c-loc); --entity-faction:var(--c-fac);
  --text-200:var(--t1); --text-300:var(--t2); --text-500:var(--t3); --text-600:var(--t4);
}
*{box-sizing:border-box;margin:0}
html,body{height:100%}
/* Symbols like ⚙ ✒ ☠ ✖ ⚠ have an emoji variant. When the UI font lacks the
   glyph, phones fall back to the emoji font and render them as colour emoji —
   so half the icon row goes technicolor while the rest stays as line art.
   Ask for the text form everywhere; the \FE0E in the markup does the same for
   browsers without this property. */
html{font-variant-emoji:text}
body{background:var(--ink9);color:var(--t1);font:14px/1.5 var(--ui);
  -webkit-font-smoothing:antialiased;display:flex;flex-direction:column;overflow:hidden}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
input,textarea,select{font:inherit;color:var(--t1);background:var(--ink7);
  border:1px solid var(--line);border-radius:4px;padding:6px 9px}
::selection{background:var(--accent-tint)}
*{scrollbar-width:thin;scrollbar-color:var(--ink65) transparent}
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-thumb{background:var(--ink65);border-radius:5px}
::-webkit-scrollbar-track{background:transparent}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* shared atoms */
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}
.muted{color:var(--t3)}
.overline,.dock-label,.detail-key,.d-label{font:600 10px var(--ui);
  letter-spacing:.2em;text-transform:uppercase;color:var(--t4)}

/* avatar — monochrome, differentiated by SHAPE not loud colour */
.av,.avatar{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  border:1px solid var(--line);background:var(--ink9);color:var(--t2);
  font:500 12px var(--ui);border-radius:50%;width:30px;height:30px}
.av-24{width:24px;height:24px;font-size:11px}
.av-40{width:40px;height:40px;font-size:15px;font-family:var(--display)}
.av-56{width:56px;height:56px;font-size:20px;font-family:var(--display)}
.av-you,.av-player{border-color:var(--accent);color:var(--accent)}
.av-location,.av-place{border-radius:6px}
.av-faction{border-radius:6px}
.av-character{}
.recent-dot{color:var(--accent);font-size:9px;margin-left:6px}

/* badges */
.badge,.trust-badge{display:inline-flex;align-items:center;gap:5px;font:500 10.5px var(--mono);
  padding:2px 9px;border:1px solid var(--line);border-radius:100px;color:var(--t3)}
.badge.accent{color:var(--accent);border-color:color-mix(in srgb,var(--accent) 34%,transparent)}
.badge.pos,.trust-badge.pos{color:var(--ok);border-color:color-mix(in srgb,var(--ok) 32%,transparent)}
.badge.neg,.trust-badge.neg{color:var(--bad);border-color:color-mix(in srgb,var(--bad) 32%,transparent)}

/* buttons */
.ghost,button.ghost{border:1px solid transparent;color:var(--t3);border-radius:4px;
  padding:5px 10px;font:500 12px var(--ui);transition:border-color .2s,color .2s}
.ghost:hover{border-color:var(--line);color:var(--t1)}
.primary,button.primary{background:var(--accent);color:var(--on-accent);border:1px solid var(--accent);
  border-radius:4px;font-weight:600}
.primary:hover{background:var(--accent-hi);border-color:var(--accent-hi)}

/* ═══════════════════════════ topbar ═══════════════════════════ */
#topbar{display:flex;align-items:center;gap:var(--sp4);height:52px;padding:0 var(--sp5);
  background:var(--ink85);border-bottom:1px solid var(--line);flex:0 0 auto}
#topbar .brand{font:600 13px var(--display);letter-spacing:.16em;color:var(--accent);text-transform:uppercase}
.scene-crumbs{display:flex;align-items:baseline;gap:var(--sp3);min-width:0;overflow:hidden}
#scene-location{font:600 13px var(--display);letter-spacing:.08em;color:var(--t1);
  text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
#scene-location:hover{color:var(--accent)}
#scene-crumb{font:500 11px var(--mono);color:var(--t3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.topbar-spacer{flex:1}
.topbar-sep{width:1px;height:18px;background:var(--line)}
#clock{font:500 11px var(--mono);color:var(--t3);letter-spacing:.04em}
.searchbtn{display:flex;align-items:center;gap:var(--sp2);padding:6px 12px;border:1px solid var(--line-soft);
  border-radius:4px;color:var(--t4);font:500 12px var(--ui)}
.searchbtn kbd{font:500 10px var(--mono);border:1px solid var(--line-soft);border-radius:3px;padding:1px 5px}
.searchbtn:hover{border-color:var(--line);color:var(--t2)}
#topbar select{background:none;border:1px solid transparent;color:var(--t3);max-width:170px;padding:4px}
#topbar select:hover{border-color:var(--line);color:var(--t1)}
#btn-app-settings{color:var(--t3);font-size:16px;line-height:1;padding:4px 7px}
#btn-app-settings:hover{color:var(--accent)}
/* home = wordmark + ⌂, one clickable unit back to the hub */
.home-link{display:flex;align-items:center;gap:var(--sp2);padding:4px 8px 4px 5px;border-radius:6px;transition:background .2s}
.home-link:hover{background:var(--ink7)}
.home-link .hl-ic{font-size:18px;line-height:1;color:var(--t3)}
.home-link:hover .hl-ic{color:var(--accent)}
#dev-link{color:var(--t4);font-size:11px;text-decoration:none;opacity:.7}
#dev-link:hover{opacity:1;color:var(--accent)}

/* ═══════════════════════════ stage ═══════════════════════════ */
#stage{flex:1;display:flex;justify-content:center;gap:var(--sp7);min-height:0;padding:0 var(--sp6)}
#col-story{flex:0 1 680px;min-width:0;display:flex;flex-direction:column}
#chat{flex:1;overflow-y:auto;padding:var(--sp6) var(--sp4) var(--sp5) 0}

/* prose + feed */
.msg{max-width:64ch;margin:0 0 var(--sp4);white-space:pre-wrap}
.msg.narrator{font:400 18px/1.66 var(--serif);letter-spacing:.003em;color:var(--t1);text-wrap:pretty}
/* While the narration streams in, text-wrap:pretty re-balances the WHOLE
   paragraph on every appended word, so words already on screen jump between
   lines — worst on a narrow phone column. Balance once, at the end. */
.msg.narrator.streaming{text-wrap:wrap}
.msg.player{margin-top:var(--sp6);font:italic 16.5px/1.55 var(--serif);color:var(--accent);white-space:pre-wrap}
.msg.player:first-child{margin-top:0}
.msg.player::before{content:"\203A\00A0";font-style:normal;opacity:.6}
.msg.player.say::before{content:"\00BB\00A0"}
.msg.player.story{color:var(--t3)}
.msg.player.story::before{content:"\270E\00A0"}
.msg.system{color:var(--t3);font:12px var(--mono)}
.msg.system.rolls{white-space:normal;max-width:none}
.msg.welcome{color:var(--t3);font:italic 16px/1.6 var(--serif);border:none;padding:0;max-width:52ch}

/* entity link in prose — quiet dotted underline, solid on hover */
.ent{cursor:pointer;color:var(--accent);border-bottom:1px dotted color-mix(in srgb,var(--accent) 45%,transparent);
  transition:border-color .12s}
.ent:hover{border-bottom-style:solid}
.ent.character{color:var(--c-char);border-bottom-color:color-mix(in srgb,var(--c-char) 45%,transparent)}
.ent.location{color:var(--c-loc);border-bottom-color:color-mix(in srgb,var(--c-loc) 45%,transparent)}
.ent.faction{color:var(--c-fac);border-bottom-color:color-mix(in srgb,var(--c-fac) 45%,transparent)}

/* roll card */
.rollcard{background:var(--ink8);border:1px solid var(--line);max-width:440px;margin:var(--sp5) 0;
  padding:var(--sp4) var(--sp4) 14px;position:relative;white-space:normal}
.rollcard::before,.rollcard::after{content:"";position:absolute;width:8px;height:8px;top:-1px}
.rollcard::before{left:-1px;border-top:1px solid var(--accent);border-left:1px solid var(--accent)}
.rollcard::after{right:-1px;border-top:1px solid var(--accent);border-right:1px solid var(--accent)}
.rollcard.fail::before,.rollcard.fail::after{border-color:var(--bad)}
.rc-head{display:flex;justify-content:space-between;align-items:baseline}
.rc-head .t{font:600 10.5px var(--ui);letter-spacing:.18em;color:var(--t3);text-transform:uppercase}
.rc-head .dc{font:500 11px var(--mono);color:var(--t3)}
.rc-body{display:flex;align-items:center;gap:var(--sp4);margin-top:var(--sp3);flex-wrap:wrap}
.rc-total{font:500 30px/1 var(--mono);color:var(--t1)}
.rc-chips{display:flex;gap:var(--sp2);flex-wrap:wrap}
.rc-chips span{font:500 10.5px var(--mono);padding:3px 8px;border:1px solid var(--line-soft);
  border-radius:3px;color:var(--t3);background:var(--ink9)}
.rc-verdict{margin-left:auto;font:700 10.5px var(--ui);letter-spacing:.14em;color:var(--ok);text-transform:uppercase}
.rollcard.fail .rc-verdict{color:var(--bad)}
.rc-verdict::before{content:"\25C6\00A0";font-size:9px}
.rollcard.dealt{animation:dealIn .35s var(--spring)}
@keyframes dealIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.rollcard.crit::before,.rollcard.crit::after{border-color:var(--accent)}
.rollcard.crit .rc-verdict{text-shadow:0 0 12px color-mix(in srgb,var(--accent) 55%,transparent)}
.rollcard.fumble .rc-total{color:var(--bad)}

/* event pills */
.msg.event{display:table;width:auto;max-width:none;font:500 11px var(--mono);letter-spacing:.04em;
  padding:4px 11px;border:1px solid var(--line-soft);border-radius:100px;color:var(--t3);margin:0 0 6px}
.msg.event.gold{color:var(--accent);border-color:color-mix(in srgb,var(--accent) 30%,transparent)}
.msg.event.xp{color:var(--ok);border-color:color-mix(in srgb,var(--ok) 30%,transparent)}
.msg.event.quest{color:var(--c-char);border-color:color-mix(in srgb,var(--c-char) 30%,transparent)}
.msg.event.warn{color:var(--bad);border-color:color-mix(in srgb,var(--bad) 40%,transparent)}
.msg.event.combat{color:var(--t2)}

/* moment cards: combat / divider / banner / item */
.combat-card,.msg.combat-card{background:var(--ink8);border:1px solid var(--line);border-left:2px solid var(--bad);
  padding:var(--sp3) var(--sp4);max-width:440px;margin:var(--sp5) 0;white-space:normal}
.combat-head{font:600 10.5px var(--ui);letter-spacing:.18em;text-transform:uppercase;color:var(--bad);margin-bottom:var(--sp2)}
.combat-row{display:flex;align-items:center;gap:var(--sp3);padding:3px 0;font:500 12px var(--mono);color:var(--t2)}
.combat-row .combat-actors{flex:0 0 auto;min-width:130px}
.combat-row.enemy .combat-actors{color:var(--bad)}
.dmg-pop{color:var(--bad);font-weight:700}
.combat-downed{color:var(--bad);font-weight:600}
.mini-bar{flex:1 1 auto;height:4px;background:var(--ink9);border:1px solid var(--line-soft);max-width:100px}
.mini-bar>div{height:100%;background:var(--bad);transition:width .4s var(--spring)}
.mini-bar.hp-you>div{background:var(--ok)}

.divider-card,.msg.divider-card{max-width:none;text-align:center;margin:var(--sp6) 0;padding:var(--sp3) 0;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);white-space:normal}
.divider-line{font:600 11px var(--ui);letter-spacing:.22em;text-transform:uppercase;color:var(--t3)}
.divider-card.travel .divider-line{color:var(--c-loc)}
.divider-card.rest .divider-line{color:var(--accent)}
.divider-card .info-line{font:500 12px var(--mono);margin-top:6px;color:var(--t3)}
.info-line.heal{color:var(--ok)}

.banner-card,.msg.banner-card{background:var(--ink8);border:1px solid var(--line);border-left:2px solid var(--accent);
  padding:var(--sp4);max-width:440px;margin:var(--sp5) 0;white-space:normal;animation:dealIn .35s var(--spring)}
.banner-title{font:600 12px var(--ui);letter-spacing:.06em;color:var(--accent)}
.banner-card.done{border-left-color:var(--ok)} .banner-card.done .banner-title{color:var(--ok)}
.banner-card.failed{border-left-color:var(--bad)} .banner-card.failed .banner-title{color:var(--bad)}
.banner-card.levelup .banner-title{font-family:var(--display);letter-spacing:.1em}
.banner-card .info-line{color:var(--t3);margin-top:5px;font-size:13px}
.banner-card .toolbar{display:flex;gap:var(--sp2);flex-wrap:wrap;padding-top:var(--sp3)}

.item-card,.msg.item-card{background:var(--ink8);border:1px solid var(--line);padding:9px 14px;
  max-width:420px;margin:var(--sp4) 0;white-space:normal}
.item-card.received{border-left:2px solid var(--ok)}
.item-card.lost{border-left:2px solid var(--t4);opacity:.85}
.item-title{font:500 12.5px var(--ui);color:var(--t1)}
.item-card.clickable{cursor:pointer}
.item-card.clickable:hover{border-color:var(--accent)}
.spend-btn{padding:1px 8px;color:var(--ok);border:1px solid color-mix(in srgb,var(--ok) 40%,transparent);
  border-radius:4px;font-weight:700;margin-left:6px}

/* ═══════════════════════════ composer ═══════════════════════════ */
#composer{flex:0 0 auto;padding:0 var(--sp4) var(--sp5) 0}
#turn-actions{display:flex;justify-content:flex-end;gap:var(--sp1);padding:0 0 var(--sp2);min-height:22px}
#turn-actions button{color:var(--t4);font:500 10.5px var(--ui);letter-spacing:.08em;padding:3px 8px;text-transform:uppercase}
#turn-actions button:hover{color:var(--accent)}
#input-row{display:flex;align-items:stretch;background:var(--ink8);border:1px solid var(--line);border-radius:6px;overflow:hidden}
#mode-switch{display:flex;border-right:1px solid var(--line-soft)}
#mode-switch button{font:600 10.5px var(--ui);letter-spacing:.1em;color:var(--t3);padding:0 14px;text-transform:uppercase}
#mode-switch button.active{color:var(--on-accent);background:var(--accent)}
#player-input{flex:1;background:none;border:none;outline:none;resize:none;overflow-y:hidden;
  font:italic 15.5px/1.5 var(--serif);color:var(--t1);padding:13px var(--sp4);max-height:140px}
#player-input::placeholder{color:var(--t4)}
#btn-continue,#btn-send{border:none;border-left:1px solid var(--line-soft);border-radius:0;background:none;
  font:600 10.5px var(--ui);letter-spacing:.14em;text-transform:uppercase;padding:0 var(--sp4)}
#btn-continue{color:var(--t3)} #btn-continue:hover{color:var(--accent)}
#btn-send{color:var(--accent)} #btn-send.primary{background:none;color:var(--accent)}
#btn-send:hover{background:var(--accent);color:var(--on-accent)}
#col-story.low-hp #chat{box-shadow:inset 0 0 60px color-mix(in srgb,var(--bad) 12%,transparent)}

/* ═══════════════════════════ dock ═══════════════════════════ */
#dock{flex:0 0 300px;padding:var(--sp6) 0 var(--sp5);display:flex;flex-direction:column;gap:var(--sp5);overflow-y:auto}
.dock-sec{background:var(--ink8);border:1px solid var(--line);border-radius:8px;padding:var(--sp4)}
.dock-label{margin-bottom:var(--sp3)}
.you-row{display:flex;align-items:center;gap:var(--sp3);cursor:pointer}
.you-row:hover .pname{color:var(--accent)}
.pname{font:600 15px var(--display);letter-spacing:.06em;color:var(--t1)}
.prole{font:italic 12.5px var(--serif);color:var(--t3);margin-top:2px}
.vitals{display:flex;gap:var(--sp4);margin-top:var(--sp4)}
.vital{flex:1}
.vital .lab{display:flex;justify-content:space-between;font:500 10.5px var(--mono);color:var(--t3);
  margin-bottom:6px;letter-spacing:.05em}
.vital .lab b{color:var(--t1);font-weight:500}
.vital .tr{height:4px;background:var(--ink7);border-radius:2px;overflow:hidden}
.vital .tr>div{height:100%;background:var(--ok)}
.vital.gold .lab b{color:var(--accent)}
.vital .tr.flash-damage{animation:hpFlash .6s ease-out}
@keyframes hpFlash{0%{box-shadow:0 0 0 2px var(--bad)}100%{box-shadow:none}}
.flash-gold{animation:goldTick .6s ease-out}
@keyframes goldTick{0%{transform:scale(1.25)}100%{transform:none}}
.levelup-banner{margin-top:var(--sp3);padding:6px 10px;border:1px solid var(--accent-dim);border-radius:4px;
  color:var(--accent);font:500 11px var(--ui)}
.face-row{display:flex;flex-direction:column;gap:var(--sp3)}
.face{display:flex;align-items:center;gap:var(--sp3);cursor:pointer}
.face .fname{font:500 13px var(--ui);color:var(--t2)}
.face .fmood{font:italic 12px var(--serif);color:var(--t4)}
.face:hover .fname{color:var(--t1)}
.dock-empty{font:italic 12.5px var(--serif);color:var(--t4)}
.quest-title{display:flex;gap:var(--sp2);align-items:baseline;font:600 13px var(--ui);color:var(--t1)}
.quest-title::before{content:"\2726";color:var(--accent);font-size:12px}
.quest-desc{font:italic 13px var(--serif);color:var(--t3);margin-top:var(--sp2);line-height:1.5}
.dock-btnrow{display:flex;gap:var(--sp3)}
.journal-btn{flex:1;display:flex;align-items:center;justify-content:center;gap:var(--sp2);padding:12px;
  border:1px solid var(--accent-dim);border-radius:6px;color:var(--accent);font:600 11px var(--ui);
  letter-spacing:.14em;text-transform:uppercase;transition:background .2s,color .2s}
.journal-btn:hover{background:var(--accent);color:var(--on-accent)}
.journal-btn kbd{font:500 10px var(--mono);border:1px solid currentColor;border-radius:3px;padding:0 5px;opacity:.7}
.cta{width:100%;margin-top:var(--sp3);padding:10px}

/* ═══════════════════════════ hover card ═══════════════════════════ */
#hovercard{position:fixed;z-index:var(--z-hover);width:320px;background:var(--ink8);border:1px solid var(--line);
  border-radius:8px;box-shadow:0 16px 40px #000a;padding:var(--sp4);display:none}
#hovercard.open{display:block}
.hc-head{display:flex;gap:var(--sp3);align-items:center}
.hc-name{font:600 14px var(--display);letter-spacing:.04em}
.hc-type{font:500 10px var(--ui);letter-spacing:.14em;color:var(--t4);text-transform:uppercase;margin-top:2px}
.hc-know{font:italic 14px/1.55 var(--serif);color:var(--t2);margin-top:var(--sp3)}
.hc-meta{display:flex;gap:var(--sp2);margin-top:var(--sp3);flex-wrap:wrap}

.d-head{display:flex;gap:var(--sp4);align-items:center;margin-bottom:var(--sp3)}
.d-nm{font:600 21px var(--display);letter-spacing:-.005em}
.d-ty{font:600 10px var(--ui);letter-spacing:.16em;color:var(--t4);text-transform:uppercase;margin-top:3px}
.d-ep{font:italic 15px/1.55 var(--serif);color:var(--t2);margin-top:var(--sp3)}
.d-badges{display:flex;gap:var(--sp2);margin-top:var(--sp4);flex-wrap:wrap}
.d-sec{margin-top:var(--sp5);padding-top:var(--sp5);border-top:1px solid var(--line-soft)}
.d-label{margin-bottom:var(--sp3)}
.d-know{font:400 14.5px/1.6 var(--serif);color:var(--t2)}
.fact{display:flex;justify-content:space-between;gap:var(--sp4);padding:8px 0;border-bottom:1px dotted var(--line-soft)}
.fact .k{color:var(--t3);font:500 12px var(--ui)}
.fact .v{color:var(--t1);font:500 12.5px var(--mono);text-align:right}
.d-conn{display:flex;flex-direction:column;gap:var(--sp2)}
.d-conn .lc{display:flex;align-items:center;gap:var(--sp3);padding:8px 10px;border:1px solid var(--line-soft);
  border-radius:6px;cursor:pointer;transition:border-color .2s}
.d-conn .lc:hover{border-color:var(--line)}
.d-conn .lc .nm{font:500 13px var(--ui);color:var(--t2)}
.d-conn .lc .rel{margin-left:auto;font:italic 12px var(--serif);color:var(--t4)}
.d-inv{display:flex;align-items:center;gap:var(--sp3);padding:7px 0;border-bottom:1px dotted var(--line-soft);
  font-size:13px;color:var(--t2)}
.d-inv .tag{margin-left:auto;font:500 10px var(--mono);color:var(--t4)}
.tag.scar{color:var(--bad);border-color:color-mix(in srgb,var(--bad) 40%,transparent)}

/* ═══════════════════════════ journal hub ═══════════════════════════ */
#journal{position:fixed;inset:0;z-index:var(--z-journal);background:rgba(9,7,4,.72);display:none;
  align-items:stretch;justify-content:center;padding:var(--sp6)}
#journal.open{display:flex}
/* A bar across the top (title + the ONE close), rail + content below.
   j-body and j-detail share the content cell — exactly one is ever shown. */
#journal .book{width:min(1120px,100%);background:var(--ink85);border:1px solid var(--line);border-radius:10px;
  display:grid;grid-template-columns:210px 1fr;grid-template-rows:auto 1fr;
  grid-template-areas:"bar bar" "nav content";
  min-height:0;position:relative;box-shadow:0 30px 80px #000c;overflow:hidden}
/* min-width:0 is load-bearing: grid/flex items refuse to shrink below their
   min-content by default, which pushed the ✕ outside the clipped book on a
   narrow phone — the control vanished entirely. */
.j-bar{grid-area:bar;display:flex;align-items:center;gap:var(--sp2);height:52px;min-width:0;
  padding:0 var(--sp2) 0 var(--sp5);border-bottom:1px solid var(--line-soft)}
.jb-back{display:none;align-items:center;justify-content:center;min-width:44px;min-height:44px;
  font-size:20px;line-height:1;color:var(--accent)}
.jb-back:hover{color:var(--accent-hi)}
#journal.detail-open .jb-back{display:flex}
.j-nav{grid-area:nav;border-right:1px solid var(--line-soft);padding:var(--sp4) 0;
  display:flex;flex-direction:column;min-height:0;min-width:0;overflow-y:auto}
.j-title{flex:1 1 auto;min-width:0;font:600 13px var(--display);letter-spacing:.14em;
  color:var(--accent);text-transform:uppercase;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.j-tabs{display:flex;flex-direction:column}
.j-tabs>button{text-align:left;padding:10px var(--sp5);font:500 12.5px var(--ui);letter-spacing:.04em;
  color:var(--t3);border-left:2px solid transparent}
.j-tabs>button.on{color:var(--t1);border-left-color:var(--accent);background:var(--ink8)}
.j-tabs>button:hover{color:var(--t1)}
.j-tools{padding:var(--sp4) var(--sp5) 0;display:flex;flex-direction:column;gap:var(--sp2)}
.j-tools input[type=text],#codex-search{width:100%;font-size:12px}
.j-tools label{font-size:11px;display:flex;align-items:center;gap:6px}
.j-body{grid-area:content;min-width:0;overflow-y:auto;padding:var(--sp5)}
/* an empty category should read as "nothing here yet", not as a crash */
.j-body>p.muted{padding:var(--sp7) var(--sp4);text-align:center;
  font:italic 14px/1.65 var(--serif);color:var(--t4);max-width:34ch;margin:0 auto}
/* the ONE close control of this layer (NN/g: never a second X on the same
   screen). It is the only way out, so it does not whisper: --t2, not --t4. */
.j-close{flex:0 0 auto;min-width:44px;min-height:44px;display:flex;
  align-items:center;justify-content:center;color:var(--t2);font-size:15px}
.j-close:hover{color:var(--accent)}
.pane-head{margin-bottom:var(--sp5)}
.pane-head h2{font:600 26px/1.1 var(--display);letter-spacing:-.01em}
.pane-head .sub{font:italic 13px var(--serif);color:var(--t3);margin-top:4px}

/* section labels inside panes */
.detail-key{margin:var(--sp5) 0 var(--sp3)}
.detail-key:first-child{margin-top:0}

/* chronicle timeline */
.tl-wrap{position:relative;padding-left:var(--sp6)}
.tl-wrap::before{content:"";position:absolute;left:7px;top:6px;bottom:6px;width:1px;background:var(--line)}
.turn-card.journal-card{position:relative;background:none;border:none;padding:0 0 var(--sp5);cursor:pointer;max-width:60ch}
.turn-card.journal-card::before{content:"";position:absolute;left:calc(-1*var(--sp6) + 3px);top:6px;width:9px;height:9px;
  border-radius:50%;background:var(--ink9);border:1px solid var(--line)}
.turn-head{display:flex;align-items:baseline;gap:var(--sp3);flex-wrap:wrap}
.turn-head .num{font:500 10.5px var(--mono);color:var(--t4);letter-spacing:.06em;text-transform:uppercase}
.turn-head strong{font:500 16px var(--serif);color:var(--t1);font-weight:500}
.turn-card.journal-card .info-line{font:400 13px/1.5 var(--serif);color:var(--t3);margin-top:4px}
.turn-card.journal-card:hover strong{color:var(--accent)}
.chip.present{display:inline-flex;font:500 11px var(--ui);color:var(--t2);padding:3px 9px;border:1px solid var(--line-soft);
  border-radius:100px;margin:var(--sp2) 6px 0 0}

/* codex cards (people / factions / items / lore) */
.info-card,.codex-card{background:var(--ink8);border:1px solid var(--line-soft);border-radius:8px;
  padding:var(--sp4);margin-bottom:var(--sp3);cursor:pointer;transition:border-color .2s,transform .16s var(--spring)}
.codex-card:hover{border-color:var(--line);transform:translateY(-1px)}
.codex-card.selected{border-color:var(--accent)}
.info-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp3)}
.name-box{display:flex;align-items:center;gap:var(--sp3);min-width:0}
.name-box strong{font:600 14px var(--display);color:var(--t1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.info-head .muted{font:500 10px var(--ui);letter-spacing:.12em;text-transform:uppercase}
.info-line{font:400 13px/1.5 var(--serif);color:var(--t3);margin-top:6px}
.info-line.muted{color:var(--t4)}
.codex-card.type-character{border-left:2px solid var(--c-char)}
.codex-card.type-location{border-left:2px solid var(--c-loc)}
.codex-card.type-faction{border-left:2px solid var(--c-fac)}
.codex-card.type-item{border-left:2px solid var(--c-item)}
.codex-card.type-lore{border-left:2px solid var(--t4)}

/* places tree indent handled inline by JS via margin-left */

/* NO side panel — at any width. The journal has ONE content area: it shows the
   index OR an entry, never both. Selecting drills in, Back returns, and the
   journal's ✕ stays the only close control. Nothing slides in, nothing shifts.
   (Also NN/g's preferred fix: replace in place instead of stacking.) */
.j-detail{grid-area:content;min-width:0;overflow-y:auto;padding:var(--sp5);display:none}
#journal.detail-open .j-body{display:none}
#journal.detail-open .j-detail{display:block}
.j-detail > *{max-width:640px}        /* keep the entry readable in a wide area */
.codex-link{cursor:pointer;padding:4px 0;border-bottom:1px dotted var(--line-soft);font:400 13px var(--serif);color:var(--t2)}
.codex-link:hover{color:var(--accent)}
.tag{display:inline-block;background:var(--ink7);border:1px solid var(--line-soft);border-radius:4px;padding:1px 7px;
  font:500 11px var(--mono);color:var(--t3);margin:0 5px 5px 0}
.stat-row{display:flex;justify-content:space-between;padding:5px 0;border-bottom:1px dotted var(--line-soft);font-size:13px}

/* suggestion cards (quest inbox) */
.suggestion-card{background:var(--ink8);border:1px solid var(--accent-dim);border-radius:8px;padding:var(--sp4);margin-bottom:var(--sp3)}
.suggestion-card .toolbar{display:flex;gap:var(--sp2);padding-top:var(--sp3)}
.star-btn{color:var(--t4);font-size:15px;padding:0 4px}
.star-btn.focused{color:var(--accent)}

/* ═══════════════════════════ palette ═══════════════════════════ */
#palette{position:fixed;inset:0;z-index:var(--z-palette);background:rgba(9,7,4,.6);display:none;align-items:flex-start;justify-content:center;padding-top:14vh}
#palette.open{display:flex}
.pal{width:560px;max-width:92vw;background:var(--ink8);border:1px solid var(--line);border-radius:10px;box-shadow:0 30px 80px #000c;overflow:hidden}
#pal-input{width:100%;background:none;border:none;border-bottom:1px solid var(--line-soft);border-radius:0;font:15px var(--ui);padding:var(--sp4)}
.pgroup{font:600 10px var(--ui);letter-spacing:.18em;color:var(--t4);text-transform:uppercase;padding:var(--sp3) var(--sp4) var(--sp1)}
.prow{display:flex;align-items:center;gap:var(--sp3);padding:9px var(--sp4);cursor:pointer}
.prow:hover,.prow.sel{background:var(--ink7)}
.prow .pn{font:500 13px var(--ui);color:var(--t2)}
.prow .pt{margin-left:auto;font:500 10px var(--mono);color:var(--t4)}
.pfoot{padding:var(--sp2) var(--sp4) var(--sp3);font:11px var(--ui);color:var(--t4);border-top:1px solid var(--line-soft)}

/* ═══════════════════════════ modals ═══════════════════════════ */
#modal-overlay{position:fixed;inset:0;background:rgba(8,10,14,.72);display:flex;align-items:center;justify-content:center;z-index:var(--z-modal);}
#modal-overlay.hidden,.modal.hidden{display:none}
.modal{position:relative;background:var(--ink8);border:1px solid var(--line);border-radius:10px;padding:var(--sp6);width:520px;max-width:94vw;max-height:88vh;overflow-y:auto}
.modal h2{margin-bottom:var(--sp4);padding-right:44px;font:600 15px var(--display);letter-spacing:.08em;text-transform:uppercase;color:var(--t1)}
/* web convention is an ✕ top-right; this layer had none, unlike every other */
.modal-close{position:absolute;top:6px;right:6px;min-width:44px;min-height:44px;display:flex;
  align-items:center;justify-content:center;color:var(--t3);font-size:15px;border-radius:8px;z-index:2}
.modal-close:hover{color:var(--accent);background:var(--ink7)}
.form-grid{display:grid;grid-template-columns:140px 1fr;gap:var(--sp2) var(--sp3);align-items:center}
.form-grid label{color:var(--t3);font-size:12px}
.detail-key{color:var(--t4);font:600 10px var(--ui);letter-spacing:.16em;text-transform:uppercase;margin-top:var(--sp4)}
.modal textarea{width:100%;margin-top:6px}
.modal-buttons{display:flex;justify-content:flex-end;gap:var(--sp2);margin-top:var(--sp5)}
.statbuy{margin-top:var(--sp3)}
.statbuy-row{display:grid;grid-template-columns:90px 28px 30px 28px 1fr;gap:6px;align-items:center;margin-bottom:5px}
.statbuy-name{color:var(--t3);font-size:12px}
.statbuy-value{text-align:center;font-family:var(--mono)}
.statbuy-bar{height:4px;background:var(--ink9);border-radius:2px;overflow:hidden}
.statbuy-bar>div{height:100%;background:var(--accent)}
.budget{margin-top:var(--sp2);font-size:13px}
.budget.ok{color:var(--ok)} .budget.warn{color:var(--bad)}
button:disabled{opacity:.4;cursor:not-allowed}
#nw-generate,#nc-suggest{color:var(--accent);border:1px solid var(--accent-dim);border-radius:4px;padding:8px 12px;font:500 12px var(--ui)}

/* ═════════════════════════ the "?" help affordance ═════════════════════════
   A toggletip: always visible (hidden-until-hover cuts discoverability by
   >20% and cannot exist on touch at all), never a `title`. The glyph is small
   and quiet — it must not out-shout the label it sits beside — but the hit
   area is a full 44px, well past the 24px WCAG 2.5.8 floor. */
.help-dot{
  /* Sized in em so the dot tracks whatever type it sits next to. */
  width:1.45em;height:1.45em;flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center;
  margin-left:.5em;vertical-align:middle;position:relative;
  border:1px solid var(--accent-dim);border-radius:50%;background:none;
  color:var(--t3);font:600 .72em/1 var(--ui);text-transform:none;letter-spacing:0;
  cursor:help;transition:color .15s var(--spring),border-color .15s var(--spring);
}
/* Grow the touch target past the ring without moving the layout. */
.help-dot::after{content:"";position:absolute;top:50%;left:50%;
  width:44px;height:44px;transform:translate(-50%,-50%)}
.help-dot:hover,.help-dot[aria-expanded="true"]{color:var(--accent-hi);border-color:var(--accent)}
.help-dot:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

.help-pop{
  /* Top layer: positioned against the viewport by placeHelp(), so no z-index. */
  position:fixed;margin:0;inset:auto;width:300px;max-width:calc(100vw - 16px);
  background:var(--ink85);border:1px solid var(--line);border-radius:8px;
  padding:var(--sp4);box-shadow:0 12px 32px rgba(0,0,0,.5);
  display:none;
}
/* Each open-state selector stands alone on purpose: a browser without
   :popover-open drops only that line and still honours .open below, instead of
   invalidating a combined selector and leaving every panel stuck on screen. */
.help-pop:popover-open{display:block}
.help-pop.open{display:block}          /* fallback path when popover is absent */
.help-pop h3{font:600 11px var(--ui);letter-spacing:.14em;text-transform:uppercase;
  color:var(--accent);margin:0 0 var(--sp2)}
.help-pop p{font:400 13.5px/1.6 var(--serif);color:var(--t2);margin:0;text-transform:none;letter-spacing:0}
/* WCAG 1.4.13 "hoverable": an invisible bridge across the 8px gap, so the
   pointer can reach the panel without it closing underneath it. */
.help-pop::before{content:"";position:absolute;left:0;right:0;height:10px}
.help-pop[data-flip="down"]::before{top:-10px}
.help-pop[data-flip="up"]::before{bottom:-10px}

/* Hosts that carry a data-help — keep the dot on the label's baseline. */
.h2-help,.form-grid label,.detail-key,.act-row{display:flex;align-items:center}
.act-row{margin-top:var(--sp3)}
#turn-actions{align-items:center}

#toast{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);background:var(--ink8);border:1px solid var(--accent);
  border-radius:6px;padding:9px 16px;display:none;z-index:var(--z-toast);font-size:13px}
#toast.error{border-color:var(--bad);color:var(--bad)}
.spin{display:inline-block;animation:spin 1s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* ═══════════════════════════ responsive ═══════════════════════════ */

/* ═══════ mobile: a dedicated one-screen app shell — no page scroll ═══════ */
#mobile-nav{display:none}
.dock-grab{display:none}
#dock-scrim{display:none}
@media (max-width:820px){
  body{height:100svh;overflow:hidden}

  /* topbar: single compact row that clears the notch/status bar */
  #topbar{height:calc(52px + env(safe-area-inset-top));padding-top:env(safe-area-inset-top);
    padding-left:max(var(--sp3),env(safe-area-inset-left));padding-right:max(var(--sp3),env(safe-area-inset-right));
    flex-wrap:nowrap;gap:var(--sp2);align-items:center}
  #topbar .topbar-sep{display:none}
  #topbar .brand,#dev-link,#lang-toggle,#clock,#scene-crumb{display:none}
  .scene-crumbs{flex:1 1 auto;min-width:0}
  #scene-location{font-size:13px}
  .searchbtn{display:none}   /* search lives in the bottom nav ("Find") on mobile */
  #btn-home,#btn-app-settings{min-width:40px;min-height:40px;display:inline-flex;
    align-items:center;justify-content:center;padding:0;font-size:18px}

  /* stage fills the rest; ONLY the feed scrolls */
  #stage{flex-direction:column;gap:0;padding:0;overflow:hidden;min-height:0}
  #col-story{flex:1 1 auto;min-height:0;
    padding-left:max(var(--sp4),env(safe-area-inset-left));padding-right:max(var(--sp4),env(safe-area-inset-right))}
  #chat{flex:1 1 auto;overflow-y:auto;padding:var(--sp4) 2px var(--sp3);-webkit-overflow-scrolling:touch}

  /* composer: language-proof 3-row layout — modes / input / (continue|send) */
  #composer{flex:0 0 auto;padding:0 0 var(--sp3)}
  #turn-actions{padding-bottom:var(--sp2);gap:var(--sp3)}
  #turn-actions button{min-height:34px}
  #input-row{flex-wrap:wrap;background:none;border:0;gap:var(--sp2)}
  #mode-switch{order:-2;flex:1 1 100%;border:1px solid var(--line);border-radius:8px;overflow:hidden}
  #mode-switch button{flex:1 1 0;min-height:44px;border-right:1px solid var(--line-soft)}
  #mode-switch button:last-child{border-right:0}
  #player-input{order:-1;flex:1 1 100%;min-width:0;background:var(--ink8);border:1px solid var(--line);
    border-radius:8px;min-height:48px}
  #btn-continue,#btn-send{flex:1 1 0;min-width:0;min-height:48px;border:1px solid var(--line);
    border-radius:8px;white-space:nowrap}
  #btn-continue{background:var(--ink8);color:var(--t2)}
  #btn-send.primary{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}

  /* dock -> bottom sheet, above the nav, clear of the home-indicator */
  #dock{position:fixed;left:0;right:0;bottom:calc(60px + env(safe-area-inset-bottom));z-index:var(--z-dock);
    max-height:70svh;overflow-y:auto;background:var(--ink85);border:1px solid var(--line);border-bottom:0;
    border-radius:16px 16px 0 0;transform:translateY(135%);transition:transform .3s var(--spring);
    padding:var(--sp6) max(var(--sp4),env(safe-area-inset-left)) var(--sp5);gap:var(--sp4);box-shadow:0 -24px 60px #000b}
  #dock.open{transform:none}
  /* A sheet is dismissed by swipe + scrim tap, with a grabber — not by an ✕
     (Material/Apple both). The grabber keeps a 48px hit target around a 36px
     pill; drag it down or tap it, or tap the scrim. */
  .dock-grab{display:flex;align-items:center;justify-content:center;position:absolute;
    top:0;left:50%;transform:translateX(-50%);width:72px;height:30px;touch-action:none;font-size:0}
  .dock-grab::before{content:"";width:36px;height:4px;border-radius:2px;background:var(--line)}
  .dock-grab:active::before{background:var(--t4)}
  #dock-scrim{display:block;position:fixed;inset:0;background:rgba(9,7,4,.5);
    z-index:calc(var(--z-dock) - 1);opacity:0;pointer-events:none;transition:opacity .25s}
  body.dock-open #dock-scrim{opacity:1;pointer-events:auto}
  .dock-btnrow{display:none}

  /* bottom navigation: 60px + home-indicator, 48px touch targets */
  #mobile-nav{display:flex;flex:0 0 auto;align-items:stretch;background:var(--ink85);border-top:1px solid var(--line);
    z-index:var(--z-nav);height:calc(60px + env(safe-area-inset-bottom));padding-bottom:env(safe-area-inset-bottom);
    padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right)}
  #mobile-nav button{flex:1 1 0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;
    min-height:48px;color:var(--t4);font:600 9.5px var(--ui);letter-spacing:.06em;text-transform:uppercase}
  #mobile-nav button .mn-ic{font-size:18px;color:var(--t3);line-height:1}
  #mobile-nav button:active,#mobile-nav button:active .mn-ic{color:var(--accent)}


  /* journal = fullscreen overlay, svh height, safe areas */
  #journal{padding:0}
  #journal .book{border-radius:0;flex-direction:column;width:100%;height:100svh}
  /* ── ONE column, three levels: categories → entries → entry. ──────────
     A horizontally scrolling strip of 7 tabs was the wrong pattern: Material
     is explicit that past five destinations you do not use a nav bar. So the
     categories become a plain vertical list you drill into, with a single
     back control in the bar. Nothing scrolls sideways, everything is thumb-
     sized, and it scales to any number of categories. */
  #journal .book{grid-template-columns:1fr;grid-template-areas:"bar" "content";
    border-radius:0;width:100%;height:100svh;border:0}
  .j-bar{height:calc(52px + env(safe-area-inset-top));padding:env(safe-area-inset-top) var(--sp2) 0
    max(var(--sp3),env(safe-area-inset-left))}
  .j-close .esc{display:none}
  .j-nav{grid-area:content;border-right:0;padding:0;overflow-y:auto}

  /* level 0 — the category list */
  .j-tabs{flex-direction:column}
  .j-tabs>button{display:flex;align-items:center;justify-content:space-between;
    text-align:left;min-height:56px;padding:0 max(var(--sp4),env(safe-area-inset-right)) 0
      max(var(--sp4),env(safe-area-inset-left));
    border-left:0;border-bottom:1px solid var(--line-soft);font:500 15px var(--ui);color:var(--t2)}
  .j-tabs>button::after{content:"\203A";color:var(--t4);font-size:18px;line-height:1}
  .j-tabs>button.on{background:transparent;color:var(--t2);border-left:0}
  .j-tools{display:none}

  /* exactly one level on screen at a time — level 0 is the category list, so
     the entries pane must be OFF here (it shares the same grid cell) */
  .j-body{display:none}
  #journal.pane-open .j-nav{display:none}
  #journal.pane-open .j-body{display:block}
  #journal.pane-open.detail-open .j-body{display:none}
  #journal.pane-open .jb-back{display:flex}
  /* the entry sits IN the column and replaces the index — no second fixed layer,
     so the journal's ✕ stays the only close control on screen */
  .j-body,.j-detail{padding:var(--sp4) max(var(--sp4),env(safe-area-inset-left))
    calc(var(--sp6) + env(safe-area-inset-bottom))}
  .j-detail{min-height:0;overflow-y:auto}

  #palette{padding-top:calc(env(safe-area-inset-top) + 6vh)}
  .pfoot{display:none}   /* keyboard hint is meaningless on touch */
  .pane-head h2{font-size:22px}

  /* modals: full-width responsive sheet, stacked form, safe-area, no overflow */
  #modal-overlay{align-items:center;
    padding:calc(env(safe-area-inset-top) + var(--sp3)) var(--sp3) calc(env(safe-area-inset-bottom) + var(--sp3))}
  .modal{width:100%;max-width:none;max-height:100%;padding:var(--sp5) var(--sp4);border-radius:12px}
  .modal h2{font-size:14px}
  .form-grid{grid-template-columns:1fr;gap:2px 0}
  .form-grid label{margin-top:var(--sp3)}
  .form-grid>*{min-width:0}
  .modal input,.modal select{width:100%;min-width:0;min-height:44px}
  .modal textarea{width:100%;min-width:0}
  .modal-buttons{position:sticky;bottom:0;background:var(--ink8);padding-top:var(--sp3);margin-top:var(--sp4)}
  .modal-buttons button{flex:1 1 auto;min-height:46px;white-space:nowrap;padding:0 12px;font-size:12.5px}
  #nw-generate,#nc-suggest{width:100%;min-height:44px;justify-content:center}
  .statbuy-row{grid-template-columns:1fr 38px 34px 38px 1fr;gap:8px;align-items:center}
  .statbuy-row>*{min-width:0}
  .statbuy-row button{min-height:40px}
}
@media (max-width:400px){
  #mobile-nav button{font-size:8.5px}
  .msg.narrator{font-size:16.5px}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important}
}

/* ═══════════════════ dev console compatibility (dev.html/dev.js) ═════════════
   Kept so the developer console keeps working on the shared stylesheet. */
#topbar strong{font:600 12px var(--display);letter-spacing:.1em;color:var(--accent);margin-right:10px}
#cost-badge{font:500 11px var(--mono);color:var(--t3)}
#main-tabs{display:flex;gap:2px;align-self:stretch}
#main-tabs button{color:var(--t3);padding:0 14px;border-bottom:2px solid transparent;
  font:600 11px var(--ui);letter-spacing:.14em;text-transform:uppercase}
#main-tabs button.active{color:var(--t1);border-bottom-color:var(--accent)}
.view{display:none;flex:1 1 auto;min-height:0}
.view.active{display:flex}

/* ═══════════════════════ start screen / hub ════════════════════════ */
#home{position:fixed;inset:0;z-index:var(--z-home);background:var(--ink9);display:none;overflow:auto}
#home.open{display:block}
.home-inner{max-width:1080px;margin:0 auto;padding:var(--sp7) var(--sp6) var(--sp8)}
.home-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--sp5)}
.home-brand{font:600 20px var(--display);letter-spacing:.18em;color:var(--accent);text-transform:uppercase}
#home-settings{color:var(--t3);font-size:18px;line-height:1;padding:6px 8px}
#home-settings:hover{color:var(--accent)}
.home-cols{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp7)}
.home-col-head{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:var(--sp4);
  padding-bottom:var(--sp3);border-bottom:1px solid var(--line-soft)}
.home-col-head h2{font:600 13px var(--ui);letter-spacing:.16em;text-transform:uppercase;color:var(--t2)}
.home-col-head .sm{font-size:12px;padding:5px 10px}
.home-list{display:flex;flex-direction:column;gap:var(--sp3)}
.home-empty{font:400 14px var(--serif);font-style:italic;color:var(--t4);padding:var(--sp5) 0}
.hcard{position:relative;display:flex;align-items:stretch;background:var(--ink8);
  border:1px solid var(--line-soft);border-radius:10px;overflow:hidden;transition:border-color .15s}
.hcard:hover{border-color:var(--line)}
.hcard-main{flex:1 1 auto;min-width:0;text-align:left;padding:var(--sp4) var(--sp4);display:flex;
  flex-direction:column;gap:3px;cursor:pointer}
.hcard-main.static{cursor:default}
.hcard-name{font:500 16px var(--display);color:var(--t1)}
.hcard-sub{font:400 13px var(--serif);font-style:italic;color:var(--t3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hcard-stats{font:500 11px var(--mono);color:var(--t4);letter-spacing:.02em;margin-top:2px}
.hcard-acts{display:flex;align-items:center;gap:4px;padding:0 var(--sp3);flex:0 0 auto}
.hcard-play{background:var(--accent-tint);color:var(--accent-hi);border:1px solid var(--accent-dim);
  border-radius:7px;padding:7px 14px;font:600 12px var(--ui);letter-spacing:.04em}
.hcard-play:hover{background:var(--accent);color:var(--on-accent)}
.hcard-ic{width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;
  color:var(--t4);font-size:14px;border-radius:7px}
.hcard-ic:hover{color:var(--accent);background:var(--ink7)}
.hcard-ic.del:hover{color:var(--bad);background:transparent}
.hcard-confirm{position:absolute;inset:0;background:var(--ink85);display:flex;align-items:center;
  justify-content:flex-end;gap:var(--sp3);padding:0 var(--sp4)}
.hcard-confirm .hc-q{margin-right:auto;font:500 13px var(--ui);color:var(--t2)}
.hcard-confirm .hc-yes{background:var(--bad);color:var(--on-accent);border-radius:7px;padding:7px 14px;font:600 12px var(--ui)}
.hcard-confirm .hc-no{color:var(--t3);padding:7px 12px;font:500 12px var(--ui)}
.hcard-confirm .hc-no:hover{color:var(--t1)}
/* gender picker */
.gender-pick{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.gchip{border:1px solid var(--line);color:var(--t2);border-radius:20px;padding:6px 13px;
  font:500 12.5px var(--ui);transition:all .12s}
.gchip:hover{border-color:var(--accent-dim);color:var(--t1)}
.gchip.on{background:var(--accent);border-color:var(--accent);color:var(--on-accent)}
.gcustom{flex:1 1 120px;min-width:110px}
/* placement chooser */
.place-list{display:flex;flex-direction:column;gap:6px;max-height:52vh;overflow:auto;margin:var(--sp2) 0 var(--sp4)}
.place-row{display:flex;flex-direction:column;gap:2px;text-align:left;padding:var(--sp3) var(--sp4);
  background:var(--ink7);border:1px solid var(--line-soft);border-radius:8px}
.place-row:hover{border-color:var(--accent-dim);background:var(--ink65)}
.pr-name{font:500 15px var(--display);color:var(--t1)}
.pr-sub{font:400 12.5px var(--serif);font-style:italic;color:var(--t3)}

@media (max-width:820px){
  .home-inner{padding:calc(env(safe-area-inset-top) + var(--sp5))
    max(var(--sp4),env(safe-area-inset-right)) calc(env(safe-area-inset-bottom) + var(--sp6))
    max(var(--sp4),env(safe-area-inset-left))}
  .home-cols{grid-template-columns:1fr;gap:var(--sp6)}
  .hcard-play{padding:9px 14px}
  .hcard-ic{width:38px;height:38px}
  .gcustom{flex-basis:100%;min-height:42px}
}
#graph-left{flex:1 1 auto;overflow-y:auto;padding:12px;min-width:0}
#node-detail{flex:0 0 400px;border-left:1px solid var(--line);background:var(--ink8);padding:14px;overflow-y:auto}
.toolbar{display:flex;gap:10px;align-items:center;padding:0 0 10px;flex-wrap:wrap}
table{width:100%;border-collapse:collapse;font-size:13px}
th{text-align:left;color:var(--t3);font-weight:600;padding:4px 8px;border-bottom:1px solid var(--line)}
td{padding:4px 8px;border-bottom:1px solid var(--ink7)}
tbody tr{cursor:pointer}
tbody tr:hover{background:var(--ink7)}
tbody tr.selected{background:var(--ink65)}
.flag{color:var(--accent)}
pre{background:var(--ink9);border:1px solid var(--line);border-radius:4px;padding:8px;overflow-x:auto;
  font-family:var(--mono);font-size:12px;white-space:pre-wrap}
#view-turns,#view-review,#view-costs{flex-direction:column;padding:12px 16px;overflow-y:auto}
.turn-card{background:var(--ink8);border:1px solid var(--line);border-radius:4px;padding:10px 14px;margin-bottom:10px;max-width:70em}
.turn-card.rolled_back{opacity:.45}
.turn-card .num{font-family:var(--mono);color:var(--accent)}
.turn-card details{margin-top:6px}
.turn-card summary{cursor:pointer;color:var(--t3);font-size:12px}
.roll{font-family:var(--mono);font-size:12px;color:var(--accent)}
.bar{height:4px;background:var(--ink7);overflow:hidden;margin:3px 0 10px}
.bar>div{height:100%;background:var(--ok)}
.bar.hp>div{background:var(--bad)}
.chip{display:inline-block;padding:1px 8px;border-radius:10px;font-size:11px;font-family:var(--mono);margin-right:6px;border:1px solid var(--line)}
.chip.success,.chip.strong_success,.chip.critical_success{color:var(--ok);border-color:var(--ok)}
.chip.failure,.chip.hard_failure,.chip.critical_failure{color:var(--bad);border-color:var(--bad)}
.roll-line{display:flex;align-items:center;gap:8px;margin:2px 0}
.roll-formula{font-family:var(--mono);font-size:11px;color:var(--t3)}
/* NOTE: do not re-add a bare .recent-dot here — the dev console never uses it,
   and this block is loaded by the play UI too, so it silently repainted the
   codex "recently seen" dot green. Generic class names in this block bleed. */

/* ═══════════════════════ mental map (places pane) ═══════════════════════ */
.wg-map{width:100%;height:auto;display:block;border:1px solid var(--line-soft);border-radius:8px;
  background:radial-gradient(ellipse 75% 65% at 50% 42%,var(--ink8),var(--ink9) 72%)}
.m-region-label{font:600 12px var(--display);letter-spacing:.3em;fill:var(--t4);text-anchor:middle;text-transform:uppercase}
.m-tether{fill:none;stroke:var(--line);stroke-width:1;opacity:.7}
.mnode{cursor:pointer}
.mnode .ring{fill:var(--ink9);stroke:var(--t3);stroke-width:1.4}
.mnode:hover .ring,.mnode.here .ring{stroke:var(--accent)}
.mnode .ini{font:600 11px var(--ui);fill:var(--t1);text-anchor:middle}
.mnode .mlabel{font:600 11px var(--ui);letter-spacing:.1em;fill:var(--t2);text-anchor:middle;text-transform:uppercase}
.mnode:hover .mlabel{fill:var(--t1)}
.mnode .msub{font:italic 10.5px var(--serif);fill:var(--t4);text-anchor:middle}
.m-pin{fill:var(--accent)}
.m-here{font:600 8.5px var(--ui);letter-spacing:.18em;fill:var(--accent);text-anchor:middle}
.m-compass{stroke:var(--t4);fill:var(--t4);opacity:.5}
.m-compass-l{font:600 10px var(--display);fill:var(--t3);text-anchor:middle}

/* ═══════════════════════ accounts: login + admin ═══════════════════════ */
.hidden{display:none}
#login-screen{position:fixed;inset:0;z-index:var(--z-login);display:flex;align-items:center;justify-content:center;
  background:var(--ink9);
  padding:calc(env(safe-area-inset-top) + var(--sp5)) var(--sp4) calc(env(safe-area-inset-bottom) + var(--sp5))}
#login-screen.hidden{display:none}
.login-box{display:flex;flex-direction:column;gap:var(--sp3);width:320px;max-width:100%;
  padding:var(--sp7) var(--sp6);border:1px solid var(--line);border-radius:12px;background:var(--ink8)}
.login-brand{font:600 24px var(--display);letter-spacing:.14em;text-transform:uppercase;
  text-align:center;color:var(--accent)}
.login-box input{min-height:44px;font-size:15px}
.login-box input:focus{outline:none;border-color:var(--accent)}
.login-box button{min-height:44px;font-size:15px}
.login-error{color:var(--bad);font-size:13px;min-height:16px;text-align:center}

/* account cluster in the home header */
.home-account{display:flex;align-items:center;gap:var(--sp3)}
#user-chip{color:var(--t3);font-size:12px;letter-spacing:.04em}
#btn-logout{color:var(--t3)} #btn-logout:hover{color:var(--accent)}

/* admin: account management modal */
.admin-list{display:flex;flex-direction:column;gap:6px;margin-bottom:var(--sp4)}
.admin-row{display:flex;align-items:center;justify-content:space-between;gap:var(--sp3);
  padding:var(--sp3) var(--sp4);border:1px solid var(--line-soft);border-radius:8px}
.admin-meta{display:flex;flex-direction:column;gap:2px}
.admin-name{color:var(--t1);font-weight:600}
.admin-count{color:var(--t3);font-size:12px}
.admin-you{color:var(--t4);font-size:12px}
.admin-del{color:var(--bad);border:1px solid color-mix(in srgb,var(--bad) 40%,transparent);
  border-radius:6px;padding:5px 12px;font-size:12px}
.admin-del:hover{background:var(--bad);color:var(--on-accent)}

@media (max-width:820px){
  #user-chip{display:none}   /* save header space on phones */
}
