/* ===========================================================================
   Qi Men Ahead
   Two palettes, both taken from the supplied designs:
     parchment  light, warm paper
     oxblood    dark, with a paper texture behind the board
   The board markup is generated in app.js; the class names here are the
   contract between the two. Cross-cell alignment inside the nine palaces is
   load-bearing, not cosmetic — see .flagrow and .pips.
   =========================================================================== */

:root{
  --ground:#F2ECE4; --panel:#FBF7F1; --sunk:#EDE6DC;
  --line:#DDD0C3; --line-soft:#E8DED2;
  --ink:#43201F; --dim:#8A6A5E; --faint:#A8917F;
  --accent:#8F6410; --accent-soft:#C6A15C; --accent-wash:#F5EAD3;
  --plate-internal:#E7DCCB;
  --glass:rgba(251,247,241,.42); --glass-open:rgba(251,247,241,.62);
  --glass-edge:rgba(255,255,255,.5);
  --shadow:rgba(67,32,31,.20);
  /* The same linen the Oxblood theme uses, in its light form. A soft wash of
     the ground colour sits over it so panels and glyphs keep their contrast. */
  --texture:linear-gradient(rgba(242,236,228,.45), rgba(242,236,228,.55)),
            url('img/texture-parchment.jpg');
  --cjk:'Noto Serif TC','Songti TC','PingFang TC',serif;
  --ui:'Barlow Semi Condensed',system-ui,-apple-system,sans-serif;
  --radius:8px;

  /* Bottom-sheet stops. The collapsed height includes the iPhone home-indicator
     inset, so the composer and handle never sit under Safari's toolbar. */
  --safe-b:env(safe-area-inset-bottom, 0px);
  --brand-w:14px;                      /* the vertical brand strip beside the board */
  --brand-gap:6px;
  /* The collapsed sheet holds handle (44) + composer (52) + credit line (18) =
     114px. It was 104, so the credit line sat outside the sheet's own
     overflow:hidden and was being clipped.

     The lift then raises the composer off the bottom edge so it sits nearer
     the chart rather than leaving one large void between them. Collapsed
     content pins to the TOP of the sheet, so a taller sheet moves the composer
     up instead of stretching it. It is only taken where there is height to
     spare — a small phone keeps every pixel for the chart. Measured against
     dvh, not --vvh, so the on-screen keyboard never changes it. */
  --sheet-lift:clamp(0px, calc(100dvh - 720px), 64px);
  --sheet-collapsed:calc(114px + var(--sheet-lift) + var(--safe-b));
  /* Percentages of #app, NOT dvh. #app is sized from visualViewport, which
     iOS shrinks when the keyboard opens; dvh follows the LAYOUT viewport,
     which it does not. Using dvh here made the sheet 611px inside a 300px app
     with its top 311px above the screen, taking the conversation with it. */
  --sheet-partial:48%;
  --sheet-expanded:92%;
}
:root[data-theme="oxblood"]{
  --ground:#2A1618; --panel:rgba(51,25,28,.93); --sunk:rgba(36,19,21,.93);
  --line:#4B2C30; --line-soft:#3D2427;
  --ink:#EFE4DB; --dim:#AC9289; --faint:#7E6259;
  --accent:#D9A441; --accent-soft:#8A6428; --accent-wash:rgba(59,37,25,.9);
  --plate-internal:rgba(31,15,18,.93);
  --glass:rgba(51,25,28,.42); --glass-open:rgba(51,25,28,.62);
  --glass-edge:rgba(255,255,255,.12);
  --shadow:rgba(0,0,0,.45);
  --texture:linear-gradient(rgba(24,12,13,.45), rgba(24,12,13,.6)), url('img/texture-oxblood.jpg');
}

*{box-sizing:border-box}
html,body{margin:0;padding:0;-webkit-font-smoothing:antialiased}
body{background:var(--ground); color:var(--ink); font-family:var(--ui)}
[hidden]{display:none !important}
button{font:inherit; color:inherit; cursor:pointer}
button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{
  outline:2px solid var(--accent); outline-offset:1px;
}
.cjk{font-family:var(--cjk)}
.gloss{font-size:9px; line-height:1; letter-spacing:.07em; text-transform:uppercase; color:var(--faint)}
.sub{font-size:10.5px; color:var(--faint)}

