/* OVERPRINT chrome, frosted: everything around the sheet floats on it as glass. Tokens and the sheet's own rules live in figure.css, which the export inlines.
   The glass is PROVE's three tiers retinted to the stock: panels at .85, the toolbar at .78, the card and the tip at .92 with the deeper shadow. */
:root { --s1: 8px; --s2: 16px; --s3: 24px; --s5: 40px; --label: 500 .8125rem/1 var(--font-text);
  --glass: rgba(245, 240, 235, .85); --glass-bar: rgba(230, 224, 210, .78); --glass-deep: rgba(255, 255, 255, .92); --glass-line: rgba(185, 180, 169, .45);
  --chip: rgba(230, 224, 210, .45); --field: rgba(255, 255, 255, .5);
  --shadow: 0 4px 24px rgba(0, 0, 0, .06), 0 1px 3px rgba(0, 0, 0, .04); --shadow-deep: 0 8px 40px rgba(0, 0, 0, .1);
  --lift: cubic-bezier(.34, 1.56, .64, 1); --slide: cubic-bezier(.4, 0, .2, 1) }
/* The chrome's tokens (glass, chips, fields, shadows, spacing, the label font, easing) are set here, the figure's (stock, inks, blend,
   fonts, rules) in figure.css, so no token is set in both files. Each dark set is written twice, as figure.css's is: one rule cannot
   match both the system's dark (a media query) and the theme button's (data-theme). */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) {
  --glass: rgba(38, 34, 32, .82); --glass-bar: rgba(38, 34, 32, .78); --glass-deep: rgba(38, 34, 32, .92); --glass-line: rgba(236, 231, 220, .14);
  --chip: rgba(236, 231, 220, .06); --field: rgba(236, 231, 220, .06);
  --shadow: 0 4px 24px rgba(0, 0, 0, .35), 0 1px 3px rgba(0, 0, 0, .2); --shadow-deep: 0 8px 40px rgba(0, 0, 0, .45) } }
:root[data-theme="dark"] {
  --glass: rgba(38, 34, 32, .82); --glass-bar: rgba(38, 34, 32, .78); --glass-deep: rgba(38, 34, 32, .92); --glass-line: rgba(236, 231, 220, .14);
  --chip: rgba(236, 231, 220, .06); --field: rgba(236, 231, 220, .06);
  --shadow: 0 4px 24px rgba(0, 0, 0, .35), 0 1px 3px rgba(0, 0, 0, .2); --shadow-deep: 0 8px 40px rgba(0, 0, 0, .45) }
html, body { height: 100% } body { margin: 0; display: flex; flex-direction: column; background: var(--stock); color: var(--black); font: 1rem/1.55 var(--font-text) }
header { padding: 12px var(--s2); border-bottom: var(--rule-heavy); display: flex; gap: var(--s3); align-items: center; justify-content: space-between; user-select: none }
h1 { margin: 0; font: 800 1.25rem var(--font-text); text-transform: uppercase; letter-spacing: .01em; white-space: nowrap }
#progress { height: 2px; width: 0; background: var(--pink); transition: width 12s cubic-bezier(.1, .7, .3, 1), opacity 300ms 300ms }
body.printing #progress { width: 90% } body.printed #progress { width: 100%; opacity: 0; transition: width 200ms, opacity 300ms 300ms }

