/* Ported from the inspector sketch (2026-09-15). The right column explains what the
   application just did; the left runs it and carries the walkthrough underneath. */
:root {
  --ink:#1a1d21; --muted:#6b7280; --line:#e3e6ea; --bg:#fff; --panel:#f7f8fa;
  --green:#2e7d32; --red:#c62828; --amber:#ef6c00; --blue:#0369a1;
  --hi-green:#f0f9f2; --hi-blue:#eff6fb;
}
* { box-sizing:border-box; }
/* Three panes, fixed to the viewport. The page itself never scrolls — each pane
   scrolls its own content, so the walkthrough, the conversation and the evidence stay
   on screen together and nothing you are reading slides away while you work. */
html, body { height:100%; }
body { font-family:system-ui,sans-serif; margin:0; color:var(--ink); background:var(--bg);
       height:100vh; overflow:hidden; }
code,.mono { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }

.app { display:grid; grid-template-columns:1fr 1fr; height:100vh; overflow:hidden; }
@media (max-width:980px){ .app { grid-template-columns:1fr; overflow-y:auto; } }
/* The walkthrough is the only pane read continuously, so it is the stable anchor: it sits
   on the left and nothing ever covers it. The Configuration drawer slides over the right,
   where you are not working while you configure. */
.walkthrough { display:grid; grid-template-rows:minmax(0,1fr) auto; height:100vh;
               overflow:hidden; border-right:1px solid var(--line); background:var(--panel); }

/* Chat above, inspector below. Both bounded, both scrolling internally, so a long answer
   cannot push the evidence of what happened off the screen. */
.workbench { display:grid; grid-template-rows:minmax(0,2fr) minmax(0,3fr); gap:1rem;
             padding:1.25rem 1.5rem; min-height:0; overflow:hidden; }

/* ---------- pane 1: chat ---------- */
.chat { display:flex; flex-direction:column; min-height:0;
        border:1px solid var(--line); border-radius:5px; background:#fff;
        padding:1rem 1.1rem; }
.chat header { font-weight:600; margin-bottom:.8rem; flex:none; font-size:.95rem; }
#log { flex:1 1 auto; min-height:0; overflow-y:auto; padding-right:.25rem; }
.msg { margin:0 0 1rem; }
.msg.you p { color:var(--muted); border-left:2px solid var(--line); padding-left:.6rem; }
.msg .who { font-size:.7rem; text-transform:uppercase; letter-spacing:.06em; color:var(--muted); margin-bottom:.25rem; }
.msg p { margin:.3rem 0 0; line-height:1.5; }
/* A model answers in markdown whether asked to or not. Headings are capped well below the
   walkthrough's own so a reply cannot shout over the instructions. */
.reply { margin-top:.35rem; line-height:1.55; }
.reply > :first-child { margin-top:0; }
.reply > :last-child { margin-bottom:0; }
.reply p { margin:.5rem 0; }
.reply h1, .reply h2, .reply h3, .reply h4 { font-size:.92rem; margin:.7rem 0 .3rem; }
.reply ul, .reply ol { margin:.4rem 0; padding-left:1.3rem; }
.reply li { margin:.15rem 0; }
.reply code { font-family:ui-monospace,monospace; font-size:.85em; background:#eceef1;
  padding:.05em .3em; border-radius:3px; }
.reply pre { background:#eceef1; padding:.55rem .7rem; border-radius:4px; overflow-x:auto;
  font-size:.8rem; margin:.5rem 0; }
.reply pre code { background:none; padding:0; }
.reply blockquote { margin:.5rem 0; padding-left:.7rem; border-left:2px solid var(--line);
  color:var(--muted); }
