/* =========================================================================
   northsetpro — the writing environment.

   Design posture, straight from the spec: never interrupt, always be
   available, make the world visible without being asked. So the chrome is
   quiet, the page is the only bright surface, and nothing ever floats over
   the text the writer is typing. Flags are dots in a gutter, not popups.
   ========================================================================= */

/* ONE THEME, DARK. Previously the palette flipped on prefers-color-scheme but
   the dark branch never overrode --paper, so the sheet stayed #ffffff while the
   script text went light — a white page with near-invisible text. Rather than
   patch the override, dark is now simply the theme: a single set of values,
   nothing to keep in sync, nothing to forget. The page is a warm off-black
   sheet, not a glowing white rectangle, because a writer stares at it for
   hours. A light theme can come back later behind :root[data-theme="light"]. */
:root {
  --paper:      #1a191e;   /* the page itself */
  --page-edge:  #2f2d36;
  --bg:         #111015;   /* the desk the page sits on */
  --panel:      #17161b;
  --line:       #2b2933;
  --line-soft:  #232128;
  --ink:        #ece9e3;
  --muted:      #9c968c;
  --faint:      #6d685f;
  --accent:     #d4694a;
  --accent-tint:#2c1e18;

  --script-ink: #e8e4dc;   /* the words on the page */
  --script-dim: #5c5750;   /* placeholders, scene numbers in the margin */

  --flag-error: #e05a48;
  --flag-warn:  #d8a03f;
  --flag-ask:   #6f9dc9;

  --ui:     'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --mono:   'SF Mono', ui-monospace, 'Roboto Mono', Menlo, monospace;
  --script: 'Courier Prime', 'Courier New', Courier, monospace;

  --r-sm: 8px; --r-ctrl: 11px; --r-card: 15px; --r-pill: 999px;
  --rail-w: 268px;
  --world-w: 318px;
  --top-h: 46px;

  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font-family: var(--ui); font-size: 14px; line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}
button { font: inherit; color: inherit; }
::selection { background: var(--accent-tint); }

/* ============================ top bar ============================ */
.top {
  height: var(--top-h); display: flex; align-items: center; gap: 10px;
  padding: 0 12px; background: var(--panel);
  border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 40;
}
.brand {
  font-family: var(--mono); font-size: 11px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--muted); font-weight: 600;
  padding-right: 10px; margin-right: 2px; border-right: 1px solid var(--line);
  white-space: nowrap;
}
.brand b { color: var(--ink); font-weight: 700; }
.doctitle {
  font-weight: 600; font-size: 14px; padding: 4px 9px; border-radius: var(--r-sm);
  outline: none; min-width: 60px; max-width: 340px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.doctitle:hover  { background: var(--line-soft); }
.doctitle:focus  { background: var(--line-soft); box-shadow: inset 0 0 0 1px var(--line); }
.spacer { flex: 1; }

.pill {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .06em;
  color: var(--faint); white-space: nowrap; padding: 3px 8px;
  border-radius: var(--r-pill); background: var(--line-soft);
}
.pill.on { color: var(--accent); background: var(--accent-tint); }

.tb {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 30px; padding: 0 10px; border: 1px solid transparent;
  background: transparent; border-radius: var(--r-ctrl);
  cursor: pointer; color: var(--muted); white-space: nowrap;
}
.tb:hover  { background: var(--line-soft); color: var(--ink); }
.tb.solid  { background: var(--accent); color: #fff; }
.tb.solid:hover { opacity: .88; }
.tb svg { width: 16px; height: 16px; stroke-width: 1.9; }
.tb[disabled] { opacity: .4; pointer-events: none; }

/* ============================ frame ============================ */
.work {
  display: grid; grid-template-columns: var(--rail-w) minmax(0, 1fr) var(--world-w);
  height: calc(100vh - var(--top-h));
}
.work.no-rail  { grid-template-columns: 0 minmax(0, 1fr) var(--world-w); }
.work.no-world { grid-template-columns: var(--rail-w) minmax(0, 1fr) 0; }
.work.no-rail.no-world { grid-template-columns: 0 minmax(0, 1fr) 0; }

.pane {
  background: var(--panel); overflow: hidden auto; display: flex; flex-direction: column;
}
.pane.rail  { border-right: 1px solid var(--line); }
.pane.world { border-left:  1px solid var(--line); }
.work.no-rail .pane.rail, .work.no-world .pane.world { display: none; }

.pane-head {
  display: flex; align-items: center; gap: 8px; padding: 12px 14px 8px;
  position: sticky; top: 0; background: var(--panel); z-index: 5;
}
.pane-head .t {
  font-family: var(--mono); font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--faint); font-weight: 700;
}
.pane-sub {
  padding: 0 14px 10px; font-family: var(--mono); font-size: 10.5px; color: var(--faint);
}

/* ============================ binder ============================ */
.binder { padding: 0 8px 40px; }
.bnode {
  display: flex; align-items: flex-start; gap: 7px; padding: 6px 8px;
  border-radius: var(--r-sm); cursor: pointer; position: relative;
}
.bnode:hover { background: var(--line-soft); }
.bnode.on    { background: var(--accent-tint); }
.bnode.on .btitle { color: var(--accent); font-weight: 600; }

.bnum {
  font-family: var(--mono); font-size: 10px; color: var(--faint);
  min-width: 17px; text-align: right; padding-top: 2px; flex: none;
}
.bcol { min-width: 0; flex: 1; }
.btitle {
  font-size: 12.5px; line-height: 1.35; overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.bsyn {
  font-size: 11px; color: var(--muted); margin-top: 2px; line-height: 1.35;
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.bsyn.stale { color: var(--flag-warn); }
.bsyn.stale::after { content: ' · may be out of date'; font-family: var(--mono); font-size: 9.5px; }
.bmeta {
  font-family: var(--mono); font-size: 9.5px; color: var(--faint);
  margin-top: 3px; display: flex; gap: 8px; flex-wrap: wrap;
}

/* structure rows read as headers, not as scenes */
.bnode.kind-act, .bnode.kind-sequence { margin-top: 10px; }
.bnode.kind-act .btitle, .bnode.kind-sequence .btitle {
  font-family: var(--mono); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; font-weight: 700; color: var(--muted);
}
.bnode.kind-sequence .btitle { letter-spacing: .1em; color: var(--faint); }
.bnode[data-depth="1"] { padding-left: 16px; }
.bnode[data-depth="2"] { padding-left: 26px; }

/* The dot, not the popup. Flags surface here and the writer looks when they
   surface for coffee, not mid-sentence. */
.bdots { position: absolute; left: 1px; top: 9px; display: flex; flex-direction: column; gap: 2px; }
.bdot  { width: 5px; height: 5px; border-radius: 50%; }
.bdot.error { background: var(--flag-error); }
.bdot.warn  { background: var(--flag-warn); }
.bdot.ask   { background: var(--flag-ask); }

.empty-hint { padding: 18px 16px; color: var(--faint); font-size: 12px; line-height: 1.6; }

/* ============================ the page ============================ */
.center { overflow: auto; background: var(--bg); position: relative; }
.pagewrap {
  padding: 30px 40px 240px; display: flex; flex-direction: column;
  align-items: center; min-width: min-content;
}
/* FIXED width → wrapping and page breaks never change when the window
   resizes. Stable pagination is worth more than a fluid layout here. */
.pagestack { position: relative; width: 816px; flex: 0 0 auto; }
.sheets { position: absolute; inset: 0 auto auto 0; width: 816px; z-index: 0; pointer-events: none; }
.sheet {
  position: absolute; left: 0; width: 816px; height: 1056px; background: var(--paper);
  border: 1px solid var(--page-edge); border-radius: 3px;
  box-shadow: 0 6px 26px rgba(0, 0, 0, .45);
}
/* Page number sits INSIDE the sheet, top right, where a screenplay puts it —
   half an inch down, an inch from the right edge. It used to hang above the
   sheet on a negative offset, which put it on top of the previous page's
   bottom border at every break. */
.sheet .pnum {
  position: absolute; top: 48px; right: 96px;
  font-family: var(--script); font-size: 14px; font-weight: 400;
  color: var(--script-dim); letter-spacing: 0;
}
/* Page 1 carries no number, by convention. */
.sheet:first-child .pnum { display: none; }
.script {
  position: relative; z-index: 1; padding: 96px 96px 96px 144px;
  font-family: var(--script); font-size: 16px; line-height: 1;
  color: var(--script-ink); outline: none; min-height: 1056px;
}

.blk {
  margin: 0; white-space: pre-wrap; word-wrap: break-word; position: relative; padding: 1px 0;
}
.blk[data-type="scene_heading"] { text-transform: uppercase; font-weight: 700; margin-top: 28px; }
.blk[data-type="scene_heading"]:first-child { margin-top: 0; }
.blk[data-type="action"]        { margin-top: 14px; }
.blk[data-type="character"]     { text-transform: uppercase; margin-left: 192px; margin-top: 14px; }
.blk[data-type="parenthetical"] { margin-left: 144px; }
.blk[data-type="dialogue"]      { margin-left: 96px; margin-right: 96px; }
.blk[data-type="transition"]    { text-transform: uppercase; text-align: right; margin-top: 14px; }
.blk[data-type="shot"]          { text-transform: uppercase; font-weight: 700; margin-top: 14px; }
.blk[data-type="general"]       { margin-top: 6px; }
.blk[data-type="cast_list"]     { text-transform: uppercase; margin-left: 96px; color: var(--muted); }
.blk[data-type="new_act"], .blk[data-type="end_of_act"] {
  text-transform: uppercase; font-weight: 700; text-align: center; margin: 24px 0;
}
.blk[data-type="sequence"] { text-transform: uppercase; text-align: center; color: var(--muted); margin: 18px 0; }
.blk[data-type="summary"], .blk[data-type="outline_1"],
.blk[data-type="outline_2"], .blk[data-type="outline_3"] {
  font-family: var(--ui); font-size: 13px; color: var(--muted); margin: 8px 0;
}
.blk[data-type="note"] {
  font-family: var(--ui); font-size: 13px; background: var(--accent-tint);
  border-left: 3px solid var(--accent); padding: 6px 10px; margin: 10px 0;
}
.blk[data-type="scene_heading"]::before {
  content: attr(data-num); position: absolute; left: -92px; top: 1px;
  font-family: var(--script); font-weight: 400; color: var(--faint);
}
.blk[data-type="scene_heading"]::after {
  content: attr(data-num); position: absolute; right: -44px; top: 1px;
  font-family: var(--script); font-weight: 400; color: var(--faint);
}
.blk.empty::after {
  content: attr(data-ph); color: var(--script-dim); text-transform: none; font-weight: 400;
  position: absolute; left: 0; top: 1px; pointer-events: none;
}
.blk[data-type="character"].empty::after     { left: 0; }
.blk[data-type="note"].empty::after,
.blk[data-type="summary"].empty::after       { font-family: var(--ui); }

/* ============================ world pane ============================ */
.world-body { padding: 0 14px 60px; }
.wsec {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .15em;
  text-transform: uppercase; color: var(--faint); font-weight: 700;
  margin: 18px 0 8px; padding-top: 12px; border-top: 1px solid var(--line-soft);
}
.wsec:first-child { border-top: 0; padding-top: 0; margin-top: 4px; }
.wrow { display: flex; justify-content: space-between; gap: 10px; padding: 4px 0; font-size: 12.5px; }
.wrow .k { color: var(--muted); }
.wrow .v { font-family: var(--mono); font-size: 11.5px; text-align: right; }
.wcard {
  border: 1px solid var(--line-soft); border-radius: var(--r-sm);
  padding: 9px 10px; margin-bottom: 7px; background: var(--bg);
}
.wcard .n { font-size: 12.5px; font-weight: 600; }
.wcard .s { font-size: 11.5px; color: var(--muted); margin-top: 3px; line-height: 1.4; }
.wnote { font-size: 11.5px; color: var(--faint); line-height: 1.5; }
.chips { display: flex; flex-wrap: wrap; gap: 5px; }
.chip {
  font-family: var(--mono); font-size: 10px; padding: 3px 7px;
  border-radius: var(--r-pill); background: var(--line-soft); color: var(--muted);
}

/* A measured claim about the corpus always carries its own caveat — the 38
   scripts skew recent, prestige and awards-season, and a threshold derived
   from them reads a competent genre script as underwritten. */
.caveat {
  font-size: 10.5px; color: var(--faint); line-height: 1.5;
  border-left: 2px solid var(--line); padding-left: 8px; margin-top: 8px;
}

/* ============================ element dropdown ============================ */
.eldrop { position: relative; }
.elcur {
  display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 10px;
  border: 1px solid var(--line); background: var(--bg); border-radius: var(--r-ctrl);
  cursor: pointer; min-width: 148px;
}
.elcur .chev { margin-left: auto; color: var(--faint); font-size: 10px; }
.elmenu {
  position: absolute; top: 36px; left: 0; min-width: 216px; z-index: 60;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-card);
  box-shadow: 0 16px 44px rgba(0, 0, 0, .55); padding: 6px; display: none;
  max-height: 68vh; overflow: auto;
}
.elmenu.open { display: block; }
.elgroup {
  font-family: var(--mono); font-size: 9px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--faint); padding: 9px 10px 4px; font-weight: 700;
}
.elitem {
  display: flex; align-items: center; gap: 9px; padding: 7px 10px;
  border-radius: var(--r-sm); cursor: pointer; font-size: 13px;
}
.elitem:hover { background: var(--line-soft); }
.elitem.sel   { background: var(--accent-tint); color: var(--accent); font-weight: 600; }
.elitem .k { margin-left: auto; font-family: var(--mono); font-size: 10px; color: var(--faint); }

/* ============================ menus / dialogs ============================ */
.menu {
  position: absolute; top: 40px; right: 12px; z-index: 60; min-width: 232px;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-card);
  box-shadow: 0 16px 44px rgba(0, 0, 0, .55); padding: 6px;
}
.menu[hidden] { display: none; }
.mi {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  padding: 8px 10px; border: 0; background: transparent; border-radius: var(--r-sm);
  cursor: pointer; font-size: 13px;
}
.mi:hover { background: var(--line-soft); }
.mi .sub { margin-left: auto; font-family: var(--mono); font-size: 10px; color: var(--faint); }
.msep { height: 1px; background: var(--line); margin: 5px 4px; }
.mlabel {
  display: flex; align-items: center; gap: 8px; padding: 8px 10px;
  font-size: 12.5px; color: var(--muted);
}