/* Controls. Rest is a hairline pill, hover deepens the ground, press is the ink landing. */
.btn { font: var(--label); text-transform: uppercase; letter-spacing: .08em; color: var(--black); background: none; border: 1px solid var(--black); border-radius: 10px; padding: var(--s1) 12px; cursor: pointer; user-select: none; transition: background .2s, color .2s, border-color .2s }
.btn:hover { background: var(--stock-deep) }
.btn:active, .btn[aria-pressed="true"], .btn.primary { background: var(--black); color: var(--stock) }
.btn:focus-visible { outline: 2px solid var(--black); outline-offset: 2px }
input { font: inherit; padding: var(--s1) 12px; background: var(--stock-deep); color: var(--black); border: 1px solid var(--black-30); border-radius: 10px; outline: none }
#from { width: 64px; padding-inline: 6px }
input:focus { border-color: var(--black); box-shadow: inset 0 0 0 1px var(--black) }
label, .eyebrow { font: var(--label); text-transform: uppercase; letter-spacing: .08em; color: var(--black-60) }
.chip { font: .8125rem var(--font-text); color: var(--black); background: var(--chip); border: 1px solid var(--glass-line); border-radius: 20px; padding: 6px 12px; cursor: pointer; transition: background .2s, border-color .2s }
.chip:hover { background: var(--glass-deep); border-color: var(--black) }
/* A pressed chip is the ink landing, in the candidates list too, where #hits button and #hits .chip outrank .chip[aria-pressed] alone. */
.chip[aria-pressed="true"], #hits .chip[aria-pressed="true"] { background: var(--black); color: var(--stock); border-color: var(--black) } .chip small { opacity: .7; margin-left: 4px; font-size: .75rem }
/* Two copies of one sheet: what needs app.py is hidden until hero.js's probe says the app answers, what is true only statically until it says static. */
body:not([data-mode="app"]) .needs-app { display: none } body:not([data-mode="static"]) .static-only { display: none }

/* Search and its candidates. Nothing is picked for you. A term counts works instead of listing people; its notes and field chips print in the same list. */
.search { position: relative; display: flex; gap: 6px; align-items: center } #q { flex: 1; min-width: 0 } header .search { margin-left: auto } header #q { width: min(320px, 50vw); box-sizing: border-box } header #hits { left: auto; right: 0 }
#hits { position: absolute; top: 100%; left: 0; z-index: 4; background: var(--glass-deep); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border: 1px solid var(--glass-line); border-radius: 12px; box-shadow: var(--shadow-deep); max-height: min(480px, 70vh); overflow: auto; display: none; width: min(480px, 90vw) }
#hits button { display: block; width: 100%; text-align: left; font: inherit; line-height: 1.4; color: inherit; background: none; border: 0; border-bottom: 1px solid var(--glass-line); padding: var(--s1) 12px; cursor: pointer }
#hits button:hover, #hits button:focus-visible { background: var(--chip); outline: none }
/* A row: the candidate, which opens alone, and its pin, which adds it as a layer. The glyph before the name says its kind. */
#hits .hit { display: flex; border-bottom: 1px solid var(--glass-line) } #hits .hit[aria-selected="true"] { background: var(--chip); box-shadow: inset 2px 0 var(--black) } #hits .hit > button { border-bottom: 0 } #hits .hit > button:first-child { flex: 1; min-width: 0 }
#hits .hit b::before { font: 700 .8125rem var(--font-data); color: var(--black-60); margin-right: 6px } .hit.person b::before { content: "○" } .hit.work b::before { content: "□" } .hit.term b::before { content: "◇" }
#hits .pin { flex: none; width: auto; align-self: center; margin-right: var(--s1); padding: 4px 10px; font: var(--label); font-size: .6875rem; text-transform: uppercase; letter-spacing: .08em; border: 1px solid var(--black-30); border-radius: 9999px }
#hits .pin:hover { border-color: var(--black); background: var(--black); color: var(--stock) }
#hits .turns { display: flex; justify-content: space-between; align-items: center; gap: var(--s1) } #hits .turns button { width: auto; border: 0 } #hits .back { padding: 0; color: var(--black-60) }
#hits p { margin: 0; padding: var(--s1) 12px; font-size: .875rem; color: var(--black-60) }
#hits p a { color: var(--black) } #hits .big { font: .75rem var(--font-data); color: var(--pink) }
#hits .failed { color: var(--black); border-bottom: 1px solid var(--glass-line) } #hits .failed button { flex: none; padding: 0; color: var(--black-60) }
#hits small, .id, .facts, #shown { font: .75rem var(--font-data); color: var(--black-60) } #hits .who { font-size: .8125rem; color: var(--black) }
#filters { position: sticky; top: 0; z-index: 1; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; background: var(--glass-deep); border-bottom: 1px solid var(--glass-line) } #filters[hidden] { display: none }
#narrow { flex: 1 1 200px; min-width: 0; padding: 4px 8px; font-size: .8125rem } #filters label { display: flex; align-items: center; gap: 4px; cursor: pointer }
#facets { flex-basis: 100%; display: flex; flex-wrap: wrap; gap: 4px } #facets:empty { display: none } #facets .chip { padding: 3px 9px; font-size: .75rem }
#sorts { display: flex; gap: 4px; margin-left: auto } #sorts .chip { padding: 3px 9px; font-size: .75rem }
#hits .term { color: var(--black); border-bottom: 1px solid var(--glass-line) } #hits .term svg { vertical-align: middle } #hits .chips { gap: 6px; padding: var(--s1) 12px }
#kinds { display: flex; gap: 4px } #kinds .chip { padding: 4px 10px }
#hits .chip { display: inline-block; width: auto; border: 1px solid var(--glass-line); border-radius: 20px; padding: 6px 12px; font-size: .8125rem }

