/* deckroom chrome. One accent, warm paper, system type. No uppercase transforms, no tracked
   caps, no em-dash-lookalike decorative bars: the app obeys the same register its gate enforces. */

/* CENTURY GOTHIC, SELF-HOSTED. Adrian 2026-08-18: "centruy gothic is fune to use - they are
   licesnsesd". local() first so an installed copy is used where there is one, then the woff2, so a
   slide renders in the deck's real typeface on every machine and in the printed PDF rather than
   falling back to a geometric lookalike with different letterforms. Named 'Century Gothic' exactly,
   so every stack the extractor emits from the file picks it up with no mapping. */
@font-face { font-family: 'Century Gothic'; src: local('Century Gothic'), url('/studio/fonts/CenturyGothic-Regular.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: block; }
@font-face { font-family: 'Century Gothic'; src: local('Century Gothic Bold'), local('Century Gothic'), url('/studio/fonts/CenturyGothic-Bold.woff2') format('woff2'); font-weight: 700; font-style: normal; font-display: block; }
@font-face { font-family: 'Century Gothic'; src: local('Century Gothic Italic'), url('/studio/fonts/CenturyGothic-Italic.woff2') format('woff2'); font-weight: 400; font-style: italic; font-display: block; }
@font-face { font-family: 'Century Gothic'; src: local('Century Gothic Bold Italic'), url('/studio/fonts/CenturyGothic-BoldItalic.woff2') format('woff2'); font-weight: 700; font-style: italic; font-display: block; }
/* geometric fallback for a tenant whose deck names a font we do not hold (Montserrat, self-hosted) */
@font-face { font-family: 'CG Fallback'; src: url('/studio/fonts/Montserrat-Regular.woff2') format('woff2'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'CG Fallback'; src: url('/studio/fonts/Montserrat-Bold.woff2') format('woff2'); font-weight: 700; font-display: swap; }

:root {
  --accent: #1F4E8C;
  --accent-deep: #143A6B;
  --ink: #20242B;
  --body: #49505A;
  --muted: #8A919B;
  --line: #E3E7EC;
  --wash: #F4F6F9;
  --paper: #FFFFFF;
  --shell: #EDF0F4;
  --well: #FDF6EC;
  --well-line: #E8CFA0;
  --good: #2E7D57;
  --bad: #B4383D;
  --disp: 'Avenir Next', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body { font-family: var(--disp); color: var(--ink); background: var(--shell); font-size: 15px; }
button { font: inherit; cursor: pointer; border: 1px solid var(--line); background: var(--paper); color: var(--ink); border-radius: 8px; padding: 7px 14px; }
button:hover { border-color: var(--accent); color: var(--accent); }
button.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
button.primary:hover { background: var(--accent-deep); color: #fff; }
button:disabled { opacity: .5; cursor: default; }
input, textarea, select { font: inherit; color: var(--ink); border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; background: var(--paper); width: 100%; }
input:focus, textarea:focus, button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
h1, h2, h3 { margin: 0; }

/* ---- gate page ---- */
.gate-page { display: grid; place-items: center; min-height: 100vh; background: linear-gradient(160deg, #10233f 0%, #1F4E8C 60%, #2c66b0 100%); }
.gate-card { background: var(--paper); border-radius: 16px; padding: 42px 44px; width: min(440px, 92vw); box-shadow: 0 24px 60px rgba(10, 25, 50, .35); }
.wordmark { font-weight: 700; letter-spacing: .01em; color: var(--accent); margin: 0 0 18px; }
.gate-card h1 { font-size: 26px; line-height: 1.2; margin-bottom: 10px; }
.gate-sub { color: var(--body); line-height: 1.55; margin: 0 0 22px; }
.gate-card label { display: block; font-weight: 600; margin-bottom: 6px; }
.gate-card input { margin-bottom: 12px; }
.gate-card button { width: 100%; background: var(--accent); border-color: var(--accent); color: #fff; padding: 10px; }
.gate-card button:hover { background: var(--accent-deep); }
.gate-msg { min-height: 1.2em; color: var(--bad); margin: 10px 0 0; }
.gate-foot { color: var(--muted); font-size: 13px; margin: 18px 0 0; line-height: 1.5; }

/* ---- studio shell ---- */
.topbar { display: flex; align-items: center; gap: 14px; padding: 10px 16px; background: var(--paper); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 40; }
.topbar .wordmark { margin: 0; }
.topbar .deckname { font-weight: 600; color: var(--body); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar .who { color: var(--muted); font-size: 13px; }
/* Bella code-lane door seat picker (2026-09-04): a small inline chip, not a modal, since it gates
   one optional feature and must never block the room from being usable while it waits. */
.topbar .seat-picker { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); }
.topbar .seat-picker button { min-height: 28px; border: 1px solid var(--line); border-radius: 100px; background: var(--paper); color: var(--body); font: inherit; font-size: 12px; padding: 3px 10px; cursor: pointer; }
.topbar .seat-picker button:hover { background: var(--line); }
.studio { display: grid; grid-template-columns: 270px 1fr 330px; gap: 0; height: calc(100vh - 53px); }
.rail { background: var(--paper); border-right: 1px solid var(--line); overflow-y: auto; padding: 14px; }
.rail-right { border-right: 0; border-left: 1px solid var(--line); }
.rail h2 { font-size: 13px; color: var(--muted); font-weight: 600; margin: 18px 0 8px; }
.rail h2:first-child { margin-top: 0; }

.deck-item { display: block; width: 100%; text-align: left; padding: 9px 10px; border-radius: 8px; border: 1px solid transparent; background: none; margin-bottom: 2px; }
.deck-item:hover { background: var(--wash); }
.deck-item.on { background: #E8EFF9; border-color: #C6D8F0; color: var(--accent-deep); }
.deck-item small { display: block; color: var(--muted); }
.newdeck input, .newdeck textarea { margin-bottom: 8px; }
.newdeck textarea { min-height: 92px; resize: vertical; }

.dropzone { border: 1.5px dashed var(--line); border-radius: 10px; padding: 16px 12px; text-align: center; color: var(--muted); font-size: 13px; line-height: 1.5; }
.dropzone.hot { border-color: var(--accent); background: #F2F7FE; color: var(--accent); }
.filelist { list-style: none; margin: 8px 0 0; padding: 0; font-size: 13px; }
.filelist li { display: flex; gap: 8px; align-items: baseline; padding: 5px 2px; border-bottom: 1px solid var(--wash); }
.filelist .fname { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.filelist .fsniff { font-family: var(--mono); font-size: 11px; color: var(--good); }
.filelist .fkind { font-size: 10.5px; border-radius: 999px; padding: 1px 8px; background: #E8EFF9; color: var(--accent-deep); white-space: nowrap; }
.filelist .fkind.lock { background: #FBEAEA; color: var(--bad); }
.iq-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.iq-chip { background: rgba(255,255,255,.14); border: 1px solid rgba(255,255,255,.45); color: #fff; border-radius: 999px; padding: 7px 16px; font-size: 14px; }
.iq-chip:hover { background: rgba(255,255,255,.28); border-color: #fff; color: #fff; }
/* the framework choice: the team's own templates as pictures, so the shape of the deck is picked
   from what it will actually look like rather than described in a sentence */
.fwpick { width: min(1080px, 92vw); color: #fff; text-align: left; }
.fwpick h2 { font-size: 34px; line-height: 1.15; margin: 0 0 8px; }
.fwcards { display: grid; gap: 14px; margin: 22px 0 18px; }
.fwcard { display: block; width: 100%; text-align: left; background: rgba(255,255,255,.09); border: 1.5px solid rgba(255,255,255,.28);
  border-radius: 14px; padding: 16px 18px; color: #fff; transition: background .12s, border-color .12s, transform .12s; }
.fwcard:hover, .fwcard:focus-visible { background: rgba(255,255,255,.17); border-color: #fff; transform: translateY(-1px); }
.fwcard .fw-name { display: block; font-size: 19px; font-weight: 600; }
.fwcard .fw-meta { display: block; font-size: 13px; opacity: .82; margin: 3px 0 12px; line-height: 1.45; }
.fw-strip { display: flex; gap: 6px; overflow: hidden; }
.fw-strip img, .fw-strip i { flex: none; width: 92px; height: 52px; border-radius: 4px; object-fit: cover;
  background: rgba(255,255,255,.16); box-shadow: 0 1px 4px rgba(0,0,0,.28); }
.fw-strip-free i { background: repeating-linear-gradient(135deg, rgba(255,255,255,.14) 0 7px, rgba(255,255,255,.05) 7px 14px); }
.iq-fw { font-size: 13px; opacity: .86; margin: 10px 0 0; }
.linkish { background: none; border: 0; color: #fff; text-decoration: underline; font-size: 13px; padding: 0 0 0 8px; }

/* ---- stage ---- */
.stage { display: flex; flex-direction: column; min-width: 0; background: var(--shell); }
/* overflow hidden on BOTH: a transform scales pixels, not the layout box, so the 1600px canvas
   inside a smaller viewport pushed the whole PAGE into horizontal scroll (measured 2026-08-17:
   288-608px of page overflow at 1280-1600 wide; Adrian: "things are getting cut off even in
   desktop"). The scale wrapper is sized to the scaled canvas exactly, so clipping loses nothing. */
.canvas-wrap { flex: 1; display: grid; place-items: center; min-height: 0; padding: 18px; overflow: hidden; position: relative; /* anchors the .inline-hint coach mark */ }
.canvas-scale { position: relative; overflow: hidden; }
.slide-canvas { width: 1600px; height: 900px; background: var(--paper); box-shadow: 0 12px 40px rgba(15, 25, 40, .18); border-radius: 6px; overflow: hidden; transform-origin: top left; }
.thumbs { display: flex; gap: 8px; padding: 10px 16px 14px; overflow-x: auto; background: transparent; }
/* the strip carries real miniatures: face on top, the spoken label under it */
.thumb { flex: none; width: 128px; height: 92px; border-radius: 6px; border: 2px solid transparent; background: var(--paper); color: var(--muted); font-size: 10.5px; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 2px; text-align: center; padding: 3px 3px 2px; overflow: hidden; }
.t-face { display: block; width: 120px; height: 67px; overflow: hidden; border-radius: 4px; background: #fff; pointer-events: none; }
.t-mini { display: block; width: 1600px; height: 900px; transform: scale(0.075); transform-origin: top left; pointer-events: none; }
.t-mini .rp, .t-mini .sl { height: 900px; }
.lc-pick { font-size: 12px; color: var(--muted); display: inline-flex; align-items: center; gap: 4px; margin-left: auto; user-select: none; }
.thumb.on { border-color: var(--accent); color: var(--accent-deep); font-weight: 600; }
.thumb .t-role { pointer-events: none; }

/* ---- right rail ---- */
.tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 12px; }
.tabs button { flex: 1 1 auto; padding: 6px 8px; font-size: 13px; border-radius: 7px; }
.tabs button.on { background: var(--accent); color: #fff; border-color: var(--accent); }
.slotrow { width: 100%; text-align: left; background: none; border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; margin-bottom: 6px; display: block; }
.kindchip { font-size: 11px; font-weight: 600; background: #E8EFF9; color: var(--accent-deep); border-radius: 999px; padding: 2px 10px; vertical-align: 2px; }
.slot-details { margin-top: 10px; }
.slot-details summary { font-size: 12.5px; color: var(--muted); cursor: pointer; margin-bottom: 6px; }
.slotrow:hover { border-color: var(--accent); }
.slotrow .s-name { font-weight: 600; font-size: 13px; }
.slotrow .s-val { color: var(--body); font-size: 12.5px; line-height: 1.4; display: block; margin-top: 2px; max-height: 3.9em; overflow: hidden; }
.chip { display: inline-block; font-size: 11px; border-radius: 999px; padding: 1px 8px; margin-left: 6px; vertical-align: 1px; }
.chip.deterministic { background: #E9F2EC; color: var(--good); }
.chip.model { background: #E8EFF9; color: var(--accent-deep); }
.chip.human { background: var(--well); color: #9A6B1F; }
.editor { border: 1px solid var(--accent); border-radius: 10px; padding: 10px; margin-bottom: 10px; background: #FAFCFF; }
#row-editor { display: flex; flex-direction: column; gap: 8px; margin: 8px 0; }
.row-edit { display: flex; flex-direction: column; gap: 4px; border: 1px solid var(--line); border-radius: 8px; padding: 8px 30px 8px 8px; position: relative; background: var(--paper); }
.row-edit input { font-size: 13px; padding: 6px 8px; }
.row-edit .row-del { position: absolute; top: 6px; right: 6px; width: 20px; height: 20px; padding: 0; font-size: 13px; line-height: 1; color: var(--bad); border: none; background: none; }
#row-add { width: 100%; font-size: 12.5px; border-style: dashed; }
.editor textarea { min-height: 84px; resize: vertical; margin: 6px 0 8px; }
.editor .row { display: flex; gap: 6px; }
.options { margin: 8px 0 0; padding: 0; list-style: none; }
.options li { margin-bottom: 6px; }
.options button { width: 100%; text-align: left; font-size: 13px; line-height: 1.4; }
.finding { border-left: 3px solid var(--bad); background: #FDF4F4; padding: 7px 10px; border-radius: 0 8px 8px 0; font-size: 13px; margin-bottom: 6px; }
.finding.ok { border-color: var(--good); background: #F1F8F3; }
.rule { display: flex; gap: 8px; align-items: flex-start; border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; margin-bottom: 6px; font-size: 13px; line-height: 1.45; }
.rule.off { opacity: .45; }
.rule .ev { color: var(--muted); font-size: 11px; white-space: nowrap; }
.logrow { font-family: var(--mono); font-size: 11.5px; color: var(--body); padding: 5px 0; border-bottom: 1px solid var(--wash); }
.note { color: var(--muted); font-size: 13px; line-height: 1.5; }
.toast { position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%); background: var(--ink); color: #fff; border-radius: 10px; padding: 10px 18px; z-index: 90; box-shadow: 0 10px 30px rgba(0,0,0,.3); }
.toast.bad { background: var(--bad); }

/* ---- slide internals (theme tokens arrive as --dk-* on .slide-canvas) ---- */
.slide-canvas { --pad: 80px; font-family: var(--dk-font-text, var(--disp)); color: var(--dk-ink, #20242B); }
.sl { position: relative; width: 100%; height: 100%; padding: 64px var(--pad) 76px; display: flex; flex-direction: column; background: var(--dk-paper, #fff); }
.sl [data-slot] { border-radius: 4px; }
/* the affordance says TEXT: an I-beam invites typing the way a pointer never does (Adrian
   2026-08-19: inline editing existed and nothing told a person it did) */
.sl [data-slot]:hover { cursor: text; }  /* the outline is the hover chrome, sized to the painted text */
/* id-anchored so no later hover rule can outrank the editing state */
#slide-canvas [data-slot][contenteditable] {
  outline: 2px dashed var(--dk-ink, #303840); outline-offset: 2px; cursor: text;
  background: rgba(255,255,255,.94); color: var(--ink);
  box-shadow: 0 4px 18px rgba(0,0,0,.22); caret-color: var(--accent);
}
/* the one-time coach mark: says the canvas is the editor, until first use or dismissal */
.inline-hint { position: absolute; bottom: 14px; left: 50%; transform: translateX(-50%);
  background: var(--ink); color: #fff; border-radius: 20px; padding: 9px 16px; z-index: 40;
  display: flex; align-items: center; gap: 10px; font-size: 14px; white-space: nowrap;
  box-shadow: 0 10px 30px rgba(0,0,0,.3); }
.inline-hint button { background: none; border: none; color: #fff; opacity: .7; padding: 0 2px; font-size: 16px; line-height: 1; }
.inline-hint button:hover { opacity: 1; color: #fff; }
.sl .well { display: inline-block; background: var(--dk-well, #FDF6EC); border: 1px dashed var(--dk-well-line, #E8CFA0); color: #9A6B1F; font: 500 17px/1.5 var(--mono); padding: 2px 8px; border-radius: 4px; }
.sl .eyebrow { font-weight: 600; font-size: 19px; color: var(--dk-accent, #1F4E8C); margin: 0 0 12px; }
.sl .pager { position: absolute; right: var(--pad); bottom: 34px; font-size: 17px; color: var(--dk-muted, #8A919B); }
.sl .capsule { position: absolute; top: 30px; left: var(--pad); background: var(--dk-wash, #F6F8FA); color: var(--dk-body, #49505A); font-size: 17px; padding: 5px 14px; border-radius: 999px; }

.sl-cover { justify-content: center; }
.sl-cover h1 { font-size: 66px; line-height: 1.12; max-width: 18ch; margin: 0 0 14px; }
.sl-cover .sub { font-size: 23px; color: var(--dk-body, #49505A); }
.sl-cover .disc { position: absolute; right: -140px; top: -140px; width: 560px; height: 560px; border-radius: 50%; background: var(--dk-accent, #1F4E8C); opacity: .09; }

.sl-agenda h1, .sl-generic h1 { font-size: 44px; line-height: 1.2; margin: 0 0 12px; }
.sl-agenda { justify-content: center; }
.sl-agenda .lede { font-size: 26px; color: var(--dk-body); margin: 0 0 34px; max-width: 60ch; line-height: 1.5; }
.sl-agenda ol { margin: 0; padding-left: 26px; columns: 2; column-gap: 56px; font-size: 24px; line-height: 1.7; color: var(--dk-body); }
.sl-agenda li { margin-bottom: 14px; break-inside: avoid; }

.sl-divider .idx { display: flex; gap: 10px; margin-bottom: 22px; }
.sl-divider .idx span { font-size: 17px; font-weight: 600; color: #C7CCD3; padding: 6px 13px; border-radius: 999px; background: var(--dk-wash); }
.sl-divider .idx .on { background: var(--dk-accent); color: #fff; }
.sl-divider h1 { font-size: 58px; line-height: 1.15; max-width: 20ch; margin: 0 0 26px; }
.sl-divider .pair h3 { font-size: 19px; color: var(--dk-accent); margin: 0 0 6px; }
.sl-divider .pair p { font-size: 22px; line-height: 1.55; color: var(--dk-body); margin: 0 0 18px; max-width: 56ch; }

.sl-cards .cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.sl-cards .card { border: 1px solid var(--dk-line, #E3E7EC); border-radius: 12px; overflow: hidden; }
.sl-cards .card header { background: var(--dk-accent); color: #fff; padding: 13px 16px; font-size: 21px; font-weight: 700; }
.sl-cards .card .crow { display: grid; grid-template-columns: 96px 1fr; gap: 10px; padding: 13px 16px; border-top: 1px solid var(--dk-line); }
.sl-cards .card .crow span { font-weight: 700; font-size: 17px; color: var(--dk-muted); }
.sl-cards .card .crow p { margin: 0; font-size: 18px; line-height: 1.5; color: var(--dk-body); }

.sl-matrix { justify-content: center; }
.sl-matrix table { width: 100%; border-collapse: collapse; font-size: 19px; table-layout: fixed; }
.sl-matrix th, .sl-matrix td { border: 1px solid var(--dk-line); padding: 26px 18px; text-align: left; vertical-align: top; line-height: 1.5; }
.sl-matrix thead th { background: var(--dk-accent); color: #fff; text-align: center; font-size: 19px; }
.sl-matrix .corner { background: var(--dk-paper); border: none; width: 120px; }
.sl-matrix .rowh { background: var(--dk-wash); font-weight: 700; width: 120px; }
.sl-matrix .challenge { background: var(--dk-wash); border-left: 3px solid var(--dk-accent); padding: 10px 14px; font-size: 19px; margin: 0 0 14px; color: var(--dk-body); }

.sl-table table { width: 100%; border-collapse: collapse; font-size: 17.5px; }
.sl-table th, .sl-table td { border: 1px solid var(--dk-line); padding: 13px 12px; text-align: left; line-height: 1.45; vertical-align: top; }
.sl-table thead th { background: var(--dk-wash); font-weight: 700; }

.sl-closing { align-items: center; flex-direction: row; gap: 44px; }
.sl-closing .disc { background: var(--dk-accent); color: #fff; border-radius: 50%; aspect-ratio: 1; width: 430px; flex: none; display: flex; flex-direction: column; justify-content: center; padding: 0 64px; }
.sl-closing .disc h1 { font-size: 62px; line-height: 1.1; margin: 10px 0 12px; }
.sl-closing .disc p { font-size: 21px; line-height: 1.55; margin: 0; opacity: .95; }

/* ---- topbar links ---- */
.btnlink { font: inherit; text-decoration: none; border: 1px solid var(--line); background: var(--paper); color: var(--ink); border-radius: 8px; padding: 7px 14px; }
.btnlink:hover { border-color: var(--accent); color: var(--accent); }

/* ---- role library overlay ---- */
.overlay { position: fixed; inset: 0; background: rgba(16, 22, 32, .55); z-index: 60; display: grid; place-items: center; padding: 4vh 4vw; }
/* author display:grid would otherwise defeat the hidden attribute (UA display:none loses the cascade) */
.overlay[hidden] { display: none; }
.ov-panel { background: var(--shell); border-radius: 16px; width: min(1240px, 100%); max-height: 92vh; display: flex; flex-direction: column; overflow: hidden; box-shadow: 0 30px 80px rgba(10, 20, 40, .4); }
.ov-head { display: flex; align-items: center; gap: 14px; padding: 14px 20px; background: var(--paper); border-bottom: 1px solid var(--line); }
.ov-head h2 { font-size: 17px; }
.ov-head .note { flex: 1; }
/* max-content rows: default auto rows compress to equal shares of the shrunken flex height and
   clip every card (measured live 2026-08-17: rows 192.75px vs 476px content; toggling
   grid-auto-rows to max-content in-page restored full cards) */
.lib-grid { overflow-y: auto; padding: 18px 20px; display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); grid-auto-rows: max-content; gap: 16px; }
.lib-card { background: var(--paper); border: 1px solid var(--line); border-radius: 12px; overflow: hidden; display: flex; flex-direction: column; }
/* fixed image height, not aspect-ratio: an aspect-ratio img resolves ~0 intrinsic height during
   grid track sizing, which collapsed every row to an equal share and clipped the card bodies
   (measured live 2026-08-17: rows 192.75px against 474px cards) */
.lib-card > img { width: 100%; height: 200px; object-fit: cover; display: block; border-bottom: 1px solid var(--line); background: var(--wash); }
.lib-card .lc-noimg { width: 100%; height: 200px; display: grid; place-items: center; color: var(--muted); font-size: 13px; background: var(--wash); border-bottom: 1px solid var(--line); }
.lib-card .lc-body { padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.lib-card .lc-name { font-weight: 700; font-size: 14px; }
.lib-card .lc-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.lib-card .lc-chip { font-size: 11px; border-radius: 999px; padding: 1px 8px; background: #E8EFF9; color: var(--accent-deep); }
.lib-card .lc-chip.alias { background: var(--wash); color: var(--muted); }
.lib-card .lc-used { font-size: 12.5px; line-height: 1.45; color: var(--body); }
.lib-card .lc-when { font-size: 12px; line-height: 1.45; color: var(--muted); }
.lib-card .lc-row { display: flex; gap: 6px; margin-top: auto; padding-top: 8px; }
.lib-card .lc-row button { font-size: 12.5px; padding: 5px 10px; }
.lib-card textarea { font-size: 12.5px; min-height: 56px; resize: vertical; }

/* ---- visual suggestions ---- */
.vsug { border: 1px solid var(--line); border-radius: 10px; padding: 9px 11px; margin-bottom: 7px; background: var(--paper); }
.vsug b { font-size: 13px; display: block; margin-bottom: 3px; }
.vsug p { margin: 0; font-size: 12.5px; color: var(--body); line-height: 1.45; }
.vsug button { margin-top: 7px; font-size: 12px; padding: 4px 10px; }
.vsug-preview { position: relative; width: 100%; height: 150px; overflow: hidden; border: 1px solid var(--line); border-radius: 8px; margin-top: 8px; background: var(--wash); }

/* ---- immersive intake ---- */
.intake { position: fixed; inset: 0; background: linear-gradient(160deg, #10233f 0%, #1F4E8C 65%, #2c66b0 100%); z-index: 70; display: grid; place-items: center; overflow-y: auto; }
.intake[hidden] { display: none; }
.iq { width: min(760px, 92vw); color: #fff; padding: 40px 0; }
.iq .iq-count { font-size: 14px; opacity: .75; margin: 0 0 14px; }
.iq h2 { font-size: clamp(26px, 3.6vw, 38px); line-height: 1.2; color: #fff; margin: 0 0 10px; }
.iq .iq-help { font-size: 16px; line-height: 1.55; opacity: .82; margin: 0 0 26px; }
.iq input[type=text], .iq textarea { font-size: 19px; padding: 14px 16px; border-radius: 12px; border: 1px solid rgba(255,255,255,.35); background: rgba(255,255,255,.96); color: var(--ink); }
.iq textarea { min-height: 130px; resize: vertical; }
.iq .iq-row { display: flex; gap: 12px; align-items: center; margin-top: 22px; }
.iq .iq-row button { padding: 11px 22px; font-size: 16px; border-radius: 10px; }
.iq .iq-row .ghost { background: transparent; color: #fff; border-color: rgba(255,255,255,.45); }
.iq .iq-row .ghost:hover { border-color: #fff; color: #fff; }
.iq .iq-enter { font-size: 13px; opacity: .65; }
.iq .dots { display: flex; gap: 7px; margin-top: 34px; }
.iq .dots i { width: 8px; height: 8px; border-radius: 50%; background: rgba(255,255,255,.3); }
.iq .dots i.on { background: #fff; }
.iq .iq-thinking { font-size: 22px; line-height: 1.5; }

/* ---- outline review ---- */
.outline-review { width: min(1080px, 94vw); background: var(--paper); border-radius: 18px; color: var(--ink); padding: 34px 38px 30px; margin: 4vh 0; box-shadow: 0 30px 80px rgba(5, 15, 35, .5); }
.outline-review .or-thru { font-size: clamp(21px, 2.4vw, 27px); line-height: 1.3; margin: 0 0 6px; }
.outline-review .or-sub { color: var(--body); font-size: 14.5px; line-height: 1.55; margin: 0 0 18px; }
.or-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; margin-bottom: 20px; }
.or-cards .cardrow { margin: 0; font-size: 13.5px; line-height: 1.5; }
.or-cards .cardrow b { display: block; font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.or-chain { border-top: 1px solid var(--line); }
.or-beat { display: grid; grid-template-columns: 34px 1fr 230px; gap: 14px; padding: 13px 0; border-bottom: 1px solid var(--wash); align-items: start; }
.or-beat .or-n { font-size: 15px; font-weight: 700; color: var(--muted); padding-top: 8px; }
.or-beat input, .or-beat textarea { font-size: 14.5px; padding: 7px 10px; }
.or-beat .or-h { font-weight: 600; font-size: 15.5px; }
.or-beat .or-connect { font-size: 12px; color: var(--muted); line-height: 1.45; margin: 5px 0 6px; }
.or-beat .or-job { display: inline-block; font-size: 11px; background: #E8EFF9; color: var(--accent-deep); border-radius: 999px; padding: 1px 9px; margin-bottom: 5px; }
.or-beat select { width: 100%; font-size: 13px; }
.or-beat .or-roleimg { width: 100%; height: 110px; object-fit: cover; border-radius: 8px; border: 1px solid var(--line); margin-top: 6px; background: var(--wash); }
.or-actions { display: flex; gap: 10px; margin-top: 20px; align-items: center; }
.or-actions .note { flex: 1; }

/* ---- block face on library cards ---- */
.lc-block { border-top: 1px dashed var(--line); padding-top: 7px; margin-top: 2px; }
.lc-block .lc-bname { font-size: 12.5px; font-weight: 700; color: var(--accent-deep); }
.lc-block .lc-brecipe { font-size: 12px; color: var(--body); line-height: 1.45; margin: 3px 0 5px; }
.lc-block .lc-bslots { display: flex; flex-wrap: wrap; gap: 4px; }
.lc-block .lc-bslots span { font-size: 10.5px; font-family: var(--mono); background: var(--wash); border-radius: 5px; padding: 1px 6px; color: var(--body); }

/* ---- report + brand pages ---- */
.page { max-width: 1180px; margin: 0 auto; padding: 26px 22px 60px; }
.page h1 { font-size: 24px; margin: 0 0 4px; }
.page .sub { color: var(--body); margin: 0 0 26px; line-height: 1.5; }
.page h2 { font-size: 16px; margin: 30px 0 12px; color: var(--ink); }
.page .cardrow { background: var(--paper); border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; margin-bottom: 8px; }
.page table { width: 100%; border-collapse: collapse; background: var(--paper); border: 1px solid var(--line); border-radius: 10px; font-size: 13.5px; }
.page th, .page td { text-align: left; padding: 8px 12px; border-bottom: 1px solid var(--wash); vertical-align: top; }
.page thead th { color: var(--muted); font-weight: 600; font-size: 12.5px; }
.prov { color: var(--muted); font-size: 11.5px; margin-top: 3px; }
.swatch { display: inline-flex; align-items: center; gap: 7px; border: 1px solid var(--line); border-radius: 8px; padding: 5px 10px; margin: 0 6px 6px 0; background: var(--paper); font-family: var(--mono); font-size: 12px; }
.swatch i { width: 18px; height: 18px; border-radius: 5px; border: 1px solid var(--line); display: inline-block; }
.brand-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 16px; }
.brand-col { background: var(--paper); border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; }
.brand-col h2 { margin: 0 0 4px; }
.brand-col .colsub { color: var(--muted); font-size: 12.5px; line-height: 1.45; margin: 0 0 12px; }
.brand-entry { border-top: 1px solid var(--wash); padding: 9px 0; }
.brand-entry p { margin: 0; font-size: 13.5px; line-height: 1.5; }
.brand-entry .row { display: flex; gap: 6px; margin-top: 6px; }
.brand-entry .row button { font-size: 11.5px; padding: 3px 9px; }
.brand-add { margin-top: 10px; display: flex; flex-direction: column; gap: 6px; }
.brand-add textarea { min-height: 52px; font-size: 13px; resize: vertical; }
.pagehead { display: flex; align-items: baseline; gap: 14px; }
.pagehead .spacer { flex: 1; }

/* ---- replicator templates (per-role bespoke rendering; .rp lives inside .slide-canvas) ---- */
.rp { position: relative; width: 100%; height: 100%; padding: 62px 84px 70px; display: flex; flex-direction: column; background: #fff; font-family: var(--dk-font-text, 'Poppins', var(--disp)); color: #20242B; }
.rp .rp-eyebrow { font-size: 18px; font-weight: 700; color: var(--a); margin: 0 0 10px; }
.rp h1 { font-size: 52px; line-height: 1.12; font-weight: 700; margin: 0 0 12px; max-width: 26ch; letter-spacing: -0.01em; }
.rp .rp-sub { font-size: 21px; line-height: 1.5; color: #5A6270; margin: 0 0 26px; max-width: 62ch; }
.rp .rp-hint { font-size: 14px; color: #8A919B; display: block; margin-top: 6px; }
.rp .rp-banner { margin-top: auto; background: linear-gradient(90deg, #F2F6FB, #FBF3EC); border-radius: 14px; padding: 16px 22px; font-size: 19px; line-height: 1.5; }
.rp .rp-banner b { color: var(--a); }
.rp .rp-on-dark { color: #fff; }
.rp .rp-foot { font-size: 14px; color: #8A919B; margin: 10px 0 0; }

/* cover: full-bleed dark field + arc device (the Coles 360 cover grammar) */
.rp-cover { background: #262B33; color: #fff; flex-direction: row; padding: 0; overflow: hidden; }
.rp-cover .rp-cover-panel { flex: 1.1; display: flex; flex-direction: column; justify-content: center; padding: 0 70px 0 84px; z-index: 1; }
.rp-cover .rp-brandbar { font-size: 20px; font-weight: 700; color: #fff; margin: 0 0 26px; }
.rp-cover h1 { font-size: 64px; color: #fff; max-width: 14ch; }
.rp-cover .rp-cover-sub { font-size: 22px; color: #C7CCD3; line-height: 1.5; margin: 14px 0 0; max-width: 40ch; }
.rp-cover .rp-cover-date { font-size: 17px; color: #8A919B; margin: 26px 0 0; }
.rp-cover .rp-cover-art { flex: 1; position: relative; }
.rp-cover .rp-arc { position: absolute; inset: -20% -30% -20% 10%; border-radius: 50%; background: radial-gradient(circle at 35% 50%, transparent 38%, var(--a) 39%, var(--b) 78%, transparent 79%); }

/* need-vs-habit: two evidence panels + bars + stat pills */
.rp-need .rp-need-panels { display: grid; grid-template-columns: 1.15fr 1fr; gap: 22px; flex: 1; min-height: 0; }
.rp-need .rp-panel { background: #F6F8FB; border-radius: 16px; padding: 22px 24px; }
.rp-need .rp-panel-warm { background: #FBF4EC; }
.rp-need .rp-panel h3 { font-size: 20px; margin: 0 0 16px; }
.rp-bars { display: flex; flex-direction: column; gap: 10px; }
.rp-bar-row { display: grid; grid-template-columns: 170px 1fr 52px; gap: 12px; align-items: center; }
.rp-bar-label { font-size: 16px; color: #49505A; }
.rp-bar-track { height: 18px; border-radius: 9px; background: #E6EAF0; overflow: hidden; display: block; }
.rp-bar-track i { display: block; height: 100%; border-radius: 9px; }
.rp-bar-val { font-size: 15px; font-weight: 700; color: #49505A; text-align: right; }
.rp-stats { display: flex; flex-direction: column; gap: 14px; }
.rp-stat b { font-size: 44px; color: var(--a); display: block; line-height: 1; }
.rp-stat span { font-size: 16.5px; color: #49505A; line-height: 1.45; display: block; margin-top: 4px; }

/* journey: the infinity loop */
.rp-loop { display: grid; grid-template-columns: 1.2fr 1fr; gap: 26px; flex: 1; min-height: 0; align-items: center; }
.rp-loop svg { width: 100%; height: auto; }
.rp-loop-legend { display: flex; flex-direction: column; gap: 12px; }
.rp-loop-stage { display: flex; gap: 12px; align-items: flex-start; }
.rp-loop-stage i { width: 26px; height: 26px; border-radius: 50%; color: #fff; font-style: normal; font-weight: 700; font-size: 14px; display: grid; place-items: center; flex: none; margin-top: 2px; }
.rp-loop-stage b { font-size: 18px; }
.rp-loop-stage p { margin: 2px 0 0; font-size: 15.5px; line-height: 1.45; color: #49505A; }
.rp-loop-stage span { font-size: 13.5px; color: #8A919B; }

/* budget: dark money slide + gantt */
.rp-budget { background: #14171C; }
.rp-budget .rp-sub { color: #A8B0BB; }
.rp-money { width: 100%; border-collapse: collapse; margin: 6px 0 22px; }
.rp-money th { text-align: left; font-size: 14px; color: #8A919B; font-weight: 600; padding: 8px 12px; border-bottom: 1px solid #2A2F37; }
.rp-money td { padding: 12px; font-size: 16.5px; line-height: 1.45; color: #D6DBE2; border-bottom: 1px solid #22262D; vertical-align: top; }
.rp-money td b { color: #fff; }
.rp-money .rp-share { font-size: 24px; font-weight: 700; white-space: nowrap; }
.rp-gantt { border: 1px solid #2A2F37; border-radius: 14px; padding: 14px 16px; }
.rp-gantt-head { display: grid; grid-template-columns: 130px 1fr; margin-bottom: 6px; }
.rp-gantt-head span:first-child { grid-column: 1; }
.rp-gantt-head { grid-template-columns: 130px repeat(9, 1fr) ; gap: 0; font-size: 11.5px; color: #6B727D; }
.rp-gantt-row { display: grid; grid-template-columns: 130px 1fr 170px; gap: 10px; align-items: center; padding: 6px 0; }
.rp-gantt-label { font-size: 15px; font-weight: 600; color: #D6DBE2; }
.rp-gantt-track { position: relative; height: 20px; border-radius: 10px; background: #22262D; display: block; }
.rp-gantt-track i { position: absolute; top: 0; bottom: 0; border-radius: 10px; }
.rp-gantt-note { font-size: 13px; color: #8A919B; }

/* measurement: method cards */
.rp-cards { display: grid; gap: 16px; flex: 1; min-height: 0; align-content: start; }
.rp-card { border: 1px solid #E3E7EC; border-radius: 14px; overflow: hidden; background: #fff; }
.rp-card header { color: #fff; padding: 12px 16px; font-size: 18px; font-weight: 700; }
.rp-card p { margin: 0; padding: 14px 16px 6px; font-size: 16.5px; line-height: 1.5; color: #49505A; }
.rp-card span { display: block; padding: 0 16px 14px; font-size: 13.5px; color: #8A919B; }

/* urgency: dark stacked evidence */
.rp-urgency { background: #1B1E24; }
.rp-urgency .rp-sub { color: #A8B0BB; }
.rp-reasons { display: flex; flex-direction: column; gap: 12px; margin: 8px 0; }
.rp-reason { background: #262B33; border-left: 4px solid var(--a); border-radius: 0 12px 12px 0; padding: 14px 18px; }
.rp-reason b { font-size: 19px; color: #fff; }
.rp-reason p { margin: 3px 0 0; font-size: 16px; line-height: 1.5; color: #B9C0C9; }
.rp-close { margin-top: auto; font-size: 22px; font-weight: 600; max-width: 50ch; }

/* 4D framework question slide */
.rp-4d { background: #F7F8FA; }
.rp-4d-cols { display: grid; grid-template-columns: 1fr 0.92fr; gap: 44px; flex: 1; min-height: 0; align-items: center; }
.rp-4d h1 { font-size: 46px; font-weight: 400; line-height: 1.18; max-width: 20ch; }
.rp-4d h1 b { font-weight: 700; }
.rp-4d-pills { margin-top: 26px; display: flex; flex-direction: column; gap: 18px; }
.rp-4d-pill span { display: inline-block; background: #D9DEE5; border-radius: 999px; padding: 6px 22px; font-size: 16.5px; font-weight: 700; }
.rp-4d-pill p { margin: 8px 0 0; font-size: 17.5px; line-height: 1.5; color: #3A4048; max-width: 48ch; }
.rp-4d-photos { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; gap: 16px; height: 100%; max-height: 560px; }
.rp-4d-tile { background: #E4E8ED; border-radius: 18px; display: grid; place-items: center; overflow: hidden; }
.rp-4d-tile-tall { grid-row: span 2; }
.rp-4d-tile-wide { grid-column: 1; }

/* channel mockup tiles (dark) */
.rp-exec { background: #1C2027; }
.rp-exec-tiles { display: grid; gap: 18px; flex: 1; min-height: 0; align-content: start; margin-top: 6px; }
.rp-exec-tile { margin: 0; display: flex; flex-direction: column; gap: 10px; }
.rp-exec-frame { background: #262B33; border: 1px solid #333A44; border-radius: 14px; min-height: 280px; display: grid; place-items: center; overflow: hidden; }
.rp-exec-tile figcaption { text-align: center; font-size: 15.5px; color: #C7CCD3; font-weight: 600; }

/* channel plan + flighting table */
.rp-plan h1 { font-size: 40px; }
.rp-plan .rp-plan-date { font-weight: 400; color: #5A6270; }
.rp-plan-table { width: 100%; border-collapse: collapse; margin: 14px 0 16px; font-size: 14.5px; }
.rp-plan-table th { background: #6B727D; color: #fff; text-align: left; padding: 8px 10px; font-size: 13.5px; }
.rp-plan-table th.rp-plan-wk { background: var(--a); text-align: center; min-width: 62px; }
.rp-plan-table td { border: 1px solid #E3E7EC; padding: 8px 10px; vertical-align: top; line-height: 1.4; }
.rp-plan-table .rp-plan-desc { color: #5A6270; font-size: 13.5px; max-width: 34ch; }
.rp-plan-table .rp-plan-inv { font-weight: 700; white-space: nowrap; }
.rp-plan-cell.on { background: var(--a); }
.rp-plan-total { display: flex; justify-content: space-between; align-items: center; background: var(--a); color: #fff; border-radius: 8px; padding: 12px 18px; font-size: 19px; }
.rp-plan-total b { font-size: 23px; }

/* exact templates: the original slide's measured geometry, content lifted out */
.xt { position: relative; padding: 0; display: block; overflow: hidden; }
.xt > div { position: absolute; }
/* text overflows its shape box in PowerPoint routinely, so a text box never clips; painted
   shapes do (a gradient card header must respect its own rounded corners) */
.xt .xt-block, .xt .xt-image, .xt .xt-chrome, .xt .xt-svg, .xt .xt-table { overflow: hidden; }
.xt .xt-text { display: flex; flex-direction: column; line-height: 1.2; }
.xt .xt-text p { margin: 0; }
.xt .xt-bul { display: inline-block; }
/* an empty slot keeps the original's typography as a ghost, so the composition still reads as
   the slide it came from; the editing affordance appears on hover, not as permanent chrome */
.xt .xt-ghost { opacity: .38; }
.xt .xt-svg svg { display: block; width: 100%; height: 100%; }
/* PowerPoint STRETCHES a picture to its shape box (and crops with srcRect first): cover
   would add a centre-crop of its own, which moved every photo in the round trip */
.xt .xt-chrome img { width: 100%; height: 100%; object-fit: fill; }
.xt .xt-image { border-radius: 8px; display: grid; place-items: center; }
.xt .xt-image img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: fill; border-radius: inherit; }
/* AN EMPTY WELL TINTS, IT NEVER REPAINTS. An opaque #EEF1F5 put a white box across the cover's
   red circle, punched two white squares into a dark slide and flattened the closing slide's photo
   circle. A neutral translucent grey darkens a light ground and lightens a dark one, so the
   composition survives either way, and the dashed edge says "a picture belongs here". */
.xt .xt-image.xt-open { background: rgba(128,136,148,.16); box-shadow: inset 0 0 0 1.5px rgba(128,136,148,.34); }
.xt .xt-image.xt-open:hover { background: rgba(128,136,148,.24); box-shadow: inset 0 0 0 2px var(--dk-accent, #9B1432); }
/* the affordance is one clear invitation, in plain words, never the snake_case slot name */
.xt .xt-empty { display: inline-flex; align-items: center; gap: 6px; border-radius: 999px; padding: 7px 15px 7px 11px; font-size: 15px; font-weight: 600; letter-spacing: .01em;
  color: #5C6673; background: rgba(255,255,255,.82); box-shadow: 0 1px 3px rgba(16,20,26,.14); font-family: var(--disp); white-space: nowrap; }
.xt .xt-image.xt-open:hover .xt-empty { color: var(--dk-accent, #9B1432); background: #fff; }
.xt .xt-empty svg { width: 17px; height: 17px; flex: none; }
/* a well is any size the source slide made it, so the invitation scales down to a bare plus
   rather than clipping mid-word in a 90px box */
.xt .xt-image.xt-open { container-type: size; }
@container (max-width: 190px) { .xt .xt-empty { font-size: 13px; padding: 5px 11px 5px 8px; } }
@container (max-width: 120px), (max-height: 74px) {
  .xt .xt-empty { padding: 6px; border-radius: 50%; }
  .xt .xt-empty span, .xt .xt-empty { gap: 0; }
  .xt .xt-empty { font-size: 0; }
  .xt .xt-empty svg { width: 15px; height: 15px; }
}
/* the original's copy sits ON this picture, so the empty space carries a scrim that copy reads
   against; without it the photo-split slide showed white text on a white well */
.xt .xt-image.xt-open.xt-backdrop { background: rgba(26,30,36,.74); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.22); }
.xt .xt-image.xt-open.xt-backdrop .xt-empty { color: #3B434E; background: rgba(255,255,255,.9); }
.xt .xt-table table { width: 100%; height: 100%; border-collapse: collapse; table-layout: fixed; }
.xt .xt-table td { vertical-align: middle; padding: 0 8px; }
/* A ROW WITH NO WORDS IN IT COLLAPSES, AND A 1PX ROW IS NOT SOMETHING ANYBODY CAN CLICK. A table's
   height is fixed by its box, so the rows that carry words take all of it and a row somebody has
   just added is left at its min-content height - measured at 170x1 on the Mars flighting grid, and
   a double-click on it reached the table, not the cell. Every other empty body cell only has height
   because it paints a MASK of the reference deck's words, which an added row has none of. The
   zero-width space gives the cell one line-box of the column's own type and prints nothing. */
.xt .xt-table td .xt-minted-cell { display: block; min-height: 1.9em; }
.xt .xt-table td .xt-minted-cell::before { content: "\200b"; }
.xt [data-slot]:hover { cursor: text; }  /* one grammar: hover chrome only, never a second box */

/* structural xx placeholder: truthful regions in theme colour, never a wrong-brand guess */
.rx { gap: 14px; }
.rx .rx-tag { font-size: 13px; font-weight: 700; display: block; margin-bottom: 6px; }
.rx .rx-heading h1 { font-size: 44px; color: #C7CCD3; }
.rx .rx-block { border: 1.5px dashed #D7DCE3; border-radius: 12px; padding: 14px 16px; }
.rx .rx-block p { margin: 0; font-size: 17px; color: #B9C0C9; }
.rx .rx-bars { display: flex; flex-direction: column; gap: 8px; }
.rx .rx-bars i { display: block; height: 14px; border-radius: 7px; opacity: .55; }
.rx .rx-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.rx .rx-card { border: 1px solid #E3E7EC; border-radius: 10px; overflow: hidden; }
.rx .rx-card b { display: block; height: 26px; opacity: .8; }
.rx .rx-card p { margin: 0; padding: 10px 12px; font-size: 14px; color: #B9C0C9; }
.rx .rx-image { min-height: 120px; background: repeating-linear-gradient(45deg, #F4F6F9, #F4F6F9 12px, #EDF0F4 12px, #EDF0F4 24px); }
.rx .rx-rows { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.rx .rx-rows span { background: #F4F6F9; border-radius: 5px; padding: 6px; font-size: 12px; color: #B9C0C9; text-align: center; }
.rx .rx-footer { margin-top: auto; font-size: 14px; color: #C7CCD3; }

/* live library previews: the card's face is the render a pick produces today */
.lc-preview { position: relative; width: 100%; height: 200px; overflow: hidden; border-bottom: 1px solid var(--line); background: var(--wash); }
.lc-preview-canvas { width: 1600px; height: 900px; transform: scale(0.243); transform-origin: top left; pointer-events: none; }
.lc-preview-canvas .rp, .lc-preview-canvas .sl { height: 900px; }
.lc-thumbface { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.lc-kindtag { position: absolute; top: 8px; right: 8px; font-size: 10.5px; font-weight: 700; background: rgba(255,255,255,.92); color: var(--accent-deep); border-radius: 999px; padding: 2px 9px; }
.lc-inspo { position: absolute; right: 8px; bottom: 8px; width: 74px; height: 42px; object-fit: cover; border-radius: 6px; border: 2px solid #fff; box-shadow: 0 2px 8px rgba(0,0,0,.25); }

/* real images inside template frames + the editor's picker strip */
/* absolute fill: grid-centered tiles collapsed a 100%-height img to a sliver (pixels caught it,
   the DOM check lied) */
.rp-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
.rp-4d-tile, .rp-exec-frame, .rp-cover-art { position: relative; }
.img-picker { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin: 8px 0; }
.img-picker img { width: 100%; aspect-ratio: 16/10; object-fit: cover; border-radius: 6px; border: 1px solid var(--line); cursor: pointer; }
.img-picker img:hover { border-color: var(--accent); }

/* wells stay honest inside templates */
.rp .well { display: inline-block; background: #FDF6EC; border: 1px dashed #E8CFA0; color: #9A6B1F; font: 500 15px/1.5 var(--mono); padding: 2px 8px; border-radius: 4px; }
/* the exact-template canvas is class "rp xt", so this LATER rule was beating .xt's hover; and
   var(--a) is only defined by the blocks renderer, so on exact templates the outline collapsed to
   none: the hover affordance was painted and dead. Fallback colour + the I-beam fix both. */
.rp [data-slot]:hover { cursor: text; }   /* one grammar: the hover chrome is the only hover box */
.rp.xt [data-slot]:hover { cursor: text; }

/* ---- print/export ---- */
@media print {
  body { background: #fff; }
  .topbar, .rail, .thumbs, .toast, .briefbar, .inline-hint { display: none !important; }
  .studio { display: block; height: auto; }
  .canvas-wrap { padding: 0; display: block; overflow: visible; }
  /* one slide per page at the deck's own size, with no editor chrome and no rounded corner or
     drop shadow to print a grey band down the page edge */
  .print-slide { page-break-after: always; break-after: page; width: 1600px; height: 900px;
    border-radius: 0; box-shadow: none; transform: none; margin: 0; }
  .print-slide:last-child { page-break-after: auto; break-after: auto; }
  /* the well's invitation is an editing affordance: it does not belong on a presented slide */
  .print-slide .xt-empty, .print-slide .well, .print-slide .xt-ghost { display: none !important; }
  .print-slide .xt-image.xt-open { background: none !important; box-shadow: none !important; }
  .xt [data-slot]:hover { outline: none; }
}
@page { size: 1600px 900px; margin: 0; }

/* a chart is a live object in the deck, not a picture of one: it draws the deck's own series
   colours and it accepts the plan's numbers */
.xt .xt-chart { overflow: visible; }
.xt .xt-chart:not(.xt-open) svg { display: block; width: 100%; height: 100%; }
/* the drop zone's own plus mark is an ICON, not the chart: without the :not() above it inherited
   width:100%;height:100% and painted a plus the size of a quarter of the slide, straight across
   the two panels beneath it */
.xt .xt-chart.xt-open { overflow: hidden; }
.xt .xt-chart:not(.xt-own):not(.xt-open)::after { content: 'reference data'; position: absolute; right: 4px; top: 2px;
  font: 600 10px var(--disp); color: rgba(90,98,110,.6); background: rgba(255,255,255,.8); padding: 1px 6px; border-radius: 999px; }
.xt .xt-chart:hover { cursor: pointer; }  /* same grammar for charts: chrome, not a second outline */
@media print { .xt .xt-chart:not(.xt-own)::after { display: none; } }

/* THE ACTIVATION ROW: a channel list where the icon is decoration and the LABEL is the message.
   The glyph is aria-hidden in the markup, so a screen reader reads the channel once; strokes take
   currentColor, so the icon inherits the row's own text contrast rather than inventing a lighter
   grey of its own; and the label never renders under 12px, which is the craft gate's TINY bar.
   Nothing here may be the only carrier of meaning: with images off, the list still reads. */
.xt .xt-icons { overflow: hidden; display: flex; flex-direction: column; justify-content: flex-start; }
/* the LIST is centred in its column, the ROWS are left-aligned inside it: icons that do not share
   a left edge read as noise, and a ragged list under three centred rows reads as a mistake. Both
   are satisfied by centring the block and aligning within it. */
.xt .xt-act { list-style: none; margin: 0 auto; padding: 0; width: max-content; max-width: 100%;
  display: flex; flex-direction: column; gap: .85em; text-align: left; }
.xt .xt-act-row { display: flex; align-items: flex-start; gap: .62em; line-height: 1.22; }
.xt .xt-act-icon { width: 1.62em; height: 1.62em; flex: none; margin-top: -.05em; opacity: .92; }
.xt .xt-act-label { font-size: max(12px, 1em); font-weight: 400; }
/* inside a table cell the list is one row and must not add height to the row */
.xt .xt-table .xt-act { gap: .35em; margin: 0; width: auto; }
.xt .xt-table .xt-act-row { align-items: center; gap: .5em; }
.xt .xt-table .xt-act-icon { width: 1.7em; height: 1.7em; min-width: 16px; min-height: 16px; margin-top: 0; opacity: 1; }
.xt .xt-icons.xt-open, .xt .xt-chart.xt-open { border-radius: 8px; display: grid; place-items: center;
  background: rgba(128,136,148,.10); box-shadow: inset 0 0 0 1.5px rgba(128,136,148,.28); }
.xt .xt-icons.xt-open:hover, .xt .xt-chart.xt-open:hover { background: rgba(128,136,148,.18); box-shadow: inset 0 0 0 2px var(--dk-accent, #9B1432); cursor: pointer; }
.xt .xt-icons.xt-open:hover .xt-empty, .xt .xt-chart.xt-open:hover .xt-empty { color: var(--dk-accent, #9B1432); background: #fff; }
@media print { .xt .xt-icons.xt-open, .xt .xt-chart.xt-open { background: none !important; box-shadow: none !important; } }

/* THE SCRIM under light copy laid on a photograph. Soft on all four edges so it reads as the
   picture getting darker where the words are, never as a grey box someone dropped on top; the
   deepest part sits under the start of the lines, which is where the copy is densest. It carries
   data-chrome so the relaxer never treats it as a thing the copy has to clear.

   Two shapes were tried and both read as a panel. A radial gradient sized to its own box stops
   dead at the boundary at around .5 alpha and laid a grey rectangle across the shopper's head; a
   four-edge fade could not work either, because the copy here spans 97% of the picture's width and
   a horizontal wash has nowhere to fade to. What reads as photography is a bottom-weighted
   vignette across the whole picture, ramping in from above the first line. */
.xt .xt-scrim { position: absolute; pointer-events: none;
  background: linear-gradient(180deg, rgba(8,10,14,0) 0%, rgba(8,10,14,.34) 26%, rgba(8,10,14,.58) 52%, rgba(8,10,14,.66) 100%); }
/* a copy block that does NOT reach the picture's edge fades out below itself as well */
.xt .xt-scrim.xt-scrim-tail {
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 82%, rgba(0,0,0,0) 100%);
  mask-image: linear-gradient(180deg, #000 0%, #000 82%, rgba(0,0,0,0) 100%); }

/* the upload queue: a row that STAYS, because a toast is gone the moment you switch tabs and a
   1GB upload that dies silently is indistinguishable from one that worked */
#uploadq { display: grid; gap: 8px; margin: 8px 0 10px; }
.uq-row { border: 1px solid var(--edge, #DCE1E7); border-radius: 8px; padding: 8px 10px; background: #fff; }
.uq-top { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; font-size: 12px; }
.uq-name { font-weight: 600; color: var(--body, #20242B); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.uq-state { color: var(--muted, #8A919B); flex: none; }
.uq-bar { height: 4px; border-radius: 3px; background: #EEF1F5; margin-top: 6px; overflow: hidden; }
.uq-bar i { display: block; height: 100%; background: var(--dk-accent, #9B1432); transition: width .2s linear; }
.uq-done .uq-bar i { background: #1B6E45; }
.uq-failed { border-color: #C0392B; background: #FDF3F2; }
.uq-failed .uq-state { color: #C0392B; }
.uq-failed .uq-bar i { background: #C0392B; }
.uq-retry { margin-top: 8px; font-size: 12px; padding: 5px 10px; border-radius: 6px; border: 1px solid #C0392B; background: #fff; color: #C0392B; cursor: pointer; }
.uq-retry:hover { background: #C0392B; color: #fff; }

/* ---------------------------------------------------------------- the operator wall
   There are two bands and they already exist: the per-tenant team code, and CADMIN (operator).
   A team member is here to answer a brief and read a deck, so the instrument surfaces (gate
   measurements, the learned-rule table, the raw event log, the ingestion report) are hidden from
   them entirely rather than merely de-emphasised. Nothing about the deck itself is gated: they can
   edit every slot on the canvas, generate, ask for changes and export.
   The wall is a CSS + render gate on the SAME session bands, not a new credential. */
body:not([data-role="operator"]) [data-admin] { display: none !important; }
body[data-role="operator"] [data-admin] { position: relative; }
body[data-role="operator"] .tabs button[data-admin]::after {
  content: ""; position: absolute; top: 4px; right: 4px; width: 4px; height: 4px;
  border-radius: 50%; background: var(--dk-accent, #C8102E);
}
.railnote { font-size: 12px; color: var(--muted, #6b7280); margin: 0 0 10px; }
.askbox { display: flex; flex-direction: column; gap: 8px; }
.askbox textarea { min-height: 92px; resize: vertical; font: inherit; }
.askscope { display: flex; gap: 6px; }
.askscope button { flex: 1; }
.askscope button.on { background: var(--dk-accent, #C8102E); color: #fff; border-color: transparent; }
.diffrow { border-left: 3px solid var(--dk-accent, #C8102E); padding: 8px 10px; margin: 8px 0; background: rgba(0,0,0,.03); }
.diffrow .was { text-decoration: line-through; opacity: .6; }
.changed-row { padding: 7px 0; border-bottom: 1px solid rgba(0,0,0,.07); font-size: 12.5px; }
.changed-row b { font-weight: 600; }
.changed-row.jump { cursor: pointer; border-radius: 6px; padding-left: 4px; padding-right: 4px; }
.changed-row.jump:hover { background: var(--wash); }
.chday { margin: 12px 0 2px; font-size: 11px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; }
.chwhen { color: var(--muted); font-size: 11px; }
.brandfact { padding: 8px 0; border-bottom: 1px solid rgba(0,0,0,.07); font-size: 12.5px; }
.brandfact .src { color: var(--muted, #6b7280); font-size: 11px; }
.deckgroup { margin-bottom: 14px; }
.deckgroup > h4 { font-size: 10.5px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--muted, #6b7280); margin: 0 0 4px; font-weight: 600; }
.deckgroup .worktype { font-size: 10.5px; color: var(--muted, #6b7280); margin: 6px 0 2px 2px; }

/* ---- the chrome review grid (template-image approvals; operator only) ---- */
.chrome-head h1 { font-size: 24px; margin: 0 0 6px; }
.chrome-head .note { max-width: 760px; line-height: 1.55; }
.chrome-mode { display: flex; align-items: center; gap: 12px; margin: 14px 0 10px; font-weight: 600; }
.chrome-filters { display: flex; gap: 8px; margin: 0 0 18px; }
.chrome-filters button.on { border-color: var(--accent); color: var(--accent); font-weight: 600; }
.chrome-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }
.chrome-card { background: var(--paper); border: 1px solid var(--line); border-radius: 12px; padding: 12px; display: flex; flex-direction: column; gap: 8px; }
.chrome-card.approved { border-color: var(--good); }
.chrome-card.rejected { border-color: var(--bad); opacity: .75; }
.chrome-imgbox { height: 120px; display: grid; place-items: center; background:
  repeating-conic-gradient(#f0f0f0 0% 25%, #fafafa 0% 50%) 0 0/16px 16px; border-radius: 8px; overflow: hidden; }
.chrome-imgbox img { max-width: 100%; max-height: 100%; object-fit: contain; }
.chrome-meta { display: flex; justify-content: space-between; gap: 8px; font-size: 12px; color: var(--muted); }
.chrome-roles { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chrome-label { font: inherit; font-size: 13px; border: 1px solid var(--line); border-radius: 6px; padding: 6px 8px; }
.chrome-actions { display: flex; gap: 8px; }
.chrome-actions button { flex: 1; }
.chrome-actions button.danger { background: var(--bad); border-color: var(--bad); color: #fff; }

/* ---- the focused editor pane + slide tools (the rail is NOT a mirror of the slide) ---- */
#editor-pane { margin-bottom: 10px; }
#editor-pane .editor { margin-bottom: 0; box-shadow: 0 6px 22px rgba(16, 40, 80, .10); }
#slide-tools { margin-bottom: 10px; }
/* WRAP, NEVER CLIP. 13 buttons in one non-wrapping flex line inside a ~300px rail cut every
   tool after "Visual options" out of view: Duplicate, Copy, Paste, Reset and Remove existed in
   the DOM and were unreachable by a person (Adrian, 2026-08-26: "I'm not able to copy whole
   slides still weirdly"). */
.stools-row { display: flex; flex-wrap: wrap; gap: 6px; }
.stools-row button { font-size: 12.5px; padding: 6px 10px; }

/* ---- rail pick C: search, filter chips, recent + fold ---- */
#rail-q { margin-bottom: 8px; }
.rail-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 10px; }
.rail-chip { font-size: 12px; padding: 3px 10px; border-radius: 999px; }
.rail-chip.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.rail-chip.work { border-style: dashed; }
.rail-sub { font-size: 12px; color: var(--muted); font-weight: 600; margin: 4px 0 6px; }
.rail-all summary { color: var(--accent); font-size: 13.5px; cursor: pointer; padding: 8px 2px; }
.rail-all { margin-top: 6px; }

/* the moved thumbnail says so itself */
@keyframes thumb-flash { 0%, 100% { box-shadow: none; } 30% { box-shadow: 0 0 0 3px var(--accent); } 60% { box-shadow: 0 0 0 3px rgba(31,78,140,.35); } }
.thumb.flash { animation: thumb-flash 1.2s ease; }

/* a LIFTED copy block sits at the picture's TOP, so its scrim ramps the other way: darkest where
   the first line is, fading out below (the eyebrow was measuring 2.1:1 in the old ramp's weakest
   zone while the headline below it sat in the dark part) */
.xt .xt-scrim.xt-scrim-flip {
  background: linear-gradient(180deg, rgba(8,10,14,.66) 0%, rgba(8,10,14,.58) 48%, rgba(8,10,14,.34) 74%, rgba(8,10,14,0) 100%); }
.xt .xt-scrim.xt-scrim-flip.xt-scrim-tail {
  -webkit-mask-image: none; mask-image: none; }

/* ---- the briefing bar: brief in place, the handover's loop, cover-email flags ---- */
.briefbar { display: flex; align-items: center; gap: 12px; padding: 6px 16px; background: var(--wash);
  border-bottom: 1px solid var(--line); position: sticky; top: 53px; z-index: 39; }
.briefbar #bb-brief { display: flex; align-items: baseline; gap: 8px; max-width: 40%; overflow: hidden;
  border: none; background: none; padding: 4px 2px; text-align: left; }
.briefbar #bb-brief b { font-size: 12.5px; color: var(--muted); }
.briefbar #bb-brief span { font-size: 13px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.briefbar #bb-brief:hover span { color: var(--accent); }
.bb-stages { display: flex; gap: 0; margin-left: auto; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.bb-stages button { border: none; border-radius: 0; font-size: 12px; padding: 5px 10px; background: var(--paper); color: var(--body); }
.bb-stages button.on { background: var(--accent); color: #fff; }
.briefbar #bb-flags { font-size: 12.5px; border-radius: 999px; padding: 4px 12px; }
.briefbar #bb-flags.hot { border-color: #C77700; color: #8a5200; background: #FFF6E8; }
body.has-brief .studio { height: calc(100vh - 89px); }
.ov-narrow { width: min(680px, 94vw); }
.ov-narrow #meta-text { min-height: 300px; resize: vertical; font-size: 14px; line-height: 1.5; margin: 12px 0; }
.ov-foot { display: flex; justify-content: flex-end; }

/* ---- direct manipulation: selection, handles, guides, drag ghosts ---- */
/* PPT/Canva selection grammar: a 1.5px frame, small round corner grips, pill edge grips.
   The chrome wraps the PAINTED text (drag.js measures line boxes), never the template's box.
   FITTS'S LAW (Adrian 2026-08-19: "the things to drag are too small to change it easily"):
   the PAINTED grip stays small; the HIT AREA is an 18px invisible square around it, and the
   whole selection outline is a grab band that MOVES the element, exactly how PPT's frame works. */
.drag-select { position: absolute; pointer-events: none; outline: 1.5px solid var(--accent); outline-offset: 1px; z-index: 60; }
.drag-select .dh { position: absolute; width: 18px; height: 18px; background: transparent;
  pointer-events: auto; z-index: 62; display: grid; place-items: center; }
.drag-select .dh::after { content: ''; display: block; background: #fff; border: 1.5px solid var(--accent);
  box-shadow: 0 1px 2px rgba(0,0,0,.25); }
/* corners: 7px painted circles on 18px targets */
.dh-nw::after, .dh-ne::after, .dh-sw::after, .dh-se::after { width: 7px; height: 7px; border-radius: 50%; }
.dh-nw { left: -9px; top: -9px; cursor: nwse-resize; }
.dh-ne { right: -9px; top: -9px; cursor: nesw-resize; }
.dh-sw { left: -9px; bottom: -9px; cursor: nesw-resize; }
.dh-se { right: -9px; bottom: -9px; cursor: nwse-resize; }
/* edges: painted pills, one axis each (Canva stretch grammar), same fat targets */
.dh-n::after, .dh-s::after { width: 14px; height: 5px; border-radius: 3px; }
.dh-e::after, .dh-w::after { width: 5px; height: 14px; border-radius: 3px; }
.dh-n { top: -9px; left: calc(50% - 9px); cursor: ns-resize; }
.dh-s { bottom: -9px; left: calc(50% - 9px); cursor: ns-resize; }
.dh-e { right: -9px; top: calc(50% - 9px); cursor: ew-resize; }
.dh-w { left: -9px; top: calc(50% - 9px); cursor: ew-resize; }
/* the frame bands: 14px invisible strips along the outline; grab anywhere on the frame to move */
.drag-select .db { position: absolute; pointer-events: auto; z-index: 61; cursor: move; }
.db-t { left: 0; right: 0; top: -7px; height: 14px; }
.db-b { left: 0; right: 0; bottom: -7px; height: 14px; }
.db-l { top: 0; bottom: 0; left: -7px; width: 14px; }
.db-r { top: 0; bottom: 0; right: -7px; width: 14px; }
/* the context toolbar travels to the selection (Canva/PPT: controls at the work, eye never leaves) */
/* display:flex OVERRIDES the hidden attribute's UA display:none, so a "hidden" toolbar kept
   painting invisibly over the canvas and swallowing the pointer wherever it last sat. Found by
   the studio drive 2026-08-21: hover on the slot under it could never land. */
.ctx-toolbar[hidden] { display: none; }
.ctx-toolbar { position: absolute; z-index: 72; display: flex; align-items: center; gap: 2px;
  background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 3px 4px;
  box-shadow: 0 4px 14px rgba(0,0,0,.18); white-space: nowrap; }
.ctx-toolbar button { border: 0; background: transparent; padding: 5px 8px; border-radius: 6px;
  font-size: 12px; cursor: pointer; color: var(--ink); line-height: 1; }
.ctx-toolbar button:hover { background: var(--wash); }
.ctx-toolbar .sep { width: 1px; align-self: stretch; margin: 2px 2px; background: var(--line); }
.ctx-toolbar .fs-val { font-size: 11px; color: var(--muted); min-width: 34px; text-align: center; }
/* the right-click menu: PPT's per-selection menu, vertical */
.ctx-menu { position: fixed; z-index: 90; min-width: 190px; background: #fff; border: 1px solid var(--line);
  border-radius: 8px; padding: 4px; box-shadow: 0 6px 20px rgba(0,0,0,.2); }
.ctx-menu button { display: block; width: 100%; text-align: left; border: 0; background: transparent;
  padding: 7px 10px; border-radius: 6px; font-size: 13px; cursor: pointer; color: var(--ink); }
.ctx-menu button:hover { background: var(--wash); }
.ctx-menu .sep { height: 1px; margin: 4px 6px; background: var(--line); }
.drag-guides { position: absolute; inset: 0; pointer-events: none; z-index: 59; }
.drag-guides .dg { position: absolute; background: #E0359A; }
.drag-guides .dg-v { top: 0; bottom: 0; width: 1px; }
.drag-guides .dg-h { left: 0; right: 0; height: 1px; }
.xt [data-slot].dragging { cursor: grabbing; opacity: .92; }
.thumb-ghost { opacity: .35; }
.thumb-drag { box-shadow: 0 10px 24px rgba(16,40,80,.25); }
/* THE MEASUREMENT CHIP, live while a box is being moved or resized. It rides with the box rather
   than the cursor, because it is describing that rectangle. It exists only for the length of a
   gesture (removed on drop, on Escape and on pointercancel), and it is excluded from print and
   from every screenshot path alongside the rest of the drag chrome, so it can never reach an
   exported slide. */
.drag-measure {
  position: absolute; z-index: 62; pointer-events: none; white-space: nowrap;
  display: flex; align-items: center; gap: 8px;
  background: var(--ink, #1b1b1f); color: #fff; border-radius: 6px;
  padding: 5px 8px; font-size: 11px; line-height: 1; font-variant-numeric: tabular-nums;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .28);
}
.drag-measure b { font-weight: 600; display: flex; align-items: center; }
.drag-measure .dm-sep { display: inline-block; width: 8px; }
.drag-measure em { font-style: normal; opacity: .62; }
.drag-measure .dm-gaps { display: flex; gap: 7px; opacity: .8; border-left: 1px solid rgba(255,255,255,.22); padding-left: 8px; }
.drag-measure .dm-gaps i { font-style: normal; }
@media print { .drag-select, .drag-guides, .drag-measure { display: none !important; } }

/* what a person placed stays visible above template furniture */
.xt .xt-hand { z-index: 5; }
/* the files overlay body scrolls; the dropzone stays put at the top */
.files-body { padding: 14px 20px 20px; overflow: auto; max-height: 70vh; }
/* the deck chat: a quiet thread, me right, the deck's strategist left */
/* overflow-wrap: a snake_case slot name in a card label ("footer_attribution_disclaimer_text") is
   ONE word to the line breaker, because underscores make no break points, so a long one ran out of
   the card and clipped at this scroll container's edge instead of wrapping (Adrian, 2026-08-26).
   Inherited, so every bubble, diffrow and note in the thread is covered. */
.chat-thread { max-height: 46vh; overflow: auto; display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; overflow-wrap: anywhere; }
.chat-me { align-self: flex-end; max-width: 90%; background: var(--accent); color: #fff; border-radius: 10px 10px 3px 10px; padding: 7px 10px; font-size: 12.5px; line-height: 1.45; white-space: pre-wrap; }
.chat-ai { align-self: flex-start; max-width: 95%; background: var(--wash); border-radius: 10px 10px 10px 3px; padding: 8px 10px; font-size: 12.5px; line-height: 1.5; white-space: pre-wrap; }
.chat-ai .diffrow { background: #fff; margin-top: 8px; }
.chat-brief { display: block; margin-top: 8px; border: 1px dashed var(--accent); background: #fff; color: var(--accent); border-radius: 8px; padding: 6px 10px; font-size: 12px; cursor: pointer; text-align: left; }
.chat-brief:hover { background: #F2F7FE; }
/* the guided tour: one spotlight, a card beside it, the rest dimmed */
.tour-dim { position: fixed; inset: 0; background: transparent; z-index: 95; } /* click-catcher; the ring's shadow does the dimming */
.tour-ring { position: fixed; z-index: 96; border: 2px solid var(--accent); border-radius: 10px;
  box-shadow: 0 0 0 4000px rgba(16, 22, 32, .45), 0 0 18px rgba(31, 78, 140, .6); pointer-events: none; }
.tour-card { position: fixed; z-index: 97; width: 300px; background: #fff; border-radius: 10px;
  padding: 14px 16px; box-shadow: 0 10px 30px rgba(0,0,0,.3); }
.tour-card h4 { margin: 0 0 6px; font-size: 14.5px; }
.tour-card p { margin: 0 0 10px; font-size: 12.5px; line-height: 1.5; color: var(--ink); }
.tour-foot { display: flex; align-items: center; gap: 8px; }
.tour-foot .note { flex: 1; font-size: 11px; }
.tour-foot button { font-size: 12px; padding: 5px 12px; }
/* a slot a What-changed row points at lights up long enough to find */
@keyframes slot-flash { 0% { outline: 3px solid var(--accent); outline-offset: 2px; } 100% { outline: 3px solid transparent; outline-offset: 2px; } }
.xt [data-slot].slot-flash { animation: slot-flash 1.6s ease; }
.fgroup h5 { margin: 10px 0 4px; font-size: 11px; color: var(--muted); font-weight: 600; letter-spacing: .02em; text-transform: capitalize; }
.fgen summary { color: var(--accent); font-size: 13px; cursor: pointer; padding: 8px 2px; }
.fgen-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; padding: 6px 0; }
.fgen-grid img { width: 100%; aspect-ratio: 16/10; object-fit: cover; border-radius: 4px; border: 1px solid var(--line); }
.vsug-visual .vsug-cap { font-size: 12.5px; line-height: 1.45; margin: 6px 0 8px; }

/* ---- the processing view under an upload row: what was READ, revealed at reading pace ---- */
.uq-peek { margin: 8px 0 2px; border-left: 2px solid var(--accent, #9B1432); padding: 4px 0 4px 12px; }
.uq-peek.failed { border-left-color: #C62828; }
.uq-peekhead { font-size: 12.5px; color: var(--muted, #8a93a0); margin-bottom: 4px; }
.uq-peek.reading .uq-peekhead::after { content: ''; display: inline-block; width: 10px; text-align: left;
  animation: uq-dots 1.2s steps(4) infinite; }
@keyframes uq-dots { 0% { content: ''; } 25% { content: '.'; } 50% { content: '..'; } 75% { content: '...'; } }
.uq-swatch { display: inline-block; width: 10px; height: 10px; border-radius: 2px; vertical-align: -1px; }
.uq-peekrow { display: grid; grid-template-columns: 2em 1fr auto; gap: 8px; align-items: baseline;
  font-size: 12.5px; line-height: 1.5; animation: uq-in .18s ease-out; }
@keyframes uq-in { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
.uq-pn { color: var(--muted, #8a93a0); font-variant-numeric: tabular-nums; }
.uq-pt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.uq-pm { color: var(--muted, #8a93a0); white-space: nowrap; font-size: 11.5px; }

/* the drop target reads as a place files GO: taller, dashed, and alive on hover */
#dropzone { border: 2px dashed var(--edge, #3a4250); border-radius: 12px; padding: 26px 18px;
  text-align: center; cursor: pointer; transition: border-color .15s, background .15s; }
#dropzone.hot { border-color: var(--accent, #9B1432); background: rgba(155, 20, 50, .06); }

/* ---- the inference card: the machine's guess at WHY you changed a line, yours to correct ---- */
.infer-card { border: 1px solid var(--edge, #DCE1E7); border-left: 3px solid var(--dk-accent, #9B1432);
  border-radius: 10px; padding: 12px 14px; margin: 0 0 12px; background: #fff;
  animation: uq-in .2s ease-out; }
.ic-head { font-weight: 700; font-size: 13px; margin-bottom: 6px; }
.ic-inf { font-size: 13px; line-height: 1.5; margin: 0 0 8px; }
.ic-rulelab { font-size: 11.5px; color: var(--muted, #8a93a0); margin-bottom: 4px; }
.ic-rule { width: 100%; font: inherit; font-size: 12.5px; line-height: 1.45; border: 1px solid var(--edge, #DCE1E7);
  border-radius: 6px; padding: 6px 8px; resize: vertical; }
.ic-acts { display: flex; gap: 8px; align-items: center; margin-top: 8px; flex-wrap: wrap; }
.ic-acts button { font-size: 12px; padding: 5px 10px; border-radius: 7px; border: 1px solid var(--edge, #DCE1E7);
  background: #fff; cursor: pointer; }
.ic-accept { background: var(--dk-accent, #9B1432) !important; color: #fff; border-color: transparent !important; }
.ic-note { font-size: 11px; color: var(--muted, #8a93a0); }


/* option A hover chrome: the same painted box the selection will use, one shade lighter */
.drag-hover { position: absolute; pointer-events: none; outline: 1px solid #9aa3ad; outline-offset: 1px; z-index: 55; }

/* ---------------------------------------------------------------- multi-select and group transform
   The group chrome borrows the single-selection grammar (accent outline, white round grips) so a
   person reads one selection language on the canvas, not two. moveable paints its own control box;
   these rules only recolour it to the accent. */
/* TOP of the canvas, not the bottom: the coach-mark toast is bottom-centred and the two
   collided into one unreadable strip on the first drive. */
#group-badge {
  position: absolute; left: 50%; transform: translateX(-50%); top: 10px; z-index: 80;
  background: var(--ink, #1b1b1f); color: #fff; font-size: 13px; line-height: 1;
  padding: 9px 14px; border-radius: 999px; pointer-events: none; white-space: nowrap;
  display: flex; align-items: center; gap: 10px;
}
/* the pill itself stays click-through, so it can never swallow a marquee started under it; only
   the buttons take the pointer */
#group-badge .gb-acts { display: flex; gap: 4px; pointer-events: auto; }
#group-badge .gb-acts button {
  font: inherit; font-size: 12px; line-height: 1; color: #fff; cursor: pointer;
  background: rgba(255, 255, 255, 0.14); border: 0; border-radius: 999px; padding: 6px 9px;
}
#group-badge .gb-acts button:hover { background: var(--accent, #E01A22); }
/* the format painter: a pressed toolbar state, a loaded-brush cursor, and the same top badge
   grammar as a group selection (bottom-centre is the coach mark's spot) */
.ctx-toolbar button.on { background: var(--accent); color: #fff; }
.ctx-toolbar button.on:hover { background: var(--accent-deep, var(--accent)); }
#canvas-wrap.painting [data-slot] { cursor: copy; }
#painter-badge {
  position: absolute; left: 50%; transform: translateX(-50%); top: 10px; z-index: 81;
  background: var(--accent); color: #fff; font-size: 13px; line-height: 1;
  padding: 9px 14px; border-radius: 999px; pointer-events: none; white-space: nowrap;
}
.moveable-control-box .moveable-line { background: var(--accent) !important; }
.moveable-control-box .moveable-control {
  background: #fff !important; border: 1.5px solid var(--accent) !important;
  width: 9px !important; height: 9px !important; margin-top: -5px !important; margin-left: -5px !important;
}
.moveable-control-box .moveable-area { cursor: move; }

/* the ask rail's second verb, and the one action that cannot be undone by an inverse */
.diffrow button.ghost { background: transparent; color: var(--muted); border: 1px solid var(--line); }
.diffrow button.ghost:hover:not(:disabled) { color: var(--body); border-color: var(--body); }
.diffrow.danger { border-left: 3px solid var(--accent); padding-left: 9px; }

/* the room has moved on: quiet, dismissible, never reloads by itself */
.newbuild { position: fixed; left: 50%; transform: translateX(-50%); bottom: 18px; z-index: 9999;
  display: flex; align-items: center; gap: 10px; padding: 10px 12px 10px 16px; border-radius: 999px;
  background: var(--body, #20242B); color: #fff; box-shadow: 0 8px 24px rgba(16,20,26,.28); font-size: 13px; }
.newbuild button { border-radius: 999px; padding: 6px 14px; font-size: 12.5px; }
.newbuild button.ghost { background: transparent; color: rgba(255,255,255,.75); border: 1px solid rgba(255,255,255,.35); }

/* ---------------------------------------------------------------- Sources view
   WHERE EVERY ELEMENT CAME FROM, painted ON the slide rather than listed beside it. Adrian on the
   receipts panel, 2026-09-04: "Don't feel like this is doing enough to change the slide picked or
   how somehting ois picekd visuallly differenelyt" - a log nobody acts on. So this is a lever: the
   red state is a box waiting for a number, and clicking the counter jumps to it.
   Off by default and purely additive: nothing here paints unless .show-sources is on. */
/* THE LENS MUST NOT MOVE THE THING IT LOOKS AT. This rule started life as
   `.show-sources [data-src] { position: relative }` so the corner tag had something to anchor to,
   and it RELAID OUT THE WHOLE SLIDE: every shape on the canvas carries an inline top/left, and
   under position:relative those stop being placement and become an OFFSET from normal flow, so a
   box measured at 24.67% down the slide painted at 91.8%. Caught by reading the screenshot - the
   diagnosis slide came back almost empty - after three measurements had said the geometry was
   fine, because the geometry WAS fine. Shapes are already absolutely positioned and anchor a
   ::after on their own; only a table cell is static, and relative on a cell with no offsets of its
   own moves nothing. */
.show-sources td[data-src] { position: relative; }
/* THE TAG SITS TOP-RIGHT AND MOSTLY WAITS TO BE ASKED. Anchored top-left it covered the first few
   characters of every line it labelled, which is the lens obscuring the thing it exists to explain.
   Left-aligned copy starts at the left edge and rarely reaches the right one, so the corner swaps;
   and only the state that needs ACTION ("no source") shouts by default. The rest answer on hover,
   so the view stays a lever rather than becoming wallpaper. */
.show-sources [data-src]::after {
  content: attr(data-src); position: absolute; top: -1px; right: -1px; z-index: 40;
  font: 600 9px/1.35 ui-sans-serif, system-ui, sans-serif; letter-spacing: .04em; text-transform: uppercase;
  padding: 1px 5px; border-radius: 0 0 5px 0; color: #fff; pointer-events: none; opacity: .92;
}
.show-sources [data-src="person"]  { outline: 1.5px solid #1B7F4B; outline-offset: -1px; }
.show-sources [data-src="draft"]   { outline: 1.5px solid #B26A00; outline-offset: -1px; }
.show-sources [data-src="copied"]  { outline: 1.5px solid #6B4FA8; outline-offset: -1px; }
.show-sources [data-src="template"]{ outline: 1.5px dashed #9AA3AE; outline-offset: -1px; }
.show-sources [data-src="empty"]   { outline: 1.5px dotted #9AA3AE; outline-offset: -1px; }
.show-sources [data-src="none"]    { outline: 2px solid #C62828; outline-offset: -1px; background: rgba(198,40,40,.07); }
.show-sources [data-src="person"]::after  { background: #1B7F4B; content: "you"; }
.show-sources [data-src="draft"]::after   { background: #B26A00; content: "drafted"; }
.show-sources [data-src="copied"]::after  { background: #6B4FA8; content: "copied"; }
.show-sources [data-src="template"]::after{ background: #9AA3AE; content: "template"; }
.show-sources [data-src="empty"]::after   { background: #C3C9D1; content: "empty"; }
.show-sources [data-src="none"]::after    { background: #C62828; content: "no source"; opacity: .95; }
/* Only "no source" shouts: it is the one a person has to do something about. Every other tag waits
   for the pointer, so a slide under the lens still reads as the slide. */
.show-sources [data-src]:not([data-src="none"])::after { opacity: 0; transition: opacity .12s; }
.show-sources [data-src]:not([data-src="none"]):hover::after { opacity: .92; }

.srcbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 7px 12px; border-bottom: 1px solid #E3E7EC; background: #FBFCFD; font-size: 12px; }
.srcbar b { font-weight: 600; }
.srcbar .sb { display: inline-flex; align-items: center; gap: 5px; }
.srcbar .sb i { width: 9px; height: 9px; border-radius: 2px; display: inline-block; font-style: normal; }
.srcbar .sb-person i { background: #1B7F4B; } .srcbar .sb-draft i { background: #B26A00; }
.srcbar .sb-copied i { background: #6B4FA8; } .srcbar .sb-template i { background: #9AA3AE; }
.srcbar .sb-none i { background: #C62828; }
.srcbar button.jump { border-color: #C62828; color: #C62828; padding: 3px 9px; font-size: 11.5px; }
.srcbar button.jump:hover { background: #C62828; color: #fff; }
.srcbar .note { color: #6B7480; }

/* A DATA TABLE NEEDS ITS COLUMN NAMES TO SURVIVE BEING FILLED IN. They used to live in the
   inputs' placeholders, which vanish the moment somebody types - so from row two on, a chart's
   numbers were entered against nothing. */
.row-f { display: block; }
.row-f > span { display: block; font-size: 10px; font-weight: 600; letter-spacing: .03em;
  text-transform: uppercase; color: #6B7480; margin: 0 0 2px 2px; }
.row-f > input { width: 100%; box-sizing: border-box; }

/* the wireframe's eyebrow line: a real named field, not a debug tag */
.rx .rx-eyebrow { margin: 0 0 4px; font-size: 15px; color: #B9C0C9; }

/* ---- WHAT IS THIS FILE FOR (the upload declaration, 2026-09-05) ------------------------------
   Adrian: "there's been confusion as to what has been uploaded - maybe we need to be clear when we
   upload as to what this is as well." The role a person declares outranks the classifier's guess,
   so it reads first in the row and an undeclared file says so rather than passing as sorted. */
.filelist .frole { font-size: 10.5px; border-radius: 3px; padding: 1px 7px; white-space: nowrap;
  font-weight: 600; letter-spacing: .03em; background: #E7F0EA; color: var(--good); }
.filelist .frole.r-template,
.filelist .frole.r-reference { background: var(--well); color: #8A6212; }
.filelist .frole.r-asset { background: var(--wash); color: var(--muted); }
.filelist .frole.undeclared { background: #FBEAEA; color: var(--bad); font-weight: 500; }

.declare-overlay { position: fixed; inset: 0; background: rgba(32,36,43,.5); z-index: 900;
  display: grid; place-items: center; padding: 24px; }
.declare-card { background: var(--paper); border-radius: 10px; padding: 22px 24px 18px;
  width: min(560px, 100%); max-height: 90vh; overflow: auto;
  box-shadow: 0 24px 60px -18px rgba(32,36,43,.45); font-family: var(--disp); }
.declare-card h3 { margin: 0 0 4px; font-size: 18px; color: var(--ink); }
.declare-files { margin: 0 0 16px; font-family: var(--mono); font-size: 11.5px; color: var(--muted);
  word-break: break-all; }
.declare-roles { display: grid; gap: 7px; margin-bottom: 16px; }
.declare-roles button { display: block; width: 100%; text-align: left; cursor: pointer;
  border: 1px solid var(--line); border-radius: 7px; padding: 9px 12px; background: var(--paper);
  font: inherit; transition: .12s; }
.declare-roles button:hover { border-color: var(--accent); background: var(--wash); }
.declare-roles button b { display: block; font-size: 14px; color: var(--ink); }
.declare-roles button span { display: block; font-size: 12px; color: var(--body); margin-top: 1px; }
.declare-card label { display: block; font-size: 12px; color: var(--body); margin-bottom: 9px; }
.declare-card input { display: block; width: 100%; margin-top: 3px; font: inherit; font-size: 13px;
  padding: 7px 10px; border: 1px solid var(--line); border-radius: 6px; color: var(--ink); }
.declare-actions { display: flex; justify-content: flex-end; margin-top: 4px; }
.declare-card .declare-skip { font: inherit; font-size: 12.5px; cursor: pointer; background: none;
  border: 0; color: var(--muted); text-decoration: underline; padding: 4px 2px; }
.declare-why { margin: 10px 0 0; font-size: 11.5px; color: var(--muted); line-height: 1.45; }