/* ============================ gate / overlay ============================ */
.gate {
  position: fixed; inset: 0; z-index: 90; background: var(--bg);
  display: flex; align-items: center; justify-content: center; padding: 24px;
}
.gate[hidden] { display: none; }
.gate-card { max-width: 400px; text-align: center; }
.gate-card h1 {
  font-family: var(--mono); font-size: 13px; letter-spacing: .2em; text-transform: uppercase;
  font-weight: 700; margin: 0 0 14px;
}
.gate-card p { color: var(--muted); font-size: 13.5px; line-height: 1.6; margin: 0 0 20px; }
.btn {
  display: inline-flex; align-items: center; gap: 8px; padding: 10px 18px;
  border: 0; border-radius: var(--r-ctrl); background: var(--accent); color: #fff;
  cursor: pointer; font-size: 13.5px; font-weight: 500;
}
.btn.ghost { background: transparent; color: var(--muted); border: 1px solid var(--line); }

/* ============================ smarttype ============================ */
#stPop {
  position: fixed; z-index: 80; min-width: 200px; max-width: 300px; display: none;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-sm);
  box-shadow: 0 12px 32px rgba(0, 0, 0, .55); padding: 4px;
}
#stPop.show { display: block; }
.stit {
  padding: 6px 9px; border-radius: 6px; font-family: var(--mono);
  font-size: 11.5px; cursor: pointer; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.stit.on { background: var(--accent-tint); color: var(--accent); }

/* ============================ toast ============================ */
#toast {
  position: fixed; left: 50%; bottom: 26px; transform: translate(-50%, 14px);
  background: #2a2831; color: var(--ink); padding: 9px 16px;
  border-radius: var(--r-pill); font-size: 12.5px; z-index: 100;
  opacity: 0; pointer-events: none; transition: opacity .18s, transform .18s;
  max-width: 80vw; text-align: center;
}
#toast.show { opacity: 1; transform: translate(-50%, 0); }

@media (max-width: 1180px) {
  .work { grid-template-columns: var(--rail-w) minmax(0, 1fr) 0; }
  .pane.world { display: none; }
}
@media (max-width: 860px) {
  .work { grid-template-columns: 0 minmax(0, 1fr) 0; }
  .pane.rail { display: none; }
  .pagewrap { padding: 16px 8px 200px; }
}

/* ============================ view modes ============================
   Corkboard and Outliner are the SAME nodes through a different lens.
   Moving a card moves the scene; editing a synopsis edits the exact text
   the context builder feeds the model. That equivalence is the point —
   a second, drifting copy of the outline would be worse than none. */
.modes { display: inline-flex; gap: 2px; padding: 2px; background: var(--line-soft); border-radius: var(--r-ctrl); }
.mode {
  border: 0; background: transparent; padding: 5px 11px; border-radius: 9px;
  cursor: pointer; font-size: 12.5px; color: var(--muted);
}
.mode:hover { color: var(--ink); }
.mode.on { background: var(--panel); color: var(--ink); font-weight: 600; box-shadow: 0 1px 3px rgba(0,0,0,.5); }

.find {
  width: 210px; height: 30px; padding: 0 11px; font-size: 12px; font-family: var(--ui);
  border: 1px solid var(--line); background: var(--bg); color: var(--ink);
  border-radius: var(--r-ctrl); outline: none;
}
.find:focus { border-color: var(--accent); }
.find::placeholder { color: var(--faint); font-size: 11px; }

.views { background: var(--bg); overflow: auto; grid-column: 2; grid-row: 1; }
.center[hidden] { display: none; }
.views[hidden] { display: none; }
.views-body { padding: 22px 26px 90px; }

/* ---- corkboard ---- */
.cork { display: grid; grid-template-columns: repeat(auto-fill, minmax(224px, 1fr)); gap: 14px; align-items: start; }
.cork-div {
  grid-column: 1 / -1; font-family: var(--mono); font-size: 9.5px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--faint); font-weight: 700;
  padding: 14px 0 2px; border-bottom: 1px solid var(--line); margin-bottom: 2px;
}
.card {
  background: var(--paper); border: 1px solid var(--page-edge); border-radius: var(--r-sm);
  padding: 10px 11px 9px; box-shadow: 0 2px 10px rgba(0,0,0,.35);
  cursor: grab; position: relative; min-height: 128px; display: flex; flex-direction: column;
}
/* Same on the cards: a dot in the corner, not a rail. */
.card::before {
  content: ''; position: absolute; top: 11px; right: 11px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--card-label, transparent);
}
.card-top { padding-right: 14px; }
.card.dragging { opacity: .4; }
.card.dragover { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-tint); }
.card-top { display: flex; justify-content: space-between; font-family: var(--mono); font-size: 9.5px; color: var(--faint); }
.card-title { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .02em; margin: 6px 0 5px; line-height: 1.3; }
.card-syn { font-size: 12px; color: var(--muted); line-height: 1.45; outline: none; flex: 1; min-height: 34px; }
.card-syn:empty::before { content: attr(data-ph); color: var(--script-dim); }
.card-syn:focus { color: var(--ink); }
.card-stale { font-family: var(--mono); font-size: 9px; color: var(--flag-warn); margin-top: 4px; }
.card-foot { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; margin-top: 8px; }
.card-status { margin-left: auto; font-family: var(--mono); font-size: 9px; color: var(--faint); }

/* ---- outliner ---- */
.outl { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.outl th {
  text-align: left; font-family: var(--mono); font-size: 9px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--faint); font-weight: 700;
  padding: 6px 8px; border-bottom: 1px solid var(--line); position: sticky; top: 0; background: var(--bg);
}
.outl td { padding: 7px 8px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
.outl tr:hover td { background: var(--panel); }
.outl .mono { font-family: var(--mono); font-size: 11px; color: var(--muted); }
.outl .small { font-size: 10px; }
.outl-struct td { background: var(--line-soft); font-family: var(--mono); font-size: 10px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted); font-weight: 700; }
.outl-syn { color: var(--muted); outline: none; min-width: 200px; }
.outl-syn:focus { color: var(--ink); background: var(--panel); }
.outl-syn.stale { color: var(--flag-warn); }
.swatch { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 6px; vertical-align: middle; }
.mini {
  font: inherit; font-size: 11px; padding: 2px 4px; border: 1px solid transparent;
  background: transparent; color: var(--muted); border-radius: 5px; max-width: 100%;
}
.mini:hover { border-color: var(--line); background: var(--panel); }

/* the gate carries a real instruction when the allowlist blocks saving */
.gate-card { max-width: 460px; }
.gate-card p code {
  font-family: var(--mono); font-size: 11.5px; background: var(--line-soft);
  padding: 2px 5px; border-radius: 5px; color: var(--ink); word-break: break-all;
}
.gate-card p a { color: var(--accent); }

/* ============================ the pass ============================
   The Analyze control is a four-state object: idle · running · analyzed
   (clean) · findings, plus a dimmed "stale" when the pages have moved since.
   It is the one place the app renders a verdict, and it never does so on its
   own — the room is silent until spoken to. */