/* The sheet fills the viewport. The hero sits on it until a root is picked, then the glass does. */
main { flex: 1; display: flex; min-height: 0 }
.stage { flex: 1; position: relative; display: flex; flex-direction: column; min-height: 0; min-width: 0; container: stage / inline-size } .strip { display: contents }
#hero { position: absolute; inset: 0; z-index: 1; overflow-y: auto; box-sizing: border-box; max-width: 760px; margin: 0 auto; padding: var(--s5) var(--s2); display: flex; flex-direction: column; justify-content: safe center; gap: var(--s3) }
body:not(.empty) #hero, body.empty :is(.card, .zoom, #ask, #leader, #link) { display: none }
#hero h2 { margin: 0; font: 800 clamp(32px, 7vw, 56px)/1.05 var(--font-text); letter-spacing: -.01em }
#hero p { margin: 0; max-width: 60ch; font-size: 1.125rem } #hero .hint { font-size: .8125rem; color: var(--black-60) }
#hero .search, #hero #q { width: 100%; max-width: 520px; box-sizing: border-box } #hero #q { font-size: 1.125rem; padding: 12px var(--s2) }
/* The legend draws with the figure's own classes, so it is the key's swatches in a row: it needs the stock under it for the overprint to read plum. */
#hero .legend { flex: none; width: 100%; max-width: 320px; height: 48px; background: var(--stock); isolation: isolate }
#hero details { font-size: .875rem; color: var(--black-60); max-width: 60ch } #hero summary { cursor: pointer; font: var(--label); text-transform: uppercase; letter-spacing: .08em }
#hero details p { margin: var(--s1) 0 0; font-size: .875rem } #hero a { color: var(--black) }
.chips { display: flex; flex-wrap: wrap; gap: var(--s1) }
#examples { display: flex; flex-direction: column; gap: var(--s1) } #kind { display: flex; gap: 6px } #hero .pick { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1) } #hero .pick[hidden] { display: none } #hero .pick .eyebrow { margin-right: var(--s1) } #hero .chips[hidden] { display: none }   /* the flex rule above would beat the hidden attribute */