#app{
  /* --vvh is set from visualViewport when the on-screen keyboard changes the
     visible area; dvh is the fallback. Without this the sheet stays anchored to
     a viewport the keyboard is covering and the composer becomes unreachable. */
  position:relative; width:100%; max-width:430px; height:var(--vvh, 100dvh); margin:0 auto;
  overflow:hidden; background:var(--ground); background-image:var(--texture);
  background-size:cover; background-position:center; isolation:isolate;
}
.col{position:relative; height:100%; display:flex; flex-direction:column}

/* ---------- drawer ---------- */
#backdrop{
  position:absolute; inset:0; background:rgba(0,0,0,.32); z-index:30;
  opacity:0; pointer-events:none; transition:opacity 280ms ease;
}
#backdrop.on{opacity:1; pointer-events:auto}
#sidebar{
  position:absolute; top:0; bottom:0; left:0; width:274px; z-index:40;
  background:var(--panel); border-right:1px solid var(--line);
  display:flex; flex-direction:column; overflow-y:auto;
  box-shadow:2px 0 16px rgba(0,0,0,.15);
  transform:translateX(-100%); transition:transform 320ms ease;
  padding-bottom:calc(10px + env(safe-area-inset-bottom));
}
#sidebar.on{transform:translateX(0)}
.side-head{
  padding:14px 14px 10px; display:flex; justify-content:space-between; align-items:center;
  border-bottom:1px solid var(--line-soft); flex-shrink:0;
}
.side-title{font-size:11.5px; font-weight:600; letter-spacing:.08em; text-transform:uppercase; color:var(--dim)}
.icon-btn{width:24px; height:24px; border:0; background:transparent; color:var(--dim);
  display:flex; align-items:center; justify-content:center; padding:0}
.newchat{
  margin:10px 12px; padding:9px 10px; border:1px dashed var(--accent-soft);
  border-radius:var(--radius); background:transparent; color:var(--accent);
  font-size:12px; font-weight:600; text-align:center; flex-shrink:0;
}
.history{padding:2px 8px 6px}
.hrow{padding:9px 10px; border-radius:var(--radius); margin-bottom:2px; background:transparent;
  border:0; width:100%; text-align:left; display:block}