.analyze {
  display: inline-flex; align-items: center; gap: 8px; height: 30px;
  padding: 0 13px; border: 1px solid var(--line); background: var(--bg);
  border-radius: var(--r-pill); cursor: pointer; color: var(--ink);
  font-size: 12.5px; font-weight: 500; white-space: nowrap;
  transition: border-color .15s, background .15s;
}
.analyze:hover:not(:disabled) { border-color: var(--accent); }
.analyze:disabled { cursor: default; }
.analyze .sub {
  font-family: var(--mono); font-size: 10px; color: var(--faint);
  padding-left: 7px; margin-left: 1px; border-left: 1px solid var(--line);
}
.analyze .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--faint); flex: none; }
.analyze .dot.idle  { background: transparent; box-shadow: inset 0 0 0 1.5px var(--muted); }
.analyze .dot.ok    { background: #6f9f74; }
.analyze .dot.error { background: var(--flag-error); }
.analyze .dot.warn  { background: var(--flag-warn); }
.analyze .dot.ask   { background: var(--flag-ask); }

.analyze.idle     { border-color: var(--muted); }
.analyze.clean    { border-color: #3d5a41; background: #1a2a1c; }
.analyze.findings { border-color: var(--accent); background: var(--accent-tint); }
.analyze.stale    { opacity: .62; border-style: dashed; }
.analyze.running  { border-color: var(--accent); background: var(--accent-tint); }

/* the pass is running — a ring, not a bar. It is over in well under a second
   on a feature, so this is an acknowledgement, not a progress estimate. */
.analyze .ring {
  width: 12px; height: 12px; border-radius: 50%; flex: none;
  border: 2px solid var(--accent-tint);
  border-top-color: var(--accent);
  animation: nspin .62s linear infinite;
}
@keyframes nspin { to { transform: rotate(360deg); } }

/* ---- the report ---- */
.rep { max-width: 900px; margin: 0 auto; }
.rep-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 6px; }
.rep-title { font-size: 19px; font-weight: 600; letter-spacing: -.01em; }
.rep-sub { font-family: var(--mono); font-size: 11px; color: var(--faint); margin-top: 4px; }
.rep-sec {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .15em; text-transform: uppercase;
  color: var(--faint); font-weight: 700; margin: 28px 0 12px;
  padding-top: 14px; border-top: 1px solid var(--line);
}
.rep-note {
  font-family: var(--ui); font-size: 10.5px; letter-spacing: 0; text-transform: none;
  color: var(--faint); font-weight: 400; margin-left: 8px;
}
.rep-none {
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 14px 16px;
  font-size: 13px; color: var(--muted); line-height: 1.6;
}
.rep-none b { color: var(--ink); display: block; margin-bottom: 5px; }
.rep-foot {
  margin-top: 30px; padding-top: 14px; border-top: 1px solid var(--line);
  font-size: 11px; color: var(--faint); line-height: 1.6;
}

/* A finding always carries the number it came from. A judgment the writer
   can't inspect and disagree with does not render.
   NOTE the class is `.finding`, not `.find` — `.find` is the collections
   search input above and the collision silently squashed every card to
   210px. */
.finding {
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 13px 15px; margin-bottom: 10px; background: var(--panel);
}
/* Severity reads as a small dot beside the kind, not a coloured rail down the
   edge — the rail turned every finding into a notification banner. */
.finding-kind::before {
  content: ''; display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  margin-right: 7px; vertical-align: 1px; background: var(--faint);
}
.finding.sev-error .finding-kind::before { background: var(--flag-error); }
.finding.sev-warn  .finding-kind::before { background: var(--flag-warn); }
.finding.sev-ask   .finding-kind::before { background: var(--flag-ask); }
.finding-top { display: flex; align-items: center; justify-content: space-between; }
.finding-kind {
  font-family: var(--mono); font-size: 9px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--faint); font-weight: 700;
}
.finding-x {
  border: 0; background: transparent; color: var(--faint); cursor: pointer;
  font-size: 17px; line-height: 1; padding: 0 2px;
}
.finding-x:hover { color: var(--ink); }
.finding-title { font-size: 14.5px; font-weight: 600; margin: 5px 0 6px; line-height: 1.35; }
.finding-body { font-size: 13px; color: var(--muted); line-height: 1.6; }
.finding-ev {
  margin-top: 9px; font-family: var(--mono); font-size: 10.5px; color: var(--ink);
  background: var(--line-soft); display: inline-block; padding: 3px 9px; border-radius: var(--r-pill);
}
.finding-ev .ev-label { color: var(--faint); letter-spacing: .1em; text-transform: uppercase; font-size: 8.5px; }
.finding-nodes { margin-top: 9px; display: flex; flex-wrap: wrap; gap: 5px; }
.jump {
  border: 1px solid var(--line); background: transparent; color: var(--muted);
  font-size: 10.5px; padding: 3px 8px; border-radius: var(--r-pill); cursor: pointer;
}
.jump:hover { border-color: var(--accent); color: var(--accent); }

/* Measurements. Plain facts with no interpretation attached — deliberately
   quieter than the findings above them. */
.meas { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.meas td { padding: 7px 10px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
.meas .m-l { color: var(--muted); width: 210px; }
.meas .m-v { font-family: var(--mono); font-weight: 600; width: 110px; }
.meas .m-r { font-family: var(--mono); font-size: 11px; color: var(--faint); width: 260px; }
.meas .m-n { font-size: 11.5px; color: var(--faint); }

.pairs { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 5px; }
.pair { display: flex; gap: 10px; align-items: baseline; padding: 5px 9px; border-radius: var(--r-sm); background: var(--panel); }
.pair .pd { font-family: var(--mono); font-size: 12px; font-weight: 600; min-width: 40px; }
.pair .pn { font-family: var(--mono); font-size: 10.5px; color: var(--muted); }

/* the corpus door, before it opens */
.locked {
  border: 1px dashed var(--line); border-radius: var(--r-sm); padding: 11px 12px;
  font-size: 11.5px; color: var(--faint); line-height: 1.55;
}
.locked b { color: var(--muted); }
.linkbtn {
  border: 0; background: transparent; padding: 0; cursor: pointer;
  color: var(--accent); font: inherit; text-decoration: underline;
  text-underline-offset: 2px;
}

/* ============================ form controls ============================
   The app's own select and checkbox. No native <select> renders anywhere —
   the browser draws a light popup on a dark page and the option list can't be
   styled at all, and on a tool a writer stares at for hours one stray white
   rectangle is the thing they see. */
.nsel {
  display: inline-flex; align-items: center; gap: 7px; max-width: 100%;
  height: 26px; padding: 0 8px; cursor: pointer; text-align: left;
  border: 1px solid transparent; background: transparent; color: var(--muted);
  border-radius: var(--r-sm); font: inherit; font-size: 12px;
}
.nsel:hover { border-color: var(--line); background: var(--bg); color: var(--ink); }
.nsel:focus-visible { outline: none; border-color: var(--accent); color: var(--ink); }
.nsel.open { border-color: var(--accent); background: var(--bg); color: var(--ink); }
.nsel-lbl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nsel-chev { margin-left: auto; padding-left: 4px; font-size: 9px; color: var(--faint); }
.nsel-dot { width: 8px; height: 8px; border-radius: 2px; flex: none; }
.nsel-dot.none { background: transparent; box-shadow: inset 0 0 0 1px var(--line); }

.nsel-list {
  position: fixed; z-index: 200; padding: 5px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-sm); box-shadow: 0 14px 38px rgba(0, 0, 0, .6);
  max-height: 300px; overflow: auto;
}
.nsel-opt {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; border-radius: 6px; font-size: 12.5px;
  color: var(--muted); cursor: pointer; white-space: nowrap;
}
.nsel-opt:hover, .nsel-opt.cursor { background: var(--line-soft); color: var(--ink); }
.nsel-opt.on { color: var(--accent); font-weight: 600; }

.ncheck {
  display: inline-flex; align-items: center; gap: 9px; width: 100%;
  padding: 7px 10px; border: 0; background: transparent; cursor: pointer;
  border-radius: var(--r-sm); font-size: 13px; color: var(--muted); text-align: left;
}
.ncheck:hover { background: var(--line-soft); color: var(--ink); }
.ncheck-box {
  width: 15px; height: 15px; flex: none; border-radius: 4px;
  border: 1px solid var(--line); display: inline-flex; align-items: center; justify-content: center;
  color: #fff;
}
.ncheck.on { color: var(--ink); }
.ncheck.on .ncheck-box { background: var(--accent); border-color: var(--accent); }
.ncheck-box svg { width: 11px; height: 11px; }

/* ============================ the room ============================
   A closed drawer until clicked. It never opens itself, never pulses, never
   notifies — the whole point is that a writer in a run is holding something
   that cannot be picked back up once dropped. */
.room { position: fixed; right: 20px; bottom: 20px; z-index: 120; }
.room-tab {
  display: inline-flex; align-items: center; gap: 8px; height: 38px; padding: 0 16px;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted);
  border-radius: var(--r-pill); cursor: pointer; font-size: 13px;
  box-shadow: 0 6px 22px rgba(0, 0, 0, .5);
}
.room-tab:hover { border-color: var(--accent); color: var(--ink); }
.room-tab svg { width: 16px; height: 16px; }
.room.open .room-tab { display: none; }

.room-panel {
  width: 396px; max-width: calc(100vw - 40px); max-height: min(74vh, 720px);
  display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-card);
  box-shadow: 0 20px 60px rgba(0, 0, 0, .65); overflow: hidden;
}
.room-panel[hidden] { display: none; }
.room-head {
  display: flex; align-items: center; gap: 9px; padding: 11px 12px 10px;
  border-bottom: 1px solid var(--line);
}
.room-head .t {
  font-family: var(--mono); font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--faint); font-weight: 700;
}
.room-where {
  font-family: var(--mono); font-size: 10px; color: var(--faint);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1;
}
.room-x { border: 0; background: transparent; color: var(--faint); cursor: pointer; font-size: 18px; line-height: 1; }
.room-x:hover { color: var(--ink); }

.room-quick { display: flex; flex-wrap: wrap; gap: 5px; padding: 10px 12px; }
.room-chip {
  border: 1px solid var(--line); background: transparent; color: var(--muted);
  font-size: 11.5px; padding: 5px 10px; border-radius: var(--r-pill); cursor: pointer;
}
.room-chip:hover { border-color: var(--accent); color: var(--accent); }

.room-thread { flex: 1; overflow: auto; padding: 2px 12px 10px; min-height: 0; min-width: 0; }
/* Belt and braces after the .room collision: nothing inside the drawer may
   position itself, and long unbroken strings wrap instead of widening it. */
.room-panel * { position: static; max-width: 100%; }
.room-panel .rmsg-body, .room-panel .rmsg-you { overflow-wrap: anywhere; }
.rmsg { margin-bottom: 12px; min-width: 0; }
/* The asked question. Deliberately NOT pill-shaped — it read as a chip that
   was still selected, so a question asked three scenes ago looked like a live
   toggle. It is a transcript line, not a control. */