/* Glass, tier one: the cards and the dock. The bare sheet toggle slides them out and fades them back. */
.card, #ask { background: var(--glass); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border: 1px solid var(--glass-line); border-radius: 12px; box-shadow: var(--shadow) }
.card, #ask, #panel, .zoom .btn { transition: opacity .4s ease-out, transform .4s var(--slide) }
body.bare :is(.card, #ask, #panel, #leader, .zoom [data-zoom]:not([data-zoom="bare"])) { opacity: 0; pointer-events: none; transform: translateY(12px) }
.card { position: absolute; z-index: 1; padding: 12px var(--s2); box-sizing: border-box; max-width: min(380px, calc(100% - 2 * var(--s2))) }
.forms { top: var(--s2); left: var(--s2); max-width: min(680px, calc(100% - 2 * var(--s2))); background: var(--glass-bar); backdrop-filter: blur(12px) } .plate { top: var(--s2); right: var(--s2) } .key { bottom: var(--s2); right: 64px }
#views { display: flex; flex-wrap: wrap; gap: 6px } #views .btn { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; font-size: .6875rem; border-color: var(--black-30) } #views .btn[aria-pressed="true"] { border-color: var(--black) }
#note { margin: var(--s1) 0 0; font-size: .75rem; line-height: 1.4; color: var(--black-60); max-width: 44ch } #note:empty { display: none }
#views svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; pointer-events: none }   /* a glyph per form; the click reads the button */
#hero #views { flex-wrap: wrap } #hero #views .btn { padding: 6px 12px; font-size: .75rem } .forms #views svg { display: none }   /* on the card the row stays as narrow as it was, clear of the plate */
#plate-name { margin: 0; font: 800 1.75rem/1.1 var(--font-text); overflow-wrap: anywhere }
#trail { margin-bottom: 6px; font: .6875rem/1.6 var(--font-data); color: var(--black-60) } #trail:empty { display: none }
#layers { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: var(--s1) } #layers:empty { display: none }
#layers .layer { display: inline-flex; align-items: center } #layers .chip { max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 4px 10px; border-radius: 20px 0 0 20px }
#layers .chip[aria-pressed="false"] { text-decoration: line-through; color: var(--black-60) }
#layers .drop { font: .875rem/1 var(--font-data); color: var(--black-60); background: var(--chip); border: 1px solid var(--glass-line); border-left: 0; border-radius: 0 20px 20px 0; padding: 5px 8px; cursor: pointer } #layers .drop:hover { color: var(--black) }
#trail button { font: inherit; color: var(--black); background: none; border: 0; border-bottom: 1px dashed var(--black-60); padding: 0; cursor: pointer } #trail button:hover { border-bottom-style: solid }
#plate-caption, .bounds { margin: var(--s1) 0 0; font-size: .875rem; line-height: 1.6; color: var(--black-60) }
.bounds { display: flex; flex-wrap: wrap; align-items: center; gap: 6px } .bound { width: 40px; padding: 4px; text-align: center; font-family: var(--font-data); border-radius: 6px }
.bounds .btn { padding: 4px 8px }
/* The coach strip: the plate's last row, in flow, so the figure refits under it and the bare toggle slides it away with the card. */
#coach { margin: var(--s1) calc(-1 * var(--s2)) -12px; padding: 8px var(--s2); display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1); border-top: 1px solid var(--glass-line); background: var(--glass-deep); border-radius: 0 0 12px 12px; font-size: .8125rem; line-height: 1.4 }
#coach[hidden] { display: none } #coach .btn { padding: 4px 8px; font-size: .625rem } #coach .btn:first-of-type { margin-left: auto }
.key summary { font: var(--label); text-transform: uppercase; letter-spacing: .08em; cursor: pointer; list-style: none; color: var(--black-60) } .key summary::-webkit-details-marker { display: none }
.key[open] summary { color: var(--black); margin-bottom: var(--s1) }
.key div { display: flex; align-items: center; gap: var(--s1); font-size: .8125rem; line-height: 1.4; padding: 3px 0 } #key-scope:empty { display: none }
.swatch { width: 26px; height: 14px; flex: none; background: var(--stock); isolation: isolate } .swatch.wide { width: 44px }
.zoom { position: absolute; z-index: 1; bottom: var(--s2); right: var(--s2); display: flex; flex-direction: column; gap: var(--s1) }
.zoom .btn { width: 32px; height: 32px; padding: 0; display: flex; align-items: center; justify-content: center; font: 700 .875rem var(--font-data); border-radius: 50%; border-color: var(--glass-line); background: var(--glass-bar); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); box-shadow: 0 2px 10px rgba(0, 0, 0, .08) }
.zoom .btn:hover { background: var(--glass-deep); border-color: var(--black) } .zoom .btn[aria-pressed="true"] { background: var(--black); color: var(--stock) }
.zoom [data-zoom="fit"] { font-size: .625rem } .zoom svg { pointer-events: none }