.hrow.on{background:var(--sunk)}
.hrow .t{font-size:12.5px; color:var(--ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.hrow .w{font-size:10px; color:var(--faint); margin-top:2px}
.history-empty{padding:4px 12px 10px; font-size:11.5px; color:var(--faint)}

.side-section{border-top:1px solid var(--line-soft); margin-top:8px; padding:12px 12px 4px}
.side-label{font-size:10px; font-weight:600; letter-spacing:.12em; text-transform:uppercase;
  color:var(--faint); margin-bottom:8px}
.side-row{margin:8px 0 12px}
.side-foot{margin-top:auto; padding:14px 12px 4px; text-align:center;
  font-size:10px; color:var(--faint)}

/* ---------- form controls ---------- */
.field{display:flex; flex-direction:column; gap:3px; margin-bottom:8px; min-width:0}
.field>span{font-size:9.5px; letter-spacing:.12em; text-transform:uppercase; color:var(--faint)}
.field input,.field select{
  padding:7px 9px; border:1px solid var(--line); border-radius:var(--radius);
  background:var(--ground); color:inherit; font:inherit; width:100%; min-width:0;
}
button.primary{background:var(--ink); color:var(--ground); border:1px solid var(--ink);
  border-radius:var(--radius); padding:8px 14px; font-weight:600}
button.ghost{background:var(--ground); color:var(--dim); border:1px solid var(--line);
  border-radius:var(--radius); padding:8px 14px}
button.wide{width:100%}

/* ---------- top bar ---------- */
.topbar{
  height:44px; flex-shrink:0; display:flex; align-items:center; gap:9px;
  padding:0 10px; padding-top:env(safe-area-inset-top);
  height:calc(44px + env(safe-area-inset-top));
  border-bottom:1px solid var(--line); background:var(--panel);
  position:relative; z-index:10;
}
.burger{width:28px; height:28px; border:0; background:transparent; padding:0; flex-shrink:0;
  display:flex; flex-direction:column; justify-content:center; align-items:center; gap:3px}
.burger span{width:16px; height:2px; background:var(--ink); display:block}
.brand{font-size:14.5px; letter-spacing:.04em}
.brand-sub{font-size:9px; letter-spacing:.1em; text-transform:uppercase; color:var(--faint)}
.spacer{flex:1}
.round-btn{width:26px; height:26px; border-radius:50%; border:1px solid var(--line);
  background:var(--ground); color:var(--dim); padding:0; flex-shrink:0;
  display:flex; align-items:center; justify-content:center}

/* ---------- chart area ---------- */
#main{flex:1; overflow-y:auto; -webkit-overflow-scrolling:touch;
  padding:10px 9px calc(var(--sheet-collapsed-m, var(--sheet-collapsed)) + 10px);
  overscroll-behavior:contain;
  display:flex; flex-direction:column; align-items:center;
  /* Sit the chart under the top bar. Centring it in the leftover height
     looked balanced on paper, but on a tall phone it parked ~110px of dead
     space between the bar and the chart title. Slack belongs at the bottom,
     against the collapsed sheet, where it reads as breathing room. */
  justify-content:flex-start}
.empty{color:var(--faint); text-align:center; padding:52px 12px}
#chart{width:100%; display:flex; flex-direction:column; align-items:center}

.sheet-head{display:flex; justify-content:space-between; align-items:baseline;
  gap:6px; flex-wrap:wrap; width:100%; margin-bottom:6px}
.sheet-title{display:flex; align-items:baseline; gap:5px}
.sheet-title .mark{font-size:13px; letter-spacing:.04em}
.sheet-title .kind{font-size:7.5px; letter-spacing:.13em; text-transform:uppercase; color:var(--faint)}
.sheet-when{display:flex; align-items:baseline; gap:6px; background:transparent;
  border:0; padding:2px 0; border-bottom:1px dashed transparent}
.sheet-when:hover{border-bottom-color:var(--accent-soft)}
.sheet-when .stamp{font-size:9px; color:var(--dim); font-variant-numeric:tabular-nums}
.sheet-when .ju{font-size:10px; color:var(--accent)}

.stepper{display:flex; gap:8px; width:100%; margin-bottom:6px; flex-shrink:0}
.step{background:var(--panel); border:1px solid var(--line-soft); border-radius:999px;
  padding:8px 0; font-size:15px; color:var(--dim); flex:1;
  box-shadow:0 1px 3px rgba(0,0,0,.10)}
:root[data-theme="oxblood"] .step{box-shadow:0 1px 3px rgba(0,0,0,.3)}
.step.now{flex:2.2; background:var(--accent-wash); border:1.5px solid var(--accent-soft);
  color:var(--accent); font-size:12px; font-weight:700; letter-spacing:.12em}

.whenrow{display:flex; gap:6px; align-items:flex-end; width:100%; margin-bottom:8px}
.whenrow .field{flex:1; margin-bottom:0}

.pillars{display:grid; grid-template-columns:repeat(4,1fr); gap:1px;
  background:var(--line); border:1px solid var(--line); border-radius:4px;
  overflow:hidden; width:100%; flex-shrink:0}
.pil{background:var(--panel); height:70px; padding:7px 2px; display:flex;
  flex-direction:column; align-items:center; justify-content:space-between}
.pil .lab{font-size:7px; font-weight:600; letter-spacing:.1em; text-transform:uppercase; color:var(--dim)}
.pil .unit{display:flex; flex-direction:column; align-items:center; gap:3px}
.pil .g{font-family:var(--cjk); font-size:20px; line-height:1}
.pil .noble{color:var(--accent)}
.pil .gloss{display:none}

.board-label{display:flex; justify-content:space-between; width:100%; margin:8px 0 3px}
.board-label .lhs{font-size:7.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--faint)}
.board-label .rhs{font-size:9.5px; color:var(--dim)}