.rmsg-you {
  font-size: 12px; color: var(--faint); padding: 0 0 2px;
  border-left: 2px solid var(--line); padding-left: 9px;
  display: block; max-width: 100%;
}
/* Answers about a scene the writer has since left. */
.rmsg.elsewhere { opacity: .42; }
.rdiv {
  font-family: var(--mono); font-size: 9px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--faint); text-align: center; margin: 4px 0 12px; position: relative;
}
.rdiv::before, .rdiv::after {
  content: ''; position: absolute; top: 50%; width: 22%; height: 1px; background: var(--line);
}
.rdiv::before { left: 0; } .rdiv::after { right: 0; }
.rmsg-top { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.rmsg-tag {
  font-family: var(--mono); font-size: 8.5px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--accent); font-weight: 700;
}
.rmsg-meta { font-family: var(--mono); font-size: 9px; color: var(--faint); }
.rmsg-x { margin-left: auto; border: 0; background: transparent; color: var(--faint); cursor: pointer; font-size: 15px; line-height: 1; }
.rmsg-x:hover { color: var(--ink); }
.rmsg-body { font-size: 13px; line-height: 1.62; color: var(--ink); }
.rmsg-body p { margin: 0 0 9px; }
.rmsg-body p:last-child { margin-bottom: 0; }
.rerr { color: var(--flag-warn); font-size: 12.5px; }

.rdots { display: inline-flex; gap: 4px; padding: 4px 0; }
.rdots i { width: 5px; height: 5px; border-radius: 50%; background: var(--faint); animation: rbounce 1s infinite; }
.rdots i:nth-child(2) { animation-delay: .15s; }
.rdots i:nth-child(3) { animation-delay: .3s; }
@keyframes rbounce { 0%,60%,100% { opacity: .3; } 30% { opacity: 1; } }

.room-ask { display: flex; gap: 7px; align-items: flex-end; padding: 10px 12px; border-top: 1px solid var(--line); }
.room-ask textarea {
  flex: 1; resize: none; border: 1px solid var(--line); background: var(--bg);
  color: var(--ink); border-radius: var(--r-sm); padding: 8px 10px;
  font: inherit; font-size: 12.5px; outline: none; line-height: 1.45; max-height: 120px;
}
.room-ask textarea:focus { border-color: var(--accent); }
.room-send {
  width: 32px; height: 32px; flex: none; border: 0; border-radius: var(--r-sm);
  background: var(--accent); color: #fff; cursor: pointer; font-size: 14px;
}
.room-send:disabled { opacity: .45; cursor: default; }
.room-foot { padding: 0 12px 11px; font-size: 10.5px; color: var(--faint); line-height: 1.5; }

.cork-help {
  font-size: 12px; color: var(--faint); line-height: 1.6;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 10px 12px; margin-bottom: 16px;
}
.cork-help b { color: var(--muted); font-weight: 600; }

/* ============================ character dossier ============================
   Occupies the world pane rather than adding a fourth column. The one rule
   that matters visually: a value the engine proposed must never look like a
   value the writer decided. */
.backb { height: 22px; padding: 0 7px; font-size: 15px; line-height: 1; }
.dtabs { display: flex; gap: 2px; margin: 0 0 14px; }
.dtab {
  flex: 1; border: 0; background: var(--line-soft); color: var(--muted);
  font-size: 11px; padding: 5px 0; border-radius: 7px; cursor: pointer;
}
.dtab:hover { color: var(--ink); }
.dtab.on { background: var(--accent-tint); color: var(--accent); font-weight: 600; }

.dfield { margin-bottom: 13px; }
.dlab {
  font-family: var(--mono); font-size: 8.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--faint); font-weight: 700; display: flex; align-items: center; gap: 6px; margin-bottom: 4px;
}
.dval {
  font-size: 12.5px; line-height: 1.55; color: var(--ink); outline: none;
  border: 1px solid transparent; border-radius: 6px; padding: 5px 7px; margin-left: -7px;
}
.dval:hover { border-color: var(--line); }
.dval:focus { border-color: var(--accent); background: var(--bg); }
.dval.empty::before { content: attr(data-ph); color: var(--faint); font-style: italic; }