/* Glass, tier two: the card lands beside its mark with a dashed leader back to it, and follows the mark as the sheet moves. */
#panel { position: absolute; z-index: 2; width: 320px; max-height: calc(100% - 2 * var(--s2)); overflow-y: auto; box-sizing: border-box; padding: var(--s3) var(--s2) var(--s2); background: var(--glass-deep); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border: 1px solid var(--glass-line); border-radius: 16px; box-shadow: var(--shadow-deep); animation: land .4s var(--lift) }
@keyframes land { from { opacity: 0; transform: scale(.92) } }
#panel[hidden] { display: none }
#leader { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; pointer-events: none } #leader line { stroke: var(--black); stroke-dasharray: 3 3 }
#panel h2 { margin: 0 var(--s5) 0 0; font: 800 1.5rem/1.15 var(--font-text); outline: none }
#panel .close { position: absolute; top: 10px; right: 12px; width: 28px; height: 28px; padding: 0; border: 0; font: 400 1.25rem/1 var(--font-data); color: var(--black-60) }
#panel .meta { margin: var(--s1) 0 var(--s2); font-size: .875rem; color: var(--black-60) } #panel a { color: var(--black) }
.figures { display: flex; justify-content: space-between; gap: var(--s2); margin-bottom: var(--s1) } .figures b { display: block; font: 700 1.75rem/1.1 var(--font-data) }
.figures small, #panel h3 { display: block; margin: var(--s2) 0 4px; font: var(--label); text-transform: uppercase; letter-spacing: .08em; color: var(--black-60) } .figures small { margin: 4px 0 0 }
.names button { display: flex; justify-content: space-between; align-items: center; gap: var(--s1); width: 100%; text-align: left; font: inherit; color: inherit; background: none; border: 0; border-bottom: 1px solid var(--glass-line); padding: 6px 0; cursor: pointer }
.names button:hover { background: var(--chip) } .names small { font: .6875rem var(--font-data); color: var(--black-60); background: var(--chip); border-radius: 9999px; padding: 1px 8px; white-space: nowrap }
#panel .actions { display: flex; gap: var(--s1); margin-top: var(--s3) } .actions .btn { flex: 1; border-radius: 9999px }

/* The dock: ask the sheet. Turns read as a ledger, receipts name the run, the people an answer names open their card. */
#ask { position: absolute; z-index: 2; left: var(--s2); bottom: var(--s2); width: min(430px, calc(100% - 2 * var(--s2))); min-height: 160px; max-height: calc(100% - 2 * var(--s2)); box-sizing: border-box; padding: var(--s2) 20px 14px; display: flex; flex-direction: column; gap: 12px }
#ask .grip { position: absolute; top: 0; left: 0; right: 0; height: 12px; cursor: ns-resize; touch-action: none } #ask .grip::after { content: ""; display: block; width: 36px; height: 3px; margin: 4px auto 0; border-radius: 2px; background: var(--black-30) }
.ask-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s2); padding-bottom: 10px; border-bottom: 1px solid var(--glass-line) } .ask-head .eyebrow { color: var(--black) }
#log { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; scrollbar-width: thin } #log:empty { display: none }
.turn { margin: 0; font-size: .9375rem; line-height: 1.6; overflow-wrap: anywhere } .turn.you::before { content: "› "; color: var(--black-60) } .turn.said { color: var(--black) }
.receipt { font: .6875rem/1.6 var(--font-data); color: var(--black-60); margin: 0 } .receipt button { font: inherit; color: var(--black); background: none; border: 0; border-bottom: 1px dashed var(--black-60); padding: 0; cursor: pointer }
#ask form { display: flex; align-items: center; gap: 10px; border-top: 1px solid var(--glass-line); padding-top: 10px }
#ask-q { flex: 1; min-width: 0; border: 0; border-bottom: 1px solid var(--black-30); border-radius: 2px; background: var(--field); padding: 6px 4px } #ask-q:focus { border-color: var(--black); box-shadow: none }
#ask .send { width: 26px; height: 26px; padding: 0; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--black); color: var(--stock) } #ask .send svg { pointer-events: none }