/* ---------- the nine palaces ---------- */
/* The board keeps its own width; the brand sits beside it with a gap, so the
   board is never squeezed to make room for it. */
.board-row{display:flex; align-items:center; justify-content:center;
  gap:var(--brand-gap); width:100%}
/* Mirrors the brand on the other side so the board stays optically centred
   rather than being nudged left by the text beside it. */
.board-row::before{content:''; flex:0 0 var(--brand-w)}
/* Sits against the NW palace — the bottom of the board as it is drawn, with
   South at the top — rather than floating at the vertical midpoint. */
.brand-side{
  writing-mode:vertical-rl; text-orientation:mixed;
  width:var(--brand-w); flex:0 0 var(--brand-w);
  align-self:flex-end;
  font-size:9px; font-weight:700; letter-spacing:.14em; text-transform:lowercase;
  color:var(--dim); text-decoration:none; white-space:nowrap;
  text-align:end; -webkit-user-select:none; user-select:none;
}
.brand-side:hover{color:var(--ink)}

.board{
  display:grid; grid-template-columns:repeat(3,1fr);
  /* Equal rows are load-bearing: without this the centre cell makes the middle
     row taller than the other two, and E/W fall out of step with their
     neighbours. */
  grid-template-rows:repeat(3,1fr); gap:1px;
  background:var(--line); border:1px solid var(--line); border-radius:var(--radius);
  overflow:hidden; aspect-ratio:1; margin:10px 0 0; flex-shrink:0;
  /* leaves room for the brand strip and its mirror on a narrow phone */
  width:min(305px, calc(100% - 2 * (var(--brand-w) + var(--brand-gap))));
}
:root[data-theme="oxblood"] .board{border-color:rgba(255,255,255,.1)}
.cell{
  background:var(--panel); border:0; border-radius:0; padding:6px 5px 5px; text-align:left;
  display:flex; flex-direction:column; justify-content:space-between; gap:2px;
  font:inherit; color:inherit; min-width:0; overflow:hidden;
}
.cell.internal{background:var(--plate-internal)}
.cell.external{background:var(--panel)}
.cell.sel{box-shadow:inset 0 0 0 2px var(--accent)}
.cell.centre{background:var(--sunk); cursor:default; justify-content:center; align-items:center; gap:3px}

.chead{display:flex; align-items:center; justify-content:space-between; gap:3px; min-height:11px}
.chead .who{display:flex; align-items:center; gap:3px; min-width:0}
.chead .dir{font-size:8px; font-weight:700; color:var(--dim)}
.chead .gua{font-family:var(--cjk); font-size:10px; color:var(--dim)}
.chead .gloss{display:none}
.plate-tag{font-family:var(--cjk); font-size:7px; color:var(--accent); margin-left:1px}
.badges{display:flex; gap:2px; flex-shrink:0}
.badge{font-family:var(--cjk); font-size:7.5px; line-height:1.35; border-radius:2px;
  padding:0 3px; background:var(--accent); color:var(--panel)}
:root[data-theme="oxblood"] .badge{color:var(--ground)}

.triad{display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:1px; text-align:center}
.triad.bottom{align-items:end}
.slot{display:flex; flex-direction:column; align-items:center; gap:1px; min-width:0}
.slot .g{font-family:var(--cjk); font-size:16px; line-height:1;
  display:inline-flex; align-items:baseline; justify-content:center; gap:1px}
/* A lodged (hidden) stem sits BESIDE the stem it shares a palace with, never
   on top of it. line-height:1 and baseline alignment keep it out of the line
   box, so it cannot shift the number and door row below. */
.hidden-stem{
  font-family:var(--cjk); font-size:9px; line-height:1; color:var(--accent);
  display:inline-flex; align-items:baseline; gap:.5px; white-space:nowrap;
}
.hidden-stem b{font-weight:400; font-size:6.5px; opacity:.75}
.slot .num{font-size:12px; line-height:1; font-weight:600; color:var(--dim);
  font-variant-numeric:tabular-nums}
.triad .gloss{display:none}