.badge {
  font-family: var(--mono); font-size: 8px; letter-spacing: .1em; text-transform: uppercase;
  padding: 2px 5px; border-radius: 3px; font-weight: 700;
}
.badge.prop { background: #2b2333; color: #b79ad6; }
.badge.conf { background: #1e2a20; color: #7fb185; }
/* proposed: dashed and tinted, so it can never be mistaken for a decision */
.dval.prop { border-left: 2px dashed #6d5a86; background: #1c1922; border-radius: 0 6px 6px 0; }
.dact { display: flex; gap: 5px; margin-top: 6px; }
.dbtn {
  border: 1px solid var(--line); background: transparent; color: var(--muted);
  font-size: 10.5px; padding: 3px 10px; border-radius: var(--r-pill); cursor: pointer;
}
.dbtn:hover { color: var(--ink); border-color: var(--muted); }
.dbtn.ok { border-color: #4a6b4f; color: #8fc196; }
.dbtn.ok:hover { background: #1e2a20; }
.dprop { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.btn.small { padding: 7px 13px; font-size: 12.5px; border-radius: var(--r-ctrl); margin-bottom: 8px; }
.btn.small:disabled { opacity: .55; cursor: default; }
.dempty { font-size: 12px; color: var(--faint); font-style: italic; padding: 6px 0; }

.arcrow { display: flex; gap: 8px; align-items: baseline; padding: 6px 0; border-bottom: 1px solid var(--line-soft); }
.arcrow.now .arclab { color: var(--accent); font-weight: 600; }
.arcsc { font-family: var(--mono); font-size: 9.5px; color: var(--faint); flex: none; }
.arcn {
  width: 26px; font: inherit; font-family: var(--mono); font-size: 9.5px; text-align: center;
  background: transparent; border: 1px solid transparent; color: var(--muted); border-radius: 4px;
}
.arcn:hover, .arcn:focus { border-color: var(--line); background: var(--bg); outline: none; color: var(--ink); }
.arclab { font-size: 12px; flex: 1; outline: none; border-radius: 4px; padding: 1px 3px; }
.arclab:focus { background: var(--bg); box-shadow: 0 0 0 1px var(--accent); }
.archere { font-family: var(--mono); font-size: 8.5px; color: var(--accent); }
.arcx { border: 0; background: transparent; color: var(--faint); cursor: pointer; font-size: 14px; line-height: 1; }
.arcx:hover { color: var(--flag-error); }

.know { display: flex; gap: 7px; align-items: baseline; font-size: 11.5px; padding: 5px 0; }
.kdot { width: 6px; height: 6px; border-radius: 50%; flex: none; margin-top: 5px; }
.kopen { background: #7fb185; }
.kshut { background: var(--faint); }
.kclaim { flex: 1; outline: none; border-radius: 4px; padding: 1px 3px; }
.kclaim:focus { background: var(--bg); box-shadow: 0 0 0 1px var(--accent); }

/* every name, everywhere, is a way in */
.cname {
  border: 0; background: transparent; padding: 0; cursor: pointer; font: inherit;
  color: inherit; text-decoration: underline; text-decoration-style: dotted;
  text-underline-offset: 3px; text-decoration-color: var(--faint);
}
.cname:hover { color: var(--accent); text-decoration-color: var(--accent); }
.chip.cname { text-decoration: none; }
.chip.cname:hover { color: var(--accent); }
.dbtn.tiny { font-size: 9.5px; padding: 2px 7px; }
.arcrow.prop .arclab { border-left: 2px dashed #6d5a86; padding-left: 7px; background: #1c1922; }
.kclaim.prop { border-left: 2px dashed #6d5a86; padding-left: 7px; background: #1c1922; }

/* the graveyard — reached only when the writer comes looking */
.grave { border: 1px solid var(--line); border-radius: var(--r-sm); padding: 12px 14px; margin-bottom: 10px; }
.grave-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.grave-when { font-family: var(--mono); font-size: 10px; color: var(--faint); }
.grave-title { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .02em; }
.grave-syn { font-size: 12.5px; color: var(--muted); margin-top: 4px; }
.grave-text { font-family: var(--script); font-size: 12px; color: var(--faint); margin-top: 7px; line-height: 1.55; }
.grave-why { margin-top: 9px; padding-top: 8px; border-top: 1px solid var(--line-soft); }

/* echoes — optional colour, never mixed with findings */
.echo-toggle { display: flex; align-items: center; gap: 10px; font-size: 12px; color: var(--faint); margin-bottom: 12px; }
.echo { border: 1px dashed var(--line); border-radius: var(--r-sm); padding: 11px 13px; margin-bottom: 9px; }
.echo-top { display: flex; justify-content: space-between; gap: 10px; }
.echo-kind { font-family: var(--mono); font-size: 8.5px; letter-spacing: .14em; text-transform: uppercase; color: #b79ad6; font-weight: 700; }
.echo-src { font-family: var(--mono); font-size: 9.5px; color: var(--faint); text-align: right; }
.echo-title { font-size: 13.5px; font-weight: 600; margin: 5px 0 5px; }
.echo-body { font-size: 12.5px; color: var(--muted); line-height: 1.6; }
.echo-fail { font-size: 12px; color: var(--faint); margin-top: 6px; line-height: 1.55; }
.echo-fail b { color: var(--muted); }

/* ---- the second track ---- */
.stx { border-top: 1px solid var(--line-soft); padding: 9px 0 4px; }
.stx:first-of-type { border-top: 0; }
.stx-n { font-size: 12.5px; font-weight: 600; margin-bottom: 5px; }
.stx-f { margin-bottom: 7px; }
.stx-l { font-family: var(--mono); font-size: 8.5px; letter-spacing: .13em; text-transform: uppercase;
         color: var(--faint); font-weight: 700; display: flex; align-items: center; gap: 6px; margin-bottom: 3px; }

/* ---- who is ahead ---- */
.gaprow { display: flex; flex-direction: column; gap: 2px; padding: 7px 9px; border-radius: var(--r-sm);
          margin-bottom: 6px; font-size: 12px; }
.gaprow b { font-size: 11.5px; }
.gaprow span { color: var(--muted); font-size: 11.5px; line-height: 1.45; }
.gaprow.irony { background: #1e2630; border-left: 2px solid var(--flag-ask); }
.gaprow.withheld { background: #2c231a; border-left: 2px solid var(--flag-warn); }

/* the dial: audience-ahead above the line, character-ahead below */
.gapstrip { display: flex; gap: 1px; align-items: stretch; height: 54px; margin-top: 12px; }
.gapcol { flex: 1; min-width: 2px; display: flex; flex-direction: column; cursor: pointer; }
.gapcol:hover { background: var(--line-soft); }
.gapup, .gapdn { flex: 1; display: flex; }
.gapup { align-items: flex-end; }
.gapup i { width: 100%; background: var(--flag-ask); border-radius: 1px 1px 0 0; }
.gapdn i { width: 100%; background: var(--flag-warn); border-radius: 0 0 1px 1px; }
.gapmid { height: 1px; background: var(--line); }
.gaplegend { display: flex; gap: 14px; margin-top: 7px; font-size: 10px; color: var(--faint); }
.gaplegend span { display: flex; align-items: center; gap: 5px; }
.sw { width: 8px; height: 8px; border-radius: 2px; }
.sw.irony { background: var(--flag-ask); }
.sw.withheld { background: var(--flag-warn); }
.arcn.aud { color: var(--flag-ask); }
.gate-link { margin-top: 18px; font-size: 12.5px; }
.gate-link a { color: var(--muted); text-decoration: none; border-bottom: 1px solid var(--line); padding-bottom: 2px; }
.gate-link a:hover { color: var(--accent); border-color: var(--accent); }
.gaplegend .key { font-family: var(--mono); font-size: 8.5px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--faint); opacity: .7; }

/* ---- beats: the classics, live against the page ---- */
.modelpick { margin-bottom: 10px; }
.modelpick .nsel { width: 100%; border-color: var(--line); background: var(--bg); }
.beat { border: 1px solid var(--line); border-radius: var(--r-sm); padding: 10px 12px; margin-bottom: 8px; }
.beat.now { border-color: var(--accent); background: var(--accent-tint); }
.beat.next { opacity: .72; }
.beat-n { font-size: 13px; font-weight: 600; color: var(--ink); }
.beat.now .beat-n { color: var(--accent); }
.beat-w { font-family: var(--mono); font-size: 9.5px; color: var(--faint); margin-top: 2px; }
.beat-f { font-size: 12px; color: var(--muted); line-height: 1.5; margin-top: 6px; }
.beat-m { font-size: 11.5px; color: var(--faint); line-height: 1.5; margin-top: 5px; }
.beat-m b { color: var(--muted); }

/* ---- sharing ---- */
#shareMenu { min-width: 320px; }
.shrow { display: flex; align-items: center; gap: 8px; padding: 6px 10px; font-size: 12.5px; }
.shwho { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.shrole {
  font-family: var(--mono); font-size: 9px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--faint); background: var(--line-soft); padding: 2px 6px; border-radius: var(--r-pill);
}
.shx { border: 0; background: transparent; color: var(--faint); cursor: pointer; font-size: 15px; line-height: 1; }
.shx:hover { color: var(--flag-error); }
.shadd { display: flex; gap: 6px; align-items: center; padding: 6px 10px; }
.shadd input {
  flex: 1; min-width: 0; height: 28px; padding: 0 9px; font: inherit; font-size: 12px;
  border: 1px solid var(--line); background: var(--bg); color: var(--ink);
  border-radius: var(--r-sm); outline: none;
}
.shadd input:focus { border-color: var(--accent); }
.shadd .nsel { border-color: var(--line); background: var(--bg); }

/* checks that cannot speak yet — dimmer than a finding, never alarming */
.dormant { border: 1px dashed var(--line); border-radius: var(--r-sm); padding: 10px 12px; margin-bottom: 8px; }
.dormant-t { font-size: 12.5px; font-weight: 600; color: var(--muted); }
.dormant-w { font-size: 12px; color: var(--faint); line-height: 1.55; margin-top: 4px; }

/* ============================ collapsible sections ============================
   Seven things you can scan, not one column you have to read. The badge is the
   whole idea: amber only when there is something inside, so a closed pane still
   tells you where to look. */
.psec { border-bottom: 1px solid var(--line); }
.psec:last-child { border-bottom: 0; }
.phead {
  display: flex; align-items: center; gap: 9px; padding: 11px 2px;
  cursor: pointer; user-select: none;
}
.phead:hover { background: var(--line-soft); margin: 0 -14px; padding-left: 16px; padding-right: 16px; }
.pchev {
  color: var(--faint); font-size: 8px; width: 9px; flex: none;
  transition: transform .16s ease;
}
.psec.open .pchev { transform: rotate(90deg); }
.ptitle {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted); font-weight: 700; flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.psec.open .ptitle { color: var(--ink); }
.pcount {
  font-family: var(--mono); font-size: 9px; color: var(--faint);
  background: var(--line-soft); padding: 2px 7px; border-radius: var(--r-pill);
  white-space: nowrap; flex: none;
}
.pcount.alert { background: #2c231a; color: var(--flag-warn); }
.ppin {
  border: 0; background: transparent; color: var(--line); cursor: pointer;
  padding: 2px; display: flex; flex: none; border-radius: 4px;
}
.ppin svg { width: 12px; height: 12px; }
.phead:hover .ppin { color: var(--faint); }
.ppin:hover { color: var(--ink) !important; }
.ppin.on { color: var(--accent) !important; }

.ppeek {
  font-size: 11.5px; color: var(--faint); line-height: 1.45;
  padding: 0 0 11px 18px; margin-top: -3px;
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.psec.open .ppeek { display: none; }
.pbody { padding: 2px 0 15px; }
.psec:not(.open) .pbody { display: none; }
/* inside a section the old headers are redundant — the section IS the header */
.pbody > .wsec:first-child { display: none; }

/* ============================ the mumble ============================
   The nine seconds before typing. A closed tab until clicked; it never opens
   itself and never surfaces a fragment unasked. */
.mumble { position: fixed; right: 20px; bottom: 70px; z-index: 118; }
.mumble-tab {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border: 1px solid var(--line); background: var(--panel);
  color: var(--muted); border-radius: 50%; cursor: pointer;
  box-shadow: 0 6px 22px rgba(0, 0, 0, .5);
}
.mumble-tab:hover { border-color: var(--accent); color: var(--ink); }
.mumble-tab svg { width: 16px; height: 16px; }
.mumble.open .mumble-tab { display: none; }

.mumble-panel {
  width: 400px; max-width: calc(100vw - 40px); max-height: min(76vh, 760px);
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-card);
  box-shadow: 0 20px 60px rgba(0, 0, 0, .65);
}
.mumble-panel[hidden] { display: none; }
.mumble-panel * { position: static; max-width: 100%; }
.mb-head { display: flex; align-items: center; gap: 9px; padding: 11px 12px 9px; border-bottom: 1px solid var(--line); }
.mb-head .t {
  font-family: var(--mono); font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--faint); font-weight: 700;
}
.mb-where { font-family: var(--mono); font-size: 10px; color: var(--faint); flex: 1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#mbText {
  margin: 11px 12px 0; resize: none; border: 1px solid var(--line); background: var(--bg);
  color: var(--ink); border-radius: var(--r-sm); padding: 9px 11px;
  font: inherit; font-size: 13px; line-height: 1.5; outline: none; min-height: 56px;
}
#mbText:focus { border-color: var(--accent); }
.mb-tools { display: flex; align-items: center; gap: 6px; padding: 9px 12px 0; }
.mb-timer { font-family: var(--mono); font-size: 11px; color: var(--flag-error); }
.dbtn.recording { border-color: var(--flag-error); color: var(--flag-error); }
.mb-hint { padding: 8px 12px 10px; font-size: 11px; color: var(--faint); line-height: 1.5; }
.mb-out, .mb-list { overflow: auto; padding: 0 12px; }
.mb-out { flex: 0 1 auto; }
.mb-list { flex: 1 1 auto; padding-bottom: 12px; min-height: 0; }

.mb-gist { font-size: 12.5px; color: var(--muted); font-style: italic; padding: 4px 0 10px; line-height: 1.5; }
.mb-bhead { display: flex; align-items: baseline; gap: 8px; margin: 10px 0 7px; flex-wrap: wrap; }
.mb-tag {
  font-family: var(--mono); font-size: 8px; letter-spacing: .13em; text-transform: uppercase;
  font-weight: 700; padding: 2px 6px; border-radius: 3px;
}
.mb-tag.yours { background: #1e2a20; color: #8fc196; }
.mb-tag.todo  { background: #1c2530; color: #7fa9d6; }
.mb-tag.read  { background: #2b2333; color: #b79ad6; }
.mb-why { font-size: 11px; color: var(--faint); }
.mb-item { border: 1px solid var(--line); border-radius: var(--r-sm); padding: 10px 12px; margin-bottom: 7px; }
.mb-item.prop { border-style: dashed; background: #1c1922; }
.mb-line { font-family: var(--script); font-size: 12.5px; line-height: 1.5; white-space: pre-line; }
.mb-plain { font-size: 12.5px; line-height: 1.55; }
.mb-meta { font-family: var(--mono); font-size: 9.5px; color: var(--faint); margin-top: 6px; }
.mb-working { font-size: 12.5px; color: var(--muted); padding: 8px 0; display: flex; gap: 8px; align-items: center; }
.mb-err { font-size: 12.5px; color: var(--flag-warn); padding: 8px 0; line-height: 1.5; }

.mb-lhead {
  font-family: var(--mono); font-size: 9px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--faint); font-weight: 700; margin: 14px 0 8px;
  padding-top: 12px; border-top: 1px solid var(--line-soft);
}
.mb-frag { padding: 8px 0; border-bottom: 1px solid var(--line-soft); }
.mb-frag:last-child { border-bottom: 0; }
.mb-when { font-family: var(--mono); font-size: 9.5px; color: var(--faint); }
.mb-text { font-size: 12.5px; color: var(--body); margin-top: 3px; line-height: 1.5; }
.mb-where2 { font-family: var(--mono); font-size: 9.5px; color: var(--faint); margin-top: 4px; }
.mb-frag.buried .mb-where2 b { color: var(--flag-warn); }

/* ---- the library ---- */
#scriptsMenu { min-width: 330px; max-height: 60vh; overflow: auto; }
.lib {
  display: flex; align-items: center; gap: 8px; padding: 8px 10px;
  border-radius: var(--r-sm); cursor: pointer;
}
.lib:hover { background: var(--line-soft); }
.lib.on { background: var(--accent-tint); }
.lib.on .lib-t { color: var(--accent); font-weight: 600; }
.lib-col { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.lib-t { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lib-m { font-family: var(--mono); font-size: 9.5px; color: var(--faint); margin-top: 2px; }
.lib-x {
  border: 0; background: transparent; color: var(--line); cursor: pointer;
  font-size: 15px; line-height: 1; padding: 2px 4px; border-radius: 4px; flex: none;
}
.lib:hover .lib-x { color: var(--faint); }
.lib-x:hover { color: var(--flag-error); }
.lib-x.armed {
  font-family: var(--mono); font-size: 9px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--flag-error); background: #2a1a18; padding: 3px 7px;
}
.mi.warnmi { color: var(--flag-warn); font-size: 12.5px; }
.mi.warnmi:hover { background: #2c231a; }


/* =========================================================================
   THE TITLE PAGE

   A real page at the same 816px width as the script, sitting above page one.
   Typed on directly — the conventions (title a third down, credit beneath,
   contact bottom-left, draft bottom-right) are easier to hit by looking at
   the page than by filling in a form.

   Collapses to a strip, because most days you are not writing it.
   ========================================================================= */
.tp-add {
  width: 816px; margin: 0 0 22px; padding: 13px;
  background: transparent; border: 1px dashed var(--page-edge); border-radius: 3px;
  color: var(--faint); font: 400 12px/1 var(--ui); letter-spacing: .04em;
  cursor: pointer; transition: color .12s, border-color .12s;
}
.tp-add:hover { color: var(--ink); border-color: var(--line-strong); }

.titlepage { position: relative; width: 816px; margin: 0 0 22px; }

/* The bar is chrome, not page — it sits above the sheet and stays quiet
   until the pointer is somewhere near it. */
.tp-bar {
  display: flex; align-items: center; gap: 8px; height: 26px;
  opacity: .3; transition: opacity .14s;
}
.titlepage:hover .tp-bar, .titlepage.collapsed .tp-bar { opacity: 1; }
.tp-lab {
  font: 400 10px/1 var(--ui); letter-spacing: .14em; text-transform: uppercase;
  color: var(--faint); margin-right: auto;
}
.tp-btn {
  background: none; border: 0; padding: 3px 6px; border-radius: var(--r-sm, 6px);
  color: var(--faint); font: 400 11px/1 var(--ui); cursor: pointer;
}
.tp-btn:hover { color: var(--ink); background: var(--hover); }

.tp-body {
  position: relative; height: 1056px; padding: 96px;
  background: var(--paper); border: 1px solid var(--page-edge); border-radius: 3px;
  box-shadow: 0 6px 26px rgba(0, 0, 0, .45);
  font-family: var(--script); font-size: 16px; line-height: 1;
  color: var(--script-ink);
  display: flex; flex-direction: column;
}
.titlepage.collapsed .tp-body { display: none; }

/* Title block sits a little above centre — where the eye expects it. */
.tp-centre { margin: auto 0; text-align: center; }
.tp-title {
  text-transform: uppercase; text-decoration: underline; text-underline-offset: 5px;
  outline: none; word-wrap: break-word;
}
.tp-credit { margin-top: 32px; }
.tp-author { margin-top: 16px; }
.tp-source { margin-top: 32px; }

.tp-foot { display: flex; align-items: flex-end; justify-content: space-between; gap: 40px; }
.tp-foot .tp-contact { white-space: pre-wrap; text-align: left; }
.tp-foot .tp-draft { text-align: right; white-space: nowrap; }

.tp-f { outline: none; min-height: 16px; border-radius: 2px; }
.tp-f:focus { box-shadow: 0 0 0 1px var(--line-strong); }
/* Placeholders read as guidance, never as content — same treatment the
   empty blocks on the script pages get. */
.tp-f.empty::before {
  content: attr(data-ph); color: var(--script-dim); pointer-events: none;
}

/* The mumble list's empty state — dimmer than a fragment, so it never reads
   as something you wrote. */
.mb-none { font: 400 11px/1.55 var(--ui); color: var(--faint); padding: 2px 0 4px; }


/* =========================================================================
   THE X-RAY

   Lanes, one cell per scene, equal width. Equal width is deliberate: a scene
   is a unit of decision regardless of how long it runs, and making short
   scenes physically hard to click would be a design that hides the fast
   cutting from you. Length is carried by the height of the length lane,
   where it is labelled as what it is.

   Nothing in here is allowed to look like an alarm. There is no red. The
   accent means "speaking", the warn colour means "a character knows something
   we don't" — both are categories, and the legend says so.
   ========================================================================= */
.xr { margin-top: 4px; }

.xr-group { margin: 14px 0 4px; }
.xr-gtitle {
  font: 400 10px/1 var(--ui); letter-spacing: .12em; text-transform: uppercase;
  color: var(--faint); margin: 0 0 7px 152px;
}

.xr-lane { display: flex; align-items: stretch; margin-bottom: 6px; }
.xr-lane.ch { margin-bottom: 3px; }
.xr-lab {
  width: 152px; flex: 0 0 152px; padding-right: 14px; padding-top: 2px;
  font: 400 11px/1.3 var(--ui); color: var(--muted); text-align: right;
}
.xr-lab b { display: block; font-weight: 500; color: var(--ink); font-size: 11.5px; }
.xr-lab i { display: block; font-style: normal; font-size: 9.5px; color: #4e4a44; margin-top: 1px; }

.xr-track { flex: 1; display: flex; align-items: flex-end; gap: 1px; height: 34px; }
.xr-lane.ch .xr-track { height: 13px; align-items: stretch; }
/* An empty lane says what it needs. It never draws a flat line — a flat line
   is a measurement, and "we have no data" is not one. */
.xr-track.none {
  align-items: center; height: auto; min-height: 26px; padding: 5px 9px;
  font: 400 11px/1.5 var(--ui); color: var(--faint);
  border: 1px dashed var(--line); border-radius: 6px; display: block;
}

.xcell { flex: 1 1 0; min-width: 2px; border-radius: 1.5px; cursor: pointer; position: relative; }
.xcell:hover { outline: 1px solid var(--muted); outline-offset: 1px; }

.xc-len { background: #4a4650; align-self: flex-end; }
.xc-dlg { background: #3f4a55; align-self: flex-end; }
.xc-p   { background: #232128; }
.xc-p.dim { background: #3c3a44; }
.xc-p.on  { background: var(--accent); }
.xc-loc { height: 13px; background: #232128; align-self: center; }
.xc-loc.rep { outline: 1px solid var(--flag-warn); outline-offset: -1px; }

/* The gap draws from a centre line: up is the audience ahead, down is a
   character ahead. Two directions because it is a two-tailed thing, and a
   single bar would force one of them to read as "more". */
.xc-gap {
  height: 34px; background: transparent; display: flex; flex-direction: column;
  justify-content: center; align-items: stretch; gap: 1px;
}
.xc-gap i { display: block; flex: 0 0 auto; border-radius: 1px; }
.xc-gap .up { background: var(--flag-ask); align-self: stretch; max-height: 16px; }
.xc-gap .dn { background: var(--flag-warn); align-self: stretch; max-height: 16px; }

.xr-axis { display: flex; margin-top: 3px; }
.xr-axis .xr-lab { width: 152px; flex: 0 0 152px; }
.xr-ticks {
  flex: 1; display: flex; justify-content: space-between;
  font: 400 9px/1 var(--mono); color: #4e4a44; padding-top: 4px;
  border-top: 1px solid var(--line-soft);
}

.xr-legend {
  display: flex; flex-wrap: wrap; gap: 8px 20px; margin: 16px 0 0 152px;
  font: 400 11px/1 var(--ui); color: var(--muted);
}
.xr-legend span { display: flex; align-items: center; gap: 7px; }
.xr-sw { width: 11px; height: 9px; border-radius: 1.5px; flex: 0 0 auto; }

.xr-note {
  margin: 18px 0 0 152px; padding: 12px 14px; background: var(--panel);
  border: 1px solid var(--line-soft); border-radius: 10px;
  font: 400 12px/1.6 var(--ui); color: var(--muted); max-width: 78ch;
}
.xr-note b { color: var(--ink); font-weight: 500; }

@media (max-width: 900px) {
  .xr-lab, .xr-axis .xr-lab { width: 104px; flex: 0 0 104px; }
  .xr-gtitle, .xr-legend, .xr-note { margin-left: 104px; }
}

/* Location names alongside their tone, with how many scenes each holds. A
   colour the writer has to hover to decode is a puzzle, not a chart. */
.xr-locs {
  display: flex; flex-wrap: wrap; gap: 6px 18px; margin: 14px 0 0 152px;
  font: 400 11px/1 var(--ui); color: var(--muted);
}
.xr-locs span { display: flex; align-items: center; gap: 7px; }
.xr-locs b { color: var(--faint); font-weight: 400; font-family: var(--mono); font-size: 10px; }
/* Everything that does not recur shares one neutral. Naming fifty-two places
   would be a wall; the recurring ones are the question being asked. */
.xr-locs .rest { color: var(--faint); }
.xr-near {
  margin: 7px 0 0 152px; max-width: 82ch;
  font: 400 11px/1.6 var(--ui); color: var(--faint);
}
.xr-near b { color: var(--muted); font-weight: 400; }
@media (max-width: 900px) { .xr-near { margin-left: 104px; } }
@media (max-width: 900px) { .xr-locs { margin-left: 104px; } }

/* The mode tabs are a single row; "X-ray" was wrapping onto two lines and
   pushing the bar taller. */
.mode { white-space: nowrap; }

/* ---- the x-ray layer controls ----
   Chrome, so it sits quieter than the chart it governs. The two presets are
   named for what they draw, not for the writers who argued about them; the dot
   on a lane toggle marks the ones drawn with a HEIGHT, which is the whole basis of
   the split — a row of bars reads as a curve whether or not anything curves. */
.xr-layers { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.xr-lt {
  font: 400 10px/1 var(--ui); letter-spacing: .12em; text-transform: uppercase;
  color: var(--faint); margin-right: 6px;
}
.xr-sep { width: 1px; height: 16px; background: var(--line); margin: 0 6px; }

.xr-preset, .xr-lane-tog, .xr-chip {
  background: transparent; border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 4px 11px; font: 400 11px/1 var(--ui); color: var(--muted);
  cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
  transition: color .12s, border-color .12s, background .12s;
}
.xr-preset:hover, .xr-lane-tog:hover, .xr-chip:hover { color: var(--ink); border-color: var(--line-strong, #3a3742); }
.xr-preset.on { color: var(--ink); border-color: var(--accent); background: var(--accent-tint); }
.xr-preset.yours { cursor: default; }
.xr-lane-tog.on, .xr-chip.on { color: var(--ink); border-color: #3f3c47; background: #1f1d24; }
.xr-lane-tog:not(.on), .xr-chip:not(.on) { opacity: .5; }

.xr-dot { width: 6px; height: 6px; border-radius: 50%; background: #4a4650; flex: 0 0 auto; }
.xr-lane-tog.on .xr-dot { background: var(--muted); }
/* A lane drawn with a height gets a hollow dot — the ones the Talker's
   objection is actually about. */
.xr-dot.shaped { background: transparent; box-shadow: inset 0 0 0 1.5px #4a4650; }
.xr-lane-tog.on .xr-dot.shaped { box-shadow: inset 0 0 0 1.5px var(--flag-warn); }

.xr-chips { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin: 8px 0 4px; }
.xr-why {
  font: 400 11.5px/1.6 var(--ui); color: var(--muted);
  margin: 2px 0 10px; max-width: 82ch;
}
.xr-why i { color: var(--faint); }
.xr-why b { color: var(--muted); font-weight: 400; font-style: italic; }
/* The quote is attributed. The reasoning stays visible and credited without
   the preset itself wearing someone's name. */
.xr-why span { color: #4e4a44; white-space: nowrap; }

.xr-off {
  margin: 18px 0 0 152px; padding: 14px; border: 1px dashed var(--line); border-radius: 10px;
  font: 400 12px/1.5 var(--ui); color: var(--faint); max-width: 60ch;
}
@media (max-width: 900px) { .xr-off { margin-left: 104px; } }

/* ---- geography against the corpus ----
   Context, not a verdict. Rendered at the weight of a caption so it reads as
   "here is where you sit" rather than as a finding. */
.xr-corpus {
  margin: 12px 0 0 152px; max-width: 82ch;
  font: 400 11.5px/1.65 var(--ui); color: var(--muted);
}
.xr-corpus b { color: var(--ink); font-weight: 500; }
.xr-corpus i { display: block; color: #4e4a44; font-style: normal; margin-top: 3px; font-size: 11px; }

/* ---- same place, same people ---- */
.xr-echo {
  margin: 20px 0 0 152px; max-width: 82ch;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px;
}
.xr-etitle { font: 500 12px/1 var(--ui); color: var(--ink); margin-bottom: 5px; }
.xr-esub { font: 400 11.5px/1.6 var(--ui); color: var(--faint); margin-bottom: 12px; }
.xr-erow {
  display: grid; grid-template-columns: 1fr auto; gap: 2px 14px;
  padding: 9px 0; border-top: 1px solid var(--line-soft);
}
.xr-ewho { font: 500 12px/1.4 var(--ui); color: var(--ink); }
.xr-ewhere {
  font: 400 10px/1.4 var(--mono); color: var(--muted); letter-spacing: .04em;
  grid-row: 1; grid-column: 2; text-align: right; align-self: center;
}
.xr-escenes { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 5px; margin-top: 3px; }
.xr-sc {
  background: #1f1d24; border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 2px 8px; font: 400 11px/1.4 var(--mono); color: var(--muted); cursor: pointer;
}
.xr-sc:hover { color: var(--ink); border-color: var(--accent); }
.xr-esyn {
  grid-column: 1 / -1; font: 400 11.5px/1.6 var(--ui); color: var(--muted); margin-top: 5px;
}
.xr-esyn.dim { color: #4e4a44; }
.xr-emore { font: 400 11px/1 var(--ui); color: var(--faint); padding-top: 10px; border-top: 1px solid var(--line-soft); }

@media (max-width: 900px) { .xr-corpus, .xr-echo { margin-left: 104px; } }

/* =========================================================================
   SYNOPSIS PROPOSALS

   The design lives in the difference between a proposal and the writer's own
   line. A proposal is dashed, italic, dimmer, and carries a hairline down its
   left edge — all four go away the moment it is touched. It must never be
   possible to glance at the board and mistake the tool's guess for your own
   sentence.
   ========================================================================= */
.card.prop { border-style: dashed; border-color: #3a3742; }
.card.prop .card-syn { color: var(--muted); font-style: italic; }
.card.prop::before {
  content: ''; position: absolute; left: 0; top: 12px; bottom: 12px; width: 2px;
  background: var(--flag-warn); opacity: .45; border-radius: 2px;
}
.card-mark {
  display: flex; align-items: center; gap: 7px;
  margin-top: 8px; padding-top: 7px; border-top: 1px solid var(--line-soft);
}
.card-mark .who {
  font: 400 9.5px/1 var(--ui); letter-spacing: .08em; text-transform: uppercase;
  color: #4e4a44; margin-right: auto;
}
.card-mark .tick, .card-mark .xx {
  background: transparent; border: 1px solid var(--line); border-radius: 6px;
  width: 24px; height: 22px; color: var(--faint); cursor: pointer;
  font-size: 12px; line-height: 1; display: grid; place-items: center; padding: 0;
}
.card-mark .tick:hover { color: #6fae90; border-color: #3f5a4a; }
.card-mark .xx:hover { color: var(--accent); border-color: #4a352c; }

/* The offer, and afterwards the question. Never a progress bar — a bar at 10%
   implies an obligation to reach 100%, and there is none. */
.draft {
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  padding: 13px 16px; margin: 0 0 12px;
}
.draft-t { font: 400 12.5px/1.55 var(--ui); color: var(--ink); }
.draft-t b { font-weight: 500; }
.draft-c { font: 400 12px/1.55 var(--ui); color: var(--muted); margin-top: 4px; max-width: 78ch; }
.draft-r { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 11px; }
.dbtn {
  background: transparent; border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 5px 13px; font: 400 12px/1 var(--ui); color: var(--muted); cursor: pointer;
  white-space: nowrap;
}
.dbtn:hover { color: var(--ink); border-color: #3f3c47; }
.dbtn.primary { border-color: var(--accent); background: var(--accent-tint); color: var(--ink); }
.dbtn.quiet { border-color: transparent; color: var(--faint); }
.dbtn.quiet:hover { color: var(--ink); }

/* A proposed synopsis in the binder — same rule as the card: italic, dimmer,
   and a hairline, so it never passes for the writer's own line. */
.bsyn.prop {
  font-style: italic; color: var(--faint);
  border-left: 2px solid rgba(216, 160, 63, .4); padding-left: 6px;
}

/* =========================================================================
   COMPOSITION MODE — the writing run

   A full-bleed surface over everything. There is deliberately no way to see
   the binder, the world pane, a flag or the Analyze control from in here: the
   rule is absolute silence, and a rule you can peek around is a preference.
   ========================================================================= */
body.composing .top, body.composing .rail, body.composing .world,
body.composing .views, body.composing .pagewrap { display: none !important; }
/* The ROOM goes. It is the one surface that can talk back, and a writing run
   is the one place nothing may. (This first shipped hiding `#roomDock`, which
   is not what the element is called — so the drawer stayed reachable and the
   rule was enforced everywhere except where it mattered.) */
body.composing .room { display: none !important; }
/* The MUMBLE stays, and rises above the overlay. It is pull-only, it never
   speaks first, and it exists for the nine seconds before typing — which is
   precisely what this mode is for. */
body.composing .mumble { z-index: 420; }
body.composing { overflow: hidden; }

.compmode {
  position: fixed; inset: 0; z-index: 400; background: #0c0b0f;
  display: flex; flex-direction: column;
}
/* Block layout, not flex, and no CSS scroll-behavior. Centring a very tall
   scroll container with flex is fragile, and a blanket `smooth` swallows a
   long jump entirely — a 44,000px scroll to reach scene 40 simply never
   arrived. The distance decides the behaviour, in JS, below. */
.comp-stage {
  flex: 1; overflow-y: auto; overflow-x: hidden;
  padding: 34vh 24px 46vh;   /* so the caret line can sit near the top third */
}
/* The real #script, restyled — no sheet, no page edges, no shadow. A page
   border is a reminder that a page has a length. */
.compmode #script {
  width: min(680px, 100%); margin: 0 auto; padding: 0; min-height: 0;
  background: transparent; box-shadow: none; border: 0;
  font-size: 17px; line-height: 1.55;
}
.compmode #script .blk { transition: opacity .22s ease; }
.compmode #script .blk.comp-far { opacity: .22; }

.comp-bar {
  display: flex; align-items: center; gap: 16px; padding: 9px 18px;
  border-top: 1px solid #17161b;
  font: 400 10.5px/1 var(--mono); color: #3c3941; letter-spacing: .04em;
}
.comp-bar .r { margin-left: auto; }
.comp-hide {
  background: none; border: 0; color: #2f2d34; cursor: pointer;
  font: 400 14px/1 var(--mono); padding: 0 2px;
}
.comp-hide:hover { color: var(--muted); }
.compmode.bare .comp-bar { opacity: 0; }
.compmode.bare .comp-bar:hover { opacity: 1; }

/* ---- the exit report ----
   Held back until the writer stops, shown once, dismissed by anything. It is
   a card on the page they return to, never a modal that has to be answered. */
.compout {
  position: fixed; right: 20px; bottom: 20px; z-index: 300; width: min(420px, calc(100vw - 40px));
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  padding: 15px 17px; box-shadow: 0 18px 48px rgba(0,0,0,.5);
  animation: compin .28s ease both;
}
@keyframes compin { from { opacity: 0; transform: translateY(8px); } }
@media (prefers-reduced-motion: reduce) { .compout { animation: none; } }
.compout h4 { margin: 0 0 2px; font-size: 13px; font-weight: 500; }
.compout .when { font: 400 11px/1 var(--mono); color: var(--faint); margin-bottom: 11px; }
.compout .l {
  display: flex; gap: 11px; padding: 8px 0; border-top: 1px solid var(--line-soft);
  font-size: 12.5px; color: var(--muted);
}
.compout .l b { color: var(--ink); font-weight: 500; flex: 0 0 74px; }
.compout .x {
  background: none; border: 0; color: var(--faint); cursor: pointer;
  font: 400 11px/1 var(--ui); padding: 8px 0 0; margin-top: 8px;
  border-top: 1px solid var(--line-soft); width: 100%; text-align: left;
}
.compout .x:hover { color: var(--ink); }

/* =========================================================================
   SIDE BY SIDE — two of your own scenes

   Not a general split. It opens only on the pair the x-ray already flagged,
   and it highlights nothing: the shared shape is visible because the two are
   next to each other, which is the whole mechanism. Circling the repetition
   would be answering the question rather than asking it.
   ========================================================================= */
.xr-side {
  background: transparent; border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 2px 9px; margin-left: 6px;
  font: 400 10.5px/1.4 var(--ui); color: var(--faint); cursor: pointer;
}
.xr-side:hover { color: var(--ink); border-color: var(--accent); }

.cmp-wrap {
  position: fixed; inset: 0; z-index: 380; background: var(--bg);
  display: flex; flex-direction: column;
}
.cmp-bar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 11px 18px; border-bottom: 1px solid var(--line); background: var(--panel);
}
.cmp-lab {
  font: 400 10px/1 var(--ui); letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
}
.cmp-sub { font: 400 12px/1 var(--ui); color: var(--ink); }
.cmp-hint { margin-left: auto; font: 400 10.5px/1 var(--mono); color: #4e4a44; }
.cmp-x {
  background: transparent; border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 5px 13px; font: 400 11.5px/1 var(--ui); color: var(--muted); cursor: pointer;
}
.cmp-x:hover { color: var(--ink); border-color: #3f3c47; }

.cmp-cols {
  flex: 1; display: grid; grid-template-columns: repeat(var(--cols, 2), minmax(0, 1fr));
  gap: 1px; background: var(--line); overflow: hidden;
}
@media (max-width: 780px) { .cmp-cols { grid-template-columns: 1fr; overflow-y: auto; } }
.cmp-pane { background: var(--paper); display: flex; flex-direction: column; overflow: hidden; }
.cmp-head {
  display: flex; align-items: baseline; gap: 9px; padding: 12px 16px 4px;
}
.cmp-n { font: 400 10px/1 var(--mono); color: var(--faint); }
.cmp-t {
  font: 700 11.5px/1.3 var(--script); color: var(--ink); text-transform: uppercase;
  letter-spacing: .02em; flex: 1; min-width: 0;
}
.cmp-go {
  background: none; border: 0; color: var(--faint); cursor: pointer;
  font: 400 10.5px/1 var(--ui); padding: 2px 0; white-space: nowrap;
}
.cmp-go:hover { color: var(--accent); }
.cmp-meta {
  padding: 0 16px 10px; font: 400 10.5px/1.5 var(--ui); color: var(--faint);
  border-bottom: 1px solid var(--line-soft);
}
/* Independent scroll: the interesting comparison is rarely at the same offset
   in both scenes, and locking them together would force it to be. */
.cmp-body { flex: 1; overflow-y: auto; padding: 14px 16px 40px; }
.cmp-b {
  font-family: var(--script); font-size: 12.5px; line-height: 1.5;
  color: var(--script-ink); margin: 0 0 6px; white-space: pre-wrap;
}
.cmp-b[data-type="scene_heading"] { font-weight: 700; text-transform: uppercase; margin-top: 14px; }
.cmp-b[data-type="character"]     { text-transform: uppercase; margin-left: 32%; margin-bottom: 0; }
.cmp-b[data-type="parenthetical"] { margin-left: 24%; margin-bottom: 0; color: var(--muted); }
.cmp-b[data-type="dialogue"]      { margin-left: 16%; margin-right: 12%; }
.cmp-b[data-type="transition"]    { text-align: right; text-transform: uppercase; }
.cmp-none { font: 400 12px/1.5 var(--ui); color: var(--faint); }
.cmp-foot {
  padding: 10px 18px; border-top: 1px solid var(--line);
  font: 400 11.5px/1.5 var(--ui); color: var(--faint); background: var(--panel);
}

/* =========================================================================
   SEARCH

   Highlighting is painted by the browser through the CSS Custom Highlight API,
   NOT by wrapping matches in <mark>. The page is a contenteditable whose DOM is
   a view of doc.js — a <mark> injected here would be resynced into block.html
   on the next keystroke and saved into the writer's script.
   ========================================================================= */
::highlight(np-find)     { background: rgba(212, 105, 74, .26); color: var(--ink); }
::highlight(np-find-cur) { background: var(--accent); color: #141319; }
/* Fallback where the API is missing: tint the block, still no DOM change. */
.blk.find-lit { background: rgba(212, 105, 74, .08); border-radius: 2px; }
.blk.find-cur { background: rgba(212, 105, 74, .20); border-radius: 2px; }

.findpanel {
  position: fixed; z-index: 260; width: min(520px, calc(100vw - 24px));
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  overflow: hidden; box-shadow: 0 20px 50px rgba(0, 0, 0, .55);
}
.fp-head {
  display: flex; align-items: center; gap: 9px; padding: 10px 14px;
  border-bottom: 1px solid var(--line-soft);
}
.fp-head svg { flex: 0 0 auto; opacity: .5; }
.fp-q { flex: 1; font: 400 13px/1.2 var(--ui); color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fp-count { font: 400 10.5px/1 var(--mono); color: var(--faint); white-space: nowrap; }

.fp-sug { display: flex; gap: 6px; flex-wrap: wrap; padding: 9px 14px; border-bottom: 1px solid var(--line-soft); background: #141319; }
.fp-chip {
  background: transparent; border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 4px 10px; font: 400 11px/1 var(--ui); color: var(--muted); cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
}
.fp-chip:hover, .fp-chip.on { color: var(--ink); border-color: var(--accent); background: var(--accent-tint); }
.fp-chip i { font-style: normal; color: var(--faint); font-family: var(--mono); font-size: 10px; }

.fp-list { max-height: min(46vh, 380px); overflow-y: auto; }
.fp-scene {
  padding: 7px 14px 3px; font: 400 9.5px/1.3 var(--ui); letter-spacing: .1em;
  text-transform: uppercase; color: var(--faint); background: #131218;
  border-top: 1px solid var(--line-soft); position: sticky; top: 0;
}
.fp-hit {
  display: block; width: 100%; text-align: left; background: none; border: 0;
  cursor: pointer; padding: 7px 14px; border-top: 1px solid #1b1a20;
}
.fp-hit:hover, .fp-hit.on { background: #1f1d24; }
.fp-k { display: block; font: 400 9px/1.3 var(--mono); color: #4e4a44; letter-spacing: .06em; text-transform: uppercase; }
.fp-t {
  display: block; font-family: var(--script); font-size: 12px; line-height: 1.45;
  color: var(--muted); margin-top: 3px; overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.fp-t mark { background: rgba(212, 105, 74, .3); color: var(--ink); border-radius: 2px; padding: 0 1px; }
.fp-none, .fp-hint { padding: 14px; font: 400 12px/1.6 var(--ui); color: var(--faint); }
.fp-hint code {
  font-family: var(--mono); font-size: 10.5px; background: #1f1d24;
  border: 1px solid var(--line); border-radius: 4px; padding: 1px 4px; color: var(--muted);
}
.fp-foot {
  display: flex; align-items: center; gap: 12px; padding: 8px 14px;
  border-top: 1px solid var(--line-soft); font: 400 10px/1 var(--mono); color: #3f3c44;
}
.fp-foot .r { margin-left: auto; }
.fp-rep {
  margin-left: auto; background: none; border: 0; color: var(--faint);
  font: 400 10.5px/1 var(--ui); cursor: pointer; padding: 0;
}
.fp-rep:hover { color: var(--ink); }

/* Replace is the only thing here that writes into the pages, so it says so
   and it carries its count on the button rather than in a dialog. */
.fp-rep-row {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  padding: 10px 14px; border-bottom: 1px solid var(--line-soft); background: #141319;
}
.fp-repin {
  flex: 1; min-width: 160px; background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 6px 9px; font: 400 12px/1.2 var(--ui); color: var(--ink);
  outline: none;
}
.fp-repin:focus { border-color: var(--accent); }
.fp-rb {
  background: transparent; border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 5px 11px; font: 400 11px/1 var(--ui); color: var(--muted); cursor: pointer; white-space: nowrap;
}
.fp-rb:hover:not(:disabled) { color: var(--ink); border-color: #3f3c47; }
.fp-rb.warn:hover:not(:disabled) { color: var(--ink); border-color: var(--accent); background: var(--accent-tint); }
.fp-rb:disabled { opacity: .35; cursor: default; }
.fp-repnote { flex: 1 0 100%; font: 400 10.5px/1.5 var(--ui); color: var(--faint); }

/* =========================================================================
   SNAPSHOTS — what changed

   Green is not "better", it is "what is there now". Red is not "worse", it is
   "what was there before". The panel says so at the foot, because a diff that
   reads as a verdict is a diff that argues with the writer about a rewrite it
   cannot judge.
   ========================================================================= */
.snap-wrap {
  position: fixed; inset: 0; z-index: 380; background: var(--bg);
  display: flex; flex-direction: column;
}
.snap-bar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 11px 18px; border-bottom: 1px solid var(--line); background: var(--panel);
}
.snap-lab { font: 400 10px/1 var(--ui); letter-spacing: .13em; text-transform: uppercase; color: var(--faint); }
.snap-sub { font: 400 12px/1 var(--ui); color: var(--ink); flex: 1; min-width: 0; }
.snap-take, .snap-x {
  background: transparent; border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 5px 13px; font: 400 11.5px/1 var(--ui); color: var(--muted); cursor: pointer; white-space: nowrap;
}
.snap-take:hover, .snap-x:hover { color: var(--ink); border-color: #3f3c47; }

.snap-body { flex: 1; display: grid; grid-template-columns: 208px minmax(0, 1fr); overflow: hidden; }
@media (max-width: 720px) { .snap-body { grid-template-columns: 1fr; grid-template-rows: auto 1fr; } }
.snap-side { border-right: 1px solid var(--line); overflow-y: auto; background: var(--panel); }
.snap-row {
  display: block; width: 100%; text-align: left; background: none; border: 0;
  border-bottom: 1px solid var(--line-soft); padding: 9px 14px; cursor: pointer;
}
.snap-row:hover { background: #1f1d24; }
.snap-row.on { background: var(--accent-tint); }
.snap-when { display: block; font: 400 11.5px/1.3 var(--ui); color: var(--ink); }
.snap-why { display: block; font: 400 10px/1.4 var(--mono); color: var(--faint); margin-top: 2px; }
.snap-empty { padding: 14px; font: 400 11.5px/1.5 var(--ui); color: var(--faint); }

.snap-diff { overflow-y: auto; padding: 16px 20px 40px; }
.snap-head {
  font: 400 11.5px/1.5 var(--ui); color: var(--faint); margin-bottom: 14px;
  padding-bottom: 10px; border-bottom: 1px solid var(--line-soft);
}
.snap-head b { color: var(--ink); font-weight: 500; }
.snap-blk { margin-bottom: 12px; padding-left: 11px; border-left: 2px solid var(--line); }
.snap-blk.s-added   { border-left-color: rgba(111, 174, 144, .6); }
.snap-blk.s-removed { border-left-color: rgba(176, 92, 86, .6); }
.snap-blk.s-changed { border-left-color: rgba(216, 160, 63, .5); }
.snap-blk.s-moved   { border-left-color: var(--flag-ask); }
.snap-k {
  font: 400 9px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase;
  color: #4e4a44; margin-bottom: 4px;
}
.snap-t { font-family: var(--script); font-size: 12.5px; line-height: 1.55; color: var(--script-dim); }
.snap-t .del { color: #a86a63; text-decoration: line-through; }
.snap-t .add { color: #7fae90; }
.snap-none { font: 400 12.5px/1.6 var(--ui); color: var(--faint); max-width: 62ch; }
.snap-none b { color: var(--ink); font-weight: 500; }
.snap-go {
  margin-top: 6px; background: transparent; border: 1px solid var(--line);
  border-radius: var(--r-pill); padding: 5px 13px; font: 400 11.5px/1 var(--ui);
  color: var(--muted); cursor: pointer;
}
.snap-go:hover { color: var(--ink); border-color: var(--accent); }
.snap-foot {
  padding: 10px 18px; border-top: 1px solid var(--line); background: var(--panel);
  font: 400 11.5px/1.5 var(--ui); color: var(--faint);
}