#tip { position: fixed; z-index: 3; background: var(--glass-deep); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border: 1px solid var(--glass-line); border-radius: 12px; box-shadow: var(--shadow-deep); padding: 8px 12px; display: none; font-size: .75rem; line-height: 1.5; pointer-events: none; max-width: 280px }
#tip small { font: .6875rem var(--font-data); color: var(--black-60); background: var(--chip); border-radius: 9999px; padding: 1px 8px; margin-left: 4px }
/* What the sheet is waiting on, one line per wait, above the key and beside the zoom, clear of the dock; on a phone under the header. */
#status { position: fixed; z-index: 5; right: 64px; bottom: 96px; max-width: min(420px, calc(100vw - 96px)); padding: 8px 14px; display: flex; flex-direction: column; gap: 2px; background: var(--glass-deep); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border: 1px solid var(--glass-line); border-radius: 12px; box-shadow: var(--shadow); font: .75rem/1.5 var(--font-data); pointer-events: none }
#status[hidden] { display: none } #status p { margin: 0; display: flex; align-items: center; gap: var(--s1) } #status small { margin-left: auto; padding-left: var(--s2); color: var(--black-60) }
#status p::before { content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--pink); animation: waiting 1s ease-in-out infinite alternate } @keyframes waiting { to { opacity: .2 } }
footer { padding: var(--s1) var(--s2); border-top: var(--rule-heavy); font: .6875rem/1.6 var(--font-data); color: var(--black-60); display: flex; flex-wrap: wrap; gap: 4px var(--s2); align-items: center }
#theme { margin-left: auto }

/* On a sheet under 960px wide the two top cards would collide, so they become a strip above the figure. */
@container stage (max-width: 960px) {
  .strip { display: flex; flex-wrap: wrap; order: -1; border-bottom: 1px solid var(--glass-line) }
  .forms, .plate { position: static; flex: 1 1 320px; max-width: none; min-width: 0; border: 0; border-radius: 0; box-shadow: none; background: none; backdrop-filter: none }
}
/* A phone: the dock and the card become sheets from the bottom, and the leader has nowhere to point. */
@media (max-width: 600px) {
  header { gap: 12px } header #q { width: 40vw } #views { flex-wrap: nowrap; overflow-x: auto }
  #hero { justify-content: flex-start }
  #ask { left: 0; bottom: 0; width: 100%; max-height: 70vh; border-radius: 12px 12px 0 0 }
  #status { top: 64px; bottom: auto; right: var(--s2) }
  #panel { left: 0; right: 0; top: auto; bottom: 0; width: auto; max-height: 45vh; border-radius: 16px 16px 0 0; z-index: 3 } #leader { display: none }
}
@media (prefers-reduced-motion: reduce) { #panel, #status p::before { animation: none } .card, #ask, #panel, .zoom .btn, .btn, .chip { transition: none } }
:root[data-motion="still"] #panel, :root[data-motion="still"] #status p::before { animation: none } :root[data-motion="still"] :is(.card, #ask, #panel, .zoom .btn, .btn, .chip) { transition: none }