/* Always reserve three pip rows (9 is the largest palace number). Otherwise a
   1-3 pip palace has a shorter number block, and because the bottom row is
   bottom-aligned the door and stem glyphs ride higher than a 7-9 palace beside it. */
.pips{display:grid; grid-template-columns:repeat(3,2px); grid-auto-rows:2px;
  gap:1px; justify-content:center; align-content:start; height:8px}
.pips i{width:2px; height:2px; border-radius:50%; background:var(--faint); display:block}

/* One reserved badge height for the whole board — empty when a palace has no
   flags, tall enough for the busiest palace when it does. Set in app.js. */
.flagrow{height:var(--badge-h, 11px); display:flex; flex-wrap:wrap; gap:2px;
  justify-content:center; align-content:center; align-items:center}
.flag{font-family:var(--cjk); font-size:7.5px; line-height:1.3; color:var(--accent);
  border:1px solid var(--accent-soft); border-radius:2px; padding:0 2px}

.centre-stem{text-align:center}
.centre-stem .g{font-family:var(--cjk); font-size:20px; line-height:1}
.centre-rule{width:80%; height:1px; background:var(--line); margin:1px auto}
.centre-rows{width:100%; display:flex; flex-direction:column; gap:1px}
.crow2{display:flex; justify-content:space-between; gap:4px; align-items:baseline}
.crow2 .gloss{font-size:6.5px}
.crow2 .v{font-family:var(--cjk); font-size:9px; color:var(--dim)}

.board-hint{text-align:center; font-size:9px; color:var(--faint); margin:10px 0 4px}

/* ---------- palace detail ---------- */
.detail{width:100%; margin-top:10px; background:var(--panel); border:1px solid var(--line);
  border-radius:var(--radius); padding:10px 12px; font-size:12.5px}
.detail dl{display:grid; grid-template-columns:auto 1fr; gap:3px 10px; margin:0}
.detail dt{color:var(--faint); font-size:10px; letter-spacing:.06em; text-transform:uppercase}
.detail dd{margin:0}

/* ---------- reference panels (drawer) ---------- */
.panel{border-top:1px solid var(--line-soft)}
.panel summary{padding:10px 0; font-size:12px; color:var(--dim); cursor:pointer; list-style:none}
.panel summary::-webkit-details-marker{display:none}
.panel summary::before{content:"+ "; color:var(--faint)}
.panel[open] summary::before{content:"− "}
.panel>div{padding-bottom:12px; font-size:12px}
.panel p{margin:0 0 8px}
.caveat{color:var(--faint); font-size:11px}
.charttext{white-space:pre-wrap; font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:10.5px; line-height:1.5; max-height:300px; overflow:auto;
  background:var(--sunk); padding:8px; border-radius:4px}
.scenario-pick{margin-bottom:8px}
.scenario-pick select{width:100%; padding:7px 9px; border:1px solid var(--line);
  border-radius:var(--radius); background:var(--ground); color:inherit; font:inherit}
.dayhour{font-size:12px; margin-bottom:10px}
.dh-row{margin-bottom:3px}
.keystrip{display:flex; flex-direction:column; gap:6px; margin-bottom:10px}
.keys{display:flex; flex-wrap:wrap; gap:4px; align-items:center}
.keys .kname{font-size:9.5px; color:var(--faint); margin-right:4px}
.facts{font-family:var(--cjk); font-size:11px; color:var(--dim)}
.chartflag{font-family:var(--cjk); font-size:11px; color:var(--accent);
  border:1px solid var(--accent-soft); border-radius:2px; padding:1px 5px}

/* ---------- chat ---------- */
/* ---------- bottom sheet ----------
   Three discrete states, never an arbitrary position. The sheet is always
   anchored to the bottom of the app, so it can never be stranded off-screen.

   The handle row and the composer are the only children in COLLAPSED — the
   message log is display:none there. That is the fix for the trap: previously
   the log kept its full content height inside a fixed 129px overflow:hidden
   box, which pushed the handle above the panel and the composer hundreds of
   pixels below the screen. */