.reply hr { border:0; border-top:1px solid var(--line); margin:.7rem 0; }
.reply table { border-collapse:collapse; font-size:.85em; margin:.5rem 0; }
.reply th, .reply td { border:1px solid var(--line); padding:.25rem .45rem; }
.badge { display:inline-block; padding:.12rem .5rem; border-radius:3px; font-size:.72rem; color:#fff; font-weight:500; }
.badge.answered{background:var(--green)} .badge.blocked{background:var(--red)}
.badge.governed{background:var(--blue)}  .badge.error{background:var(--amber)}
.detail { display:block; margin-top:.3rem; color:var(--muted); font-size:.72rem; font-family:ui-monospace,monospace; }
.chat form { display:flex; gap:.5rem; margin-top:.8rem; flex:none; }
.chat form input { flex:1; padding:.55rem .7rem; border:1px solid var(--line); border-radius:4px; font:inherit; }
.chat form button { padding:.55rem 1rem; border:1px solid var(--ink); background:var(--ink); color:#fff; border-radius:4px; font:inherit; cursor:pointer; }
#config-notice { margin-top:.4rem; flex:none; padding:.5rem .75rem; border-left:3px solid var(--amber); background:#fff4e5; font-weight:400; font-size:.8rem; }
#config-notice:empty { display:none; }

/* ---------- pane 3: the walkthrough, in the right column ---------- */
/* The right column supplies the frame, so the pane itself is borderless. */
#guide { display:grid; grid-template-rows:auto 1fr auto; min-height:0;
         background:transparent; border:0; }
.guide-head { padding:.8rem 1.5rem .7rem; border-bottom:1px solid var(--line); }

/* The rail. Nodes fill on evidence, never on having been read — a module you clicked
   through without demonstrating anything stays hollow, which is the honest signal. */
.rail { display:flex; align-items:center; margin-bottom:.55rem; }
.rail-node { position:relative; flex:1; display:flex; flex-direction:column; align-items:center;
  gap:.2rem; background:none; border:0; padding:0; cursor:pointer; font:inherit; }
.rail-node::before { content:''; position:absolute; top:5px; left:-50%; width:100%; height:2px;
  background:var(--line); z-index:0; }
.rail-node:first-child::before { display:none; }
.rail-node.done::before, .rail-node.part::before, .rail-node.here::before { background:#bcd9c4; }
.rail-dot { position:relative; z-index:1; width:12px; height:12px; border-radius:50%;
  border:2px solid var(--line); background:#fff; transition:transform .1s; }
.rail-num { font-size:.62rem; color:var(--muted); font-family:ui-monospace,monospace; }
.rail-node:hover .rail-dot { transform:scale(1.25); }
.rail-node:hover .rail-num { color:var(--ink); }
.rail-node.done .rail-dot { background:var(--green); border-color:var(--green); }
.rail-node.part .rail-dot { border-color:var(--green);
  background:linear-gradient(90deg, var(--green) 50%, #fff 50%); }
.rail-node.here .rail-dot { border-color:var(--ink); box-shadow:0 0 0 3px rgba(26,29,33,.10); }
.rail-node.here .rail-num { color:var(--ink); font-weight:700; }

.guide-where { display:flex; align-items:baseline; gap:.75rem; }
.guide-title { font-weight:600; font-size:.9rem; flex:1; }
.guide-pos { font-size:.7rem; color:var(--muted); font-family:ui-monospace,monospace; white-space:nowrap; }

/* Position within the module. Deliberately a different shape from the rail: this one
   does measure reading, and should not be mistaken for the evidence above it. */
.stepbar { display:flex; gap:3px; margin-top:.45rem; }
.stepbar span { flex:1; height:3px; border-radius:2px; background:var(--line); }
.stepbar span.past { background:#c9d6cd; }
.stepbar span.now { background:var(--ink); }
.guide-body { overflow-y:auto; font-size:.95rem; line-height:1.65;
  padding-block:.4rem 1.5rem;
  padding-inline:max(1.5rem, calc((100% - 36rem) / 2)); }
/* Cap the measure by centring the whole column rather than capping each element: that
   way headings, tables and callouts share one left edge and the slack is split evenly
   instead of pooling on the right. Gutters never fall below 1.5rem on a narrow window.

   Not expressed in `ch` — that unit measures the digit zero, which is far wider than
   average prose, so 72ch renders at about 90 actual characters. */
.guide-body p { margin:.55rem 0 .8rem; }
.guide-body li { margin:.3rem 0; }
.guide-body li > p { margin:.25rem 0; }
.guide-body h2, .step-title { font-size:1.15rem; line-height:1.3; margin:.6rem 0 .9rem; }
.guide-body h3 { font-size:1rem; }
/* Foldable sections. Open by default — folding is for getting finished work out of the
   way, not for hiding the step from someone who has not read it yet. */
.fold { margin:.2rem 0 1.1rem; }
/* The heading sits flush with the prose beneath it and the marker hangs in the gutter the
   centred measure already leaves. A marker that indents its own heading puts every section
   title a centimetre to the right of the text it introduces. */
.fold > summary { cursor:pointer; list-style:none; font-weight:600; padding:.15rem 0;
  position:relative; color:var(--ink); }
.fold > summary::-webkit-details-marker { display:none; }
.fold > summary::before { content:'▾'; position:absolute; left:-.95rem; color:var(--muted);
  font-size:.7rem; transition:transform .1s; }
/* A nested section already carries a rule at its left edge; the marker tucks against it
   rather than reaching back across into the parent's text. */
.fold .fold > summary::before { left:-.7rem; }
.fold:not([open]) > summary::before { content:'▸'; }
/* A closed section has to look openable, not merely absent. */
.fold:not([open]) > summary::after { content:'\22EF'; margin-left:.55em; padding:0 .4em;
  border:1px solid var(--line); border-radius:3px; background:#fff; color:var(--muted);
  font-size:.85em; line-height:1.4; vertical-align:1px; }
.fold:not([open]) > summary:hover::after { border-color:var(--blue); color:var(--blue); }
.fold > summary:hover { color:var(--blue); }
.fold-h2 { font-size:1.1rem; }
.fold-h3 { font-size:1rem; }
.fold-h4 { font-size:.9rem; }
.fold .fold { margin-left:.5rem; padding-left:.5rem; border-left:1px solid var(--line); }
.guide-body pre { background:#eceef1; padding:.7rem .9rem; border-radius:4px; overflow-x:auto;
  font-size:.85rem; line-height:1.5; margin:.7rem 0; }
.guide-body code { font-family:ui-monospace,monospace; font-size:.88em;
  background:#eceef1; padding:.05em .3em; border-radius:3px; }
.guide-body pre code { background:none; padding:0; }
/* Console links carry the tenant, so following one cannot land in the wrong place. */
.guide-body a[target="_blank"] { color:var(--blue); text-decoration:none;
  border-bottom:1px solid #bcd6ea; }
.guide-body a[target="_blank"]:hover { border-bottom-color:var(--blue); background:var(--hi-blue); }
.guide-body a[target="_blank"]::after { content:'↗'; font-size:.75em; margin-left:.15em;
  color:var(--muted); }
.guide-body blockquote { margin:.9rem 0; padding:.6rem .9rem; border-left:3px solid #b6bcc4;
  background:#f1f3f5; border-radius:0 4px 4px 0; }
.guide-body blockquote p { margin:.25rem 0; }
.guide-body blockquote strong:first-child { text-transform:uppercase; letter-spacing:.05em;
  font-size:.74rem; }
.guide-body blockquote.warning, .guide-body blockquote.caution {
  border-left-color:var(--amber); background:#fff6ec; }
.guide-body blockquote.warning strong:first-child,
.guide-body blockquote.caution strong:first-child { color:#a34f00; }
.guide-body blockquote.important { border-left-color:var(--blue); background:var(--hi-blue); }
.guide-body blockquote.important strong:first-child { color:var(--blue); }
.guide-body blockquote.tip { border-left-color:var(--green); background:var(--hi-green); }
.guide-body blockquote.tip strong:first-child { color:var(--green); }
.guide-body img { display:block; max-width:100%; margin:1rem 0 1.2rem; }
.guide-body table { border-collapse:collapse; font-size:.84rem; margin:.8rem 0; }
.guide-body th,.guide-body td { border:1px solid var(--line); padding:.4rem .6rem; text-align:left;
  line-height:1.45; }
.guide-body th { background:#eceef1; }
.guide-evidence { font-size:.68rem; color:var(--muted); border:1px solid var(--line);
  background:#fff; border-radius:999px; padding:.1rem .5rem; white-space:nowrap; }
.evidence { font-size:.76rem; margin:0; padding:.7rem 1.75rem .9rem;
  border-top:1px solid var(--line); background:#fff; }
.evidence:empty { display:none; }
.evidence ul { max-height:22vh; overflow-y:auto; }
.evidence summary { cursor:pointer; list-style:none; display:flex; align-items:center;
  gap:.6rem; }
.evidence summary::-webkit-details-marker { display:none; }
.evidence summary h2 { margin:0; }
.evidence summary::after { content:'▾'; color:var(--muted); font-size:.7rem; }
.evidence details:not([open]) summary::after { content:'▸'; }
.evidence ul { list-style:none; margin:.5rem 0 .3rem; padding:0; }
.evidence li { padding:.12rem 0 .12rem 1.25rem; position:relative; color:var(--muted); }
.evidence li::before { position:absolute; left:0; }
.evidence li.seen { color:var(--ink); }
.evidence li.seen::before { content:'●'; color:var(--green); font-size:.7rem; top:.15rem; }
.evidence li.unseen::before { content:'○'; color:#b6bcc4; font-size:.7rem; top:.15rem; }
.evidence .gate { font-size:.6rem; text-transform:uppercase; letter-spacing:.06em;
  color:var(--amber); border:1px solid #f2c79a; border-radius:3px; padding:0 .25rem; margin-left:.3rem; }
.evidence-note { margin:.4rem 0 0; font-size:.68rem; color:#9aa1a9; line-height:1.45; }
.guide-nav { display:flex; justify-content:space-between; padding:.6rem 1.5rem; border-top:1px solid var(--line); }
.guide-nav button { padding:.32rem .8rem; font:inherit; font-size:.8rem; cursor:pointer; border:1px solid var(--line); background:#fff; border-radius:4px; }
.guide-nav button[disabled] { opacity:.4; cursor:default; }

/* ---------- pane 2: inspector, beneath the chat ---------- */
/* The header sits outside #inspect: that element is swapped out of band after every
   reply, and anything inside it would be replaced along with it. */
.inspect-pane { display:grid; grid-template-rows:auto minmax(0,1fr); min-height:0;
                border:1px solid var(--line); border-radius:5px; background:#fff; }
.pane-head { display:flex; align-items:center; gap:.45rem; flex-wrap:wrap;
             padding:.55rem .7rem .55rem 1.1rem; border-bottom:1px solid var(--line);
             background:linear-gradient(#fbfcfd,#f6f8fa); border-radius:5px 5px 0 0; }
/* Three kinds of thing sit in this header, so each gets its own visual language rather
   than one grey stripe of text: the pane's name is the only ink-black item, reference
   data is unboxed, state is a filled pill, and the one action is a square-cornered
   button. Shape carries as much of the distinction as colour does. */
.pane-head h2 { margin:0; font-size:.7rem; text-transform:uppercase; letter-spacing:.09em;
                color:var(--ink); font-weight:700; }
.pane-head .k { font-size:.6rem; text-transform:uppercase; letter-spacing:.07em;
  font-weight:600; opacity:.65; margin-right:.32rem; }
.pane-head .tenant { margin-left:auto; font-size:.72rem; color:var(--muted); }
.pane-head .tenant b { font-family:ui-monospace,monospace; font-weight:500; color:#4b5563; }
.pane-head .tenant.none b { color:var(--amber); font-weight:600; }

/* `direct` is not a switched-off setting — it is traffic leaving with nothing inspecting
   it — so it is amber, and the one state worth reading across the room. */
.pane-head .posture { display:inline-flex; align-items:center; font-size:.72rem;
  border:1px solid; border-radius:999px; padding:.14rem .55rem; white-space:nowrap; }
.pane-head .posture b { font-family:ui-monospace,monospace; font-weight:600; }
.pane-head .posture.direct { color:var(--amber); border-color:#f3c9a2; background:#fff4e5; }
.pane-head .posture.gateway { color:var(--green); border-color:#bcd9c4; background:var(--hi-green); }
.pane-head #config-notice { flex-basis:100%; margin:0; }
.inspect { padding:1rem 1.1rem; overflow-y:auto; min-height:0; }
.inspect h2 { font-size:.7rem; text-transform:uppercase; letter-spacing:.09em; color:var(--muted); margin:0 0 .6rem; font-weight:700; }
.section { margin-bottom:1.5rem; }

.pills { display:flex; flex-wrap:wrap; gap:.4rem; }
.pill {
  font-size:.72rem; padding:.22rem .6rem; border-radius:999px; border:1px solid var(--line);
  background:#fff; color:#b6bcc4; display:inline-flex; align-items:center; gap:.35rem;
  cursor:help; transition:box-shadow .12s;
}
.pill:hover, .pill:focus-visible { box-shadow:0 0 0 3px rgba(3,105,161,.12); outline:none; }
.pill::before { content:'○'; font-size:.6rem; }
.pill.on { color:var(--ink); border-color:#bcd9c4; background:var(--hi-green); font-weight:500; }
.pill.on::before { content:'●'; color:var(--green); }
.pill.cap.on { border-color:#bcd6ea; background:var(--hi-blue); }
.pill.cap.on::before { color:var(--blue); }
/* Not observable from the application. Distinct from "off", which is a claim. */
.pill.unknown { color:var(--muted); border-style:dashed; }
.pill.unknown::before { content:'?'; font-size:.66rem; font-weight:700; }
/* Not "not yet" — never, from here. The workspace a key belongs to is named nowhere in
   the response, so no message can fill this pill in and a dashed `?` reads as failure to
   a learner who has just done the work. The arrow says the same thing the tooltip does:
   this one is confirmed in the console. */
.pill.blind { color:var(--muted); border-style:dotted; background:var(--panel); }
.pill.blind::before { content:'↗'; font-size:.7rem; font-weight:600; }
/* Circumstantial: the workspace id is configured and module 2's observable half is done,
   so the control is almost certainly in force — but the application still has not seen
   it. Green outline, grey text. A filled pill stays reserved for a measurement. */
.pill.asserted { color:var(--muted); border-color:#bcd9c4; border-style:solid; background:#fff; }
.pill.asserted::before { content:'↗'; font-size:.7rem; font-weight:600; color:var(--green); }

.kv { border:1px solid var(--line); border-radius:5px; background:#fff; overflow:hidden; }
.kv .row {
  display:grid; grid-template-columns:132px 1fr; gap:.75rem;
  padding:.42rem .7rem .42rem .55rem; border-bottom:1px solid #f0f2f4;
  font-size:.78rem; border-left:3px solid transparent; cursor:help;
}
.kv .row:last-child { border-bottom:0; }
.kv .row:hover { background:#fbfcfd; }
.kv .k { color:var(--muted); font-family:ui-monospace,monospace; font-size:.72rem; }
.kv .v { font-family:ui-monospace,monospace; word-break:break-all; }
.v.ok{color:var(--green)} .v.bad{color:var(--red)} .v.cap{color:var(--blue)} .v.warn{color:var(--amber)}
.v.none { color:#b6bcc4; font-style:italic; }
.kv .v a { color:var(--blue); text-decoration:none; border-bottom:1px solid #bcd6ea; }
.kv .v a::after { content:'↗'; font-size:.8em; margin-left:.2em; color:var(--muted); }

/* changed-field emphasis */
.kv .row.hi { border-left-color:var(--green); background:var(--hi-green); }
.kv .row.hi .k { color:var(--ink); font-weight:600; }
.kv .row.hi.cap { border-left-color:var(--blue); background:var(--hi-blue); }
.kv .row.hi .delta {
  font-size:.6rem; letter-spacing:.07em; text-transform:uppercase; font-weight:700;
  color:var(--green); margin-left:.45rem; vertical-align:1px;
}
.kv .row.hi.cap .delta { color:var(--blue); }
.was { display:block; color:#b6bcc4; font-style:italic; font-size:.72rem; margin-top:.12rem; }
.was::before { content:'was '; }

/* ---------- the guardrail verdict ---------- */
/* The two sides of a call are scanned independently and can conclude differently, so each
   gets its own card rather than one merged summary. Closed, a card is a single line; the
   pane is fixed-height and a verdict that pushes the response rows off it is no use. */
.scan { border:1px solid var(--line); border-radius:5px; background:#fff; margin-bottom:.4rem; }
.scan > summary { display:flex; flex-wrap:wrap; align-items:center; gap:.4rem; cursor:pointer;
  list-style:none; padding:.45rem .6rem; font-size:.78rem; }
.scan > summary::-webkit-details-marker { display:none; }
.scan > summary::before { content:'▸'; color:var(--muted); font-size:.7rem; }
.scan[open] > summary::before { content:'▾'; }
.scan > summary:hover { background:#fbfcfd; }
.scan .side { font-family:ui-monospace,monospace; font-size:.66rem; color:var(--muted);
  text-transform:uppercase; letter-spacing:.07em; font-weight:700; }
.scan .act { font-family:ui-monospace,monospace; font-weight:600; }
.scan .act.bad { color:var(--red); }
.scan .dets { display:flex; flex-wrap:wrap; gap:.3rem; margin-left:auto; }
/* A detection that did not fire is a negative result, not an absence, so it is rendered
   and not omitted — in the same hollow grey pill an unproven control above uses. Telling
   `injection` from `dlp` is the whole reading, so the two states differ in colour, weight
   and glyph rather than in any one of them. */
.det { font-size:.68rem; padding:.1rem .45rem; gap:.28rem; }
.det.fired { color:var(--ink); border-color:#e8c4c4; background:#fdf3f3; font-weight:600; }
.det.fired::before { content:'●'; color:var(--red); }
.scan .silent { font-size:.72rem; color:#b6bcc4; font-style:italic; }
.scan > .kv { border:0; border-top:1px solid var(--line); border-radius:0; }
.scan .masked { border-top:1px solid var(--line); padding:.5rem .6rem; cursor:help; }
.scan .mk { color:var(--muted); font-family:ui-monospace,monospace; font-size:.72rem; margin-bottom:.3rem; }
/* The point of this block is that the record holds XXXX where the card was, so the text
   is shown verbatim and bounded rather than truncated — a redaction you cannot read in
   full proves nothing. */
.scan .mv { font-family:ui-monospace,monospace; font-size:.78rem; line-height:1.5;
  word-break:break-word; max-height:7rem; overflow:auto;
  background:var(--panel); border-radius:4px; padding:.35rem .5rem; }
.scan .pat { display:inline-block; margin:.35rem .3rem 0 0; padding:.1rem .45rem;
  font-family:ui-monospace,monospace; font-size:.68rem; color:var(--muted);
  border:1px solid var(--line); border-radius:999px; }

.note { margin-top:.6rem; font-size:.75rem; line-height:1.5; color:var(--muted); border-left:2px solid var(--line); padding-left:.7rem; }
.note b { color:var(--ink); }

/* ---------- configuration panel ---------- */
/* The learner has a browser and nothing else, so the application edits its own config.
   Field names are the real variable names on purpose — this is configuring an
   integration, not a settings screen. */
#cfg-backdrop { display:none; position:fixed; inset:0; z-index:35;
  background:rgba(26,29,33,.18); }
body.cfg-open #cfg-backdrop { display:block; }

.configure { display:none; position:fixed; top:0; right:0; bottom:0; width:min(520px,50vw);
  z-index:40; background:var(--panel); border-left:1px solid var(--line);
  box-shadow:-12px 0 32px rgba(0,0,0,.14); grid-template-rows:auto minmax(0,1fr); }
body.cfg-open .configure { display:grid; }
.cfg-head { display:flex; align-items:center; gap:.75rem; padding:1rem 1.5rem;
  border-bottom:1px solid var(--line); background:#fff; }
.cfg-head h2 { margin:0; font-size:1rem; }
.cfg-x { margin-left:auto; border:0; background:none; font-size:1.4rem; line-height:1;
  color:var(--muted); cursor:pointer; padding:0 .2rem; }
.cfg-x:hover { color:var(--ink); }
form.cfg { display:grid; grid-template-rows:minmax(0,1fr) auto; min-height:0; margin:0; }
.cfg-body { overflow-y:auto; padding:1rem 1.5rem; }
.cfg-hint { font-size:.7rem; color:var(--muted); margin-left:auto; }
.cfg-row { display:grid; grid-template-columns:1fr; gap:.15rem; margin-bottom:.9rem;
  border-left:3px solid transparent; padding-left:.6rem; }
.cfg-row.needed { border-left-color:var(--amber); }
.cfg-row label { font-family:ui-monospace,monospace; font-size:.78rem; font-weight:600;
  display:flex; align-items:baseline; gap:.5rem; }
.cfg-module { font-family:system-ui,sans-serif; font-size:.65rem; font-weight:400; color:var(--muted); }
.cfg-row input { padding:.4rem .55rem; border:1px solid var(--line); border-radius:4px;
  font-family:ui-monospace,monospace; font-size:.78rem; width:100%; }
.cfg-row small { color:var(--muted); font-size:.7rem; }
.cfg-actions { display:flex; align-items:center; gap:.6rem; padding:.8rem 1.5rem;
  border-top:1px solid var(--line); background:#fff; }
.cfg-actions button { padding:.4rem 1rem; border:1px solid var(--ink); background:var(--ink);
  color:#fff; border-radius:4px; font:inherit; font-size:.82rem; cursor:pointer; }
.cfg-actions button.ghost { background:#fff; color:var(--ink); }
.cfg-saved { font-size:.75rem; color:var(--green); }
/* The only control in the header, so it is the only square-cornered thing in it and the
   only one that reacts to a pointer. Pills state what is true; this changes it. */
.configure-open { margin-left:.35rem; padding:.22rem .6rem; font:inherit; font-size:.72rem;
  font-weight:500; display:inline-flex; align-items:center; gap:.35rem; color:var(--ink);
  border:1px solid #c7ccd4; background:#fff; border-radius:5px; cursor:pointer;
  box-shadow:0 1px 1px rgba(16,24,40,.04); }
.configure-open::before { content:'⚙'; font-size:.82rem; color:var(--muted); line-height:1; }
.configure-open:hover { border-color:#9aa1ab; background:var(--panel); }
.configure-open:focus-visible { outline:2px solid var(--blue); outline-offset:1px; }
button.link { background:none; border:0; padding:0; font:inherit; font-size:inherit;
  color:var(--blue); text-decoration:underline; cursor:pointer; }

/* ---------- popover ---------- */
#tip {
  position:fixed; z-index:50; max-width:330px; background:var(--ink); color:#fff;
  border-radius:6px; padding:.7rem .8rem; font-size:.76rem; line-height:1.5;
  box-shadow:0 8px 28px rgba(0,0,0,.22); pointer-events:none; opacity:0;
  transition:opacity .11s; display:none;
}
#tip.show { opacity:1; display:block; }
#tip h4 { margin:0 0 .3rem; font-size:.78rem; }
#tip p { margin:0 0 .4rem; color:#cfd6de; }
#tip p:last-child { margin-bottom:0; }
#tip .metric {
  border-top:1px solid #33404f; padding-top:.4rem; margin-top:.45rem;
  color:#8fd4c4; font-size:.72rem;
}
#tip .metric b { color:#b6ece0; font-weight:600; }