.chat{
  position:absolute; left:0; right:0; bottom:0; z-index:20;
  height:var(--sheet-collapsed);
  display:flex; flex-direction:column; justify-content:flex-start; overflow:hidden;
  background:transparent; border:0; border-radius:0;
  transition:height 340ms cubic-bezier(.22,.9,.32,1), background 340ms ease;
}
.chat.dragging{transition:none}          /* follow the finger, snap on release */

.chat[data-sheet="partial"],
.chat[data-sheet="expanded"]{
  border-top-left-radius:22px; border-top-right-radius:22px;
  background:var(--glass-open);
  backdrop-filter:blur(20px) saturate(160%); -webkit-backdrop-filter:blur(20px) saturate(160%);
  border:1px solid var(--glass-edge); border-bottom:none;
  box-shadow:0 -10px 34px var(--shadow), inset 0 1px 0 var(--glass-edge);
}
/* Collapsed is content-sized: the handle, the composer card and the credit
   line define it, so a taller composer can never be clipped by a stale magic
   number. --sheet-collapsed is only the floor (it carries the tall-phone
   lift); the measured height is what #main actually reserves. */
.chat[data-sheet="collapsed"]{height:auto; min-height:var(--sheet-collapsed)}
.chat[data-sheet="partial"]{height:var(--sheet-partial)}
.chat[data-sheet="expanded"]{height:var(--sheet-expanded)}
/* The guaranteed way back. Always rendered, always inside the sheet, always
   above the safe-area inset. A drag can also move the sheet, but this tap
   target is the fallback that cannot fail. */
.handle{
  padding:9px 0 7px; display:flex; flex-direction:column; align-items:center; gap:4px;
  flex-shrink:0; background:transparent; border:0; width:100%;
  touch-action:none;                      /* the handle drags the sheet, not the page */
  min-height:44px;                        /* comfortable tap target */
}
.handle:active .grip{background:var(--accent)}
.grip{width:34px; height:4px; border-radius:2px; background:var(--line); display:block}
.handle-label{font-size:10.5px; color:var(--dim); letter-spacing:.02em}
.chat[data-sheet="collapsed"] .handle-label{color:var(--accent)}
/* min-height:0 is load-bearing: without it a flex child refuses to shrink
   below its content and overflows the sheet. overscroll-behavior:contain stops
   a scroll at the end of the messages from chaining to the page. */
.log{
  flex:1 1 auto; min-height:0; overflow-y:auto; overflow-x:hidden;
  -webkit-overflow-scrolling:touch;
  overscroll-behavior:contain; padding:2px 14px 8px;
  display:flex; flex-direction:column; gap:10px;
}
.chat[data-sheet="collapsed"] .log{display:none}
.chat-empty{text-align:center; color:var(--faint); font-size:12px; padding:14px 8px}

.turn{display:flex}
.turn.me{justify-content:flex-end}
.turn.them{justify-content:flex-start}
.bubble{max-width:82%; min-width:0; padding:8px 12px; font-size:13px; line-height:1.5;
  white-space:pre-wrap; overflow-wrap:anywhere}
.turn.me .bubble{border-radius:14px 14px 4px 14px; background:var(--ink); color:var(--ground)}
.turn.them .bubble{border-radius:14px 14px 14px 4px; background:var(--sunk); color:var(--ink)}
.turn.err .bubble{color:var(--accent)}
.turn .thinking{color:var(--faint); font-style:italic}

/* Long technical content — verses, formation names, claims — wraps rather than
   widening its container. The document must never gain horizontal width from
   chat or detail content. */
.disclose-body, .why, .tech, .detail, .detail dd{overflow-wrap:anywhere; min-width:0}
html, body{overflow-x:hidden}

.disclose{display:flex; gap:6px; flex-wrap:wrap; margin-top:7px}
.disclose-btn{font-size:11px; padding:4px 10px; border-radius:999px;
  border:1px solid var(--line); background:var(--ground); color:var(--dim)}
.disclose-btn.on{border-color:var(--accent); color:var(--accent)}
.disclose-body{margin-top:7px; font-size:12.5px; line-height:1.55}
.disclose-body .tech{font-size:11.5px}
.tech .trow{display:grid; grid-template-columns:96px 1fr; gap:2px 10px; padding:4px 0;
  border-top:1px solid var(--line-soft)}
.tech .tk{color:var(--faint); font-size:10px; letter-spacing:.06em; text-transform:uppercase}
.tech .sub{font-size:10.5px; color:var(--faint)}
.tech .pending{color:var(--accent); font-size:11px}
.tech .cjk{font-family:var(--cjk)}

/* One card: what you are writing sits on top, the send button on its own row
   beneath it. Roomier to type into than a single line with the button crowding
   the end of the text. */
.ask{flex-shrink:0; padding:8px 12px calc(8px + var(--safe-b))}
.chat[data-sheet="partial"] .ask,
.chat[data-sheet="expanded"] .ask{border-top:1px solid var(--glass-edge)}
.ask-box{
  border:1px solid var(--line); border-radius:20px; background:var(--panel);
  padding:11px 13px 9px; display:flex; flex-direction:column; gap:7px;
}
.chat[data-sheet="partial"] .ask-box,
.chat[data-sheet="expanded"] .ask-box{border-color:var(--glass-edge)}
.ask-box:focus-within{border-color:var(--dim)}
.ask textarea{
  width:100%; resize:none; border:0; background:transparent; padding:0;
  font-size:14px; line-height:1.45; font-family:inherit;
  color:var(--ink); max-height:96px; min-height:22px;
}
.ask textarea:focus{outline:none}
.ask-actions{display:flex; align-items:center; justify-content:flex-end}
.ask #send{width:34px; height:34px; border-radius:50%; background:var(--ink);
  color:var(--ground); border:0; padding:0; flex-shrink:0;
  display:flex; align-items:center; justify-content:center}
.chat-note{flex-shrink:0; text-align:center; font-size:9.5px; color:var(--faint);
  padding:0 12px calc(6px + var(--safe-b))}
.chat[data-sheet="partial"] .chat-note,
.chat[data-sheet="expanded"] .chat-note{display:none}

@media (prefers-reduced-motion:reduce){*{transition:none !important; animation:none !important}}

/* ---------- account block in the drawer ---------- */
.side-account{border-top:1px solid var(--line-soft); margin-top:8px; padding:10px 12px 4px}
.acct-row{display:flex; justify-content:space-between; align-items:baseline; gap:8px; margin-bottom:9px}
.whoami{font-size:11px; color:var(--faint); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.credits{font-size:11px; font-weight:600; color:var(--accent); white-space:nowrap}
.credits.none{color:var(--dim)}
a.adminlink{display:block; text-align:center; text-decoration:none; box-sizing:border-box}

/* A finished conversation can be read but not continued. */
.readonly-note{
  flex-shrink:0; margin:0 12px calc(8px + env(safe-area-inset-bottom));
  padding:9px 12px; border:1px dashed var(--line); border-radius:var(--radius);
  font-size:11.5px; color:var(--faint); text-align:center;
}

/* ---------- Live Reading checklist ----------
   Shown while a forecast runs. Rows only tick on real backend events; the
   timer and captions are local and never advance the list. */
.live-reading{display:flex; flex-direction:column; gap:9px; min-width:210px}
.lr-head{font-size:12px; color:var(--dim); letter-spacing:.01em}
.lr-list{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:7px}
.lr-item{display:flex; align-items:flex-start; gap:8px; font-size:12.5px; line-height:1.35}
.lr-mark{width:12px; flex-shrink:0; text-align:center; font-size:11px; line-height:1.4}
.lr-body{display:flex; flex-direction:column; gap:2px; min-width:0}
.lr-label{color:var(--faint)}
.lr-caption{font-size:11px; color:var(--faint); opacity:.85}

.lr-item.lr-done .lr-mark{color:var(--accent)}
.lr-item.lr-done .lr-label{color:var(--ink)}
.lr-item.lr-active .lr-mark{color:var(--accent); animation:lr-pulse 1.6s ease-in-out infinite}
.lr-item.lr-active .lr-label{color:var(--ink)}
.lr-item.lr-pending .lr-mark{color:var(--line)}
/* A stopped row is what an in-flight step becomes on failure: visibly halted,
   never left pulsing. */
.lr-item.lr-stopped .lr-mark{color:var(--faint); animation:none}
.lr-item.lr-stopped .lr-label{color:var(--faint); text-decoration:line-through; text-decoration-thickness:1px}

.lr-timer{font-size:11px; color:var(--faint); font-variant-numeric:tabular-nums}

@keyframes lr-pulse{0%,100%{opacity:1}50%{opacity:.35}}
@media (prefers-reduced-motion:reduce){
  .lr-item.lr-active .lr-mark{animation:none}
}

/* ---------- history row options ---------- */
.hrow-wrap{display:flex; align-items:stretch; gap:2px}
.hrow-wrap .hrow{flex:1; min-width:0}
.hrow-more{
  flex:0 0 28px; border:0; background:transparent; color:var(--faint);
  border-radius:var(--radius); font-size:15px; line-height:1; padding:0;
}
.hrow-more:hover{background:var(--sunk); color:var(--dim)}
.hrow-confirm{
  margin:0 4px 8px; padding:10px 11px; border:1px solid var(--line);
  border-radius:var(--radius); background:var(--sunk);
}
.hc-q{font-size:12.5px; color:var(--ink); line-height:1.4}
.hc-s{font-size:11px; color:var(--faint); margin-top:3px; line-height:1.4}
.hc-a{display:flex; gap:6px; margin-top:9px}
.hc-a button{flex:1; padding:6px 0; font-size:12px; border-radius:var(--radius);
  border:1px solid var(--line); background:var(--ground); color:var(--dim)}
.hc-a .hc-go{border-color:var(--accent); color:var(--accent); font-weight:600}

/* ---------- welcome tour ----------
   A small card over a dimmed app, with a ring around the real control being
   described. Sits above the drawer so it is never hidden behind it. */
.wt-root{position:fixed; inset:0; z-index:60; display:flex; align-items:flex-end;
  justify-content:center; padding:0 14px calc(18px + var(--safe-b))}
.wt-scrim{position:absolute; inset:0; background:rgba(0,0,0,.55)}
.wt-spot{
  position:fixed; border-radius:12px; pointer-events:none;
  border:2px solid var(--accent);
  box-shadow:0 0 0 9999px rgba(0,0,0,.55), 0 0 18px rgba(217,164,65,.45);
  transition:top 220ms ease, left 220ms ease, width 220ms ease, height 220ms ease;
}
/* When the spotlight is showing, the ring's own shadow supplies the dimming. */
.wt-spot:not([hidden]) ~ .wt-scrim,
.wt-root:has(.wt-spot:not([hidden])) .wt-scrim{background:transparent}

.wt-card{
  position:relative; width:100%; max-width:360px;
  background:var(--panel); border:1px solid var(--line); border-radius:16px;
  padding:18px 18px 16px; box-shadow:0 20px 50px rgba(0,0,0,.45);
}
/* Move the card to the top when the highlighted control is low on screen. */
.wt-root:has(.wt-card-top){align-items:flex-start; padding-top:calc(18px + env(safe-area-inset-top))}

.wt-dots{display:flex; align-items:center; gap:6px; margin-bottom:12px}
.wt-dot{width:6px; height:6px; border-radius:50%; background:var(--line); display:block}
.wt-dot.on{background:var(--accent); width:18px; border-radius:3px}
.wt-count{margin-left:auto; font-size:10.5px; color:var(--faint);
  font-variant-numeric:tabular-nums}

.wt-title{font-size:17px; margin:0 0 8px; line-height:1.3; font-weight:600}
.wt-body{font-size:13.5px; line-height:1.6; color:var(--dim)}
.wt-body strong{color:var(--accent)}

.wt-actions{display:flex; gap:9px; align-items:center; margin-top:18px}
.wt-skip{flex:0 0 auto; padding:10px 16px; min-height:44px; font-size:13px;
  border:1px solid var(--line); border-radius:var(--radius);
  background:transparent; color:var(--dim)}
.wt-next{flex:1; padding:10px 16px; min-height:44px; font-size:14px; font-weight:600;
  border-radius:var(--radius)}

@media (prefers-reduced-motion:reduce){ .wt-spot{transition:none} }
