
/* GRID, not a column: the ribbon spans the whole window, as it does in
   PowerPoint, and the thumbnail column starts below it. That gives the
   controls the width they need without making either rail wider. */
.deck{position:fixed;inset:0;z-index:100;background:var(--chrome-0);
  color:var(--chrome-ink);
  display:grid;grid-template-columns:auto minmax(0,1fr);
  grid-template-rows:auto auto auto minmax(0,1fr);font-family:var(--sans);}
/* Row 1 is the document's own bar, and only ever ONE of these two is in
   it: .deck-qat while editing, .deck-top while presenting. Rows 2 and 3
   are the full-width tab strip and ribbon; thumbnails and stage share
   row 4. */
.deck-top,.deck-qat{grid-column:1/-1;grid-row:1;}
.deck>.deck-create{grid-column:1;grid-row:4;min-height:0;}
.deck>.rbn-tabs{grid-column:1/-1;grid-row:2;}
.deck>.edit-tools{grid-column:1/-1;grid-row:3;}
.deck-main{grid-column:2;grid-row:4;}
.deck[hidden]{display:none!important;}
/* T614: PARKED, NOT TAKEN DOWN. Back to the collection hides the editor
   with its deck still in hand, and display:none threw its whole style
   and layout away for Open as slides to build again. Parked it keeps
   them: hidden as before to the page's scripts ([hidden]); its contents
   skipped -- not styled, laid out, drawn, focused, found or read out --
   until it is shown (content-visibility); and its own empty box off the
   page, where nothing is hit. Nothing inherited changes either way
   (visibility, pointer-events), so showing it again restyles nothing
   underneath (64b-collection-slides.js cpsPark). */
.deck.parked[hidden]{display:grid!important;content-visibility:hidden;
  transform:translateX(-300vw);}
@media print{.deck.parked[hidden]{display:none!important;}}
.deck [hidden]{display:none!important;}
body.deck-open{overflow:hidden;}

.deck-top{display:flex;align-items:center;gap:9px;padding:10px 18px;
  border-bottom:1px solid var(--chrome-line);background:var(--chrome-1);
  flex:none;}
/* ---- T581: PRESENTING, THE BAR IS FOLDED AWAY -----------------------
   Out of the grid (so the slide has the whole height) and above the top
   edge until it is asked for: .top-peek while the pointer is at the top,
   .top-pinned from the Controls tab, or a control inside it focused.
   Only while presenting -- editing never shows .deck-top at all. */
.deck:not(.editing):not(.creating) .deck-top{position:absolute;left:0;
  right:0;top:0;z-index:40;transform:translateY(-100%);opacity:0;
  pointer-events:none;box-shadow:0 10px 30px #0007;
  transition:transform .18s ease,opacity .18s ease;}
.deck.top-peek:not(.editing):not(.creating) .deck-top,
.deck.top-pinned:not(.editing):not(.creating) .deck-top,
.deck:not(.editing):not(.creating) .deck-top:focus-within{transform:none;
  opacity:1;pointer-events:auto;}
/* the faint tab that is left: half-hidden until the pointer finds it,
   gone while the bar is out, and never in the editor */
.deck-top-handle{position:absolute;top:0;left:50%;translate:-50% 0;
  z-index:39;height:20px;padding:0 10px;display:flex;align-items:center;
  gap:5px;border:1px solid var(--chrome-line);border-top:none;
  border-radius:0 0 8px 8px;background:var(--chrome-1);
  color:var(--chrome-ink-2);font:10.5px var(--sans);cursor:pointer;
  opacity:.22;transition:opacity .15s ease;}
.deck-top-handle .bic{width:12px;height:12px;}
.deck-top-handle:hover,.deck-top-handle:focus-visible{opacity:1;}
.deck.editing .deck-top-handle,.deck.creating .deck-top-handle,
.deck.top-peek .deck-top-handle,.deck.top-pinned .deck-top-handle{
  display:none;}
@media print{.deck-top-handle{display:none!important;}}
/* The global presentations rail is inert behind a full-screen deck.  This
   drawer is owned by the deck instead, so it can take focus and remains
   usable while presenting; it lists what is open right now: the deck on
   screen and the open notebooks (T382). */
.deck-pres-drawer{position:absolute;z-index:35;left:14px;top:58px;
  width:min(340px,calc(100vw - 28px));max-height:calc(100vh - 74px);
  display:flex;flex-direction:column;gap:9px;padding:11px;
  overflow:auto;border:1px solid var(--chrome-line);border-radius:9px;
  background:var(--chrome-2);box-shadow:0 16px 48px #0008;}
.deck-pres-drawer[hidden]{display:none!important;}
.deck-pres-drawer-head{display:flex;align-items:center;gap:8px;
  padding-bottom:8px;border-bottom:1px solid var(--chrome-line);
  color:var(--chrome-ink);font:600 11px var(--mono);letter-spacing:.08em;
  text-transform:uppercase;}
.deck-pres-list{display:flex;flex-direction:column;gap:5px;min-height:24px;}
.deck-pres-row{display:flex;align-items:center;gap:8px;min-width:0;
  padding:8px 9px;border:1px solid var(--chrome-line);border-radius:6px;
  background:#ffffff05;color:var(--chrome-ink);cursor:pointer;text-align:left;
  font:12px var(--sans);}
.deck-pres-row:hover,.deck-pres-row.current{border-color:var(--cyan);
  background:color-mix(in srgb,var(--accent) 13%,transparent);}
.deck-pres-row .bic{width:14px;height:14px;flex:none;color:var(--cyan);}
.deck-pres-row-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
.deck-pres-row-kind{flex:none;color:var(--chrome-ink-2);
  font:9px var(--mono);letter-spacing:.07em;text-transform:uppercase;}
.deck-pres-empty{padding:8px;border:1px dashed var(--chrome-line);
  border-radius:6px;color:var(--chrome-ink-2);font:11px var(--sans);}
.deck-pres-doors{display:flex;gap:6px;}
.deck-pres-doors .dbtn{flex:1 1 auto;min-width:0;justify-content:center;
  white-space:nowrap;}
.deck-pres-row[disabled]{cursor:default;}
/* ---- T448: THE OPEN-ITEMS BAR, WHERE YOU PUT IT --------------------
   A pop-up is the rules above. A RAIL sits flush down the left and the
   stage gives up the width, the way it does for an inspector pane; a
   STRIP lies across the top and the stage gives up the height. Both
   drop the pop-up's shadow and its floating corners on the docked edge,
   because a docked thing is part of the frame, not over it.
   A docked bar is not positioned OVER the deck at all: it becomes a
   track of the deck's own grid, so the stage measures its own smaller
   width and sizeSlideTo fits the page to it -- the same trick that
   makes .deck.pane-open work, said in grid rather than in padding. */
.deck{--openbar-w:264px;--openbar-h:104px;}
.deck-pres-drawer.dock-left,.deck-pres-drawer.dock-top{
  position:static;max-height:none;border-radius:0;box-shadow:none;}
/* a rail: a third column, ahead of the slide column and the stage */
.deck.openbar-left{grid-template-columns:auto auto minmax(0,1fr);}
.deck.openbar-left>.deck-pres-drawer{grid-column:1;grid-row:4;
  width:var(--openbar-w);min-height:0;border-width:0 1px 0 0;}
.deck.openbar-left>.deck-create{grid-column:2;}
.deck.openbar-left>.rbn-tabs,.deck.openbar-left>.edit-tools{grid-column:1/-1;}
.deck.openbar-left>.deck-main{grid-column:3;}
/* a strip: a band of its own under the document bar, full width */
.deck.openbar-top{grid-template-rows:auto auto auto auto minmax(0,1fr);}
.deck.openbar-top>.deck-pres-drawer{grid-column:1/-1;grid-row:2;
  width:auto;max-height:var(--openbar-h);border-width:0 0 1px;}
.deck.openbar-top>.deck-create{grid-row:5;}
.deck.openbar-top>.rbn-tabs{grid-row:3;}
.deck.openbar-top>.edit-tools{grid-row:4;}
.deck.openbar-top>.deck-main{grid-row:5;}
/* across the top it is a ROW of rows, not a column: the head, the items
   and the doors flow left to right so the strip stays one band deep */
.deck-pres-drawer.dock-top{flex-direction:row;align-items:center;
  gap:12px;padding:7px 12px;overflow-x:auto;}
.deck-pres-drawer.dock-top .deck-pres-drawer-head{flex:none;
  padding:0 12px 0 0;border-bottom:0;border-right:1px solid var(--chrome-line);}
.deck-pres-drawer.dock-top .deck-pres-list{flex-direction:row;flex-wrap:wrap;
  align-items:center;gap:6px;flex:1;min-width:0;}
.deck-pres-drawer.dock-top .deck-pres-row{width:auto;max-width:260px;
  padding:5px 8px;}
.deck-pres-drawer.dock-top .deck-pres-sec{margin:0;}
.deck-pres-drawer.dock-top .deck-pres-doors{flex:none;}
/* a section heading inside the bar, so three lists read as three */
.deck-pres-sec{margin:5px 0 0;color:var(--chrome-ink-2);
  font:600 9px var(--mono);letter-spacing:.1em;text-transform:uppercase;}
/* the verbs on a row. They are quiet until the row is under the pointer,
   because "very little controls" must not become a wall of icons -- and
   they FLOAT over the row's right end rather than taking a column of it,
   so five icons do not clip the name down to "presentat…" on every row
   whether you are pointing at it or not. */
.deck-pres-row{position:relative;}
.deck-pres-acts{display:flex;gap:2px;flex:none;opacity:0;
  position:absolute;right:5px;top:50%;transform:translateY(-50%);
  padding-left:14px;border-radius:5px;
  background:linear-gradient(90deg,transparent,var(--chrome-2) 14px);
  transition:opacity .12s;}
.deck-pres-row:hover .deck-pres-acts,
.deck-pres-row:focus-within .deck-pres-acts,
.deck-pres-acts:has(>.deck-pres-act.on){opacity:1;}
.deck-pres-act{display:inline-flex;align-items:center;justify-content:center;
  width:21px;height:21px;padding:0;border:1px solid transparent;
  border-radius:5px;background:none;color:var(--chrome-ink-2);
  cursor:pointer;}
.deck-pres-act:hover{border-color:var(--chrome-line);
  background:color-mix(in srgb,var(--accent) 22%,transparent);
  color:var(--chrome-ink);}
.deck-pres-act.on{color:var(--cyan);opacity:1;}
.deck-pres-act .bic{width:12px;height:12px;}
.deck-pres-ver .deck-pres-row-name{color:var(--chrome-ink-2);}
.deck-brand{font-family:var(--mono);font-size:10.5px;letter-spacing:.22em;
  text-transform:uppercase;color:var(--cyan);}
.deck-status{font-family:var(--sans);font-size:11.5px;padding:0 10px;
  height:30px;box-sizing:border-box;display:inline-flex;align-items:center;
  border-radius:15px;background:var(--surface-active);
  color:var(--chrome-ink-2);letter-spacing:0;
  white-space:nowrap;}
.deck-status.draft{background:color-mix(in srgb,var(--warning) 15%,transparent);
  color:var(--warning);}
.deck-status.saved{background:color-mix(in srgb,var(--success) 15%,transparent);
  color:var(--success);}
/* T526: "unsaved — saving…" with the autosave armed is the ordinary
   state after every edit; it reads quietly, not as a warning */
.deck-status.draft.pending{background:var(--surface-active);
  color:var(--chrome-ink-2);}
.deck-status:empty{display:none;}
.deck-spring{flex:1;}
/* T679: the sans, like .toggle (core.css) */
.dbtn{font-family:var(--sans);font-size:12px;
  border:1px solid var(--btn-border,#ffffff22);
  background:var(--btn-bg,#ffffff0a);color:var(--btn-ink,#cdd9e3);
  padding:6px 11px;border-radius:6px;
  cursor:pointer;
  /* what changes on hover, press and disable -- not `all`
     (2026-10-09, speed): `all` has every restyle of a button
     compare every animatable property, and eases any geometry a
     class changes (T487 below met that in the ribbon) */
  transition:color .15s,background-color .15s,border-color .15s,
    box-shadow .15s,opacity .15s;}
.dbtn:hover{border-color:var(--cyan);color:var(--chrome-ink);}
/* the way out of a modal state: coral so it reads as "stop", but an
   outline rather than a fill, because it undoes rather than commits */
.dbtn.dbtn-warn{border-color:color-mix(in srgb,var(--danger) 45%,transparent);
  color:var(--danger);}
.dbtn.dbtn-warn:hover{border-color:var(--danger);color:var(--danger);
  background:color-mix(in srgb,var(--danger) 12%,transparent);}
.dbtn.primary{background:var(--cyan);border-color:var(--cyan);
  color:var(--on-accent);
  font-weight:600;box-shadow:0 0 0 1px color-mix(in srgb,var(--accent) 40%,transparent),0 2px 12px color-mix(in srgb,var(--accent) 40%,transparent);}
.dbtn.primary:hover{background:color-mix(in srgb,var(--accent) 88%,white);
  border-color:color-mix(in srgb,var(--accent) 88%,white);
  box-shadow:0 0 0 1px color-mix(in srgb,var(--accent) 53%,transparent),0 2px 16px color-mix(in srgb,var(--accent) 53%,transparent);}
/* T205: pressed is the DEEP ACCENT the button inherits -- cyan in the
   default theme, the tab's own hue in the colourful one -- so a lit
   control never wears a colour its neighbours do not */
.dbtn[aria-pressed="true"]{background:var(--accent-deep,var(--cyan-deep));
  border-color:var(--accent-deep,var(--cyan-deep));
  color:var(--on-accent-deep,#fff);}
.deck-save{display:flex;gap:7px;align-items:center;}


/* ---------- the thin document bar (editing) --------------------------
   28px of controls that never change with the selection. It is allowed
   to be a row of chrome above the tools — which the ribbon itself is
   emphatically not — because it REPLACED chrome rather than adding it:
   File, Save, undo, redo and the save readout were a block in the left
   column, zoom and Present were groups in the ribbon, and all of it is
   now one line that no tab can take away (2026-08-20, user). */
.deck-qat{display:flex;align-items:center;gap:6px;padding:4px 10px;
  border-bottom:1px solid var(--chrome-line);background:var(--chrome-1);
  flex:none;min-height:34px;flex-wrap:nowrap;overflow-x:clip;}
.deck-qat[hidden]{display:none!important;}
/* nowrap + flex:none: a squeezed flex item shrinks to min-content and
   its label wraps INSIDE the button ("File" over its caret) — a second
   line by another name. The bar's width pressure goes to fitQat's
   rungs instead (2026-08-24). */
.deck-qat .dbtn{padding:4px 9px;white-space:nowrap;flex:none;}
/* T487: NO TRANSITION ON WHAT THE FITTERS MEASURE. .dbtn transitions
   `all`, so a rung's padding change ANIMATED over 150ms: fitQat's
   synchronous measurement right after adding a class saw the OLD
   padding (a transition starts from the value before the change),
   judged the rung a failure and reached for the next; the observer on
   the bar then watched the buttons shrink and re-ran it against a
   half-way size, and at 1300px the two states flip-flopped forever
   (driven: forty class mutations in four seconds). Colour and border
   still ease; geometry snaps. The ribbon's rungs change padding too,
   and get the same rule. */
.deck-qat .dbtn,.deck .edit-tools .dbtn{
  transition-property:border-color,color,background-color,box-shadow;}
/* T487: ONE HEIGHT, ONE BASELINE. Measured at 1500px the bar carried
   four heights on three baselines -- 24px@y5 words, 22px@y6 carets,
   23px@y6 File and Save, 26px@y4 undo and redo (2026-09-15 review).
   Every control is the ribbon's button height now, and a button
   centres its own content. The readout keeps inline-block: its
   ellipsis needs a block container (see below). */
.deck-qat .dbtn,.deck-qat .qat-name,.deck-qat .qat-nameedit{
  height:var(--rbn-btn-h);box-sizing:border-box;
  padding-top:0;padding-bottom:0;}
.deck-qat .qat-name{line-height:calc(var(--rbn-btn-h) - 2px);}
.deck-qat .rbn-stack{flex-direction:row;align-items:center;gap:6px;}
.deck-qat .rbn-cell{height:var(--rbn-btn-h);gap:3px;}
.deck-qat .dc-menuwrap,.deck-qat .dc-savegrp{display:inline-flex;
  align-items:center;height:var(--rbn-btn-h);}
.qat-sep{width:1px;align-self:stretch;margin:3px 3px;
  background:var(--chrome-line);flex:none;}
.qat-btn{white-space:nowrap;flex:none;}
/* the name reads as a title, not a button, until you go near it */
/* flex:none (T397): every button on this bar is flex:none and the two
   springs have a zero basis, so the name was the ONE item the bar could
   shrink -- and it shrank to "pres..." before fitQat ever saw an
   overflow, with a spring's worth of empty space on either side of it
   (2026-09-13, user: "There is not enough room for the presentation
   name"). Now the name keeps its width and the bar's pressure goes where
   it was designed to go: fitQat's rungs. */
.qat-name{font-family:var(--sans);font-size:12.5px;color:var(--chrome-ink-2);
  background:none;border:1px solid transparent;border-radius:6px;
  padding:3px 9px;cursor:text;flex:none;max-width:34vw;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;}
.qat-name:hover{border-color:var(--chrome-line);color:var(--chrome-ink);}
.qat-name:empty::before{content:"untitled";color:var(--chrome-ink-3);}
.qat-nameedit{font-family:var(--sans);font-size:12.5px;
  background:var(--input-bg);color:var(--chrome-ink);
  border:1px solid var(--cyan);border-radius:6px;padding:3px 9px;
  min-width:190px;outline:none;}
/* THE READOUT, beside the Save button it reports on. It was 10px, and
   its ellipsis had never once fired: text-overflow needs a BLOCK
   CONTAINER, and .deck-status is an inline-flex, whose bare text is an
   anonymous flex item no ellipsis can reach — so "autosaved to
   presentation.junoview.html · 12:41" was sliced off mid-glyph at 26ch
   (2026-08-29, T70, user: "make sure everything is fitting inside its
   box"). inline-block centres by line-height exactly as align-items did,
   and gives the ellipsis somewhere to land. */
.deck-qat .deck-status{display:inline-block;height:var(--rbn-btn-h);
  line-height:var(--rbn-btn-h);
  font-size:11px;flex:none;width:34ch;max-width:34ch;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;}
/* Keep the readout's slot even while it is empty.  Autosave changes this
   text from "unsaved" to "saving" to a destination and back; hiding the
   whole item for the empty state made every control after Save jump when
   the state changed.  The slot is only removed by fitQat's deliberate
   compact rung. */
.deck-qat .deck-status:empty{visibility:hidden;}
/* the countdown rewrites itself once a second; a fixed cell keeps the
   button — and so the whole bar — from twitching on every tick */
.deck-qat .qat-auto .qat-tick{display:inline-block;min-width:4.2ch;
  text-align:right;font-variant-numeric:tabular-nums;}
/* ---- fitQat's rungs (see fitQat in deck.js): this bar never clips.
   Rung 1 tightens spacing and swaps the .qat-long/.qat-short label pair
   ("Autosave"→"Auto") — words are SHORTENED, never hidden (icon-only was
   rejected twice). Rung 2 drops the save readout (informative, not a
   control; the Save button's tooltip carries the same words). T487
   swapped the two: the readout was the FIRST thing to go, and at 1300px
   it went whole -- 219px of words -- for a 30px shortfall the cheap rung
   would have covered (2026-09-15 review). The floor scrolls the bar
   sideways so Present and Help are always reachable; its menus float
   via floatMenu (position:fixed), so the scroll box cannot cut them
   off. */
.deck-qat .qat-short{display:none;}
.deck-qat.qat-c1{gap:3px;}
.deck-qat.qat-c1 .dbtn{padding-left:6px;padding-right:6px;}
.deck-qat.qat-c1 .qat-name{max-width:16vw;}
.deck-qat.qat-c1 .qat-long{display:none;}
.deck-qat.qat-c1 .qat-short{display:inline;}
.deck-qat.qat-c2 .deck-status{display:none;}
.deck-qat.qat-scroll{overflow-x:auto;overflow-y:hidden;
  scrollbar-width:thin;}
/* ---- T602: THIS BAR IS THE TITLE ROW, SPLIT AS POWERPOINT SPLITS IT --
   (2026-09-30: the user picked this after a first try crowded the tabs
   in among File, Find and Present.) Left: app.js moves #open-tabs-row
   in (Home and the open files, as tabs). Middle: the command search.
   Right: Save, the readout, Autosave and undo/redo -- PowerPoint's
   quick-access corner. File, Find, Full screen and Present are on the
   strip below. While the tabs are here the bar is a shade darker than
   the strip, the tab on screen wears the STRIP's colour (--tab-on) and
   the line under the bar is drawn inside it, so that tab joins the
   strip; and the tab names the deck, so the name steps aside (File >
   Rename... and a double-click on the tab rename it, the edit field
   taking the name's place while you type). */
.deck-qat{--tab-on:var(--chrome-1);--tab-row:var(--chrome-0);}
.deck-qat:has(> .open-tabs-row:not([hidden])){background:var(--chrome-0);
  border-bottom-width:0;box-shadow:inset 0 -1px 0 var(--chrome-line);}
.deck-qat:has(> .open-tabs-row:not([hidden])) .qat-name{display:none;}
.deck-qat .open-tabs-row{margin-left:-6px;}
/* the save readout gives up its width before the tabs do: at 1440px
   with four decks open it kept all 34ch while every tab was down to
   "p...". Its width still comes from the room, never from its words, so
   a new state does not move the controls after it (the reason it has a
   fixed slot); the full words are its tooltip */
.deck-qat .deck-status{flex:0 4 34ch;width:auto;min-width:11ch;}
.deck-qat.qat-c1 .open-tabs-row{min-width:160px;}
/* the command search, centred between the tabs and the saving corner.
   T632: it gives up its width before the tabs do (shrink 4, as the
   readout's) -- at 1366 with five files open it kept 192px while the
   strip scrolled tabs out of sight. Its floor is where "Search
   commands" is still whole: the words need a 146px box, and the old
   140 cut the last letter off (measured, 2026-10-23) */
.deck-qat .rbn-search{flex:0 4 260px;min-width:150px;height:var(--rbn-btn-h);
  box-sizing:border-box;margin:0 8px;}
/* building: no ribbon to search, and the panel is narrow */
.deck.creating .deck-qat .rbn-search{display:none;}
/* T607: ...so narrow that the name's kept width (T397, above) pushed
   Autosave half out of the 430px panel and undo and redo off its end at
   every window size: the bar went straight to its scroll rung with the
   two buttons you reach for most scrolled away. In the panel the name is
   the one thing that can give: it shrinks to an ellipsis (its tooltip
   and File > Rename... keep it whole) before fitQat's rungs start.
   While the open files are tabs, the presentation's own tab is lit in
   the notebook's title row right beside the panel, so the name steps
   aside there as it does in the editor's title row. */
.deck.creating .deck-qat .qat-name{flex:0 1 auto;min-width:72px;}
body.tabs-row-on .deck.creating .deck-qat .qat-name{display:none;}
/* ---- T602: the strip under it is PowerPoint's File Home Insert row ----
   File first, the ribbon's tabs, then the verbs at the right before the
   fold -- since T639 only Present and the zoom (2026-10-24, owner:
   "having the tab on the same line as lots of other things is just way
   too much"); Find is on Home, Full screen and Auto-hide on View.
   Button-high for a 28px strip. While building there is no ribbon, so
   the strip is File and Present alone. T639: the strip's buttons are in
   the tabs' own sans, where they were 11px monospace beside 13px sans
   tabs -- two faces on one row. */
.rbn-tabs .rbn-filewrap,.rbn-tabs .qat-playgrp{align-self:center;
  display:inline-flex;align-items:center;flex:none;}
.rbn-tabs .rbn-filewrap{margin-right:10px;}
.rbn-tabs #dc-file,
.rbn-tabs .qat-playgrp .dbtn{height:22px;box-sizing:border-box;
  padding:0 9px;line-height:1;font-family:var(--sans);font-size:12px;
  white-space:nowrap;display:inline-flex;align-items:center;gap:5px;
  transition-property:border-color,color,background-color,box-shadow;}
.rbn-tabs .qat-playgrp{margin:0 10px 0 4px;}
.rbn-tabs .qat-playgrp #dc-playmore{padding:0 7px;}
.rbn-tabs .qat-play .bic{width:12px;height:12px;}
.deck.creating .rbn-tabs .rbn-tabset,.deck.creating .rbn-tabs .et-hint,
.deck.creating .rbn-tabs .rbn-fold{display:none;}
/* fitTabStrip's rungs (05-figures-and-ribbon.js), each a step down from
   the resting sizes above: tighter tabs and buttons and no hint; then
   the tab words a point smaller; then the strip scrolls. Geometry must
   not transition under a fitter (T487), so the strip's buttons ease
   their colours only. */
.rbn-tabs .dbtn{
  transition-property:border-color,color,background-color,box-shadow;}
.rbn-tabs.rt-c1 .rbn-tab{padding:0 8px;}
.rbn-tabs.rt-c1 .rbn-filewrap{margin-right:6px;}
.rbn-tabs.rt-c1 .qat-playgrp{margin-right:6px;}
.rbn-tabs.rt-c1 #dc-file,
.rbn-tabs.rt-c1 .qat-playgrp .dbtn{padding-left:6px;padding-right:6px;}
.rbn-tabs.rt-c1 .et-hint{display:none;}
.rbn-tabs.rt-c2 .rbn-tab{padding:0 6px;font-size:12px;}
.rbn-tabs.rt-scroll{overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;}
/* ---- the zoom, in the tab row (T619) ----------------------------------
   It lived in the ribbon, then in the top bar, then floated in the
   canvas's bottom-right corner (2026-08-20) -- where, on a laptop, it
   and its twin "Slide 3 of 14" sat over the page and the stage kept
   50px under the page for them. In the tab row it costs no height: the
   row is there anyway, and it is on every tab (2026-10-09, user: "I'd
   put the zoom where ribbon layouts is"). Button-high for the 28px
   strip, like Find and Present beside it; editing only, since the
   builder has no page to zoom. */
.deck-zoombar{display:none;align-self:center;align-items:center;gap:2px;
  flex:none;margin-left:4px;}
.deck.editing .deck-zoombar{display:inline-flex;}
/* two classes on the button, so the RIBBON's density rungs (the erc1-3
   and erc-tight rules on its small buttons) do not reach up into this
   row: the strip has its own ladder, and a width the ribbon's fitter
   changes under fitTabStrip is a width fitTabStrip measured wrong */
.rbn-tabs .deck-zoombar .dbtn.rbn-sm,.rbn-tabs .deck-zoombar .dbtn.rbn-ico{
  height:22px;min-height:0;box-sizing:border-box;padding:0 8px;
  line-height:1;font-family:var(--sans);font-size:12px;white-space:nowrap;
  display:inline-flex;
  align-items:center;justify-content:center;}
.rbn-tabs .deck-zoombar .dbtn.rbn-ico{width:24px;padding:0;font-size:13px;}
.rbn-tabs.rt-c1 .deck-zoombar .dbtn.rbn-sm{padding:0 6px;}
/* T542: the words in the middle or at the foot of a box that keeps a
   height (min-height, so words that outgrow it still grow the box) */
/* (.an-text is a flex ROW -- the words and the move handle -- so the
   vertical place is the cross axis) */
.an-item.an-text.an-va-m{align-items:center;}
.an-item.an-text.an-va-b{align-items:flex-end;}
/* T536: the mini toolbar -- the ribbon's own faces, beside the run */
.mini-tb{position:fixed;z-index:70;display:flex;align-items:center;gap:3px;
  padding:4px;border-radius:9px;background:var(--chrome-1);
  border:1px solid var(--chrome-line);box-shadow:0 6px 20px var(--shadow);}
.mini-tb[hidden]{display:none;}
.mini-tb .dbtn{font-family:var(--sans);font-size:12px;height:26px;
  min-width:26px;padding:0 7px;justify-content:center;}
.mini-tb .mini-b{font-weight:700;}
.mini-tb .mini-i{font-style:italic;font-family:Georgia,serif;}
.mini-tb .mini-u{text-decoration:underline;}
.mini-tb .mini-s{text-decoration:line-through;}
.mini-tb .dbtn[aria-pressed="true"]{background:var(--accent-deep,var(--cyan-deep));
  border-color:var(--accent-deep,var(--cyan-deep));color:var(--on-accent-deep,#fff);}
.mini-tb .mini-sw{display:inline-flex;gap:3px;padding:0 2px 0 4px;
  border-left:1px solid var(--chrome-line);margin-left:2px;}
.mini-tb .mini-swb{width:18px;height:18px;border-radius:50%;
  border:1px solid #ffffff44;padding:0;cursor:pointer;}
/* T543: the highlighter's markers -- square, as a marker's tip is */
.hl-row{display:flex;align-items:center;gap:5px;padding:4px 6px 6px;}
.hl-sw{width:20px;height:20px;border-radius:4px;border:1px solid #00000040;
  padding:0;cursor:pointer;}
.hl-sw:hover{outline:2px solid var(--cyan);outline-offset:1px;}
.hl-row .hl-none{font-size:11.5px;padding:3px 8px;margin-left:4px;}
.mini-tb .mini-hl{display:inline-flex;border-left:1px solid var(--chrome-line);
  margin-left:2px;padding-left:2px;}
.mini-tb .hl-row{padding:0 2px;gap:3px;}
.mini-tb .hl-sw{width:16px;height:16px;}
.mini-tb .hl-none{height:22px;min-width:22px;padding:0 4px;margin-left:1px;}
/* T524: "Slide 3 of 14 · Methods". T619 moved it from the canvas's
   bottom-left corner to the head of the slide list, beside the chooser
   of how the slides are listed. The column is ~185px on a 1366 laptop,
   too narrow for both words on one line, so the head WRAPS: the chooser
   keeps its word whole and the readout drops under it, giving way to an
   ellipsis only if its own line is too short. In a wider column the two
   share the line. The same face and height as the chooser. */
.deck-where{display:none;flex:0 1 auto;min-width:0;max-width:100%;}
.deck.editing .deck-where{display:flex;}
/* four classes, so neither the small-button base rule nor the
   ribbon's density rungs (erc1-3 and erc-tight, later in this file)
   resize it */
.film-head .deck-where .dbtn.rbn-sm{min-width:0;font-size:11px;
  padding:4px 8px;gap:5px;line-height:1.4;}
.film-head .deck-where .dbtn.rbn-sm .bic{width:12px;height:12px;}
.deck-where #where-t{overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
.qat-play{flex:none;white-space:nowrap;}

/* ---------- the tab strip ---------------------------------------------
   One job's worth of groups at a time. Tabs, the permanent ribbon-layout
   chooser and the hint stay in one button-high strip. */
.rbn-tabs{display:flex;align-items:stretch;gap:2px;padding:0 10px;
  background:var(--chrome-1);border-bottom:1px solid var(--chrome-line);
  flex:none;height:28px;overflow-x:clip;}
.rbn-tabs[hidden]{display:none!important;}
.rbn-tab{font-family:var(--sans);font-size:13px;letter-spacing:0;font-weight:500;
  background:none;border:none;border-bottom:2px solid transparent;
  color:var(--chrome-ink-2);padding:0 13px;cursor:pointer;white-space:nowrap;
  transition:color .12s,border-color .12s;}
.rbn-tab:hover{color:var(--chrome-ink);}
.rbn-tab[aria-selected="true"]{color:var(--chrome-ink);
  border-bottom-color:var(--cyan);}
.rbn-tab[hidden]{display:none;}
/* a group belongs to exactly one tab and is out of the row entirely when
   that tab is not the one showing — display:none, never visibility, so it
   costs no width in the fit measurement */
.rbn-grp[data-off]{display:none!important;}
/* FOLDED: the group row goes, the tab strip stays. A bar that vanishes
   completely leaves you no way to ask for it back (2026-08-20). */
.deck.rbn-fold>.edit-tools{display:none;}
/* ---- ...and the bar can put ITSELF away (off by default) --------------
   TRANSFORM, never display:none. fitEditRibbon bails on a folded bar
   because it measures 0 (and so did the strip's ceiling until T582), so
   a peek that used the fold would re-fit the row from nothing sixty
   times a second. Rolled up the bar is still laid out, still
   measurable, and the density ladder is unaffected.
   The ROW goes to zero so the stage takes the height; the bar keeps its
   106px and parks behind the tab strip, which never moves -- so the
   guarantee above still holds, there is always something to reach for.
   `:not(.rbn-fold)` is the present bar's own precedence rule
   (body.pb-auto.pb-peek:not(.pb-folded), app.css): an explicit fold beats
   a peek, so the two mechanisms cannot fight.
   IN FRONT OF THE SLIDE (2026-10-23, owner: "the auto-hide ribbon
   appears behind the slide"). The bar was z-index 1 and the strip 2,
   but nothing between the bar and the slide makes a stacking context,
   so the slide's own layers -- .annot-layer at 6, its svg, the boxes
   in it -- were ranked against the bar directly and won: a peeking bar
   came down UNDER the text boxes and frames it overlaps. 130 is over
   the stage's layers and the auto-hidden slide column (120), ties the
   column's resize handles and beats them by coming later, and stays
   under the strip (131) and the title row (132) it parks behind --
   the strip's general 131 now holds here too, where it was cut to 2
   to sit just over a bar at 1. Menus (240), .vfull (135) and the
   other full-window surfaces are still above it. */
.deck.editing.rbn-auto{grid-template-rows:auto auto 0 minmax(0,1fr);}
.deck.editing.rbn-auto>.edit-tools{position:relative;z-index:130;
  transform:translateY(-100%);transition:transform .18s ease;}
.deck.editing.rbn-auto.rbn-peek:not(.rbn-fold)>.edit-tools{transform:none;
  box-shadow:0 18px 40px #00000066;}
/* T538: search the commands -- a field in the title row since T602 (it
   was in the tab strip), its list a floating surface of the editor's */
.rbn-search{align-self:center;display:inline-flex;align-items:center;
  gap:5px;flex:0 1 210px;min-width:120px;margin-right:6px;height:22px;
  padding:0 7px;border:1px solid var(--chrome-line);border-radius:6px;
  background:var(--chrome-1);}
.rbn-search:focus-within{border-color:var(--cyan);}
.rbn-search .bic{width:12px;height:12px;flex:none;opacity:.7;}
.rbn-search input{flex:1;min-width:0;border:none;outline:none;
  background:none;color:var(--chrome-ink);font:12px var(--sans);}
.rbn-search input::placeholder{color:var(--chrome-ink-3);}
/* T687: Advanced, at the box's end -- words and its mark */
.rbn-search-adv{all:unset;flex:none;display:inline-flex;align-items:center;
  gap:4px;margin-right:-4px;padding:0 6px;height:16px;border-radius:4px;
  cursor:pointer;font:11px var(--sans);color:var(--chrome-ink-2);
  border-left:1px solid var(--chrome-line);}
.rbn-search-adv:hover{background:#ffffff12;color:var(--chrome-ink);}
.rbn-search-adv:focus-visible{outline:2px solid var(--cyan);}
.rbn-search-adv .bic{width:11px;height:11px;opacity:.8;}
.rbn-search-find{border-top:1px solid var(--chrome-line);margin-top:3px;}
.find-where{align-items:center;flex-wrap:wrap;row-gap:4px;}
.find-sel,.find-num{font:inherit;font-size:12px;padding:2px 4px;
  border-radius:5px;border:1px solid var(--chrome-line);
  background:var(--chrome-1);color:var(--chrome-ink);}
.find-num{width:52px;}
.find-span{display:inline-flex;align-items:center;gap:5px;font-size:12px;}
.find-span[hidden]{display:none;}
.rbn-search-list{position:fixed;z-index:320;width:min(420px,92vw);
  max-height:60vh;overflow-y:auto;padding:4px;border-radius:9px;
  background:var(--chrome-1);border:1px solid var(--chrome-line);
  box-shadow:0 12px 34px var(--shadow);}
.rbn-search-list[hidden]{display:none;}
.rbn-search-row{display:grid;grid-template-columns:18px minmax(0,1fr) auto;
  align-items:center;gap:8px;width:100%;text-align:left;background:none;
  border:none;border-radius:6px;padding:6px 8px;cursor:pointer;
  color:var(--chrome-ink);font:12.5px var(--sans);}
.rbn-search-row .bic,.rbn-search-row svg{width:16px;height:16px;}
.rbn-search-row.on,.rbn-search-row:hover{
  background:color-mix(in srgb,var(--accent) 16%,transparent);}
.rbn-search-t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.rbn-search-w{color:var(--chrome-ink-3);font-size:11px;white-space:nowrap;}
.rbn-search-none{padding:8px 10px;color:var(--chrome-ink-2);
  font:12px var(--sans);}
/* the control a search ran, outlined for a moment so you learn where
   it lives */
.cmd-found{outline:2px solid var(--cyan)!important;outline-offset:2px;
  transition:outline-color .3s;}
/* SCOPED to the strip. Unscoped, `.rbn-fold` also matched the deck's own
   `.rbn-fold` state class — so folding the tools put 1px 9px of padding on
   a position:fixed;inset:0 element and the stage came out SMALLER than
   before, which is the exact opposite of the point (2026-08-20, caught by
   measuring the stage either side of the toggle). */
.rbn-tabs .rbn-fold{align-self:center;padding:1px 9px;line-height:1;
  flex:none;font-size:10px;}
.rbn-tabs .et-hint{align-self:center;font-family:var(--mono);
  font-size:10px;color:var(--chrome-ink-3);white-space:nowrap;padding:0 8px;}
.deck.erc-nohint .rbn-tabs .et-hint{display:none;}

/* ---------- find & replace -------------------------------------------- */
.find-pop{position:fixed;top:96px;right:22px;z-index:220;width:308px;
  background:var(--chrome-3);border:1px solid var(--chrome-line);
  border-radius:10px;padding:10px;box-shadow:0 18px 52px var(--shadow);
  display:flex;flex-direction:column;
  gap:7px;font-family:var(--sans);}
.find-pop[hidden]{display:none!important;}
.find-head{display:flex;align-items:center;justify-content:space-between;}
.find-t{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--chrome-ink-2);}
.find-row{display:flex;gap:5px;align-items:center;}
/* the Text / Formatting switch: the same treatment the ribbon tabs get,
   because it is the same idea — one surface, two sets of controls */
.find-modes{display:flex;gap:4px;}
.find-mode{flex:1;font-family:var(--mono);font-size:10px;
  letter-spacing:.1em;text-transform:uppercase;padding:4px 6px;}
.find-mode.on{background:color-mix(in srgb,var(--accent) 22%,transparent);
  color:#fff;border-color:var(--accent);}
body.light .find-mode.on{color:var(--ink);}
.find-fmt{display:flex;flex-direction:column;gap:6px;}
.find-fmt[hidden]{display:none!important;}
.find-fmt .find-ck{padding:2px 3px;border-radius:5px;}
.find-fmt .find-ck:hover{background:#ffffff0d;}
.find-fmt .ff-row{display:flex;align-items:center;gap:6px;}
.find-fmt .ff-row .find-ck{flex:1;min-width:0;}
/* the control beside a change row is narrow on purpose: the popover is
   308px and the label has to stay readable */
.find-fmt .ff-in{width:74px;font-family:var(--sans);font-size:11.5px;
  background:var(--chrome-0,#0b141d);color:var(--chrome-ink);
  border:1px solid #ffffff26;border-radius:6px;padding:3px 5px;
  outline:none;}
.find-fmt select.ff-in{width:110px;}
.find-fmt input[type=color].ff-in{width:34px;padding:1px;height:22px;}
.find-fmt .ff-none{font-size:11.5px;color:var(--chrome-ink-2);line-height:1.4;}
/* ---------- text that will not fit ----------
   EDIT MODE ONLY, and by the same rule the guides follow: it is a note
   to the author, never ink. .deck.editing gates it, so playback, print,
   the PDF and the standalone export never see it (T15). */
.deck.editing .an-text.an-overflowing{
  outline:1px dashed #f0a848;outline-offset:2px;}
.deck.editing .an-text.an-overflowing::after{
  content:"does not fit";position:absolute;right:0;bottom:-1.15em;
  font-family:var(--mono);font-size:9px;letter-spacing:.06em;
  color:#f0a848;background:color-mix(in srgb,var(--chrome-0,#0b141d) 82%,
    transparent);border-radius:3px;padding:0 4px;pointer-events:none;
  white-space:nowrap;}
/* ---------- the box the style check just took you to (T279) ----------
   EDIT MODE ONLY, the same rule .an-overflowing above follows: a note to
   the author, never ink on the page. The ordinary selection ring is what
   EVERY click puts on a box, so landing on one told you nothing about
   why you had been sent there. Removed after a beat by the chip that
   added it. */
.deck.editing .an-item.an-mismatch{
  outline:2px solid #f0a848;outline-offset:3px;
  box-shadow:0 0 0 6px color-mix(in srgb,#f0a848 22%,transparent);
  border-radius:2px;}
@media print{.an-item.an-mismatch{outline:none!important;
  box-shadow:none!important;}}
@media print{.an-overflowing{outline:none!important;}
  .an-overflowing::after{display:none!important;}}
#print-root .an-overflowing{outline:none!important;}
#print-root .an-overflowing::after{display:none!important;}

/* ---------- deck tokens ---------- */
.canvas-menu .ff-none{font-size:11.5px;color:var(--chrome-ink-2);line-height:1.4;
  padding:2px 4px 4px;}
.canvas-menu .ff-row{display:flex;align-items:center;gap:6px;}
.canvas-menu .ff-in{width:74px;font-family:var(--sans);font-size:11.5px;
  background:var(--chrome-0,#0b141d);color:var(--chrome-ink);
  border:1px solid #ffffff26;border-radius:6px;padding:3px 5px;
  outline:none;}
.canvas-menu input[type=color].ff-in{width:34px;padding:1px;height:22px;}
.tok-pop{min-width:250px;}
.tok-nm{flex:1;min-width:0;font-size:11.5px;color:var(--chrome-ink);}
body.light .tok-nm{color:var(--ink-2);}
/* a deck colour reads as a chip you can point at, not a preset: the
   ring says "this one has a name" */
.sw.sw-tok{box-shadow:0 0 0 1px #ffffff40 inset,0 0 0 2px #ffffff1a;}
/* T265: what a deck colour is actually on, beside its name. Quiet, and
   quieter still when the answer is "nothing" -- the row is an offer at
   that point, not a fault. */
.tok-use{flex:none;margin-left:auto;padding-right:8px;
  font-family:var(--mono);font-size:10px;letter-spacing:.04em;
  color:var(--chrome-ink-3,#8ea2b3);}
.tok-use.tok-none{opacity:.55;font-style:italic;}
/* T367: the spare colours nothing is wearing, behind one row. A list of
   "not used yet" is the clutter the user keeps pointing at. */
.ff-more{display:block;width:100%;text-align:left;background:none;
  border:1px dashed var(--chrome-line,#ffffff26);border-radius:6px;
  color:var(--chrome-ink-3,#8ea2b3);font-family:var(--sans);
  font-size:11px;padding:5px 9px;margin:2px 0 0;cursor:pointer;}
.ff-more:hover{border-color:var(--cyan);color:var(--chrome-ink);}
.sw-tokrow{display:flex;flex-wrap:wrap;align-items:center;gap:3px;
  width:100%;padding-bottom:3px;margin-bottom:2px;
  border-bottom:1px solid #ffffff14;}
body.light .find-fmt .find-ck:hover{background:var(--surface-hover);}
.find-in{flex:1;min-width:0;font-family:var(--sans);font-size:12px;
  background:var(--chrome-0,#0b141d);color:#eaf2f8;
  border:1px solid #ffffff26;border-radius:6px;padding:5px 8px;
  outline:none;}
.find-in:focus{border-color:var(--cyan);}
.find-opts{display:flex;gap:12px;}
.find-ck[hidden]{display:none!important;}   /* T465: the house rule */
.find-ck{font-size:11px;color:var(--chrome-ink-2);display:flex;align-items:center;
  gap:4px;cursor:pointer;}
.find-foot{display:flex;align-items:center;gap:5px;}
.find-count{font-family:var(--mono);font-size:10px;color:var(--chrome-ink-2);}
.find-list{max-height:210px;overflow-y:auto;display:flex;
  flex-direction:column;gap:2px;}
.find-hit{text-align:left;font-size:11.5px;line-height:1.35;
  background:none;border:1px solid transparent;border-radius:6px;
  color:#b9cad8;padding:4px 7px;cursor:pointer;}
.find-hit:hover{background:#ffffff0f;color:#fff;}
.find-hit.cur{border-color:var(--cyan);color:var(--chrome-ink);
  background:color-mix(in srgb,var(--accent) 12%,transparent);}
.find-hit .fh-n{font-family:var(--mono);font-size:9.5px;color:var(--chrome-ink-2);
  margin-right:6px;}
.find-hit mark{background:var(--cyan);color:var(--on-accent);border-radius:2px;
  padding:0 1px;}

.deck-main{flex:1;display:flex;min-height:0;}
.deck-stagewrap{flex:1;display:flex;flex-direction:column;min-width:0;
  position:relative;}
.deck-stage{flex:1;min-height:0;display:flex;padding:26px 78px 6px;
  overflow:hidden;}
/* it holds the keyboard for the editor (deckFocusTake) -- the whole
   canvas ringed every time a deck opened from the keyboard is no help;
   the selection outline is what says where you are */
.deck-stage:focus{outline:none;}

/* editing: the slide is a real bounded page surface (16:9 by default —
   the Page dropdown can make it 4:3 or a poster), so you can see exactly
   where things will sit when presented */
/* T467 kept 50px under the page as the zoom bar's room, since the bar
   floated over the page's bottom-right corner where the page number is
   drawn. T619 took the bar (and "Slide 3 of 14") off the canvas, so the
   foot is the head's 18px again and the page gets the rest: sizeSlideTo
   measures this padding. */
.deck.editing .deck-stage{align-items:center;justify-content:center;
  padding:18px 26px 18px;}
.deck.editing .slide{flex:none;width:100%;max-height:100%;
  aspect-ratio:var(--page-ar,16/9);margin:auto;background:var(--chrome-0,#0b141d);
  border:2px solid #ffffff2b;border-radius:12px;
  box-shadow:0 14px 60px #00000066,inset 0 0 0 1px #00000055;}
/* zoomed past the window: the stage scrolls, content anchors top-left
   (margin:auto still centers it while it fits) */
.deck.editing .deck-stage.zoomed{overflow:auto;
  align-items:flex-start;justify-content:flex-start;}
/* An item dragged past the page edge used to be simply unreachable: the
   stage clipped, and it only ever scrolled when the page itself was
   bigger than the window (2026-08-20, user: "when objects are outside of
   the view, there is no horizontal scroll to see them"). `.spill` is
   stamped by renderAnnots when anything actually sits outside the page,
   so the scrollbars appear because there IS something out there rather
   than living permanently at the edge of the canvas. */
.deck.editing .deck-stage.spill{overflow:auto;}
/* the slide keeps its own size; the room the strays need is made by
   padding the stage, so nothing on the page moves when one appears */
.deck.editing .deck-stage.spill .slide{margin:auto;}
.deck.editing .an-item{--spill-guard:0;}
/* strays are shown, not hidden: dimmed and outlined so it is obvious
   they are off the page rather than just badly placed */
.deck.editing .an-item.an-offpage{outline:1px dashed #e5484d99;
  outline-offset:2px;}
/* a custom page (poster / portrait) letterboxes in playback too */
.deck.custom-page .vpage{display:flex;}
/* the Page dropdown menu */
.sh-menu.page-menu{display:block;width:300px;padding:6px;}
.page-menu .page-opt{display:block;width:100%;text-align:left;}
.page-menu .page-opt[aria-pressed="true"]{color:#fff;
  background:var(--cyan-deep);border-radius:6px;}
/* ---- panes DOCK, they do not cover ----------------------------------
   Layers, Animation, Versions, Notebooks and Print check all share one
   shell, and that shell used to float over the top-right of the stage —
   directly on top of the page you were editing. Every one of them is a
   list you consult WHILE working on the thing underneath, so covering
   that thing is exactly backwards (2026-08-20, user: "I don't like how
   the pop-up appears ofver the top of things, and not down the side.
   Annoying to use").
   The stage now gives up the width instead: .deck.pane-open pads the
   stage by the pane's width, and because sizeSlideTo fits the page to
   stage.clientWidth the slide simply gets smaller and stays entirely
   visible. One variable drives both, so they can never disagree. */
/* 272px, not 232 (T184): a row is a kind dot, a name, an eye, a lock
   and a build number, and at 232 the name was the thing that gave way
   ("Flip book —…"). The user's own width is remembered per pane. */
.deck{--pane-w:272px;}
/* the resize handle down the left edge (T184) */
.selpane-grip{position:absolute;left:0;top:0;bottom:0;width:7px;
  cursor:ew-resize;border-radius:10px 0 0 10px;z-index:2;}
.selpane-grip:hover,.selpane-grip:active{
  background:color-mix(in srgb,var(--accent) 45%,transparent);}
.sh-menu.sp-actions{min-width:236px;}
.deck.pane-open .deck-stage{padding-right:calc(var(--pane-w) + 22px);}
.deck.pane-open.rbn-side .deck-stage{
  padding-right:calc(var(--pane-w) + var(--rbn-side-w) + 12px);}
/* the Objects pane: everything on the slide — select, hide, lock */
.selpane{position:absolute;top:8px;right:8px;bottom:8px;
  width:var(--pane-w);
  z-index:60;background:var(--chrome-3,#101c28);border:1px solid #ffffff22;
  border-radius:10px;display:flex;flex-direction:column;
  box-shadow:0 14px 44px #00000066;}
.selpane[hidden]{display:none;}
/* panes resize by their native corner grip and drag by their header; the
   position and size you choose are remembered (2026-08-18) */
.selpane{resize:both;overflow:hidden;min-width:190px;min-height:120px;}
/* the Background menu is rows, not the shape gallery's 3-column grid it
   would otherwise inherit from .sh-menu */
.sh-menu.bg-menu{display:block;width:230px;}
.bg-menu .hd-row{display:flex;gap:4px;align-items:center;}
.bg-chip{width:26px;height:20px;border-radius:5px;padding:0;
  border:1px solid #ffffff33;}
.bg-auto,.bg-w{font-size:10.5px;padding:3px 8px;flex-direction:row;}
/* wrap, don't clip: five tools never fit the pane's default width on
   one line, and a clipped "New folder" is a tool that does not exist
   (2026-08-23, seen when the tool labels took their bic() icons) */
.sp-tools{display:flex;flex-wrap:wrap;gap:5px;padding:4px 4px 9px;}
.sp-tool{font-size:10.5px;padding:4px 9px;white-space:nowrap;}
.sp-tool .bic{width:11px;height:11px;vertical-align:-2px;}
.sp-tool[disabled]{opacity:.4;cursor:default;}
.sp-folder{display:flex;align-items:center;gap:6px;padding:5px 6px;
  border-radius:6px;background:#ffffff0a;margin-top:6px;cursor:pointer;}
.sp-folder:hover{background:#ffffff14;}
.sp-gcol{width:12px;height:12px;border-radius:3px;border:none;
  cursor:pointer;flex:none;padding:0;}
.sp-gname{font-weight:600;}
.sp-row.sp-ing{margin-left:10px;border-left:2px solid transparent;
  padding-left:6px;}
/* CLEAR THE TOOLBAR. The panes live inside the stage wrap, which also
   holds the ribbon, so `top:8px` measured from above the toolbar and every
   pane covered its right-hand end — Objects, Versions and Print check have
   all been sitting on top of View and Output since the ribbon became a
   fixed 98px band. The Animations pane made it obvious by reaching Insert
   too (2026-08-17 audit). In SIDE mode the toolbar is a column on the
   right and the pane already steps aside for it horizontally, so there is
   nothing above to clear. */
/* the ribbon sits ABOVE the stage wrap now, so the panes' own 8px is
   already clear of it (the 106px clearance dated from the ribbon living
   inside the same box) */
.deck.editing:not(.rbn-side) .selpane{top:8px;}
/* T679: a pane's title is a title, as a dialog's is (.eq-t) */
.selpane-h{display:flex;align-items:center;justify-content:space-between;
  padding:8px 8px 7px 12px;font-family:var(--sans);font-size:12.5px;
  font-weight:600;letter-spacing:0;color:var(--chrome-ink);
  border-bottom:1px solid #ffffff14;}
.selpane-list{flex:1;overflow-y:auto;padding:5px;}
.selpane-empty{color:var(--chrome-ink-3);font-size:12.5px;line-height:1.5;padding:12px;}
.sp-row{display:flex;align-items:center;gap:7px;
  border-radius:7px;padding:6px 7px;color:#c9d6e2;font-size:12px;
  cursor:pointer;}
.sp-row:hover{background:#ffffff0c;}
.sp-row.sel{background:color-mix(in srgb,var(--accent) 13%,transparent);color:#fff;}
.sp-row.offrow .sp-t{opacity:.45;text-decoration:line-through;}
.sp-kind{flex:none;width:8px;height:8px;border-radius:2px;
  background:#8ba0b2;}
.sp-kind.k-cell{background:var(--cyan);}
.sp-kind.k-text{background:#f0a848;}
.sp-kind.k-rect,.sp-kind.k-arrow{background:#ff6b57;}
.sp-kind.k-image{background:#46a892;}
.sp-t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
/* THE BUILD COLUMN (T174). Monospace and a fixed width so the numbers
   line up as a column you can read straight down -- that is the whole
   point of putting them here rather than in a tooltip. Dim until the
   object actually has a build, because the common answer is "no build"
   and a list of bright dots would be noise. */
.sp-step{flex:none;display:flex;align-items:center;gap:3px;
  background:none;border:none;color:var(--chrome-ink-3);cursor:pointer;
  font-family:var(--mono);font-size:10px;padding:1px 4px;
  border-radius:4px;line-height:1;min-width:34px;justify-content:flex-end;}
.sp-step:hover{color:var(--chrome-ink);background:var(--surface-active);}
.sp-step.on{color:var(--cyan);}
/* the one hue with no token of its own: a tie is neither a warning
   nor an accent, so it gets a light value here rather than a
   twelfth entry in every theme (T284) */
.sp-step.tied{color:color-mix(in srgb,#a07be0 70%,var(--chrome-ink));}
.sp-stepn{letter-spacing:.02em;}
/* a row listed under the click it LEAVES on, in the by-build view: it is
   not arriving here, and a list that showed both the same way would read
   as the object appearing twice */
.sp-row.sp-leaving .sp-t{opacity:.6;font-style:italic;}
/* and SAID, not just dimmed: the same object is listed twice in this
   view -- once where it arrives, once where it goes -- and two identical
   rows would read as a duplicate rather than as a swap. */
.sp-row.sp-leaving .sp-t::before{content:"goes — ";
  font-style:normal;color:var(--danger);}
.sp-act{flex:none;background:none;border:none;color:var(--chrome-ink-3);
  cursor:pointer;font-size:12px;padding:1px 3px;border-radius:4px;
  line-height:1;}
.sp-act:hover{color:#fff;background:#ffffff14;}
.sp-act.on{color:var(--cyan);}
/* the middle state of the three-state lock: on, but not all the way.
   Amber rather than a dimmer cyan, so "position only" is a different
   thing at a glance and not a half-rendered version of the full one. */
.sp-act.on.half{color:var(--amber);}
/* opaque: a panel you read lists through must not have the page
   showing through it (2026-08-20) */
body.light .selpane{background:var(--chrome-2);
  border-color:var(--chrome-line);}
body.light .sp-row{color:var(--ink-2);}
body.light .sp-row.sel{background:color-mix(in srgb,var(--accent) 13%,transparent);color:var(--ink);}
body.light .sp-act:hover{color:var(--ink);background:var(--surface-active);}
/* FULLY locked objects: visible but untouchable on the canvas */
.deck.editing .an-locked,.deck.editing .an-locked *{
  pointer-events:none!important;cursor:default!important;}
/* POSITION locked: everything still works except moving it, so the only
   thing to say is "this will not drag" — said with the cursor on the
   body, and left alone on the handles, which do still resize. */
.deck.editing .an-pinned{cursor:default;}

/* vertical "code trail": each slide can descend into the cells that
   made it (down arrow / ArrowDown), one step per screen */
.vstack{flex:1;min-width:0;display:flex;flex-direction:column;
  transition:transform .35s ease;}
.vslide{flex:none;height:100%;display:flex;min-height:0;min-width:0;}
.vslide.vstep{padding:10px 0 4px;}
.vstep-in{flex:1;display:flex;flex-direction:column;min-height:0;
  min-width:0;background:var(--chrome-1,#0e1926);border:1px solid #ffffff10;
  border-radius:12px;padding:16px 20px;}
.vstep-head{display:flex;align-items:center;gap:10px;flex:none;
  margin-bottom:10px;min-width:0;}
.vstep-t{font-size:15px;font-weight:600;color:var(--chrome-ink);flex:1;
  min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
.vstep-n{font-family:var(--mono);font-size:10.5px;color:var(--chrome-ink-2);
  flex:none;}
.vstep-body{flex:1;min-height:0;overflow:auto;}
.vstep-none{color:var(--chrome-ink-2);font-size:13px;}
.vstep-thumb{flex:none;height:34px;max-width:56px;object-fit:contain;
  border-radius:5px;background:#fff;padding:2px;}

/* the trace map: minimised, numbered steps grouped per plot, arranged
   like the plots on the slide; colours tie group <-> plot */
.vslide.voverview{padding:10px 0 4px;}
.vo-in{flex:1;display:flex;flex-direction:column;min-height:0;
  min-width:0;gap:12px;}
.vo-title{flex:none;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.18em;text-transform:uppercase;color:var(--chrome-ink-2);
  text-align:center;display:flex;gap:10px;align-items:center;
  justify-content:center;flex-wrap:wrap;}
/* match the docs top-bar toggles so the trail feels part of the same tool */
.vo-xall,.vo-fbtn{font-family:var(--mono);font-size:11px;letter-spacing:.04em;
  text-transform:none;background:var(--surface-hover);border:1px solid var(--chrome-line);
  color:var(--chrome-ink);border-radius:var(--rad);padding:6px 12px;cursor:pointer;
  display:inline-flex;align-items:center;gap:7px;
  transition:color .15s,background-color .15s,border-color .15s,
    box-shadow .15s,opacity .15s;}
.vo-xall:hover,.vo-fbtn:hover{border-color:var(--cyan);color:var(--chrome-ink);}
/* the trail's Code-types / Output-types filter dropdowns */
.vo-fdrop{position:relative;display:inline-block;}
.vo-fmenu{position:absolute;top:calc(100% + 5px);left:0;z-index:40;
  background:var(--chrome-2,#16273a);border:1px solid #ffffff22;border-radius:8px;padding:5px;
  min-width:150px;display:flex;flex-direction:column;text-align:left;
  box-shadow:0 12px 34px #00000077;}
.vo-fmenu[hidden]{display:none;}
.vo-fmenu .ckf-row{display:flex;align-items:center;gap:8px;padding:5px 8px;
  border-radius:5px;cursor:pointer;color:var(--chrome-ink);font-size:12px;
  font-family:var(--sans);text-transform:none;letter-spacing:0;}
.vo-fmenu .ckf-row:hover{background:color-mix(in srgb,var(--accent) 13%,transparent);}
.vo-step.vo-filtered{display:none;}
.vo-plots{flex:none;display:flex;gap:16px;justify-content:center;
  flex-wrap:wrap;}
.vo-plot{display:flex;flex-direction:column;align-items:center;gap:6px;
  padding:9px 11px;border-radius:10px;background:var(--chrome-1,#0e1926);
  border:2px solid #ffffff22;}
.vo-plot img{max-height:11vh;max-width:16vw;width:auto;height:auto;
  object-fit:contain;border-radius:6px;background:#fff;padding:2px;}
.vo-plot-t{font-size:11px;color:var(--chrome-ink);max-width:16vw;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.vo-groups{flex:1;min-height:0;display:flex;gap:14px;}
.vo-col{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px;
  border:1.5px solid #ffffff1f;border-radius:12px;padding:11px;
  overflow:auto;background:var(--chrome-1,#0e1926);}
.vo-col-h{flex:none;font-size:12.5px;font-weight:600;color:var(--chrome-ink);
  display:flex;align-items:center;gap:8px;min-width:0;}
.vo-col-h span{overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
/* section (## heading) + subsection (### heading) dividers in the trace */
.vo-sec{font-family:var(--mono);font-size:10px;font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;color:var(--chrome-ink);
  padding:8px 2px 4px;margin-top:6px;
  border-bottom:1px solid #ffffff1f;
  display:flex;align-items:center;gap:7px;}
.vo-col>.vo-sec:first-of-type,.vo-col-h+.vo-sec{margin-top:0;}
/* section collapse chevron + hide eye (mirror the docs sidebar/section head) */
.vo-sec-chev{flex:none;font-size:11px;line-height:1;color:var(--chrome-ink-2);
  cursor:pointer;transition:transform .15s,color .15s;}
.vo-sec-chev:hover{color:var(--chrome-ink);}
.vo-sec.collapsed .vo-sec-chev{transform:rotate(-90deg);}
.vo-sec-lab{flex:1;min-width:0;cursor:pointer;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;}
.vo-sec-eye{flex:none;font-size:11px;line-height:1;color:var(--chrome-ink-2);
  cursor:pointer;opacity:0;padding:1px 4px;border-radius:4px;
  transition:opacity .12s,color .12s,background .12s;}
.vo-sec:hover .vo-sec-eye{opacity:.65;}
.vo-sec-eye:hover{opacity:1;color:var(--chrome-ink);background:var(--surface-active);}
.vo-sec-body{display:flex;flex-direction:column;gap:8px;}
.vo-sec-body.vo-sec-fold{display:none;}
.vo-subsec{font-family:var(--mono);font-size:9.5px;letter-spacing:.08em;
  color:var(--chrome-ink-2);padding:5px 2px 2px;}
.vo-step{display:flex;flex-direction:column;background:var(--chrome-4,#12202e);
  border:1px solid #ffffff14;border-radius:8px;overflow:hidden;
  flex:none;min-width:0;transition:border-color .15s;}
.vo-step-h{display:flex;align-items:center;gap:9px;width:100%;
  padding:9px 11px;background:none;border:none;cursor:pointer;
  text-align:left;font-family:var(--sans);color:var(--chrome-ink);min-width:0;}
.vo-step-h:hover{background:#1a2c3d;}
.vo-num{font-family:var(--mono);font-size:11px;font-weight:600;
  width:22px;height:22px;border-radius:6px;display:flex;
  align-items:center;justify-content:center;flex:none;
  background:color-mix(in srgb,var(--accent) 13%,transparent);color:var(--cyan);}
.vo-step-t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font-size:12.5px;}
.vo-chev{flex:none;color:var(--chrome-ink-2);font-size:13px;
  transition:transform .2s;}
.vo-step.open .vo-chev{transform:rotate(90deg);}
.vo-full{background:none;border:none;color:var(--chrome-ink-2);cursor:pointer;
  font-size:13px;flex:none;padding:2px 5px;border-radius:4px;}
.vo-full:hover{color:var(--chrome-ink);background:var(--surface-active);}
/* eyeball: hide a step while presenting */
.vo-eye{background:none;border:none;color:var(--chrome-ink-2);cursor:pointer;
  font-size:12px;flex:none;padding:2px 5px;border-radius:4px;
  line-height:1;opacity:.75;position:relative;}
.vo-eye:hover{color:var(--chrome-ink);background:var(--surface-active);opacity:1;}
.vo-eye.off{color:var(--chrome-ink-3);}
.vo-eye.off::after{content:"";position:absolute;left:4px;right:4px;
  top:calc(50% - 1px);height:1.6px;background:currentColor;
  transform:rotate(-18deg);border-radius:2px;}
.vo-step.hidden{opacity:.5;border-style:dashed;}
.vo-step.hidden .vo-step-t::after{content:" · hidden";
  color:var(--chrome-ink-2);font-family:var(--mono);font-size:10px;
  letter-spacing:.04em;}
.vo-xall.on,.vo-fbtn.on{border-color:var(--cyan);color:var(--chrome-ink);
  background:color-mix(in srgb,var(--accent) 13%,transparent);}
.vo-step-b{display:none;padding:2px 10px 10px;}
.vo-step.open .vo-step-b{display:block;}

/* scrollable playback: the slide fills the screen, the trace flows
   beneath it — scroll (or ArrowDown) between them */
.deck-stage.scrolly{display:block;overflow-y:auto;
  scroll-snap-type:y proximity;padding-top:0;padding-bottom:0;}
/* the slide fills the viewport EXACTLY so the code trace sits fully
   below the fold — its buttons never peek out under the slide */
/* PLAYBACK FILLS THE SCREEN. The stage's 78px side padding exists to
   clear the arrows and its 26/6 to float the page clear of the ribbon --
   both are EDITING affordances, and in a talk they were 156px of dead
   width and 32px of dead height that sizeSlideTo fed straight into the
   fit. On a 1920x1029 stage that sized the page to 1744x981: an 88px
   band down each side and 24px top and bottom (2026-08-29, user: "in
   presentations it doesn't seem to fill the full screen, there is a
   large margin"). Nothing needs the room -- the arrows, the Show code
   pill and the slide count are all position:absolute over the stage
   already. Same stage now fits the page at 1829x1029: full height, and
   the 45px left over per side is the honest 16:9 letterbox rather than
   padding.
   Specificity 0,3,0, so it beats the 860px media query's bare
   .deck-stage and, being later in the file, .deck-stage.scrolly and
   .deck.pane-open too; .deck.rbn-side is toggled off unless
   mode==='edit' so it cannot fight this. */
.deck:not(.editing) .deck-stage{padding:0;}
/* ...and the page wrapper gives up its own 22+8 for the same reason:
   height:100% now really is the viewport, so the slide sized to the
   full stage height sits in it exactly instead of overflowing it by
   30px and bleeding over the trail. */
.vpage{height:100%;box-sizing:border-box;padding:0;
  display:flex;flex-direction:column;min-width:0;
  scroll-snap-align:start;}
.vtrace{scroll-snap-align:start;display:flex;flex-direction:column;
  gap:14px;padding:64px 78px 60px;min-height:70%;}
/* top clears the ↑ arrow; the 78px sides are the reading margin the
   stage used to provide, moved onto the thing that actually needs to be
   inset to be read. The slide above goes full-bleed instead. */
.vtrace .vo-groups{flex:none;align-items:flex-start;}
.vtrace .vo-col{overflow:visible;}
/* several plots: the thumbnails PICK which trace shows */
.vo-plots .vo-thumb-btn{cursor:pointer;opacity:.45;
  transition:opacity .15s;}
.vo-plots .vo-thumb-btn:hover{opacity:.8;}
.vo-plots .vo-thumb-btn.sel{opacity:1;}
/* the docs dependency tree, hosted under a slide (always dark — the
   playback canvas is dark in both themes) */
.deck-tracetree .treeview{display:block;padding:0 4px 30px;}
.deck-tracetree .tt-present{display:none;}
.deck-tracetree .tree-toolbar{
  background:linear-gradient(var(--chrome-0,#0b141d) 72%,transparent);}
.deck-tracetree .tree-toolbar .tt-title{color:var(--chrome-ink-2);}
.deck-tracetree .tt-btn{background:var(--chrome-3,#101c28);border-color:#ffffff22;
  color:var(--chrome-ink);}
.deck-tracetree .tt-btn:hover{border-color:var(--cyan);color:var(--chrome-ink);}
.deck-tracetree .tree-scroll{border-color:#ffffff1a;background:
  radial-gradient(circle at 1px 1px,#ffffff12 1px,transparent 0)
  0 0/22px 22px,var(--chrome-1,#0e1926);}
.deck-tracetree .tree-node{
  background:color-mix(in srgb,var(--nc) 12%,var(--chrome-3,#101c28));
  border-color:#ffffff1c;border-top-color:var(--nc);
  box-shadow:0 1px 3px #00000040;}
.deck-tracetree .tree-node.active{border-color:var(--cyan);}
.deck-tracetree .tn-title{color:var(--chrome-ink);}
.deck-tracetree .tn-btn{color:var(--chrome-ink-2);}
.deck-tracetree .tn-btn:hover{background:#ffffff14;}
.deck-tracetree .tn-resize{border-color:#8ba0b2;}
.deck-tracetree .tree-node-body{border-top-color:#ffffff14;}
.deck-tracetree .tree-node.tn-off{border-top-color:#ffffff1c;}
.deck-tracetree .tree-node.tn-off .tn-title{color:var(--chrome-ink-2);}
.deck-tracetree .tree-empty{color:var(--chrome-ink-2);}
.deck-codepill{position:absolute;left:50%;transform:translateX(-50%);
  bottom:16px;z-index:7;display:flex;align-items:center;gap:8px;
  background:color-mix(in srgb,var(--chrome-2,#16273a) 88%,transparent);border:1px solid #ffffff2e;border-radius:22px;
  color:var(--chrome-ink);font-family:var(--mono);font-size:11.5px;
  padding:9px 17px;cursor:pointer;backdrop-filter:blur(4px);
  transition:border-color .15s,color .15s;}
.deck-codepill:hover{border-color:var(--cyan);color:var(--chrome-ink);}
.deck-codepill[hidden]{display:none;}
.cp-arr{font-size:14px;line-height:1;}
.deck-arrow.up{left:50%;top:12px;transform:translateX(-50%);
  width:44px;height:44px;font-size:24px;}
/* T469: the way back up is the same worded pill as the way down */
.deck-codepill.up{top:12px;bottom:auto;}
.deck-count{position:absolute;right:18px;bottom:12px;z-index:7;
  font-family:var(--mono);font-size:11.5px;color:var(--chrome-ink-2);}
.deck.creating .deck-count,.deck.editing .deck-count{display:none;}

/* one step, full screen */
.vfull{position:fixed;inset:0;z-index:135;background:color-mix(in srgb,var(--chrome-0,#0b141d) 98%,transparent);
  display:flex;flex-direction:column;padding:22px 44px 30px;}
.vfull[hidden]{display:none;}
.vfull-head{display:flex;align-items:center;gap:12px;flex:none;
  margin-bottom:14px;}
.vfull-t{font-size:17px;font-weight:600;color:var(--chrome-ink);flex:1;
  min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
.vfull-body{flex:1;min-height:0;overflow:auto;}

/* the figure "Plot trace" button, and (T733) View > Variables' Trace
   this variable, which wears its look but not its class: .plot-trace-btn
   is a figure's Trace, to the page and to whatever finds one */
/* the card's actions live together at the top RIGHT */
.plot-trace-btn{margin-left:auto;}
.plot-trace-btn+.cell-eye{margin-left:0;}
.plot-trace-btn,.var-trace{flex:none;font-family:var(--sans);font-size:11px;
  letter-spacing:0;border:1px solid var(--line);background:var(--paper-2);
  color:var(--ink-2);border-radius:20px;padding:3px 10px;cursor:pointer;
  transition:background .15s,color .15s,border-color .15s;white-space:nowrap;}
.plot-trace-btn:hover,.var-trace:hover{background:color-mix(in srgb,var(--accent) 9%,transparent);color:var(--cyan-deep);
  border-color:color-mix(in srgb,var(--accent) 33%,transparent);}
body:not(.light) .plot-trace-btn,body:not(.light) .var-trace{background:#0e1824;color:var(--chrome-ink-2);
  border-color:#ffffff1f;}
body:not(.light) .plot-trace-btn:hover,body:not(.light) .var-trace:hover{color:var(--cyan);border-color:color-mix(in srgb,var(--accent) 40%,transparent);}
/* ---- Plot-trace TAB: a real notebook shell holding just this plot's
   lineage cells, so every global filter + per-card control works inside it.
   No sidebar — the content spans the full width. ---- */
/* :not([hidden]) both raises specificity above .nbshell[hidden]{display:none}
   AND stops matching once activate() hides the tab, so switching tabs works */
.nbshell.tracetab:not([hidden]){display:grid;}
.nbshell.tracetab .stage{width:100%;}
.tracetab-head{margin:0 0 14px;padding-bottom:12px;
  border-bottom:1px solid #ffffff14;position:relative;}
/* Cells | Tree switcher, right in the trace header */
.trace-viewsw{position:absolute;right:0;top:6px;display:flex;gap:6px;}
.dbtn.tvw.on{background:var(--cyan-deep);border-color:var(--cyan-deep);
  color:var(--on-accent-deep,#fff);}
body.light .trace-viewsw .dbtn{background:var(--btn-bg);
  border-color:var(--btn-border);color:var(--btn-ink);}
body.light .trace-viewsw .dbtn.tvw.on{background:var(--cyan-deep);
  border-color:var(--cyan-deep);color:var(--on-accent-deep,#fff);}
.tracetab-eyebrow{display:block;font-family:var(--mono);font-size:10px;
  letter-spacing:.22em;text-transform:uppercase;color:var(--cyan);}
.tracetab-t{margin:5px 0 2px;font-size:22px;font-weight:650;color:#eef4f8;
  line-height:1.2;}
.tracetab-sub{font-size:12.5px;color:#8fa6b4;}
.tracetab-graph{margin:0 0 18px;}
.tracetab-graph .plotgraph-wrap{margin:0;}
body.light .tracetab-head{border-color:var(--line);}
body.light .tracetab-t{color:var(--ink);}
body.light .tracetab-sub{color:var(--ink-3);}
/* T733: what the trace found in the repository's files (app.js rtSay),
   and those files as cards of their own, marked as the repository's by
   a dashed edge and their badge */
.trace-repo{margin:0 0 16px;padding:9px 12px;border-radius:8px;
  border:1px solid color-mix(in srgb,var(--accent) 26%,transparent);
  background:color-mix(in srgb,var(--accent) 6%,transparent);
  font-family:var(--sans);font-size:12.5px;line-height:1.45;
  color:var(--chrome-ink-2);}
.trace-repo[hidden]{display:none;}
.trace-repo-l{margin:0;}
.trace-repo-l+.trace-repo-l{margin-top:4px;}
.trace-repo-bad{color:var(--amber);}
.trace-repo-go{margin-top:8px;}
body.light .trace-repo{color:var(--ink-2);}
.card.repo-card{border-style:dashed;}
.card.repo-card .badge{color:var(--amber);}
.repo-card-via{margin:0;font-size:12px;color:var(--chrome-ink-2);}
.repo-card-via code{font-family:var(--mono);font-size:11.5px;}
body.light .repo-card-via{color:var(--ink-3);}
.navitem-repo .navitem-t{font-style:italic;}
.pg-node.pg-repo rect{stroke:#ffffffb3;stroke-width:1.4;
  stroke-dasharray:4 3;}
.vo-step.vo-repo .chain-badge{color:var(--amber);}
.vo-repo-note{margin:4px 0 8px;font-size:12px;color:var(--chrome-ink-2);}
/* what could not be followed into the repository, said in the Code trail
   and Where this came from as the plot trace says it */
.vo-repo-note.vo-repo-bad,.prov-repo-bad{color:var(--amber);}
/* a piece's names as written: the step label is set in capitals, and
   Python's names are case-sensitive (np is not NP) */
.steplabel .rt-names{text-transform:none;letter-spacing:0;}
.var-line .var-trace{margin-left:0;padding:1px 8px;font-size:10.5px;}
/* the ◈ badge + tint that marks a Plot-trace tab in the tab strip */
/* a Plot-trace SUB-tab: smaller + indented + cyan-tinted so it reads as a
   child of the notebook tab immediately before it */
.tab.tab-sub{margin-left:6px;max-width:200px;font-size:12px;
  padding:0 8px 0 10px;background:color-mix(in srgb,var(--accent) 6%,transparent);border-color:color-mix(in srgb,var(--accent) 24%,transparent);}
.tab.tab-sub:hover{background:color-mix(in srgb,var(--accent) 11%,transparent);}
.tab.tab-sub.current{background:color-mix(in srgb,var(--accent) 13%,transparent);color:#dff3f8;
  border-color:color-mix(in srgb,var(--accent) 48%,transparent);}
.tab-trace-ic{color:var(--cyan);margin-right:4px;font-size:12px;flex:none;
  opacity:.85;}
.tab.tab-sub .tab-t{max-width:150px;}
/* a small gap + hook line before a sub-tab hints the parent→child nesting */
.tab.tab-sub::before{content:"";width:8px;height:1px;background:color-mix(in srgb,var(--accent) 40%,transparent);
  margin:0 1px 0 -6px;align-self:center;flex:none;}
body.light .tab.tab-sub{background:color-mix(in srgb,var(--accent) 7%,transparent);border-color:color-mix(in srgb,var(--accent) 30%,transparent);}
body.light .tab.tab-sub.current{background:color-mix(in srgb,var(--accent) 15%,transparent);color:var(--accent-deep);}
/* per-plot dependency graph */
.plotgraph-wrap{margin:0 0 18px;padding:12px 12px 6px;
  background:var(--chrome-1);border:1px solid var(--chrome-line);
  border-radius:10px;}
.pg-eyebrow{font-family:var(--mono);font-size:9.5px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--chrome-ink-3);margin-bottom:8px;}
.plotgraph{display:block;width:100%;height:auto;}
.pg-edge{fill:none;stroke:#f0a848;stroke-width:1.6;opacity:.6;}
.pg-node{cursor:pointer;}
.pg-node rect{stroke:#ffffff26;stroke-width:1;
  transition:filter .15s;}
.pg-node:hover rect,.pg-node:focus rect{filter:brightness(1.18);
  stroke:#ffffff66;}
.pg-node:focus{outline:none;}
/* the node fills are the code-kind palette, the same in every scheme, so
   the label ink is fixed too (T626: --chrome-0 went near-white in the
   light schemes, 2.5:1 on the mid-tone fills) */
.pg-node text{font-family:var(--sans);font-size:12px;fill:#0b141d;
  font-weight:600;pointer-events:none;}

.slide{flex:1;display:flex;flex-direction:column;min-width:0;min-height:0;
  animation:slidein .28s ease;}
@keyframes slidein{from{opacity:0;transform:translateY(8px);}
  to{opacity:1;transform:none;}}
.slide-titlecard{align-items:center;justify-content:center;text-align:center;
  gap:12px;}
.slide-eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.24em;
  text-transform:uppercase;color:var(--cyan);margin:0;}
.slide-titlecard h2{font-size:clamp(28px,4.5vw,54px);font-weight:600;
  letter-spacing:-.02em;color:var(--chrome-ink);margin:0;max-width:82%;line-height:1.15;}
.slide-meta{font-family:var(--mono);font-size:12px;color:var(--chrome-ink-2);margin:0;}
.slide-empty{align-items:center;justify-content:center;color:var(--chrome-ink-2);
  font-size:14px;text-align:center;}

.slide-head h3{font-size:clamp(18px,2.2vw,28px);font-weight:600;color:#eef4f8;
  margin:0 0 14px;letter-spacing:-.015em;}
.slide-body{flex:1;display:flex;gap:26px;min-height:0;}
.slide-fig{flex:1;min-width:0;display:flex;flex-direction:column;min-height:0;}
.slide-fig .cardbody{flex:1;min-height:0;display:flex;flex-direction:column;
  padding-left:0;}
.slide-fig .figframe{flex:1;min-height:0;display:flex;align-items:center;
  justify-content:center;border:none;border-radius:10px;padding:14px;
  overflow:hidden;background:none;}
.slide-fig .figframe img{max-width:100%;max-height:100%;width:auto;height:auto;
  object-fit:contain;margin:0;}
.slide-fig .note{background:var(--output-paper);color:var(--output-ink-2);
  border-radius:12px;
  padding:26px 32px;overflow:auto;font-size:16.5px;line-height:1.7;}
.slide-fig .caption{flex:none;color:var(--chrome-ink);margin-top:12px;padding-left:2px;
  font-size:14.5px;}
.slide-fig pre.result,.slide-fig pre.stream{flex:none;overflow:auto;}
.slide-fig .jv-xr{flex:1;min-height:0;overflow:auto;}

/* halves / quarters slide layouts */
.slide-grid{flex:1;display:grid;gap:16px;min-height:0;}
.slide-grid.halves{grid-template-columns:1fr 1fr;}
.slide-grid.quarters{grid-template-columns:1fr 1fr;
  grid-template-rows:1fr 1fr;}
.spane{display:flex;flex-direction:column;min-width:0;min-height:0;
  background:var(--chrome-1,#0e1926);border:1px solid #ffffff10;border-radius:10px;
  padding:12px 14px;}
.spane-t{font-size:13.5px;font-weight:600;color:var(--chrome-ink);margin:0 0 8px;
  letter-spacing:-.01em;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;flex:none;}
.spane .cardbody{flex:1;min-height:0;display:flex;flex-direction:column;
  padding-left:0;}
.spane .figframe{flex:1;min-height:0;display:flex;align-items:center;
  justify-content:center;border:none;border-radius:8px;padding:8px;
  overflow:hidden;}
.spane .figframe img{max-width:100%;max-height:100%;width:auto;height:auto;
  object-fit:contain;margin:0;}
.spane .note{flex:1;min-height:0;background:var(--output-paper);
  color:var(--output-ink-2);
  border-radius:8px;padding:14px 18px;overflow:auto;font-size:13.5px;
  line-height:1.6;}
.spane .jv-xr,.spane pre.result,.spane pre.stream{overflow:auto;
  min-height:0;}
.spane.empty{align-items:center;justify-content:center;color:var(--chrome-ink-3);
  font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;
  text-transform:uppercase;}

.chain-sec{border-top:1px solid #ffffff10;}
.chain-sec:first-child{border-top:none;}
.chain-h{display:flex;align-items:center;gap:10px;width:100%;
  padding:9px 4px;margin:0;background:none;border:none;cursor:pointer;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--chrome-ink-2);text-align:left;border-radius:6px;
  transition:color .15s,background .15s;}
.chain-h:hover{color:var(--chrome-ink);background:var(--surface-hover);}
.chain-chev{display:inline-block;font-size:14px;line-height:1;flex:none;
  transition:transform .2s;}
.chain-h[aria-expanded="true"] .chain-chev{transform:rotate(90deg);}
.chain-badge{font-size:9px;padding:2px 7px;border-radius:4px;
  background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--cyan);letter-spacing:.1em;flex:none;
  text-transform:lowercase;}
.chain-badge.ckmain-imports{background:#8a6d4a2b;
  color:color-mix(in srgb,#8a6d4a 40%,var(--chrome-ink));}
.chain-badge.ckmain-function{background:#46a8922b;
  color:color-mix(in srgb,#46a892 40%,var(--chrome-ink));}
.chain-badge.ckmain-data{background:#4d90c02b;
  color:color-mix(in srgb,#4d90c0 40%,var(--chrome-ink));}
.chain-badge.ckmain-constant{background:#9a7cc02b;
  color:color-mix(in srgb,#9a7cc0 40%,var(--chrome-ink));}
.chain-badge.ckmain-settings{background:#5b75892b;
  color:color-mix(in srgb,#5b7589 40%,var(--chrome-ink));}
.chain-badge.ckmain-plotting{background:color-mix(in srgb,var(--accent) 17%,transparent);color:var(--cyan);}
.chain-badge.ckmain-print{background:#cf9a4e2b;
  color:color-mix(in srgb,#cf9a4e 40%,var(--chrome-ink));}
.chain-t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.chain-b{padding:0 4px 10px;}

.deck-arrow{position:absolute;top:50%;transform:translateY(-50%);width:52px;
  height:52px;border-radius:50%;border:1px solid var(--chrome-line);
  background:var(--surface-hover);color:var(--chrome-ink);font-size:30px;line-height:1;cursor:pointer;z-index:5;
  transition:color .15s,background-color .15s,border-color .15s,
    box-shadow .15s,opacity .15s;}
.deck-arrow:hover{border-color:var(--cyan);color:var(--chrome-ink);background:color-mix(in srgb,var(--accent) 13%,transparent);}
.deck-arrow:disabled{opacity:.22;cursor:default;}
.deck-arrow.prev{left:13px;}
.deck-arrow.next{right:13px;}

.deck-foot{display:flex;align-items:center;justify-content:center;gap:16px;
  padding:9px 18px 13px;flex:none;}
.deck-count{font-family:var(--mono);font-size:11.5px;color:var(--chrome-ink-2);}
.deck-drawer{max-height:44vh;overflow-y:auto;background:#0e1b25;
  border-top:1px solid #ffffff14;padding:14px 78px 22px;flex:none;}
.deck-drawer .steplabel{color:#8fa3b4;}
.deck-drawer pre.result,.deck-drawer pre.stream{background:#13222f;
  border-color:#ffffff14;color:#b6c6d3;}

/* ---------- create mode: deck docks left, document stays interactive */
.deck.creating{width:min(var(--dc-w),94vw);right:auto;
  border-right:1px solid #ffffff22;box-shadow:8px 0 40px #00000055;}
.deck.creating .deck-stagewrap{display:none;}
.deck.creating .deck-top{display:none;}

/* .dc-head is GONE (2026-08-20): the create panel's header — File, Save,
   undo/redo and the save readout — became the thin bar across the top of
   the whole window (.deck-qat), which is where a document's own controls
   belong. Its five rules went with it rather than lingering as CSS for
   markup that no longer exists. */
.dbtn[disabled]{opacity:.4;cursor:default;pointer-events:none;}
/* ---- POSTER MODE chrome: SAME density as slides (2026-08-04). The
   2026-07-29 "bigger chrome" upsizing inflated every ribbon chip —
   including the six INVISIBLE contextual format groups held in the wrap
   flow — so the toolbar wrapped into 5-7 blank rows: a ~430px dead band
   that starved the stage and left an A0 portrait ~300px wide. The
   editor's chrome is chrome; only the PAGE deserves the space. The
   template catalog keeps its two-up poster previews. */
.deck.poster-page .lay-picker{grid-template-columns:repeat(2,1fr);
  max-height:300px;}
.deck.poster-page .lay-lb{font-size:9.5px;}
.deck.poster-page .dbtn.lay{padding:5px;}
/* T426: a poster's strip tile has a taller (portrait) icon, which
   leaves its label ONE line where a slide tile's gets two -- so the
   name must not wrap, and it is the template's short name (00-page.js)
   at the slide tiles' size; the full name stays on the tooltip */
.deck.poster-page .lay-strip .lay-lb{white-space:nowrap;
  text-overflow:ellipsis;font-size:8px;}
.dc-menuwrap{position:relative;}
.dc-menu{position:absolute;left:0;top:calc(100% + 6px);z-index:30;
  background:var(--chrome-2,#16273a);border:1px solid #ffffff22;border-radius:8px;
  padding:5px;min-width:214px;display:flex;flex-direction:column;
  box-shadow:0 12px 34px #00000066;}
/* the house rule (T596): `display:flex` beats the UA's [hidden], and only
   menus inside .deck had `.deck [hidden]` to fall back on -- so the
   reader's App menu, once opened, stayed on screen after Esc, an outside
   click or a pick, and a menu on the tab row showed before it was asked */
.dc-menu[hidden]{display:none!important;}
/* T602: File in TWO COLUMNS, since New, Open and the App menu's rows
   joined it -- one column was taller than a laptop screen. Each column
   is an ordinary column of rows; a window too narrow for two gets one,
   and a window too short for the menu scrolls it rather than cut it */
.dc-menu.dc-menu-cols{flex-direction:row;align-items:flex-start;gap:4px;
  max-height:calc(100vh - 16px);overflow-y:auto;}
.dc-menu-cols>.dc-mcol{display:flex;flex-direction:column;min-width:214px;}
.dc-menu-cols>.dc-mcol+.dc-mcol{border-left:1px solid #ffffff14;
  padding-left:4px;}
@media (max-width:560px){.dc-menu.dc-menu-cols{flex-direction:column;}
  .dc-menu-cols>.dc-mcol+.dc-mcol{border-left:0;padding-left:0;}}
.dc-mi{text-align:left;background:none;border:none;color:var(--chrome-ink);
  font-size:12.5px;font-family:var(--sans);padding:8px 11px;
  border-radius:5px;cursor:pointer;transition:background .12s;}
.dc-mi:hover{background:color-mix(in srgb,var(--accent) 15%,transparent);}
.dc-msep{height:1px;background:#ffffff14;margin:4px 6px;}
/* a link can be a row too (Support, in the Help menu: T397) */
a.dc-mi{display:block;text-decoration:none;}
/* T537: a menu row's shortcut, at its right edge, as .vw-opt rows do */
.dc-mi kbd{float:right;margin-left:14px;font-family:var(--mono);
  font-size:9.5px;opacity:.7;}
/* the "Saved to" picker: a heading + a tick beside the current target */
/* T679: a menu's heading is a word, as .hd-lab has been since T219 --
   not 9px spaced capitals in the mono */
.dc-mhead{font-family:var(--sans);font-size:11px;font-weight:600;
  letter-spacing:0;text-transform:none;color:var(--chrome-ink-2);
  padding:7px 11px 3px;}
.dc-mhead::first-letter{text-transform:uppercase;}
/* T691: File's headings apart from its rows -- a rule above, the
   accent's ink, a little more room -- and a kind's choices one row of
   boxes (.dc-mchips) */
#dc-menu .dc-mhead{color:color-mix(in srgb,var(--accent) 70%,
  var(--chrome-ink));font-size:11.5px;font-weight:700;
  margin-top:6px;padding:9px 11px 5px;
  border-top:1px solid var(--chrome-line,#ffffff14);}
#dc-menu .dc-mcol>.dc-mhead:first-child{margin-top:0;border-top:0;
  padding-top:5px;}
#dc-menu .dc-mhead-warn{color:var(--coral,#ff6b57);}
.dc-mchips{display:flex;flex-wrap:wrap;gap:5px;padding:2px 9px 6px;
  max-width:300px;}
.dc-mchips>.dc-mi{padding:5px 9px;font-size:12px;border-radius:6px;
  border:1px solid var(--chrome-line,#ffffff1f);
  background:color-mix(in srgb,var(--chrome-ink) 5%,transparent);}
.dc-mchips>.dc-mi[hidden]{display:none;}
.dc-mchips>a.dc-mi{display:inline-block;}
body.light .dc-mchips>.dc-mi{border-color:#0000001f;background:#00000008;}
.dc-mi[aria-pressed="true"]{color:var(--chrome-ink);}
/* T626: a pressed .dbtn row is an accent-deep fill, and keeps that
   fill's ink -- the row rule above, and body.light .dc-mi, outranked
   .dbtn[aria-pressed] and put dark words on it (1.02:1 in Warm) */
.dbtn.dc-mi[aria-pressed="true"]{color:var(--on-accent-deep,#fff);}
.dc-mi[aria-pressed="true"]::before{content:"\2713  ";color:var(--cyan);}
.dc-mi[disabled]{opacity:.45;cursor:default;}
/* A named version is one selectable row plus its lifecycle. Keep the
   verbs worded and beside the name; a hidden right-click route is not a
   lifecycle (T50). */
#play-menu{min-width:min(330px,calc(100vw - 16px));}
/* T717: the custom-show rows are built as .dbtn, whose flex box centred
   "Every slide", a show's name and "New custom show" under the
   left-aligned rows written into the markup */
#play-menu .dbtn.dc-mi{justify-content:flex-start;}
.pl-cutrow{display:grid;grid-template-columns:minmax(0,1fr) auto auto;
  gap:3px;align-items:stretch;}
.pl-cutpick{min-width:0;white-space:normal;}
.pl-cutact{font-size:10px;padding:5px 7px;white-space:nowrap;}
.pl-cutact .bic{width:10px;height:10px;}
/* the label is a bare chevron now, so there is nothing left to clip —
   and an ellipsis on a live control is hiding a word by another name */
.dbtn.dc-target{font-family:var(--mono);font-size:10.5px;
  letter-spacing:.02em;white-space:nowrap;}
.dbtn.dc-target.tg-file{border-color:#46a89266;
  color:color-mix(in srgb,#46a892 40%,var(--chrome-ink));}
body.light .dc-mhead{color:var(--ink-3);}
/* the document moves aside for the DOCKED editor (create mode) only.
   Under the full editor (slide-editing) it is covered whole, and laying
   it out again narrower there, and back at its own width on the way out,
   was most of the layout of every switch between a deck and the page
   behind it -- Back to the collection, Open as slides (T614,
   2026-10-12) -- and it moved the page's scroll each time */
body.creating-docs:not(.slide-editing) .docs{
  margin-left:min(var(--dc-w),94vw);}
/* ...and a card says it can be placed only there too: under the full
   editor no card can be pointed at, and the cursor, inherited by all
   that is in a card, restyled every card's contents on each switch --
   most of the style of Back to the collection's frame (fix round 3,
   2026-10-17) */
body.creating-docs:not(.slide-editing) .card{cursor:copy;}
body.creating-docs:not(.slide-editing) .card:hover{
  outline:2px solid var(--cyan);outline-offset:2px;}

.deck-create{flex:1;overflow-y:auto;display:flex;flex-direction:column;
  min-height:0;background:var(--chrome-1,#0e1926);}
/* fixed so it hugs the panel's right edge in both creating (docked
   deck) and editing (flex column) modes, and survives panel scroll */
.dc-resize{position:fixed;top:0;bottom:0;width:6px;z-index:130;
  cursor:col-resize;
  left:calc(var(--presrail-w) + min(var(--dc-w),94vw) - 1px);}
/* T652: in the editor the column starts where the editor does, after
   the Files pane when that is open (app.css, --deck-left) */
.deck.editing .dc-resize{
  left:calc(var(--deck-left,var(--presrail-w)) + min(var(--dc-w),94vw) - 1px);}
.dc-resize:hover,.dc-resize.on{background:color-mix(in srgb,var(--accent) 40%,transparent);}
@media(max-width:860px){.dc-resize{display:none;}}
.dc-block{padding:10px 14px 9px;border-bottom:1px solid #ffffff14;}
/* the slides list is the main working area — give it the lion's share
   and let it be the panel's primary scroller */
.dc-block.dc-film{flex:1 1 auto;display:flex;flex-direction:column;
  min-height:240px;border-bottom:none;padding-bottom:8px;}
.dc-block.dc-film .film-list{flex:1;overflow-y:auto;min-height:0;}
.dc-label{display:block;font-family:var(--mono);font-size:9.5px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--chrome-ink-2);
  margin-bottom:8px;}
.dc-row{display:flex;gap:6px;flex-wrap:wrap;}
.dc-hint{font-size:11.5px;color:var(--chrome-ink-2);line-height:1.5;margin:9px 0 0;}
.dc-spring{flex:1;}
/* the presentation name lives on the left rail — no need to repeat it
   in the builder; keep the element for the File > Rename flow only */
#pres-current{display:none;}
/* the name block is a zero-height sliver until a rename is active — it
   exists so the rename input is NOT inside .dc-controls, which is
   display:none while editing (2026-08-20) */
.dc-name{padding:0;border-bottom:none;}
.dc-name:has(>#pres-name:not([hidden])){padding:10px 14px 9px;
  border-bottom:1px solid #ffffff14;}
.dc-controls{display:flex;flex-direction:column;gap:9px;}
#pres-name{width:100%;background:var(--chrome-2,#16273a);border:1px solid #ffffff22;
  color:#dce6ee;font-family:var(--sans);font-size:12.5px;padding:7px 9px;
  border-radius:6px;box-sizing:border-box;}
#pres-name:focus{outline:none;border-color:var(--cyan);}
.dbtn.lay[aria-pressed="true"]{background:var(--accent-deep,var(--cyan-deep));
  border-color:var(--accent-deep,var(--cyan-deep));
  color:var(--on-accent-deep,#fff);}
/* layout picker: little diagrams instead of words */
.dbtn.lay{padding:5px 7px;line-height:0;}
.layico{display:grid;gap:2px;width:34px;height:22px;}
.layico.full{grid-template-columns:1fr;}
.layico.halves{grid-template-columns:1fr 1fr;}
.layico.rows{grid-template-rows:1fr 1fr;}
.layico.quarters{grid-template-columns:1fr 1fr;
  grid-template-rows:1fr 1fr;}
.layico i{background:#8ba0b2;border-radius:2px;display:block;}
.dbtn.lay[aria-pressed="true"] .layico i{background:#fff;}
.layico.title{display:block;position:relative;}
.layico.title i{position:absolute;border-radius:2px;}
.layico.title .tl1{left:15%;right:15%;top:26%;height:24%;}
.layico.title .tl2{left:28%;right:28%;top:62%;height:12%;opacity:.5;}
.layico.blank{display:block;border:1.5px dashed #8ba0b2;
  border-radius:3px;}
.dbtn.lay[aria-pressed="true"] .layico.blank{border-color:#fff;}
/* scrollable slide-template catalog (buttons generated from LAYOUTS) */
.lay-picker{display:grid;grid-template-columns:repeat(3,1fr);gap:5px;
  max-height:224px;overflow-y:auto;overflow-x:hidden;
  padding:2px 3px 4px;margin:0;}
.lay-picker .lay{padding:4px;display:flex;flex-direction:column;
  align-items:stretch;gap:3px;line-height:1;height:auto;}
.layico2{position:relative;width:100%;aspect-ratio:16/9;background:var(--chrome-0,#0b141d);
  border:1px solid #ffffff1a;border-radius:3px;overflow:hidden;}
.dbtn.lay[aria-pressed="true"] .layico2{border-color:#fff;}
.layico2 .li-cell{position:absolute;background:#2a4761;
  border:1px solid #4d7ea3;border-radius:1px;box-sizing:border-box;}
.layico2 .li-text{position:absolute;box-sizing:border-box;opacity:.8;
  background:repeating-linear-gradient(#9fb2c2 0 1.5px,transparent 1.5px 4px);}
/* THE NAME WRAPS INSIDE THE TILE. It was nowrap with an ellipsis, but
   an ellipsis needs a width to bite on and this span had none: the
   button is a centred flex column, so "Title + text + panel" simply
   grew to 97px inside a 72px tile and painted across its neighbour --
   the T260 failure, in the gallery. max-width pins it to the tile and
   the words wrap into the room the icon leaves (three 8px lines fit in
   the 48px a tile has under its 17px icon). overflow:hidden stays as
   the floor for a name longer than any built-in one; the button also
   carries the full name as its title. */
/* T465: the label is the ribbon's own sans at 9.5px, and the tile
   is sized so two lines of it fit WHOLE under the icon (which gives
   up 14px of width for it): every two-line name in the strip and the
   Change layout grid was 8px monospace with its second line's
   descenders cut off, and a three-line one cut to a sliver
   (2026-09-15 review, measured). The grid takes the short name too. */
.lay-lb{font-family:var(--sans);font-size:9.5px;letter-spacing:0;
  color:var(--chrome-ink-2);text-align:center;line-height:1.1;
  max-width:100%;max-height:2.2em;overflow:hidden;}
.dbtn.lay[aria-pressed="true"] .lay-lb{color:var(--on-accent-deep);}
/* title-slide text inputs */
.title-editor{display:flex;flex-direction:column;gap:7px;}
.title-editor[hidden]{display:none;}
.title-editor input{background:var(--chrome-2,#16273a);border:1px solid #ffffff22;
  color:#dce6ee;font-family:var(--sans);font-size:12.5px;padding:8px 9px;
  border-radius:6px;}
.title-editor input:focus{outline:none;border-color:var(--cyan);}
.pane-editor[hidden]{display:none;}
#dc-edit{width:100%;}
/* freeform slot editor + film thumbnails: boxes at frame positions */
.pane-editor.freeform{display:block;position:relative;}
.pane-editor.freeform .pane.slot{position:absolute;padding:4px 16px
  4px 6px;}
.pane-editor.freeform .pane.slot .pane-t{font-size:9.5px;
  -webkit-line-clamp:2;}
/* T607: the slide drawn behind the frames (slideBackdrop), filling the
   view edge to edge, as the frames' percentages do; the frames over it
   are outlines -- dashed when you point at one, solid when chosen */
.pane-editor.freeform .pe-back{position:absolute;inset:0;width:auto;
  height:auto;padding:0;border:0;border-radius:inherit;
  pointer-events:none;}
.pane-editor.has-back .pane.filled .an-cell{background:none;
  border-color:transparent;}
.pane-editor.has-back .pane.slot.filled:hover{
  outline:1px dashed color-mix(in srgb,var(--accent) 70%,transparent);
  outline-offset:1px;}
.mini-diagram.free{display:block;position:relative;}
.mini-diagram.free .mini-pane{position:absolute;}
/* a thumbnail draws EVERY kind of item, not just placed cells. Each one
   sits at its page percentage, so the strip is a true scale model of the
   slide (2026-08-20). */
.mini-tx{position:absolute;color:var(--tk-ink,#dbe6ee);line-height:1.2;
  white-space:pre-wrap;overflow:hidden;max-width:100%;
  transform-origin:0 0;pointer-events:none;}
/* T467: a light deck's thumbnails carry dark words, as the page does */
.page-light .mini-tx{color:var(--tk-ink,#1b2733);}
/* T626: a title slide's words and a heading-style box, in Heading
   text, as on the canvas (.an-title, .an-head) */
.mini-tx.is-head{color:var(--tk-heading,#dbe6ee);}
.page-light .mini-tx.is-head{color:var(--tk-heading,#16222c);}
/* T494: a placeholder in a thumbnail is as faint as on the canvas
   (.an-ph), boxed hairline so the slot's shape reads at strip size */
.mini-tx.is-ph{opacity:.38;outline:1px solid currentColor;
  outline-offset:1px;border-radius:1px;}
.mini-tx.is-t,.mini-tx.is-s{text-align:center;transform-origin:50% 50%;}
/* T724: a code box, with the canvas box's own metrics (.an-code-pre) */
.mini-tx.mini-code{font-family:var(--mono);line-height:1.45;
  padding:.6em .8em;border-radius:2px;box-sizing:border-box;}
/* ...and its kept output under a rule (T732) */
.mini-code-out{display:block;margin:.4em -.8em 0;padding:.3em .8em 0;
  border-top:1px solid currentColor;opacity:.75;font-size:.9em;}
.mini-code-out.bad{color:var(--danger);}
.mini-code-fig{display:block;max-width:100%;height:auto;margin-top:.4em;}
.mini-it{position:absolute;overflow:hidden;pointer-events:none;}
.mini-it>svg{width:100%;height:100%;display:block;overflow:visible;}
/* a shape's outline sits ON its edge, half outside: clipped, a thin
   rectangle lost its bottom edge in the strip */
.mini-it.is-shape{overflow:visible;}
.mini-it.is-img img{width:100%;height:100%;object-fit:contain;
  display:block;}
.mini-it.is-img.is-crop img{object-fit:cover;}
.mini-it.is-img.is-win img{position:absolute;object-fit:fill;max-width:none;}
/* T522: a placed note or code cell is its own rendered body, zoomed to
   the thumbnail by the canvas's rule; nothing inside a miniature scrolls */
.mini-it.is-cell.an-cell .note,.mini-it.is-cell.an-cell pre,
.mini-it.is-cell.an-cell .cardbody{overflow:hidden;}
/* arrows share one overlay in the page's own 0..100 space */
.mini-svg{position:absolute;inset:0;width:100%;height:100%;
  pointer-events:none;overflow:visible;}
.mini-diagram.title{grid-template-columns:1fr;}
.mini-pane.is-title{background:var(--tk-surface,var(--chrome-4));}
.mini-pane.is-title::before{content:"";position:absolute;left:18%;
  right:18%;top:32%;height:18%;background:#4d90c0;border-radius:1px;}
.mini-pane.is-title::after{content:"";position:absolute;left:30%;
  right:30%;top:60%;height:9%;background:#4d90c066;}

/* ---------- slide editor ----------
   Editing docks like an IDE: the builder panel stays on the left and
   the slide canvas takes the document area. The document chrome (tabs,
   filters) is hidden while editing — it acts on the hidden documents —
   and comes back for cell-picking / on Done. */
/* The editor starts after the shared app rail, so its logo and live open
   items remain the same navigation in both views. The reader's header is
   not shown at all: T602 moved the open tabs INTO the editor's own top
   bar (app.js re-homes #open-tabs-row), where T596 had kept the reader's
   header up above the editor for them -- a row of tabs stacked over a
   row of controls, which is the layer the user asked to lose. */
.deck.editing{left:var(--deck-left,var(--presrail-w));top:0;}
body.slide-editing .apptop{display:none;}
/* The editor's auto-hidden slide strip translates left over its own grid
   column. Keep the shared application rail above it, including while an
   auto-hidden rail peeks back in, so Home is never covered. */
body.slide-editing .presrail,body.slide-editing .presrail-show{z-index:134;}
/* while editing, the panel is just chrome + film strip (the template
   catalog lives in the ribbon's Layouts dropdown) — keep it slim so the
   slide canvas gets the width */
/* 200px: the panel is ONLY thumbnails now, and the width goes to the
   toolbar + canvas instead (2026-08-05) */
/* 200px was the RESTING width, not a ceiling — but it was written as a
   hard cap with the resize handle hidden beside it, so the slide column
   was the one part of the editor nobody could make bigger (2026-08-22,
   user: "the thumbnail part should be dragable to make bigger or
   smaller"). The old expression stays as the clamp's default, so a
   session that has never touched the handle is unchanged. */
/* The upper bound is MEASURED, not 46vw. The column and the ribbon are
   two tracks of one grid, so a strip dragged past the width the row of
   tools needs clips the end of that row off (overflow-x:clip, and no rung
   left). fitFilmMax() publishes the ribbon's own floor as --film-max; the
   46vw fallback is what this said before JS has run once (T80). */
.deck.editing .deck-create{
  width:clamp(150px,var(--film-w,min(var(--dc-w),200px)),var(--film-max,46vw));
  border-right:1px solid #ffffff22;}
.deck.creating .deck-create{width:min(var(--dc-w),94vw);}
/* ---- the column hides ITSELF (off by default) -------------------------
   Same taskbar model as the document view's presentations panel
   (body.prrail-auto, app.css): the surface leaves, the page takes the
   width, and it slides back when the pointer reaches the left edge.
   THE TRACK goes to zero, not the panel. .deck-create is grid track 1,
   so its clamp width is what holds the stage narrow -- but the PANEL has
   to keep that width or translateX(-100%) is 100% of nothing and its
   contents simply overflow a 0px box (the exact failure app.css:411-414
   records for the rail). Keeping it a grid item on grid-row:2/5 is also
   what puts it under the QAT with no measured offset.
   Slides (#vw-versions) is the manual half and stays as it is: it hides
   the THUMBNAILS inside a column that keeps its width. This hides the
   column. */
.deck.editing.film-auto{grid-template-columns:0 minmax(0,1fr);}
/* T469: a POSTER has nothing in the column at all -- no film, no name
   row, no controls while editing (rename is the top bar's since T447)
   -- so the track goes too; it kept a 200px empty column beside the
   sheet (2026-09-15 review) */
.deck.editing.poster-page{grid-template-columns:0 minmax(0,1fr);}
.deck.editing.poster-page>.deck-create{display:none;}
.deck.editing.film-auto>.deck-create{position:relative;z-index:120;
  transform:translateX(-100%);transition:transform .18s ease;
  box-shadow:0 0 40px #00000066;}
.deck.editing.film-auto.film-peek>.deck-create{transform:none;}
.deck.editing #layout-row{display:none;}
.deck.editing .dc-resize{display:none;}
/* ---- PowerPoint-style ribbon: labelled groups, always the same height ----
   ONE wrapping flow: the static groups and the contextual format groups are
   display:contents, so every group flows into the same rows — no dedicated
   row per section, no wasted band. min-height reserves two rows so
   selecting/deselecting never grows the ribbon or shifts the canvas. */
/* ONE row that scrolls sideways when it must, never a stack of rows.
   Wrapping was what made this read as "rows of things": a group could
   break across rows, so its label landed under whatever happened to be
   beneath it and nothing marked where one group ended. PowerPoint never
   wraps either. A constant height also means selecting an item can no
   longer shift the canvas. */
/* ---- THE RIBBON'S MEASUREMENTS, IN ONE PLACE (T369) ------------------
   Every number below used to be written out between four and sixteen
   times -- the 65px band in four rules, the 26px button height in
   eleven, the 72px tile in sixteen plus three calc() strings that
   multiplied it. "One height, one baseline" was a comment, not a
   mechanism, and every recurrence of "the buttons are all different
   sizes" has been a rule that missed one of the copies.

   They are tokens now, so the ribbon has one set of measurements and a
   density change is one line. The values are PowerPoint's: its ribbon
   body is ~92px, its small command is a ~16px icon, a ~4px gap, the
   word, and ~10px of side padding. Ours keeps the 26px button height
   the user asked for (2026-08-20, "buttons could also have more
   height") and takes the air out around it instead. T633 made the
   group names smaller and tighter (2026-10-23, owner: "the ribbon
   extends too far down"), and since T639 they cost the bar nothing at
   all: a group's name shows under it while the pointer rests on it
   (owner, 2026-10-24: "all the little titles for section ... make the
   ribbon more vertical"). The bar is the band and 3px either side, 67px
   where PowerPoint's is 92.
   T681: that is Compact's. Full size wears the names again, under the
   groups at rest (2026-10-29, owner: "the non-compact mode was supposed
   to have the below headings for groups wasn't it? Right now the only
   difference it seems is the buttons change size"), so its bar is T633's
   80px: the band, the name under it, and the air around them.

   A test pins these values (tests/test_ribbon_metrics.py): a token the
   whole sheet reads is only as good as the one place it is stated, and
   a substring test that has stopped naming any number cannot see it
   change. ---- */
.deck{
  --rbn-bar-h:80px;        /* the bar: a group's whole stack + its rule */
  --rbn-btn-h:26px;        /* a worded button, everywhere */
  --rbn-track:28px;        /* the grid row it is centred in */
  --rbn-row-gap:4px;       /* between the two tracks */
  --rbn-band:60px;         /* 2 tracks + the gap: a group's body */
  --rbn-col-gap:3px;       /* between columns */
  --rbn-btn-px:6px;        /* a button's side padding */
  --rbn-btn-gap:4px;       /* its icon to its word */
  --rbn-grp-px:6px;        /* a group's side padding */
  --rbn-tile-w:64px;       /* THE tile */
  --rbn-tile-h:56px;
  --rbn-tile-gap:4px;      /* and the step the gallery arrows scroll by,
                              which is --rbn-tile-h + this (ROW in
                              55-sections-and-strip.js) */
  --rbn-txstrip-max:684px; /* T463: the text-type strip's ceiling -- its
                              tiles are name-wide, so it is as wide as
                              they are up to this, and the ladder lowers
                              it a rung at a time (the nine built-in
                              types fit under it at rest) */
}
/* T639: COMPACT (.rbn-dense, set in 05-figures-and-ribbon.js) -- the
   same ribbon with less air, the default in a browser (owner: "a more
   compact layout (default for browsers), as you have a lot less space
   than using the app"). Only HEIGHTS move. The words stay 12px, and the
   widths and the density ladder's rungs are untouched -- a rung must be
   a step down from the resting width, and that width has not changed --
   so nothing folds sooner than it does at full size. The gallery's row
   step follows the tile (ROW_DENSE in 55-sections-and-strip.js). */
.deck.rbn-dense{
  --rbn-bar-h:59px;
  --rbn-btn-h:24px;
  --rbn-track:26px;
  --rbn-row-gap:2px;
  --rbn-band:54px;
  --rbn-tile-h:50px;
}
.deck.rbn-dense:not(.rbn-side) .edit-tools .rbn-grp{padding-top:2px;
  padding-bottom:2px;}
.deck.rbn-dense .edit-tools .dbtn.rbn-sm{padding-top:2px;padding-bottom:2px;}
.deck.rbn-dense .edit-tools .fx-tile{gap:3px;}
.deck.rbn-dense .edit-tools .fx-tile .bic{width:20px;height:20px;}
.deck.rbn-dense .rbn-tabs{height:26px;}
.deck.rbn-dense .deck-qat{min-height:30px;padding-top:2px;padding-bottom:2px;}
/* ONE row, and it neither wraps NOR scrolls. Wrapping fragmented groups
   across rows ("just all these rows of things"); a sideways scrollbar was
   rejected just as flatly. So width comes from DENSITY: fitEditRibbon()
   walks the .erc1-.erc4 ladder below until it fits, and no stage ever
   hides a word — that has been refused twice before. If even the tightest
   stage cannot fit, the toolbar moves to the right-hand edge, where it
   has a whole column to use. */
.edit-tools.ribbon{display:flex;flex-wrap:nowrap;align-items:stretch;
  gap:0;padding:0 10px;border-bottom:1px solid #ffffff14;
  background:var(--chrome-1,#0e1926);flex:none;height:var(--rbn-bar-h);
  /* Clip SIDEWAYS only. A plain overflow:hidden also clipped every
     dropdown that opens downward — the Shape menu looked like it was
     rendering behind the canvas when it was really being cut off at the
     ribbon's edge (2026-08-07, user). Fixing this per-menu would mean
     remembering floatMenu() at nine separate call sites; one rule here
     covers every menu, including ones added later. */
  overflow-x:clip;overflow-y:visible;}
/* T627: the first open of a session draws the slide before the ribbon's
   first fit (ribbonFitAfterFrame); for that one frame the bar is there,
   at its height, and its controls are not -- an unfitted row is never
   seen. Along the top they are not even laid out until then (the bar's
   height is a token and it spans the stage's 1fr column, so neither the
   stage nor the strip's column is sized by what is in it); a side
   ribbon is a column sized by its contents, so it only hides them. */
.edit-tools.ribbon.rbn-unfit>*{visibility:hidden;}
/* T639: IN FRONT OF THE SLIDE COLUMN'S HANDLE. #film-resize is fixed,
   z-index 130 and the window's whole height, and the bar was not
   positioned, so the handle lay over the ribbon where the column meets
   it: the first few px of a group there were the handle's (its tooltip,
   its col-resize cursor). The bar takes the 130 T631 gave the
   auto-hidden bar, all the time; coming later in the markup it wins
   the tie, and it stays under the tab strip (131) and the title row
   (132). */
.deck.editing>.edit-tools{position:relative;z-index:130;}
.deck:not(.rbn-side)>.edit-tools.ribbon.rbn-unfit{content-visibility:hidden;}
.rbn-static{display:contents;}
/* A GROUP is the unit you scan: its controls sit together over one
   centred label, with a rule between it and the next. Rebuilt 2026-08-07
   (user: rows of identical buttons "just confusing", next to a
   PowerPoint ribbon) — the old version had every group the same shape
   and the same button size, so nothing told you where one ended, what
   was a primary action, or what was a toggle. Its padding is
   --rbn-grp-px, and PowerPoint's is about the same: the rule between
   two groups does the separating, not a wide margin.
   T633: 4px over the band and 2px under the name, with 2px between
   them; the name is the band's foot, not a row of its own.
   T639: in Compact the name is out of the stack along the top (it shows
   on hover, below), so the group is the band and 2px either side
   (.deck.rbn-dense below). T681: at full size it is T633's again. The
   side ribbon keeps the name in its column as a heading. */
.rbn-grp{display:flex;flex-direction:column;align-items:center;
  justify-content:space-between;gap:2px;
  padding:4px var(--rbn-grp-px) 2px;
  position:relative;min-width:0;flex:none;
  border-right:1px solid #ffffff1c;}
.rbn-grp:last-child{border-right:none;}
/* the hint sits after the last group and must not look like a group */
/* The hint is a reminder, not a control, so it is the FIRST thing to go
   when the row is tight — but it goes whole. An ellipsis ("Clic…") is
   text truncation, which is the same sin as hiding a word; it is dropped
   by measurement in fitEditRibbon, before any density rung. */
.edit-tools.ribbon .et-hint{border-left:none;align-self:center;
  margin-left:auto;padding:0 10px;flex:none;white-space:nowrap;}
.deck.erc-nohint .edit-tools.ribbon .et-hint{display:none;}
.rbn-grp[hidden]{display:none;}
/* the body holds big buttons and stacks of small ones side by side */
/* A GRID of two fixed rows, filling column by column. Wrapping a flex row
   was guesswork: the contextual groups are eleven bare buttons each, and
   capping their width to force two rows actually produced four-plus rows
   inside a clipped 58px box — controls you could not see or reach
   (2026-08-07). Two 26px rows, flowed by column, cannot do that: a
   control either has a cell or the group is visibly wider. */
/* Two rows filled ACROSS, not down. grid-auto-flow:column filled the
   first column top-to-bottom before moving right, so Insert read
   "Notebook cell, Text box, Shape, Arrow…" down the columns while the eye
   read it across the rows (2026-08-07, user: "rows not columns"). The
   column COUNT is set per group by fitEditRibbon, which is the only place
   that knows how many controls are currently visible. */
/* The track is --rbn-track and the button inside it is --rbn-btn-h,
   which is deliberately the smaller of the two: the button is a target
   you hit all day (2026-08-20, user: "buttons could also have more
   height") and the 2px of track around it is what lets a control that
   arrives a little taller be absorbed rather than burst the band. T369
   took the track from 30 to 28 and the band from 65 to 60; the button
   itself did not move. */
/* T207: COLUMN-MAJOR, the PowerPoint way (2026-09-02, user: "buttons
   of all shapes and sizes... look at PowerPoint"). Controls fill a
   column top-to-bottom, two to a column, before the next column
   starts, so the two buttons that share a column share a width and
   nothing else does: a row-major grid made every column as wide as
   its widest member in EITHER row, which is how "U" ended up the
   width of "Paragraph". A tall control spans both rows and takes a
   column of its own. The markup pairs neighbours deliberately. The
   column count is no longer a variable anything sets. */
.rbn-row{display:grid;grid-auto-flow:column;
  grid-auto-columns:max-content;
  grid-template-rows:var(--rbn-track) var(--rbn-track);
  row-gap:var(--rbn-row-gap);column-gap:var(--rbn-col-gap);
  align-items:stretch;justify-items:start;height:var(--rbn-band);}
/* the tall things span both rows rather than sitting in one */
.rbn-row>.rbn-stack{grid-row:1/span 2;}
/* ...but never a CELL. It is one track high by rule, so a `rbn-tall` on
   one reserves a row nothing can fill -- how "How it arrives" ended up
   300px wide on a single row of a 60px band (T370). sizeRibbonGroups
   counts it as one cell to match. `.rbn-odd` is excepted: that class
   means "the last cell of an odd group, centred in the band", which is
   a span the cell really does want. */
.rbn-row>.rbn-cell.rbn-tall:not(.rbn-odd){grid-row:auto;}
/* a dropdown's WRAPPER is the cell; the button fills it */
.rbn-row>.sh-drop,.rbn-row>.dc-menuwrap{display:flex;}
/* ...and a wrapper whose button is hidden must not KEEP its cell. The
   column count skips it ("a wrapper counts as the one cell it
   contributes") but the grid did not, so the two disagreed by one cell
   per hidden button and the overflow landed in an implicit third row —
   which is how the opacity slider printed on top of the COLOUR caption
   the moment it shared a group with the sometimes-hidden Fill button
   (2026-08-17). One rule, every wrapper, including ones added later. */
.rbn-row>.sh-drop:has(>.dbtn[hidden]),
.rbn-row>.dc-menuwrap:has(>.dbtn[hidden]){display:none;}
.rbn-row>.sh-drop>.dbtn,.rbn-row>.dc-menuwrap>.dbtn{width:100%;height:100%;}
/* the ONE wrapper that holds two real buttons rather than one. Scoped to
   .tx-split so the rule above still governs every other wrapper: Text
   takes the cell and the caret takes what it needs, which is about 18px.
   The caret is never hidden — the :has(>.dbtn[hidden]) rule above would
   take the whole control down with it (2026-08-22). */
.rbn-row>.sh-drop.tx-split>.dbtn{width:auto;}
.rbn-row>.sh-drop.tx-split>.dbtn[data-tool]{flex:1;min-width:0;}
.rbn-row>.sh-drop.tx-split>.tx-caret{flex:none;padding-left:4px;
  padding-right:4px;}
/* T463: the split whose button is a TILE (Send it away): the caret is
   the tile's height, centred beside it, rather than the band's */
.rbn-row>.sh-drop.tx-split.rbn-tall>.tx-caret{height:var(--rbn-tile-h);
  align-self:center;}
/* T748: ...and the two are ONE control, as Present and its caret are on
   the row above (2026-11-02, owner: "the add a clone drop down menu
   button looks weird. Can't it look more like the present button"): no
   gap, the inner corners square, one faint seam between them */
.rbn-row>.sh-drop.tx-split.rbn-tall{gap:0;align-items:center;}
.rbn-row>.sh-drop.tx-split.rbn-tall>.fx-tile{border-top-right-radius:0;
  border-bottom-right-radius:0;}
.rbn-row>.sh-drop.tx-split.rbn-tall>.tx-caret{border-top-left-radius:0;
  border-bottom-left-radius:0;border-left-color:#ffffff14;margin-left:-1px;
  padding-left:5px;padding-right:5px;}
.rbn-row>.sh-drop.tx-split.rbn-tall>.tx-caret:hover{
  border-left-color:var(--cyan);}
.tx-type-menu{min-width:248px;}
/* two or three controls that are ONE decision and therefore ONE cell —
   the zoom stepper, for instance, whose minus and plus must never end up
   on different rows */
.rbn-cell{display:flex;align-items:stretch;gap:3px;height:var(--rbn-track);}
/* The readout renames itself from "Zoom 25%" to "Zoom 100%", and it is the
   widest thing in the View group's first column — so without a floor the
   whole group breathed as you zoomed and shoved Output sideways with it.
   Held to the longest label it can hold, in CHARACTERS so it survives
   every density rung, which is the same fix the app bar's view column
   already uses for the Tree button that renames itself. */
#zoom-val{min-width:calc(9ch + 2 * var(--rbn-btn-px) + 2px);
  justify-content:center;}
/* T219: the group's name in words you can read from a desk away --
   it was 8.5px spaced capitals (2026-09-03, user: "the words like
   'Slide', 'Layout' and all that are tiny down the bottom").
   T633: 10px now, and still sans in sentence case, which is what made
   the 8.5px capitals tiny (2026-10-23, owner: "the ribbon extends too
   far down" -- the names first). It is the line the band stands on:
   a word's height and no more, with its descenders in the group's 2px
   foot. The buttons' words stay 12px; a name is a label, not a target. */
.rbn-lab{font-family:var(--sans);font-size:10px;letter-spacing:0;
  text-transform:none;color:var(--chrome-ink-2);line-height:1;white-space:nowrap;}
/* T639: THE NAME ON HOVER (2026-10-24, owner: "all the little titles for
   section e.g. like the page layout and stuff make the ribbon more
   vertical, perhaps they could go or be on the side or something").
   Three were shown side by side, measured live: gone (Tight / Normal /
   Airy lose the word Spacing), standing up beside each group (every
   group wider, so Header & footer folded at 1280px), and this -- picked
   by the owner. The name is a small label hung under its group while
   the pointer rests on the group or the keyboard is inside it (.rbn-kbd,
   initRibbonNames in 05-figures-and-ribbon.js), over the
   slide's margin, so it costs neither height nor width. It is still in
   the group's markup, read out with it, and still the door's name when
   the group folds (a folded door says its name, so it shows none).
   Pointer events pass through it to the slide. The short delay keeps a
   sweep across the row from flashing every name. AT REST IT IS A 1px
   CLIPPED BOX (the visually-hidden pattern), not opacity:0: a name wider
   than its group stood out past it, and even an invisible box widens the
   bar's scroll width -- which the fit and the never-wraps walk both read
   (a one-row layout measured 2-3px over with its rungs unspent). Not
   display:none either, which would take the name from a screen reader.
   The fade is an animation, since the box only gets its size as it is
   shown. */
/* T681: Compact's. At full size the name stands under its group, in
   the stack -- except under a fold's door, which says its name itself */
.deck:not(.rbn-dense):not(.rbn-side) .edit-tools .rbn-grp.rbn-folded>.rbn-lab{
  visibility:hidden;}
.deck.rbn-dense:not(.rbn-side) .edit-tools .rbn-grp{justify-content:center;}
.deck.rbn-dense:not(.rbn-side) .edit-tools .rbn-grp>.rbn-lab{position:absolute;
  left:50%;top:calc(100% - 4px);transform:translateX(-50%);z-index:5;
  width:1px;height:1px;padding:0;border:0;overflow:hidden;
  clip-path:inset(50%);border-radius:5px;background:var(--chrome-3);
  font-size:11px;color:var(--chrome-ink);pointer-events:none;}
.deck.rbn-dense:not(.rbn-side) .edit-tools .rbn-grp:not(.rbn-folded):hover>.rbn-lab,
.deck.rbn-dense:not(.rbn-side) .edit-tools .rbn-grp.rbn-kbd:not(.rbn-folded)>.rbn-lab{
  width:auto;height:auto;padding:3px 8px;border:1px solid var(--chrome-line);
  overflow:visible;clip-path:none;box-shadow:0 4px 14px var(--shadow);
  animation:rbn-lab-in .12s .25s both;}
@keyframes rbn-lab-in{from{opacity:0;}to{opacity:1;}}

/* --- ONE button size, everywhere. Four sizes (big / small / icon /
   whatever the moved File controls were) meant nothing shared a baseline
   and no size carried meaning — "so many sizes, and they don't align, and
   they are just kind of everywhere" (2026-08-07). Emphasis is a JOB FOR
   COLOUR: Present is accented, everything else is identical, so the eye
   has exactly one thing to land on instead of six competing ones.
   `.rbn-big`, the icon-over-label button that survived for that one
   accented control, went with it: Present became an ordinary button in
   the Output group and nothing has carried the class since. Thirteen
   rules were still being shipped for it, four of them rungs of the
   density ladder, which made the ladder read as though it still had a
   lever it had not had for ten days (2026-08-17 audit). --- */
/* every ribbon button is the same height and sits on the same baseline */
/* THE HEIGHT OF A RIBBON BUTTON, in one place. A joined run is on this
   list too (T310): .rbn-cell is a fixed --rbn-track so a dropdown wrapper
   fills its grid track, and align-items:stretch then pushed the segments
   inside a run to 29px while every button beside them sat at 26 --
   nine buttons across Design and Animation standing 3px proud of their
   own row ("Button spacing and sizing still weird", 2026-09-05). The
   RUN takes the canonical height and its segments fill it, so the two
   cannot drift apart again at any density rung. */
.rbn-row>.dbtn,.rbn-row .sh-drop>.dbtn,
.rbn-row .dc-menuwrap>.dbtn,
.rbn-row>.rbn-cell.rbn-seg{height:var(--rbn-btn-h);box-sizing:border-box;
  align-self:center;}
/* two or three small buttons stacked in the height of one big one */
.rbn-stack{display:flex;flex-direction:column;gap:3px;
  justify-content:center;}
.rbn-stack.rbn-cols{flex-direction:row;align-items:stretch;gap:3px;}
.rbn-stack .rbn-col{display:flex;flex-direction:column;gap:3px;
  justify-content:center;}
.dbtn.rbn-sm{display:flex;align-items:center;gap:var(--rbn-btn-gap);
  padding:3px var(--rbn-btn-px);
  font-family:var(--sans);font-size:12px;white-space:nowrap;min-height:0;
  line-height:1.4;}
/* the flex gap is the ONLY spacer here: `.dbtn .bic` also carries
   margin-right:4px, which stacked on it, so a button with a .bic had
   10px between icon and word and one with a bare svg had 6px -- two
   rhythms on one row, and 4px of width on most of the bar. */
.dbtn.rbn-sm i,.dbtn.rbn-sm svg{width:15px;height:15px;flex:none;
  margin-right:0;}
/* a row of icon-only squares, for things whose icon says it all */
.dbtn.rbn-ico{display:flex;align-items:center;justify-content:center;
  width:var(--rbn-btn-h);height:var(--rbn-btn-h);padding:0;font-size:12px;}
.dbtn.rbn-ico i,.dbtn.rbn-ico svg{width:14px;height:14px;}
/* Save + its destination chevron, welded into one split button so they
   read as one decision rather than two rival save controls */
.dc-savegrp{display:flex;align-items:stretch;}
.dc-savegrp .dbtn{border-radius:0;}
.dc-savegrp>.dbtn:first-child{border-radius:6px 0 0 6px;}
.dc-savegrp .dc-menuwrap>.dbtn{border-radius:0 6px 6px 0;
  border-left-color:#ffffff14;padding-left:6px;padding-right:6px;}
.dc-savegrp .dc-menuwrap>.dbtn:hover{border-left-color:var(--cyan);}
/* ---- TWO REGIONS, and the rule the bar keeps above all others: NOTHING
   THAT IS ALWAYS THERE MAY MOVE WHEN YOU SELECT SOMETHING (2026-08-17,
   user, having asked before: "having buttons jump around sucks ... have
   everything that stays constant always in the one space on the left, and
   everything new always appears on the right").

   LEFT is constant. File, Slide, View and Output are on screen in that
   order whatever you have selected, and nothing further right can push
   them, because flex lays out in order and they come first.

   RIGHT is the region that changes: Notebooks and Insert while nothing is
   selected, the selected item's own groups when something is. The swap
   therefore happens at ONE boundary, at the far end, and the constant
   half never feels it. Selecting a line used to insert four groups in the
   MIDDLE — View slid 150px sideways and Output vanished (2026-08-17
   screenshots).

   Groups also pack left rather than being flung at the window edge by an
   auto margin, which turned every spare pixel into one void in the middle
   of the bar — ~560px of it once File stopped carrying Close the editor
   ("there is lot's of weird space around"). ---- */
.rbn-file{order:1;}
.rbn-slide{order:0;}      /* T215: the page itself first on Design */
.rbn-pagesize{order:0;}   /* T464: its size beside it, then the layouts */
/* T479: the Background block -- two columns of two tracks each and the
   deck-wide verb, on the shelf or in a group */
.bg-block{display:flex;align-items:center;gap:12px;}
.bg-col{display:flex;flex-direction:column;gap:4px;}
.bg-cell{height:var(--rbn-track);align-items:center;}
.bg-cell .cell-lab{min-width:72px;}
.bg-run{display:flex;align-items:center;gap:3px;}
.bg-run .bg-chip{width:20px;height:20px;}
.bg-run .bg-w,.bg-run .bg-auto{font-size:10.5px;padding:2px 7px;}
.bg-push{white-space:nowrap;}
.rbn-view{order:3;}
/* T639: the Window group after View, at the tab's end -- set once and
   left, so it comes after what you look at the page with */
.rbn-window{order:4;}
/* T681: View's groups between Views and Window, in the markup's order */
.rbn-vguides,.rbn-vover,.rbn-vcheck,.rbn-vpanels{order:3;}
/* Design reads Slide, Page furniture, Type -- the markup's order.
   Without a rung Page furniture sat at 0 and came FIRST (T178). */
.rbn-furn{order:3;}
/* ---- everything below here is the CHANGING region. Output and Notebooks
   belong to it because they stand down for a selection: a group that can
   disappear cannot be part of the half that promises never to move. ---- */
/* Output is gone: Print check was its only control, and one button
   under its own heading is a heading doing no work. It sits with the
   other ways of LOOKING at the page now (2026-08-20). */
.rbn-type{order:4;}
/* T444: the deck's type on Text follows Write; the deck-wide colours
   and spacing on Design follow Page furniture */
.rbn-decktype{order:6;}
/* T545: Typing -- AutoCorrect's switch -- after the deck's type; with
   no rung it sat at 0 and came first */
.rbn-typing{order:7;}
.rbn-deckwide{order:4;}
/* T444: the Style system is a tall tile, like History (T463: sized by
   the one standing-tile rule beside .fx-tile) */
/* The default contextual surface is two tabs, rather than one long tray:
   Style is how a thing looks; Object is where it is, where it came from,
   and how it is reused (2026-09-11, ribbon-layout correction). */
.rbn-fontgrp{order:0;}
.rbn-paragrp{order:1;}
.rbn-linegrp{order:2;}
/* T289: transitions lead the Animation tab, the way the Transitions
   tab leads Animations in PowerPoint. Exit and Page turn are given
   rungs at the same time: without one a group sits at 0 and comes
   FIRST, which is how "Disappear" and a flip book's page turn were
   arriving ahead of "Appear" (the same latent bug deck.css:1341
   already records for Page furniture, and the 2026-09-05 review found
   again on Home). */
/* T594: Slide transition is on the Present tab now, after the talk's
   own groups (Play, Version, Talk are 1-3) */
.rbn-trans{order:4;}
.rbn-anim{order:1;}
.rbn-exit{order:3;}
.rbn-focus{order:3;}      /* T472: after Leaves early, before Motion */
.rbn-motion{order:4;}     /* T385: after Leaves, before the slide */
.rbn-flipfx{order:5;}
/* T453: the choosers lead and the two groups of VERBS follow them
   (2026-09-14, user: "put all the ones for whole slide and build order
   to the right hand side"). They are the buttons you press rather than
   the options you pick, so they keep a place of their own that no
   chooser can push around. T463: they follow the choosers rather than
   being pushed to the far edge -- the shelf takes a line of its own
   (below), so the hole that margin-left:auto left in the middle of the
   row was buying nothing, and it was the one tab whose groups did not
   pack from the left (2026-09-15, user: "the animations tab still
   looks odd"). */
.rbn-build{order:8;}
.rbn-rule{order:9;}   /* T625: the verb about many slides, after them */
/* T594: BUILD ORDER LEADS. With four groups on the tab there is no row
   to squeeze it out of, and the Animation panel is the one door that
   holds everything the tab no longer shows, so it comes first, where a
   narrow window never reaches it (T589 was the rescue for its old seat
   at the far right). */
.rbn-order{order:0;}
/* ---- T453: THE SHELF ------------------------------------------------
   One strip in the ribbon that a chooser's whole row moves into, so the
   options land IN the bar rather than in a pop-up over the slide, and
   only ever one row at a time. It takes the middle: the choosers are to
   its left, the verb groups to its right, and it collapses to nothing
   when it is empty so the ribbon looks exactly as it did. */
/* The shelf gets a LINE OF ITS OWN while it is open, and no space at
   all while it is not. Squeezed into the gap between the choosers and
   the verb groups it had about 230px, which showed two and a half of
   the thirteen movements -- and there is no gap to grow into, because
   the row is already full.
   T498: A ROW OF ITS OWN, NOT A WRAPPED LINE. This was flex-wrap:wrap
   with the shelf on a 100% basis, and the comment here claimed line
   one was "exactly the groups it always was" -- it was not: the
   groups were items of the same wrapping container, so once the fold
   ladder had nothing left to give (every chooser compact, Leaves early
   folded, Build order and Whole slide never folded by T445) the last
   group went onto the shelf's line instead of clipping, and the bar
   grew from 157px to 258px and shoved the slide down (Animation with a
   selection at <=1050, the third review pass). The bar is a two-row
   GRID while a shelf is open: every group is pinned to row one and
   auto-placed across it in order-modified document order -- the same
   `order` the flex row honours -- so row one is a nowrap row that clips
   sideways exactly as the closed bar does, and the shelf is row two
   across the whole width. Sixty-three max-content columns and a 1fr
   tail rather than an implicit grid: the shelf spans 1/-1, which needs
   explicit lines, the empty columns cost nothing, and the tail is what
   lets the shelf reach the far edge when the groups do not. The
   shelf's own width is contained so its content (twenty-two shapes)
   cannot widen the columns the groups sit in. Closing it restores the
   flex row and the ribbon's own height. A side rail (T465) never opens
   a shelf and keeps its column.
   .shelf-open is set by rbnShelfOpen and cleared by rbnShelfClose, the
   only two writers of the shelf's `hidden` -- not a :has(.rbn-shelf...)
   on the bar, which made every change anywhere in the ribbon re-walk
   its three thousand elements (2026-10-09, speed). */
.deck:not(.rbn-side) .edit-tools.ribbon.shelf-open{
  display:grid;grid-template-rows:var(--rbn-bar-h) auto;
  grid-template-columns:repeat(63,max-content) minmax(0,1fr);
  height:auto;min-height:var(--rbn-bar-h);}
.deck:not(.rbn-side) .edit-tools.ribbon.shelf-open .rbn-grp{
  grid-row:1;}
.deck:not(.rbn-side) .edit-tools.ribbon>.rbn-shelf:not([hidden]){
  grid-row:2;grid-column:1/-1;contain:inline-size;min-width:0;}
.rbn-shelf{min-width:0;display:flex;
  align-items:center;gap:9px;padding:2px 12px;
  border-top:1px solid var(--chrome-line,#ffffff1f);}
.rbn-shelf[hidden]{display:none!important;}
/* a word in the sans, as a menu's heading is (T679) -- not spaced
   capitals in the mono ("SHAPES", 2026-10-30 review) */
.rbn-shelf-name{flex:none;color:var(--chrome-ink-2);
  font:600 11px var(--sans);letter-spacing:0;text-transform:none;}
/* THE SCROLLER IS THE BODY, not the shelf. Twenty-two shapes are wider
   than any window, and with the shelf itself scrolling, its own name and
   its close button scrolled away under the tiles -- the X sat on top of
   whichever shape happened to be beneath it. Only the row moves now; the
   two things that frame it stay put. */
.rbn-shelf-body{display:flex;align-items:center;flex:1 1 auto;min-width:0;
  overflow-x:auto;overflow-y:hidden;}
/* ONE LINE, not the group's two. A .rbn-row is a two-track grid that
   flows down and then across, which is right inside a group 90px tall
   and wrong on a shelf that has a whole width to spend: it showed three
   of the thirteen movements and hid the rest in a second track nothing
   could see. Here the row is a flex line and everything is on it. */
.rbn-shelf-body>.rbn-row{display:flex;align-items:center;
  height:auto;column-gap:var(--rbn-col-gap);}
.rbn-shelf-body>.rbn-row>*{flex:none;}
/* A tile STRIP is a scroll box inside its group -- a fixed height, wrap
   on, overflow hidden, and little arrows to page through it. On the
   shelf there is nothing to scroll past: it lays its tiles out in one
   line and shows all of them, which is the whole point of coming here.
   The arrows go with the scrolling. */
.rbn-shelf-body .strip-frame{overflow:visible;width:max-content;
  flex:none;}
.rbn-shelf-body .strip-frame>.fx-strip.fx-strip{flex-wrap:nowrap;overflow:visible;
  width:max-content;max-width:none;}   /* T469: not the row's 3- or 4-tile width
  (the class twice outranks each strip's own width rule, which comes later) */
.rbn-shelf-body .strip-nav{display:none;}   /* T469: the column, not just its buttons */
.rbn-shelf-body .strip-more,.rbn-shelf-body .strip-prev,
.rbn-shelf-body .strip-next{display:none;}
/* T454: a row too wide for the bar says so, rather than simply ending.
   The fade is on the SCROLLER, so it marks the edge the tiles run off
   and leaves the name and the close button alone. */
.rbn-shelf.can-scroll .rbn-shelf-body{
  mask-image:linear-gradient(90deg,#000 calc(100% - 28px),transparent);}
/* last in the line, outside the scroller, so it is always reachable and
   never over a tile */
.rbn-shelf-close{flex:none;align-self:center;}
/* ---- T586: THE SHELF IS ONE SLIM LINE --------------------------------
   (2026-09-30, user: "the drop down menu like this with things like
   shapes here, just makes the actual view of the screen so so small.
   This is on a laptop, but even on my big monitor before I was finding
   that it was getting really squished".) The shelf laid its options out
   as full ribbon tiles -- 56px, icon over word, in a 60px band -- over a
   scrollbar of its own, so opening Shapes stacked ~75px more chrome on
   the ribbon and the slide shrank to fit what was left. On the shelf a
   tile is its icon BESIDE its word, 30px tall; the scrollbar is thin,
   and the wheel scrolls the line (rbnShelfBoot). By id, so no strip's
   own size rule further down can put the tall tile back. */
#rbn-shelf-body{scrollbar-width:thin;}
#rbn-shelf-body .strip-frame,#rbn-shelf-body .fx-strip{height:auto;}
#rbn-shelf-body .strip-frame{border:0;background:none;}
#rbn-shelf-body .fx-tile{flex-direction:row;height:30px;min-height:0;
  width:auto;min-width:0;flex:none;padding:0 9px;gap:6px;
  white-space:nowrap;}
#rbn-shelf-body .fx-tile .bic{width:16px;height:16px;}
#rbn-shelf-body .fx-tile .sh-ico{width:18px;height:15px;}
/* the door that owns the shelf reads as pressed while it does */
.rbn-grp.rbn-shelved .rbn-foldbtn{
  background:color-mix(in srgb,var(--accent) 30%,transparent);
  border-color:var(--accent,var(--cyan));}
/* T182: the effect tiles, in the row. A tall cell spanning both rows
   (rbn-tall counts as two, like a stack), five tiles of icon over word
   the way PowerPoint's are, the one that is on lit. Disabled with
   nothing selected. */
.rbn-row>.rbn-tall{grid-row:1/span 2;}
.fx-strip{display:flex;gap:var(--rbn-tile-gap);align-items:stretch;
  height:var(--rbn-band);}
/* T205: ONE TILE. Every tall control on the ribbon -- an effect, a
   layout, a shape, a kind of text, a page size, New slide, the three
   Keep up to date doors -- is this one shape at this one size, and
   --rbn-tile-h tall whether it stands alone or sits in a frame over a
   scrollbar (2026-09-02, user: "buttons of all shapes and sizes and
   configurations all over the place"). Since T369 it says so in one
   token rather than in eleven copies of the number. */
/* T463: THE TILE IS NEVER NARROWER THAN ITS LONGEST WORD. One width for
   every tile was the T205 rule, and it held until the words did not:
   "Checkpoint…" printed past its own border on Home, "Heading 1" was
   "Head… 1" on Text, "Make clones…" was "Make clones…" cut in half on
   Object (2026-09-15, user: "Text not within the box"). PowerPoint's
   big buttons are label-width -- "Slide Master" is wider than "Reset"
   -- so a tile is THE tile wide, or its longest word wide, whichever
   is more. min-content is what makes that one rule: a two-word label
   still wraps into the tile, and a single word that cannot wrap
   widens it instead of overflowing it. A tile in a strip keeps its
   flex-basis, so a gallery stays a whole number of tiles wide. */
.fx-tile{width:min-content;min-width:var(--rbn-tile-w);
  display:flex;flex-direction:column;
  align-items:center;
  white-space:normal;text-align:center;
  justify-content:center;gap:5px;font-family:var(--sans);font-size:11px;
  line-height:1.1;color:#c9d6e2;background:none;
  border:1px solid #ffffff1f;border-radius:6px;cursor:pointer;
  padding:0 2px;}
.fx-tile .bic{width:24px;height:24px;}
.fx-tile:hover:not(:disabled){border-color:color-mix(in srgb,var(--accent) 55%,transparent);
  color:var(--chrome-ink);background:color-mix(in srgb,var(--accent) 10%,transparent);}
.fx-tile.on{background:var(--accent-deep,var(--cyan-deep));
  border-color:var(--accent-deep,var(--cyan-deep));
  color:var(--on-accent-deep,#fff);}
.fx-tile:disabled{opacity:.35;cursor:default;}
body.light .fx-tile{color:var(--ink-2);border-color:var(--line);}
body.light .fx-tile.on{color:var(--on-accent-deep,#fff);}
/* ...and ONE rule for a tile that stands in the row: --rbn-tile-h tall
   and centred in the band, whether it is the tall control itself or
   the tile inside a menu's wrapper. This was eight copies -- one per
   id -- and three tiles (Equation, Markdown, Table) had no copy at all
   and stood 60px tall beside their 56px neighbours. */
.rbn-row>.fx-tile.rbn-tall,.rbn-row>.rbn-tall>.fx-tile{
  height:var(--rbn-tile-h);align-self:center;}
/* T441's readout, on any tile: the current choice under the word. A
   tile carrying one closes its gaps so icon, word and choice all fit
   the height; pressed, the choice takes the tile's own ink. */
.fx-tile>.rbn-foldval{display:block;font:600 10px var(--mono);
  color:var(--cyan);max-width:118px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}   /* T467: room for "On click · By bullet" */
.fx-tile>.rbn-foldval[hidden]{display:none;}
.fx-tile.has-val{gap:2px;}
.fx-tile.has-val>span:first-of-type{white-space:nowrap;}
.fx-tile.on>.rbn-foldval,.fx-tile[aria-pressed="true"]>.rbn-foldval{
  color:inherit;}
body.light .fx-tile>.rbn-foldval{color:var(--cyan-deep);}
/* T380: View used to be twelve ordinary 26px rows floating in a mostly
   empty tab. They are actions of equal importance, so give each the same
   full-height icon-over-word tile as Animation and Text. They remain the
   real independently movable controls — not proxy copies — which keeps
   custom ribbon layouts, keyboard state and the narrow View menu honest. */
.rbn-row>.view-tile{position:relative;}
/* Keyboard hints are useful, but a third flex row made the words stop
   fitting in a 56px tile. Pin the hint into its corner instead. */
.view-tile kbd{position:absolute;top:2px;right:3px;font-size:8px;
  line-height:1;opacity:.62;background:none;border:0;padding:0;}
/* T679: a pair stacked two high (Rulers / Grid, Guides / Guide box) says
   its key after its word, and gives it up with the other hints */
.view-sm kbd{margin-left:1px;font:8.5px/1 var(--mono);opacity:.62;
  background:none;border:0;padding:0;}
.deck.erc-nohint .view-sm kbd{display:none;}
/* T186: the build numbers show whenever the Animation tab is up -- the
   tab is about them -- and not only while the order pane or Quick
   animate is (2026-09-02, user: "the animation numbers should appear
   when on the animation tab always") */
.deck.tab-animation .an-buildno{display:flex;}
/* T185/T518: Start, sequence and text-step behaviour sit beside the
   entrance effect, but remain separate choices -- since T594, labelled
   sections of the one Timing door */
.rbn-timing{order:2;}
.tm-sec{display:flex;align-items:center;gap:6px;flex:none;}
.tm-sec+.tm-sec{border-left:1px solid var(--chrome-line,#ffffff1f);
  padding-left:10px;margin-left:4px;}
.tm-lab{flex:none;font:600 9.5px var(--mono);letter-spacing:.08em;
  text-transform:uppercase;color:var(--chrome-ink-2);}
.anim-delaywrap .fmt-num{width:44px;}
.rbn-start .dbtn:disabled{opacity:.4;cursor:default;}
/* WHICH ONE IS ON, said louder than a theme can quiet. The colourful
   theme paints every .dbtn at three classes deep, which beat the two of
   .seq-fxb.on and left the lit chip looking like its neighbours
   (2026-09-02, user: "you can't tell which button you are on"). */
.rbn-row .seq-fx .seq-fxb[aria-pressed="true"],
.rbn-row .rbn-cell .dbtn.rbn-sm[aria-pressed="true"]{
  background:var(--accent-deep,var(--cyan-deep));
  color:var(--on-accent-deep,#fff);
  border-color:var(--accent-deep,var(--cyan-deep));}
.rbn-insert{order:6;}
/* Write and Draw share Insert's rung and follow it by source order:
   place a thing, write words, draw a line (T178) */
.rbn-write{order:6;}
/* T546: Links follows Write on the same rung, by source order */
.rbn-links{order:6;}
/* Shapes sit between Write and Draw (T197) */
.rbn-shapes{order:6;}
/* T560: Icons follow Shapes, by source order */
.rbn-icons{order:6;}
.rbn-draw{order:6;}
/* Home's layout groups follow Slides; View keeps its seat; the saved
   layouts and the refresh doors come LAST, so they are what folds first
   on a narrow window and the everyday toggles stay in view (T196) */
.rbn-layout,.rbn-this,.rbn-arrange{order:1;}
.rbn-sources{order:2;}
/* T474: Save version LAST (2026-09-15, user: "the save version group
   should definitely be last. This means the 'new slide' and 'this
   slide' can appear next to each other"). It had no rung, so it sat
   at 0 between New slide and This slide. */
.rbn-vers{order:9;}
/* T438: ON OBJECT, THE SOURCE LEADS (2026-09-14, user: "when clicking
   on an object that is an image, it needs to tell you the path as the
   first thing in that tab"). The markup put the group first in
   intent (T281) but Arrange, History and Size & place carry order 0,
   so it sat fourth. Home's Sources group keeps its seat above. */
.rbn-grp.rbn-sources[data-tab="object"]{order:-1;}
.rbn-show{order:3;}
/* T373: Spacing follows Layout, which is where it lived as a run */
.rbn-spacing{order:2;}
/* on Design (T204): Layout, then Apply to other slides, then Slide */
/* last, so it is what folds first on a narrow window */
.rbn-apply{order:1;}
/* T201: the two commands that reach the sources, drawn in the accent
   so the eye finds them ("needs more attention drawn to it") */
.dbtn.dbtn-accent{border-color:color-mix(in srgb,var(--accent) 60%,transparent);
  background:color-mix(in srgb,var(--accent) 14%,transparent);color:#eaf6fa;}
.dbtn.dbtn-accent:hover{border-color:var(--cyan);
  background:color-mix(in srgb,var(--accent) 24%,transparent);}
body.light .dbtn.dbtn-accent{color:var(--ink);}
/* T202: the Keep up to date tiles -- the effect tiles' shape, wider,
   with a bigger icon ("make them better buttons, like the animation
   'effect', full height") -- and the All images pane's rows */
.big-strip{gap:var(--rbn-tile-gap);}
/* a standing tile is the in-frame tile's height, centred in its cell */
.rbn-row>.fx-strip.big-strip{align-items:center;}
.big-strip .fx-tile{height:var(--rbn-tile-h);}
.fx-tile.big-tile[aria-pressed="true"]{background:var(--accent-deep,var(--cyan-deep));
  border-color:var(--accent-deep,var(--cyan-deep));
  color:var(--on-accent-deep,#fff);}
.img-row{display:flex;align-items:center;gap:8px;padding:6px 7px;
  border-radius:7px;cursor:pointer;color:#c9d6e2;}
.img-row:hover{background:#ffffff0c;}
.img-th{flex:none;width:46px;height:32px;border-radius:4px;
  background:var(--chrome-0,#0b141d);border:1px solid #ffffff14;
  display:flex;align-items:center;justify-content:center;overflow:hidden;}
.img-th img{width:100%;height:100%;object-fit:cover;display:block;}
.img-th .bic{width:18px;height:18px;opacity:.7;}
.img-mid{flex:1;min-width:0;}
.img-t{font-size:12px;}
/* T299: the source line under the path — the figure's number, its
   commit, and the verbs. Low-weight words on their own row rather than
   more glyphs beside the lock. */
/* T301: the one toast you can answer */
.toast-act{font:inherit;font-size:11px;margin-left:8px;padding:2px 8px;
  border:1px solid var(--accent);border-radius:5px;background:transparent;
  color:var(--accent);cursor:pointer;}
.toast-act:hover{background:var(--accent);color:var(--chrome-1);}
.img-acts{display:flex;flex-wrap:wrap;align-items:center;gap:4px 8px;
  margin-top:3px;}
.img-num{font-size:10px;color:var(--chrome-ink-3);
  font-variant-numeric:tabular-nums;}
.img-act{font:inherit;font-size:10px;line-height:1.4;padding:1px 6px;
  border:1px solid var(--chrome-line);border-radius:4px;
  background:var(--chrome-2);color:var(--chrome-ink-2);cursor:pointer;}
.img-act:hover{background:var(--chrome-3);color:var(--chrome-ink);}
.img-act.on{border-color:var(--accent);color:var(--accent);}
.img-from{font-family:var(--mono);font-size:10px;color:var(--chrome-ink-2);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
body.light .img-row{color:var(--ink-2);}
/* a saved layout's tile: the dialog's thumbnail at tile size */
.lay-strip .lay-savedth{display:block;overflow:hidden;}
.lay-strip .lay-savedth>*{width:100%;height:100%;}
/* the Drawing group follows Draw; it exists only while a tool is armed */
.rbn-cancel{order:6;}
/* T187: a FOLDED group is one worded door over a popover holding its
   row -- the real controls, moved, never copied. The popover lays the
   row out exactly as the ribbon does. */
.sh-menu.rbn-foldmenu{display:block;width:auto;padding:8px 10px;
  /* T484: never wider than the window -- a rest group of seventy atoms
     opened a popover 3112px wide in a 1300px window with 58 controls
     off the right edge (2026-09-15 review); the row wraps instead */
  max-width:calc(100vw - 16px);box-sizing:border-box;}
.rbn-foldmenu .rbn-row{height:auto;display:flex;flex-wrap:wrap;
  align-items:center;gap:var(--rbn-row-gap) var(--rbn-col-gap);}
.rbn-grp.rbn-folded>.rbn-foldwrap{display:flex;height:var(--rbn-band);
  align-items:center;}
/* T188: the text strip. A specimen "Aa" over the type's name; the strip
   scrolls and a tile cut at the edge is the affordance (T171). */
/* T196/T197: the layout tiles and the shape tiles are strips too */
.lay-strip .dbtn.lay{flex:0 0 var(--rbn-tile-w);scroll-snap-align:start;
  display:flex;width:var(--rbn-tile-w);
  min-width:0;white-space:normal;text-align:center;
  flex-direction:column;align-items:center;justify-content:center;
  gap:4px;padding:3px 3px;line-height:1.1;}
.lay-strip .layico2{width:calc(var(--rbn-tile-w) - 22px);}
/* the picker writes a heading into each of its homes; the group label
   is the strip's heading */
.lay-strip>.hd-lab,.lay-strip>.lay-sec{display:none;}
/* the one this slide wears: the review's sweep marks it, as it does
   in the two menus */
.lay-strip .dbtn.lay[aria-pressed="true"]{background:var(--accent-deep,var(--cyan-deep));
  border-color:var(--accent-deep,var(--cyan-deep));}
.shape-strip .fx-tile{flex:0 0 var(--rbn-tile-w);scroll-snap-align:start;}
.shape-strip .fx-tile .sh-ico{width:26px;height:22px;}
/* the provenance cell on the Object tab (T198): a label over a name */
.fmt-path{max-width:170px;}
.fmt-path b{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  display:block;max-width:170px;}
/* T530: the folder under the file's name, quieter and cut first */
.fmt-path i{display:block;max-width:170px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;font-style:normal;
  font-size:10px;color:var(--chrome-ink-3);}
/* three page sizes in sight and the rest a scroll or the chevron away
   (T204): Design has to seat Layout in front of this group */
.page-strip .fx-tile{flex:0 0 var(--rbn-tile-w);scroll-snap-align:start;}
/* TEXT TYPES USE THE SAME FULL-HEIGHT GALLERY AS ANIMATION. A type is a
   choice you can see, not a row of tiny pills; the first visible tile is
   the ordinary Text box and the frame's More door exposes every type. */
.strip-frame>.fx-strip.tx-strip{flex-wrap:nowrap;align-content:initial;
  overflow-x:hidden;overflow-y:hidden;}
/* T463: A NAME IS NEVER CUT. The tile is the specimen -- "Heading 1"
   set as a heading -- and at the one tile width the specimen read
   "Head… 1" (2026-09-15, user: "the text box types can't be read").
   So a text tile is as wide as its name, one line, and never narrower
   than the tile; the strip is as wide as its tiles, up to a ceiling
   the ladder lowers a rung at a time (--rbn-txstrip-max), and the
   arrows step by whole tiles past that. The nine built-in types fit
   under the ceiling at rest. */
.strip-frame .tx-strip .fx-tile{height:var(--rbn-tile-h);
  flex:0 0 auto;width:min-content;min-width:var(--rbn-tile-w);
  max-width:none;flex-direction:column;padding:2px 8px;gap:4px;
  scroll-snap-align:start;}
.tx-tile-n{display:block;line-height:1.1;font-family:var(--sans);
  white-space:nowrap;}
/* T190: the page-size tiles, each drawn at its own proportion */
.page-ico{display:block;border:1.5px solid currentColor;border-radius:2px;
  opacity:.85;box-sizing:border-box;}
/* T188: the armed mode's status, two short lines over Cancel */
.et-status{min-width:150px;}
.deck.erc-tight .et-status span+span{display:none;}
/* T191: a text box born empty shows that it is there and waiting --
   with no placeholder words and no panel (2026-08-19) a fresh box was
   a caret and nothing else, which read as "nothing happened" */
/* ...and it stays visible after you click away (T203; 2026-09-02,
   user: "text boxes with no text should still be there"): the
   placeholder no longer waits for the caret, and a box with nothing
   in it wears a faint dashed edge until it has words */
.deck.editing .an-item.an-text .an-tx:empty::before{
  content:"Type\2026";color:var(--chrome-ink-2);opacity:.8;pointer-events:none;}
.deck.editing .an-item.an-text:not(.sel):has(>.an-tx:empty){
  outline:1px dashed #ffffff3a;outline-offset:-1px;}
/* T626: lit for the PAGE it is on, not for the app's scheme -- keyed on
   body.light it was a white dash on a white slide in the dark app and a
   black one on a navy slide in the light app */
.deck.editing .page-light .an-item.an-text:not(.sel):has(>.an-tx:empty){
  outline-color:#0000002e;}
/* ...and so are the editor's hints that sit straight on the page (a
   placeholder, an empty book, a frame waiting for its notebook): inside
   a slide the chrome palette is the dark page's (.slide, T626), so on a
   light page they take the light page's quiet ink, as .an-handle does */
.deck.editing .page-light .an-item.an-text .an-tx:empty::before,
.page-light .an-flipempty,.page-light .an-verwait,
.page-light .an-embchip,.page-light .an-cell .fp-count{color:#5a6b78;}
/* the whole-deck commands at the foot of the Text styles window */
.style-mgr .opt-row{margin-top:2px;}
.style-mgr .opt-row .dbtn.rbn-sm{flex:1 1 auto;justify-content:center;}
.et-fmt .rbn-grp{order:7;flex:none;}
.edit-tools.ribbon .et-hint{order:9;margin-left:0;}
.deck-title{font-family:var(--sans);font-size:12.5px;color:var(--chrome-ink-2);
  margin-left:16px;padding-left:16px;border-left:1px solid #ffffff1a;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:40vw;}
.deck-title:empty{display:none;}
.deck-topslot{display:flex;align-items:center;gap:8px;margin-left:2px;
  flex-wrap:nowrap;}
.deck-topslot:empty{display:none;}
.deck-topright{display:flex;align-items:center;gap:8px;}
.deck-topright:empty{display:none;}
/* One line, one height, nothing wrapping. "File ▾" was breaking after the
   word and pushing its own button taller than everything beside it, which
   is what made the row look uneven (2026-08-07, user: "they are not
   inline"). */
.deck-topslot .dbtn,.deck-topright .dbtn{height:30px;box-sizing:border-box;
  white-space:nowrap;display:inline-flex;align-items:center;
  justify-content:center;line-height:1;}
.deck-topslot .dc-menuwrap,.deck-topslot .dc-savegrp{display:flex;
  align-items:center;}
.deck-topslot .deck-status{height:30px;box-sizing:border-box;}

/* --- the compaction ladder. Every stage trades SPACE, never words. ---
   ...and since T219 never TYPE either: a rung that shrank the words to
   10.5px was running on a 1800px monitor, which is how the words were
   "tiny" on a screen with room to spare (2026-09-03). PowerPoint never
   shrinks its words; it folds a group, and folding is a tall tile
   here since T218. So every rung keeps its padding and gap steps and
   has lost its font-size step. */
/* ...and the row-gap is NOT a step: erc1 used the `gap` shorthand,
   which reset the row gap too, so from the first rung the changing
   half's two rows sat closer together than the constant half's -- two
   baselines on one bar. Column only. */
.deck.erc1 .rbn-grp{padding-left:4px;padding-right:4px;}
/* T463: the text strip is the widest thing on its tab, and a scroll box
   already, so it is the first to give width back: a rung takes 80px
   off its ceiling and the arrows page the rest into view. No word is
   hidden -- every tile is still whole, and still its name's width. */
.deck.erc1{--rbn-txstrip-max:604px;}
.deck.erc1 .rbn-row{column-gap:2px;}
.deck.erc2 .dbtn.rbn-sm{padding:3px 5px;gap:3px;}
/* T372: THE TILE COMPACTS TOO. A worded button gives up padding at
   every rung, but a tile is a fixed --rbn-tile-w, so a group made of
   tiles was the one thing on the row the ladder could not shrink --
   and once Transition and Timing became tile strips that was three
   groups of the Animation tab. Measured: the tab folded four groups at
   1600px where the worded version folded two, on a row only 8px wider.
   The token makes it one line a rung, and no rung touches the type:
   the label just wraps a little sooner. */
.deck.erc2{--rbn-tile-w:58px;--rbn-txstrip-max:524px;}
.deck.erc2 .rbn-stack,.deck.erc2 .rbn-stack .rbn-col{gap:2px;}
/* spend BOX width before type size: on 1366-1440 laptops the ladder ran
   all the way to erc3's small type while the font select sat at its full
   94px and the size box at 44px — tiny mashed buttons beside roomy boxes
   (2026-08-20 diagnosis, user: "really small and mashed together. This is
   on a laptop"). Capping the boxes at erc2 stops erc3 firing at those
   widths at all (measured: 1366/1400 now stop at erc2, 10.5px type). */
.deck.erc2 .et-fmt .rbn-row .fmt-num{width:38px;}
.deck.erc2 .et-fmt .rbn-row select.etm{max-width:76px;}
.deck.erc2 .et-fmt .rbn-row .fmt-range{width:66px;}
/* NO rung hides an icon. Stripping them buys width but costs the whole
   big/small hierarchy — a label-only wall is the same flat wall that was
   rejected, arrived at from the other side. Density only, to the end. */
.deck.erc3 .rbn-grp{padding-left:3px;padding-right:3px;}
.deck.erc3{--rbn-txstrip-max:444px;}
.deck.erc3 .dbtn.rbn-sm,.deck.erc3 .rbn-row .dbtn.etm{
  padding-left:4px;padding-right:4px;}
.deck.erc3 .rbn-row .fmt-range{width:56px;}
.deck.erc3 .et-fmt .rbn-row select.etm{max-width:68px;}
.deck.erc3 .et-fmt .rbn-row .fmt-num{width:34px;}

/* every cell-sized control has to actually BE cell-sized, or it pushes
   its row past the group and over the label */
.rbn-row .dbtn.etm,.rbn-row .fmt-num,.rbn-row select.etm,
.rbn-row .fmt-opwrap,.rbn-row .fmt-szwrap,.rbn-row .rbn-partslot{
  height:var(--rbn-btn-h);box-sizing:border-box;
  padding-top:0;padding-bottom:0;}
.rbn-row .dbtn.etm{display:inline-flex;align-items:center;
  justify-content:center;font-size:12px;
  padding-left:var(--rbn-btn-px);padding-right:var(--rbn-btn-px);}
.et-fmt #fmt-path{order:-2;}
.et-fmt #fmt-srcwrap{order:-1;}
/* Object tools read from the thing itself outwards: source/basic
   appearance first, then geometry and finally structure. Typography and
   line/shape treatment now belong to the focused Style tab.
   A group's place comes from the control it holds, and the layout
   engine writes that once, as data-fmt-ord, when it puts the controls
   in their groups (rbnFmtOrder, from applyRibbonLayout) -- these were five
   :has(#fmt-...) rules that every change anywhere in the ribbon
   re-checked (2026-10-09, speed). The held-control orders come AFTER
   the two class rules on purpose: the :has() rules carried an id's
   specificity and beat them, and source order keeps that. */
.et-fmt .rbn-grp[data-tab="object"].rbn-picture{order:1;}
.et-fmt .rbn-grp[data-tab="object"].rbn-clones{order:6;}
.et-fmt .rbn-grp[data-tab="object"].rbn-clonelinks{order:7;}
.et-fmt .rbn-grp[data-tab="object"][data-fmt-ord="0"]{order:0;}
.et-fmt .rbn-grp[data-tab="object"][data-fmt-ord="2"]{order:2;}
.et-fmt .rbn-grp[data-tab="object"][data-fmt-ord="3"]{order:3;}
.et-fmt .rbn-grp[data-tab="object"][data-fmt-ord="4"]{order:4;}
.et-fmt .rbn-grp[data-tab="object"][data-fmt-ord="5"]{order:5;}
/* T409: the two clone menus -- a name box, and the kind that is on */
.cmp-menu .cmp-name{display:block;width:100%;box-sizing:border-box;
  margin:2px 0 6px;padding:5px 7px;font:inherit;font-size:12.5px;
  color:inherit;background:var(--input-bg);border:1px solid var(--line);
  border-radius:6px;}
.cmp-menu .vw-opt.on{background:color-mix(in srgb,var(--accent) 22%,
  transparent);color:var(--chrome-ink);}
.cmp-menu .vw-opt.on::after{content:"on";margin-left:auto;
  font-family:var(--mono);font-size:9px;opacity:.8;}
.cmp-menu .vw-opt[disabled]{opacity:.45;pointer-events:none;}
/* T748: the place the Add a clone button goes, the clone you are on,
   and Link's own button */
.cmp-menu .vw-opt.last::after{content:"the button does this";
  margin-left:auto;padding-left:10px;font-size:10px;opacity:.7;}
#cmp-inst-menu .vw-opt.here{background:color-mix(in srgb,var(--accent) 22%,
  transparent);}
#cmp-inst-menu .vw-opt.here::after{content:"selected";margin-left:auto;
  padding-left:10px;font-size:10px;opacity:.75;}
.cmp-menu .vw-opt.cmp-go{justify-content:center;font-weight:600;
  border-color:color-mix(in srgb,var(--accent) 60%,transparent);}
/* T748: the Link pop-up -- a title, then ticks, then which one the
   others match (the name of each beside it), then Link them */
.cmp-pop{min-width:300px;}
.cmp-pop-h{font:600 13px/1.3 var(--sans);color:var(--chrome-ink);
  padding:4px 6px 6px;}
.cmp-pop .vw-opt .fh-n{margin-left:auto;padding-left:10px;max-width:150px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;opacity:.75;
  font-size:10.5px;}
.cmp-pop .vw-opt.cmp-go{margin-top:6px;background:color-mix(in srgb,
  var(--accent) 26%,transparent);}
.cmp-pop .vw-opt.cmp-go[disabled]{opacity:.45;}
/* T748: what a selected clone or linked object is linked to, under it */
.an-cmpchip{position:absolute;z-index:5;margin-top:7px;display:flex;
  align-items:center;gap:5px;padding:2px 7px 2px 5px;white-space:nowrap;
  background:var(--chrome-1,#0e1926);color:var(--chrome-ink,#cdd9e3);
  border:1px solid var(--cyan);border-radius:6px;
  font:600 11px/1.2 var(--sans);cursor:pointer;box-shadow:0 1px 5px #0004;}
.an-cmpchip .bic{width:12px;height:12px;color:var(--cyan);}
.an-cmpchip:hover{background:color-mix(in srgb,var(--cyan) 24%,
  var(--chrome-1,#0e1926));}
/* T748: Object info -- a two-column list, its rows of links, buttons */
.sh-menu.obj-info:not([hidden]){display:flex;flex-direction:column;
  gap:4px;width:auto;min-width:320px;max-width:440px;padding:8px;}
.obj-info .oi-rows{display:grid;grid-template-columns:auto 1fr;
  column-gap:12px;row-gap:4px;padding:2px 6px 8px;
  font:12px/1.35 var(--sans);}
.obj-info .oi-k{color:var(--chrome-ink-2);}
.obj-info .oi-v{color:var(--chrome-ink);overflow-wrap:anywhere;}
.obj-info .oi-v.oi-path{font-family:var(--mono);font-size:11px;}
.obj-info .oi-go{font-size:12px;}
.obj-info .oi-btns{display:flex;flex-wrap:wrap;gap:6px;padding:8px 4px 2px;
  border-top:1px solid var(--line);margin-top:6px;}
.rbn-row .fmt-range{width:96px;}
/* The File group is assembled in JS out of nodes that were built for the
   docked panel, so it is sized here rather than in markup. They arrive
   carrying the panel's 30px height, which would burst the ribbon's
   grid rows and push the whole bar taller. (Dead since the File
   controls moved to the document bar; kept because applyRibbonLayout
   can still put a .rbn-file group back.) */
.rbn-file .dbtn{padding:3px 8px;font-size:10.5px;height:26px;
  box-sizing:border-box;display:inline-flex;align-items:center;
  justify-content:center;line-height:1;white-space:nowrap;}
/* The readout lives at the FAR END of the bar while editing, not in the
   File group: it renames itself as you work, and a thing that changes
   width in the constant half drags every group after it along. Pinned
   right with nothing beyond it, its width costs nothing and moves
   nothing, so it can say the whole string (2026-08-17). */
/* the theme/support pair and the save readout have both moved into the
   thin bar at the top, where they sit beside the rest of the document's
   own controls instead of hanging off the end of the editing tools
   (2026-08-20). */
/* It goes at the SAME stage as the hint — before any control tightens —
   and for the same reason: it is text, not a control, so dropping it
   hides nothing you can click and no word you need in order to act. It is
   worth ~110px, which is what a text selection on a 1280px window was
   short of.
   The stage matters as much as the rule. Left to survive into the rung
   ladder it pushed the ladder itself: going from "" to "unsaved" the
   moment you drew something was enough to buy a rung, and that rung
   compacted Insert by 56px. A readout that changes the size of the
   buttons is the same bug as a readout that changes their position
   (2026-08-17). */
.deck.erc-nostatus .edit-tools.ribbon>.deck-status{display:none;}
.deck.rbn-side .edit-tools.ribbon>.deck-status{margin-left:0;
  align-self:stretch;justify-content:center;margin-top:6px;}
.rbn-file .dc-menuwrap,.rbn-file .dc-savegrp{display:inline-flex;
  align-items:center;height:26px;}
/* the contextual format groups flow into the same rows as the static
   ones. Hidden means GONE (2026-08-04): keeping them in layout as
   visibility:hidden reserved every row they would wrap into — on a
   narrowed poster stage that was 5-7 rows of invisible buttons, a huge
   dead band. The ribbon's min-height still reserves two rows, so the
   common select/deselect does not shift the canvas; a selection whose
   groups need a third row may grow it slightly — an honest jump beats a
   permanent void. */
.et-fmt{display:contents;}
.et-fmt[hidden]{display:none;}
/* a SELECTION swaps the Insert group for the contextual format groups
   (PowerPoint's contextual-tab move): the toolbar keeps its two rows and
   the canvas keeps its size — it used to grow a third row and shrink
   the poster whenever you clicked anything (2026-08-05) */
/* Selecting something swaps the ribbon over to that item's tools, the way
   PowerPoint swaps in a contextual tab — the contextual groups REPLACE
   the standby ones instead of being appended to them. Appending them
   needed 2135px of a 1409px window, which no amount of density was ever
   going to close. File, Slide and View stay because you still save, zoom,
   change page and consult the object list while an item is selected;
   Present, Notebooks and Insert are all one click away again the moment
   you deselect. View joined them on 2026-08-17, when zoom moved into it —
   losing zoom the instant you select something would have been a plain
   regression. */
/* Nothing stands down for a selection any more: the TAB decides what is
   in the row, so Insert cannot collide with the format groups — they are
   on different tabs and are never asked for at the same time
   (2026-08-20). fmt-open is kept only as a styling hook. */
/* Present survives everything now: it is in the bar at the top, above
   the tabs, so no tab and no selection can take it away (2026-08-19,
   user: "clicking on something should never hide the previous options —
   Present should always be there"). */
/* the seam between ALWAYS-THERE and BECAUSE-YOU-SELECTED. On Home that
   is still a real boundary: Editing is always in the row, the format
   groups only arrive with a selection. */
.et-fmt>.rbn-grp:first-of-type{
  border-left:4px double #ffffff38;margin-left:2px;}
/* Present is accented but must not read as PRESSED: outline, not fill
   (2026-08-19, user: "the present button is always highlighted") */
#dc-play.primary{background:color-mix(in srgb,var(--accent) 14%,
  transparent);color:var(--accent);box-shadow:none;
  border-color:var(--accent);font-weight:600;}
#dc-play.primary:hover{background:var(--accent);color:var(--on-accent);}
/* Slide used to step aside as well, on a narrow window with something
   selected. Measured cost of that: selecting a text box took View 168px
   to the left. It was the single biggest jump in the bar and it fired on
   an ordinary click at an ordinary window size — exactly the thing this
   toolbar is not allowed to do. The width it bought comes from the extra
   rung below instead, which the changing region can afford and the
   constant half never pays (2026-08-17). */
/* with nothing selected there is no group to stand aside, so the big
   buttons give up their last few pixels instead — smaller, never fewer
   words */
/* The last rung spends SPACING, never type and never an icon: measured at
   a 909px ribbon, dropping the group padding, the column gap, the button
   padding and the icon gap by 1px each buys 40px, where taking the type
   from 9px to 8px would buy 48px and be unreadable. Sizing View honestly
   (two columns for its three controls, rather than a third row printed
   over its own label) costs about 60px, so this is most of it back
   (2026-08-16). */
.deck.erc-tight{--rbn-tile-w:52px;--rbn-txstrip-max:364px;}
/* T463: a readout gives up its last few characters at the tightest rung
   ("Title + pa…" under New slide); the whole name is on the tooltip */
.deck.erc-tight .fx-tile>.rbn-foldval{max-width:56px;}
/* T498: ...but a DOOR is 82px wide by rule (its floor, below), so its
   readout has 76px of content box for nothing, and the 56px cap cut
   "Every slide" to "Every sl…" and "Panel + text" to "Panel + te…"
   inside a door with 26px of room beside them (the third review pass).
   The cap is the door's own width: the door never widens for its
   readout at this rung, and nothing that fits it is cut. */
.deck.erc-tight .rbn-foldwrap .fx-tile.rbn-foldbtn>.rbn-foldval{max-width:76px;}
.deck.erc-tight .rbn-grp{padding-left:2px;padding-right:2px;}
.deck.erc-tight .rbn-row{column-gap:2px;}
.deck.erc-tight .dbtn.rbn-sm,.deck.erc-tight .rbn-row .dbtn.etm{
  padding-left:3px;padding-right:3px;gap:3px;}
/* Narrowing the square glyph buttons (zoom's minus and plus, undo and
   redo) was tried here and measured at zero: none of them is the widest
   control in its grid column, so the column keeps the width of the worded
   button above it and the saving never reaches the row. */

/* ---- THE CONSTANT HALF OPTS OUT OF THE LADDER ------------------------
   Every rung above trades type and padding for width, and any of them
   applied to File, Slide or View MOVES those groups — which is the whole
   complaint. So they are reset here, once, after the ladder, rather than
   by excluding them rung by rung: a rung added later cannot forget a
   reset it never had to write. Specificity is deliberately above every
   rung (four and five classes against their three and four), so this
   wins wherever it sits in the file rather than by being last.
   Measured after: File, Slide and View sit at exactly 386/217, 603/197
   and 800/246 with nothing selected, a line selected and a text box
   selected, at 1500px and 1920px. Zero movement. ---- */
.deck .edit-tools .rbn-grp.rbn-fixed{padding-left:7px;padding-right:7px;}
.deck .edit-tools .rbn-fixed .rbn-row{
  column-gap:var(--rbn-col-gap);row-gap:var(--rbn-row-gap);}
.deck .edit-tools .rbn-fixed .dbtn.rbn-sm,
.deck .edit-tools .rbn-fixed .rbn-row .dbtn.etm{
  padding-left:var(--rbn-btn-px);padding-right:var(--rbn-btn-px);
  gap:var(--rbn-btn-gap);}
.deck .edit-tools .rbn-fixed .rbn-stack{gap:3px;}
/* ...but it still has to answer to the WINDOW. These rungs are keyed on
   the ribbon's width alone (fitEditRibbon's ERCW, set before it measures
   anything), and the ribbon is exactly as wide with something selected as
   without — so they can only fire on a resize, never on a click. The
   status readout and the zoom readout are sized in ch, so they follow
   these steps down on their own rather than needing a rung each. */
.deck.ercw1 .edit-tools .rbn-grp.rbn-fixed{padding-left:5px;padding-right:5px;}
.deck.ercw1 .edit-tools .rbn-fixed .rbn-row{column-gap:2px;row-gap:4px;}
.deck.ercw1 .edit-tools .rbn-fixed .dbtn.rbn-sm,
.deck.ercw1 .edit-tools .rbn-fixed .rbn-row .dbtn.etm{
  padding-left:5px;padding-right:5px;gap:4px;}
.deck.ercw2 .edit-tools .rbn-grp.rbn-fixed{padding-left:4px;padding-right:4px;}
.deck.ercw2 .edit-tools .rbn-fixed .rbn-row{column-gap:2px;row-gap:4px;}
.deck.ercw2 .edit-tools .rbn-fixed .dbtn.rbn-sm,
.deck.ercw2 .edit-tools .rbn-fixed .rbn-row .dbtn.etm{
  padding-left:4px;padding-right:4px;gap:3px;}
.deck.ercw3 .edit-tools .rbn-grp.rbn-fixed{padding-left:3px;padding-right:3px;}
.deck.ercw3 .edit-tools .rbn-fixed .rbn-row{column-gap:2px;row-gap:3px;}
.deck.ercw3 .edit-tools .rbn-fixed .dbtn.rbn-sm,
.deck.ercw3 .edit-tools .rbn-fixed .rbn-row .dbtn.etm{
  padding-left:3px;padding-right:3px;gap:3px;}
.deck.ercw4 .edit-tools .rbn-grp.rbn-fixed{padding-left:2px;padding-right:2px;}
/* ercw4 had no .rbn-row rule at all, so the last width rung inherited
   ercw3's gaps and bought nothing but 1px of group padding. */
.deck.ercw4 .edit-tools .rbn-fixed .rbn-row{column-gap:2px;row-gap:3px;}
.deck.ercw4 .edit-tools .rbn-fixed .dbtn.rbn-sm,
.deck.ercw4 .edit-tools .rbn-fixed .rbn-row .dbtn.etm{
  padding-left:3px;padding-right:3px;gap:3px;}

/* ---- ...and the changing region pays for it, with a rung of its own.
   It is relaid out on every selection anyway, so extra density there
   costs nobody a moved button — and it is where the width has to come
   from now that no constant group is allowed to step aside. Worth 40px
   on a text selection, which is the 35px that was over. ---- */
.deck.erc-tight .et-fmt .rbn-grp{padding-left:2px;padding-right:2px;}
.deck.erc-tight .et-fmt .rbn-row{column-gap:2px;}
.deck.erc-tight .et-fmt .dbtn.rbn-sm,
.deck.erc-tight .et-fmt .rbn-row .dbtn.etm{
  padding-left:3px;padding-right:3px;gap:3px;}
.deck.erc-tight .et-fmt .rbn-row .fmt-range{width:56px;}
/* the boxes you type into rather than read: a font name still shows, a
   point size is at most three digits, and neither needs its resting width
   when the row is at its last rung */
.deck.erc-tight .et-fmt .rbn-row .fmt-num{width:32px;}
.deck.erc-tight .et-fmt .rbn-row select.etm{max-width:62px;}
.deck.erc-tight .et-fmt .fmt-szwrap,
.deck.erc-tight .et-fmt .fmt-opwrap{gap:2px;}
.fmt-lab{margin-left:2px;}
.et-hint{font-size:11px;color:var(--chrome-ink-2);align-self:center;margin-left:auto;
  padding:0 4px 10px;}
/* the "+ Shapes" dropdown */
.sh-drop{position:relative;display:inline-block;}
#sh-btn[aria-pressed="true"]{background:var(--cyan-deep);
  border-color:var(--cyan-deep);color:var(--on-accent-deep,#fff);}
.sh-menu{position:absolute;top:calc(100% + 5px);left:0;z-index:60;
  background:var(--chrome-2,#16273a);border:1px solid #ffffff26;border-radius:9px;padding:6px;
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px;
  box-shadow:0 14px 38px #0009;width:210px;}
.sh-menu[hidden]{display:none;}
/* ---- WINDOWS OF OPTIONS (T177) ----------------------------------------
   One worded door on the ribbon opens a panel holding a whole cluster of
   related controls: the font, the paragraph, the line, the source. The
   REAL controls live inside -- moved there in the markup, not copied --
   so every handler, state and test keeps addressing the one element it
   always did, and a ribbon layout moves the window as one atom. A tall
   window scrolls; nothing is ever clipped. ---- */
.sh-menu.opt-panel{display:block;width:auto;min-width:320px;
  max-width:min(94vw,560px);padding:10px 12px 12px;
  max-height:min(72vh,560px);overflow-y:auto;overflow-x:hidden;}
/* hidden means hidden, whatever display a row or grid asked for */
.opt-panel [hidden]{display:none!important;}
.opt-panel .hd-lab{padding:8px 2px 4px;}
.opt-panel>.hd-lab:first-child{padding-top:0;}
.opt-row{display:flex;flex-wrap:wrap;gap:4px;align-items:center;}
.opt-row.opt-grid2{display:grid;grid-template-columns:1fr 1fr;}
.opt-cols{display:flex;gap:16px;align-items:flex-start;}
.opt-cols>*{flex:1 1 auto;min-width:0;}
/* the ribbon's cell-sizing and its density rungs do not reach inside a
   window (!important, because the rungs are five classes deep): a
   control here is as tall as its words need and never shrinks */
.opt-panel .dbtn.etm,.opt-panel .dbtn.rbn-sm{height:auto!important;
  min-height:26px;padding:4px 9px!important;font-size:12px!important;
  justify-content:flex-start;white-space:nowrap;display:inline-flex;
  align-items:center;gap:6px;}
.opt-panel .opt-grid2>.dbtn{width:100%;}
.opt-panel select.etm{height:26px;max-width:none!important;width:100%;}
.opt-panel .fmt-szwrap{height:26px;}
.opt-panel .fmt-szwrap .fmt-num{width:54px!important;}
/* a SECTION inside a window: its old door stays in the DOM because
   the drawn menus are wired to it, and is never shown; its menu is laid
   flat where a dropdown used to hang */
.opt-panel .opt-sec{display:block;position:static;}
.opt-panel .opt-sec>.opt-sec-btn{display:none!important;}
.opt-panel .opt-sec>.sh-menu{position:static;box-shadow:none;border:none;
  padding:0;width:auto;max-width:none;background:none;border-radius:0;}
.opt-panel .opt-sec>.hd-lab{padding-top:8px;}
.opt-cols>.opt-sec>.hd-lab{padding-top:0;}
/* worded rows, full width, the way a menu reads */
.sh-menu.opt-panel.opt-list{display:flex;flex-direction:column;gap:3px;
  min-width:224px;}
.opt-panel.opt-list>.dbtn{width:100%;justify-content:flex-start;
  text-align:left;gap:8px;padding:6px 9px!important;}
/* Source is the important answer, not a drawer. Keep its provenance
   actions on the same row as the path and Source label. The existing
   buttons and handlers are reused; only the containment changes. */
#fmt-srcwrap.src-flat:not([hidden]),
#fmt-srcwrap.src-flat:not([hidden]) #fmt-src-menu{
  display:contents!important;}
/* T481: the wrapper's [hidden] must still win, or every layout that
   flattens the source row showed Source / Where it came from… / Lock
   figure with nothing selected (2026-09-15 review) */
#fmt-srcwrap.src-flat[hidden]{display:none!important;}
#fmt-srcwrap.src-flat #fmt-src-menu>.dbtn{width:auto;min-height:26px;
  padding:4px 7px!important;font-size:11px!important;}
/* a chip: one of several answers, and it shows which one is on */
.dbtn.opt-chip{padding:4px 10px;font-size:11px;line-height:1.4;}
.dbtn.opt-chip[aria-pressed="true"]{
  background:color-mix(in srgb,var(--accent) 22%,transparent);
  border-color:var(--accent);color:#fff;}
.dbtn.opt-chip:disabled{opacity:.4;cursor:default;}
body.light .dbtn.opt-chip[aria-pressed="true"]{color:var(--ink);}
.opt-val{font-family:var(--mono);font-size:10px;color:var(--chrome-ink-2);
  padding:0 4px;}
.line-panel .style-menu .sh-opt,.line-panel .sw-menu .sh-opt{
  padding:3px 6px;}
.sh-opt{display:flex;flex-direction:column;align-items:center;gap:3px;
  background:none;border:1px solid transparent;border-radius:7px;
  padding:7px 4px 5px;cursor:pointer;color:var(--chrome-ink-2);font-family:var(--sans);}
.sh-opt:hover{background:color-mix(in srgb,var(--accent) 13%,transparent);border-color:color-mix(in srgb,var(--accent) 40%,transparent);color:var(--chrome-ink);}
/* a row that cannot act here looks it (2026-10-30: Rotate's flips over
   a text box); its tooltip says why */
.sh-opt:disabled{opacity:.4;cursor:default;background:none;
  border-color:transparent;}
.sh-ico{width:26px;height:22px;display:block;}
/* filled crop-shape preview in the Crop menu (same clip-path as the effect) */
.crop-ico{width:30px;height:22px;display:block;border-radius:2px;
  background:linear-gradient(135deg,var(--accent-soft),var(--accent));}
/* a shape-cropped figure fills its frame so the mask actually bites into it
   (a contained figure would just have its letterbox clipped, looking unchanged) */
.an-cell.an-cropped .figframe{padding:0;}
.an-cell.an-cropped .figframe img{object-fit:cover;width:100%;height:100%;
  max-width:none;max-height:none;}
/* the "Same size" picker: a plain single-column list of text options */
/* the View menu: worded rows, each a toggle that shows its own state */
.sh-menu.vw-menu{display:flex;flex-direction:column;width:236px;
  padding:6px;gap:3px;}
.vw-opt{display:flex;align-items:center;gap:8px;width:100%;
  justify-content:flex-start;text-align:left;font-family:var(--sans);
  font-size:12.5px;padding:6px 9px;}
.vw-opt kbd{margin-left:auto;font-family:var(--mono);font-size:9px;
  border:1px solid #ffffff26;border-radius:3px;padding:0 4px;
  color:var(--chrome-ink-2);}
.sh-menu.align-menu{display:block;width:310px;padding:8px;}
.align-menu .sh-opt{flex-direction:row;justify-content:flex-start;
  gap:8px;padding:6px 8px;}
.sh-menu.same-menu{display:block;width:196px;padding:6px;}
.same-menu .sh-opt{flex-direction:row;justify-content:flex-start;
  width:100%;padding:7px 9px;font-size:12px;text-align:left;}
/* the animation pane: effect picker + build-order sequence */
/* the animation pane's body. It used to be a 340px dropdown; it is a
   docked pane now, so it takes the pane's width and the pane's scroll
   rather than carrying its own (2026-08-17). */
.anim-pane{display:block;text-align:left;}
.selpane.animpane .selpane-list{padding:10px 11px;}
.anim-h{font-family:var(--sans);font-size:11px;font-weight:600;
  letter-spacing:0;color:var(--chrome-ink-2);margin:0 2px 6px;}
.anim-h::first-letter{text-transform:uppercase;}
.anim-mini{background:var(--chrome-2,#16273a);border:1px solid #ffffff1f;color:var(--chrome-ink);
  border-radius:6px;padding:5px 8px;font-size:11.5px;cursor:pointer;
  font-family:var(--sans);white-space:nowrap;}
.anim-mini.wide{flex:1;width:100%;margin-top:10px;}
/* ---- T445: THE ANIMATION PANEL --------------------------------------
   Sections of chips and sliders above the list of clicks. Chips wrap
   because there are thirteen movements and the pane is 232px by
   default; every slider is label, track and a live readout on one
   line, so a number you are dragging says what it will be. */
/* ---- T452: CONFIGURE | ORDER ----------------------------------------
   (2026-09-14, user: "the animation pane is not the right place for
   configuring the animation details ... The animation pane is for the
   order. Please do not mix them. Or perhaps put tabs on the pane".)
   Two tabs under the pane's heading, the underline saying which one is
   showing -- the same grammar as the ribbon's own tab strip, at the
   size a 272px pane can hold. */
.anim-tabs{display:flex;gap:2px;flex:none;padding:0 8px;
  border-bottom:1px solid var(--chrome-line,#ffffff1f);}
.anim-tab{display:inline-flex;align-items:center;gap:5px;flex:1;
  justify-content:center;padding:7px 6px 6px;border:0;background:none;
  border-bottom:2px solid transparent;margin-bottom:-1px;
  color:var(--chrome-ink-2);font:600 11.5px var(--sans);cursor:pointer;
  white-space:nowrap;}
.anim-tab .bic{width:12px;height:12px;}
.anim-tab:hover{color:var(--chrome-ink);}
.anim-tab[aria-selected="true"]{color:var(--chrome-ink);
  border-bottom-color:var(--accent,var(--cyan));}
.anim-cfg{display:block;margin-bottom:10px;}
.anim-cfg:empty{display:none;}
/* Quick animate at the head of the Order tab: the same card as a
   configuration section, set off from the list it is writing */
.anim-quick{margin:0 0 10px;padding-bottom:9px;
  border-bottom:1px solid var(--chrome-line,#ffffff1f);}
.anim-cfg .anim-h{margin-top:10px;}
.anim-cfg .anim-h:first-child{margin-top:0;}
.cfg-note{font-size:11.5px;line-height:1.45;color:var(--chrome-ink-2);
  margin:0 2px 6px;}
/* T750: how to read the Order list, one line under its count */
.anim-key{font-size:11px;line-height:1.4;color:var(--chrome-ink-2);
  margin:-2px 2px 8px;}
/* T750: Configure's object card says which clicks it is on */
.cfg-clicks{font-size:11.5px;line-height:1.45;color:var(--chrome-ink);
  margin:-2px 2px 8px;}
.cfg-clicks b{color:var(--amber,#cf9a4e);font-weight:700;}
/* T750: the slide-wide presets are not about the selected object, so
   they sit under a rule of their own */
.anim-cfg .anim-h.cfg-slide{margin-top:14px;padding-top:10px;
  border-top:1px solid var(--chrome-line,#ffffff1f);}
.cfg-who{display:flex;align-items:center;gap:6px;font-size:12.5px;
  color:#fff;background:var(--chrome-2,#16273a);border-radius:7px;
  padding:6px 8px;margin-bottom:8px;min-width:0;}
.cfg-who>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.cfg-who .bic{width:13px;height:13px;flex:none;color:var(--cyan);}
.cfg-more{flex:none;font:9px var(--mono);letter-spacing:.08em;
  text-transform:uppercase;color:var(--chrome-ink-2);}
.cfg-chips{display:flex;flex-wrap:wrap;gap:4px;margin:0 0 8px;}
.cfg-chip{display:inline-flex;align-items:center;gap:4px;
  background:var(--chrome-3,#101c28);border:1px solid var(--chrome-line,#ffffff1f);
  color:#bcccd8;border-radius:6px;padding:4px 7px;font-size:11px;
  font-family:var(--sans);cursor:pointer;min-width:0;}
.cfg-chip .bic{width:12px;height:12px;flex:none;}
.cfg-chip>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.cfg-chip:hover:not(:disabled){
  border-color:color-mix(in srgb,var(--accent) 53%,transparent);color:var(--chrome-ink);}
.cfg-chip.on{background:var(--accent-deep,var(--cyan-deep));
  border-color:var(--accent-deep,var(--cyan-deep));
  color:var(--on-accent-deep,#fff);}
.cfg-chip:disabled{opacity:.4;cursor:default;}
.cfg-range,.cfg-sel{display:flex;align-items:center;gap:6px;
  margin:0 2px 6px;font-size:11px;color:var(--chrome-ink-2);}
.cfg-rl{flex:0 0 62px;}
.cfg-range input[type="range"]{flex:1;min-width:0;accent-color:var(--cyan);
  height:14px;}
.cfg-rv{flex:0 0 auto;max-width:96px;font-family:var(--mono);font-size:9.5px;
  color:var(--cyan);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
.cfg-sel select{flex:1;min-width:0;}
.cfg-acts{margin-top:2px;}
.cfg-acts .anim-mini{flex:1;}
.anim-mini.primary{background:var(--accent-deep,var(--cyan-deep));
  border-color:var(--accent-deep,var(--cyan-deep));
  color:var(--on-accent-deep,#fff);}
.cfg-seqwhat{font-size:12px;color:#c9d6e2;background:var(--chrome-2,#16273a);
  border-radius:7px;padding:7px 9px;margin-bottom:6px;}
.cfg-seqwhat b{color:var(--cyan);}
body.light .cfg-chip{background:#fff;color:var(--ink-2);}
body.light .cfg-who,body.light .cfg-seqwhat{background:#fff;
  color:var(--ink);}
body.light .cfg-note,body.light .cfg-range,body.light .cfg-sel{
  color:var(--ink-2);}
body.light .cfg-rv{color:var(--cyan-deep);}
.anim-mini:hover:not(:disabled){border-color:color-mix(in srgb,var(--accent) 53%,transparent);color:var(--chrome-ink);}
.anim-mini:disabled{opacity:.4;cursor:default;}
/* T402: ONE ROW PER CLICK. The number is the click the space bar
   counts; the name is a button that selects the thing on the slide; the
   detail line says how it arrives. A page of a flip book (or a series
   of a chart, a page of a text box) is a row of its own, indented, with
   a hollow number: it has a click but no order of its own. */
.anim-seq{display:flex;flex-direction:column;gap:4px;}
.anim-step{display:flex;align-items:center;gap:8px;background:var(--chrome-3,#101c28);
  border:1px solid #ffffff12;border-radius:8px;padding:5px 7px;}
.anim-step.cur{border-color:var(--cyan);}
.anim-num{flex:none;width:20px;height:20px;border-radius:50%;
  background:var(--amber);color:var(--on-accent);font-family:var(--mono);font-size:11px;
  font-weight:700;display:flex;align-items:center;justify-content:center;}
/* a row that costs SEVERAL clicks says so as a range, and a 20px circle
   cannot hold "3–6". Only then -- an ordinary row is untouched. */
.anim-num.wide{width:auto;min-width:20px;padding:0 6px;border-radius:10px;}
.anim-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px;}
.anim-name{background:none;border:none;padding:0;color:var(--chrome-ink);
  font:12.5px var(--sans);text-align:left;cursor:pointer;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;}
.anim-name:hover{color:var(--chrome-ink);text-decoration:underline;}
/* T417: the effect word, at the end of the row; a row for the selected
   thing that is not on the list yet; its two actions side by side */
.anim-tag{flex:none;font-size:10.5px;color:var(--chrome-ink-2);
  white-space:nowrap;}
.anim-num.off{background:none;border:1px solid #ffffff33;
  color:var(--chrome-ink-2);}
.anim-step.anim-off{margin-top:6px;border-style:dashed;}
.anim-stepctr.row{flex-direction:row;gap:4px;}
.anim-step.anim-sub{margin-left:18px;background:var(--chrome-4,#0e1824);
  padding-top:3px;padding-bottom:3px;}
.anim-step.anim-sub .anim-num{background:none;border:1px solid var(--amber);
  color:var(--amber);font-weight:600;}
.anim-step.anim-sub .anim-name{font-size:12px;color:var(--chrome-ink-2);}
/* T427: THE CONTROLS ARE A SECOND LINE, under the name, on every row
   that has them -- build rows and page or bullet rows alike. Beside the
   name they crushed it to "- cha..." in a pane 250px wide; under it
   the words stay readable and the three buttons always show. */
.anim-step{flex-wrap:wrap;}
.anim-stepctr{flex:1 0 100%;display:flex;flex-direction:row;
  justify-content:flex-end;align-items:center;gap:3px;}
.anim-stepctr.row{flex:none;}
.anim-updown{display:flex;flex-direction:row;gap:3px;}
/* T432: rows drag; the landing edge is drawn on the row under the
   pointer */
.anim-step[draggable="true"]{cursor:grab;}
.anim-step.dragging{opacity:.5;}
.anim-step.drop-above{box-shadow:0 -3px 0 0 var(--cyan);}
.anim-step.drop-below{box-shadow:0 3px 0 0 var(--cyan);}
/* T577: the middle of a row takes the drop ONTO its click, so the whole
   row lights rather than one edge */
.anim-step.drop-with{box-shadow:inset 0 0 0 2px var(--cyan);
  background:color-mix(in srgb,var(--cyan) 12%,var(--chrome-3,#101c28));}
/* T577: a second row on the same click hangs off the first -- close
   under it, its number an outline -- so "these two happen together"
   is read from the list's shape, not from a sentence */
.anim-step.anim-with{margin-top:-3px;border-top-left-radius:2px;
  border-top-right-radius:2px;border-top-color:transparent;}
.anim-step.anim-with .anim-num{background:none;border:1px dashed var(--amber);
  color:var(--amber);}
.anim-stepctr .anim-mini{padding:2px 6px;font-size:10.5px;}
/* T577: four on a row now (Earlier, Later, With prev, Remove); in a pane
   this narrow they wrap to a second line rather than clip the last */
.anim-stepctr{flex-wrap:wrap;row-gap:3px;}
.anim-stepctr .anim-mini{padding:2px 5px;white-space:nowrap;}
.sh-ico path,.sh-ico rect,.sh-ico ellipse,.sh-ico text{transition:fill .1s;}
.sh-opt-t{font-size:9.5px;letter-spacing:.02em;}

/* ---- the line menus DRAW the option instead of naming it -------------
   A word is a thing you decode into a picture. For a dash pattern, an
   arrowhead or a thickness the picture is the answer, and "Curved the
   other way" made you mirror "Curved" in your head to get there
   (2026-08-17, user: "use symbols with text on hover not typing what they
   are"). Every row draws the real thing and keeps its name in the
   tooltip. currentColor throughout, so the preview brightens with the row
   it is in and the selected one reads as selected. ---- */
/* T220: the SWATCH menus are no longer swept in with the drawn
   line-style menu. That rule stacked their chips one per row under
   the deck-colour row, which made the popup literally T-shaped
   (2026-09-03, user: "why does the text colour look like a T?").
   They lay out as a pad now: a labelled row of the deck's colours,
   a labelled block of presets, then recents. */
.sh-menu.style-menu{display:flex;flex-direction:column;
  gap:2px;width:auto;}
.style-menu .sh-opt,.sw-menu .sh-opt{flex-direction:row;align-items:center;
  gap:8px;padding:4px 8px;}
.ln-prev{display:block;flex:none;}
.sw-val{font-family:var(--mono);font-size:9.5px;color:var(--chrome-ink-2);flex:none;
  width:46px;text-align:right;white-space:nowrap;}
.sh-opt:hover .sw-val,.sh-opt[aria-pressed="true"] .sw-val{color:var(--chrome-ink);}
/* ENDS: three labelled rows, not eighteen lines all starting with the
   same word. The headings are headings, not options — naming a section is
   not the same as naming every row in it. */
.sh-menu.head-menu{display:flex;flex-direction:column;gap:2px;width:auto;}
.hd-row{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;}
.hd-row.hd-sz{grid-template-columns:repeat(4,1fr);}
/* T219: a heading inside a menu is a word, not 8.5px spaced capitals */
.hd-lab{font-family:var(--sans);font-size:11px;font-weight:600;letter-spacing:0;
  text-transform:none;color:var(--chrome-ink-2);padding:6px 3px 3px;}
.hd-lab::first-letter{text-transform:uppercase;}
.head-menu .sh-opt{padding:3px 1px;}
.hd-ico{display:block;width:100%;height:16px;}
.sh-menu.bend-menu{display:grid;grid-template-columns:repeat(5,1fr);
  gap:3px;width:auto;}
.bend-menu .sh-opt{padding:4px 2px;}
.bd-ico{display:block;width:100%;height:28px;}
/* which one you are ON. A set of pictures with no answer to "and which am
   I?" is the one thing the worded lists were no better at. */
.sh-opt[aria-pressed="true"]{background:color-mix(in srgb,var(--accent) 20%,transparent);border-color:var(--accent);
  color:var(--chrome-ink);}
.dbtn.viewtoggle{border-color:color-mix(in srgb,var(--accent) 36%,transparent);color:var(--cyan);}
.dbtn.viewtoggle:hover{border-color:var(--cyan);color:var(--chrome-ink);
  background:color-mix(in srgb,var(--accent) 12%,transparent);}
/* the floating "back to slide" toggle shown while scrolling the notebook */
/* SVG shapes fill their frame; the div carries no border/box for these */
.an-rect.an-svgshape{border:none!important;border-radius:0;
  background:none!important;}
.an-shape-svg{position:absolute;inset:0;width:100%;height:100%;
  overflow:visible;display:block;pointer-events:none;}
/* var() doesn't resolve in an SVG font-family attribute — set it via CSS */
.an-shape-svg text,.sh-ico text{font-family:var(--sans);}
.dbtn.et[aria-pressed="true"]{background:var(--cyan-deep);
  border-color:var(--cyan-deep);color:var(--on-accent-deep,#fff);}
.dbtn.etm{padding:5px 9px;font-family:var(--sans);font-size:12px;}
.dbtn.etm>svg,.dbtn.etm>i[data-ic]{width:15px;height:15px;flex:none;}
/* T489: a small door's readout -- its choice beside its word, in the
   readout face the tiles use (Change layout: "Title + text"; Styles:
   "Heading 2"). It gives way first when the row is tight. */
.dbtn.rbn-sm>.rbn-foldval,.dbtn.etm>.rbn-foldval{display:inline-block;
  font:600 10px var(--mono);color:var(--cyan);margin-left:5px;
  max-width:110px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;flex:0 1 auto;min-width:0;}
.dbtn.rbn-sm>.rbn-foldval[hidden],.dbtn.etm>.rbn-foldval[hidden]{
  display:none;}
.dbtn.rbn-sm[aria-pressed="true"]>.rbn-foldval,
.dbtn.etm[aria-pressed="true"]>.rbn-foldval{color:inherit;}
body.light .dbtn.rbn-sm>.rbn-foldval,body.light .dbtn.etm>.rbn-foldval{
  color:var(--cyan-deep);}
.deck.erc-tight .dbtn.rbn-sm>.rbn-foldval,
.deck.erc-tight .dbtn.etm>.rbn-foldval{max-width:56px;}
/* T489: the typeface select wears the ribbon's ONE surface -- it was
   the one control in the Font group on a different fill, edge and
   type size (2026-09-15 review) */
select#fmt-font{background:var(--btn-bg,#ffffff0a);
  border:1px solid var(--btn-border,#ffffff22);
  color:var(--btn-ink,#cdd9e3);font-family:var(--sans);font-size:12px;
  padding:4px 6px;border-radius:6px;}
select#fmt-font:hover{border-color:var(--cyan);color:var(--chrome-ink);}
select#fmt-font[hidden]{display:none;}
.dbtn.etm[aria-pressed="true"]{background:var(--cyan-deep);
  border-color:var(--cyan-deep);color:var(--on-accent-deep,#fff);}
/* precise point-size input + opacity slider live in the format bar */
.fmt-szwrap,.fmt-opwrap{display:inline-flex;align-items:center;gap:4px;
  flex:none;}
.fmt-szwrap[hidden]{display:none;}
.fmt-num{width:44px;background:var(--chrome-2,#16273a);border:1px solid #ffffff22;
  color:var(--chrome-ink);font-family:var(--mono);font-size:11px;padding:4px 5px;
  border-radius:6px;-moz-appearance:textfield;}
.fmt-num::-webkit-outer-spin-button,
.fmt-num::-webkit-inner-spin-button{-webkit-appearance:none;margin:0;}
.fmt-unit,.fmt-opval{font-family:var(--mono);font-size:10.5px;color:var(--chrome-ink-2);}
.fmt-opval{min-width:34px;text-align:right;}
/* 2026-10-30: the opacity readout is a field, sized as the readout was */
input.fmt-opval{width:40px;min-width:0;height:22px;box-sizing:border-box;
  padding:0 3px;border:1px solid var(--chrome-line,#ffffff22);
  border-radius:5px;background:transparent;-moz-appearance:textfield;}
input.fmt-opval::-webkit-outer-spin-button,
input.fmt-opval::-webkit-inner-spin-button{-webkit-appearance:none;margin:0;}
input.fmt-opval:focus{outline:none;border-color:var(--accent);
  color:var(--chrome-ink);}
/* a typed number in a window's section: line spacing, paragraph
   spacing, a weight of your own (2026-10-30) */
.opt-num{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;
  color:var(--chrome-ink);white-space:nowrap;}
.opt-num input{width:58px;height:24px;box-sizing:border-box;font:inherit;
  font-family:var(--mono);font-size:11px;padding:0 5px;
  border:1px solid var(--chrome-line,#ffffff22);border-radius:5px;
  background:var(--chrome-1,#0f1b26);color:var(--chrome-ink);}
.opt-num input:focus{outline:none;border-color:var(--accent);}
.opt-unit{font-family:var(--mono);font-size:10.5px;color:var(--chrome-ink-2);}
.opt-row.opt-nums{gap:12px;margin-top:4px;}
.sw-own{flex:0 0 100%;padding:6px 2px 1px;margin-top:2px;
  border-top:1px solid var(--chrome-line,#ffffff1a);}
.fmt-range{width:96px;accent-color:var(--cyan);cursor:pointer;height:16px;}
.sw{width:18px;height:18px;border-radius:50%;padding:0;cursor:pointer;
  border:2px solid #ffffff30;}
.sw[aria-pressed="true"]{border-color:#fff;
  box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 67%,transparent);}
.fmt-lab{font-family:var(--mono);font-size:9px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--chrome-ink-2);}
.sw.trans{background:var(--chrome-2,#16273a);position:relative;overflow:hidden;}
.sw.trans::after{content:"";position:absolute;left:-2px;right:-2px;
  top:50%;height:2px;background:#ff6b57;
  transform:rotate(-45deg);}
/* recent colours, newest first — filled from the custom picker's history
   whenever a colour menu opens (2026-08-19, user: recents should be in
   the colour menus, not buried in the picker) */
/* T273: WRAP, like .sw-tokrow below. `.sw-menu .fmt-lab` gives the
   heading `flex:0 0 100%` -- basis 100%, shrink 0 -- and the chips are
   `flex:none`, so on a nowrap row the heading took the whole width and
   pushed all seven chips out past the right edge of a 216px card. The
   popup showed a RECENTLY USED heading with nothing under it, every
   time (2026-09-05, from the user's screenshot). */
.sw-recrow{display:flex;flex-wrap:wrap;align-items:center;gap:7px;}
.sw-recrow[hidden]{display:none!important;}
.sw-rc{width:18px;height:18px;border-radius:50%;padding:0;cursor:pointer;
  border:2px solid #ffffff30;flex:none;}
/* custom-colour swatch: a rainbow chip that opens the full picker */
.sw.sw-custom{background:conic-gradient(from 0deg,#ff6b57,#f0a848,#46a892,
  var(--accent),#7a6cff,#ff6b57);position:relative;overflow:hidden;}
.sw.sw-custom::after{content:"+";position:absolute;inset:0;display:flex;
  align-items:center;justify-content:center;font-size:11px;line-height:1;
  color:#fff;font-weight:800;text-shadow:0 1px 2px #000b;}
/* professional colour picker popover (hex / rgb / rgba + alpha + recents) */
.color-pop{position:fixed;z-index:160;width:236px;background:#0e1b28;
  border:1px solid #ffffff26;border-radius:10px;padding:12px;
  box-shadow:0 16px 46px #000a;display:flex;flex-direction:column;gap:9px;
  font-family:var(--sans);}
.color-pop[hidden]{display:none;}
.cp-head{font-family:var(--mono);font-size:10px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--chrome-ink-2);}
.cp-native{width:100%;height:38px;border:1px solid #ffffff22;border-radius:6px;
  background:none;cursor:pointer;padding:2px;}
.cp-row{display:flex;align-items:center;gap:8px;}
.cp-lab{font-family:var(--mono);font-size:9.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--chrome-ink-2);width:38px;flex:none;}
.cp-in{flex:1;min-width:0;background:var(--chrome-2,#16273a);border:1px solid #ffffff22;
  color:var(--chrome-ink);font-family:var(--mono);font-size:12px;padding:6px 8px;
  border-radius:6px;}
.cp-in:focus{outline:none;border-color:var(--cyan);}
.cp-in.bad{border-color:#ff6b57;}
.cp-alpha{flex:1;min-width:0;accent-color:var(--cyan);}
.cp-aval{font-family:var(--mono);font-size:10px;color:var(--chrome-ink-2);width:34px;
  text-align:right;flex:none;}
.cp-recent{display:flex;flex-wrap:wrap;gap:5px;}
.cp-recent:empty{display:none;}
.cp-sw-chk{background-image:linear-gradient(45deg,#33475a 25%,transparent 25%,
  transparent 75%,#33475a 75%),linear-gradient(45deg,#33475a 25%,#1a2836 25%,
  #1a2836 75%,#33475a 75%);background-size:8px 8px;
  background-position:0 0,4px 4px;}
.cp-rsw{width:18px;height:18px;border-radius:4px;border:1px solid #ffffff22;
  cursor:pointer;padding:0;position:relative;overflow:hidden;}
.cp-rsw::after{content:"";position:absolute;inset:0;background:var(--cpc);}
.cp-foot{display:flex;align-items:center;gap:8px;}
.cp-preview{width:28px;height:28px;border-radius:6px;border:1px solid #ffffff26;
  flex:none;position:relative;overflow:hidden;}
.cp-preview::after{content:"";position:absolute;inset:0;
  background:var(--cpc,var(--accent));}
.cp-apply{background:var(--cyan-deep);border-color:var(--cyan-deep);
  color:var(--on-accent-deep,#fff);}
.deck.editing .deck-arrow,.deck.editing .deck-foot{display:none;}
.slide{position:relative;}
/* image annotations */
/* ---- tables ---------------------------------------------------------
   The rules are drawn in --tbl-sw, which drawTable sets from strokePx —
   the same page-relative currency every other stroke on the canvas uses.
   A fixed 1px hairline would disappear on an A0 poster and be a fence at
   10% zoom (2026-08-20). */
.an-table{position:absolute;overflow:hidden;}
.an-tbl{width:100%;height:100%;border-collapse:collapse;
  table-layout:fixed;font-family:inherit;font-size:inherit;color:inherit;}
.an-tbl td,.an-tbl th{border:var(--tbl-sw,1px) solid var(--tbl-line,
  currentColor);padding:.28em .45em;vertical-align:top;
  overflow-wrap:anywhere;text-align:left;font-weight:inherit;}
.an-tbl th{font-weight:700;
  background:color-mix(in srgb,currentColor 12%,transparent);}
.an-table.nogrid .an-tbl td,.an-table.nogrid .an-tbl th{border-color:
  transparent;}
.an-tbl td[contenteditable="plaintext-only"],
.an-tbl th[contenteditable="plaintext-only"]{outline:2px solid var(--cyan);
  outline-offset:-2px;cursor:text;}
.deck.editing .an-table{cursor:move;}
.deck.editing .an-table.sel{outline:2px solid var(--cyan);outline-offset:1px;}
/* a grip per column boundary: widths are dragged, never typed */
.an-tblgrip{position:absolute;top:0;bottom:0;width:9px;margin-left:-4.5px;
  cursor:col-resize;z-index:6;}
.an-tblgrip:hover{background:color-mix(in srgb,var(--accent) 35%,
  transparent);}
.an-image{position:absolute;}
/* T388: a live page. The cover is the editor's handle on it. */
.an-web{position:absolute;overflow:hidden;background:#fff;
  border-radius:var(--tk-rad,4px);}
.an-webframe{width:100%;height:100%;border:0;display:block;}
.an-webempty{display:flex;align-items:center;justify-content:center;
  height:100%;color:#44525c;font:12px var(--sans);}
.an-webcover{position:absolute;inset:0;display:flex;align-items:flex-end;
  padding:6px;cursor:move;
  background:linear-gradient(transparent 72%,#0009);}
.an-webcover span{font:10.5px var(--mono);color:#fff;background:#0b141dcc;
  padding:2px 6px;border-radius:4px;}
/* T724: a box of code. Its fill, ink and edge are the theme's, written
   inline; the face is a <pre>. While typing, a transparent textarea lies
   over it with the SAME font, size, padding and wrapping, so the caret
   and the selection sit on the coloured letters underneath -- change one
   of these four on one of them and the caret drifts off its letter. */
.an-code{position:absolute;border:1px solid transparent;
  border-radius:var(--tk-rad,8px);font-family:var(--mono);line-height:1.45;}
.deck.editing .an-code{cursor:move;}
.an-code.an-editing{cursor:text;}
.an-code-pre,.an-code-ta{display:block;margin:0;padding:.6em .8em;
  font:inherit;line-height:inherit;letter-spacing:0;white-space:pre-wrap;
  overflow-wrap:anywhere;tab-size:4;-moz-tab-size:4;border:0;
  border-radius:inherit;box-sizing:border-box;
  text-rendering:auto;font-variant-ligatures:none;font-kerning:none;}
.an-code-pre{background:none;color:inherit;}
.an-code-pre code{font:inherit;background:none;color:inherit;padding:0;}
.an-code-ta{position:absolute;inset:0;width:100%;height:100%;resize:none;
  overflow:hidden;background:transparent;color:transparent;outline:none;
  cursor:text;z-index:1;}
.an-code-ta::selection{background:var(--cb-sel);color:transparent;}
/* the textarea's words are transparent, so its hint takes the box's ink */
.an-code-ta::placeholder{color:var(--cb-ink);opacity:.5;font-style:italic;}
.an-code-ph{opacity:.5;font-style:italic;}
.an-code.an-editing .an-code-ph{display:none;}
/* the source in a frame of its own: the editor's textarea lies over it
   and not over the output under it (T732) */
.an-code-src{position:relative;border-radius:inherit;}
/* "Python around the outer edge when clicked on": a slim label on the
   top edge -- the language and Run -- just outside the selection
   outline, only while the box is selected or being typed in. The
   colours, the size and the box are the Code tab's since T732. */
.an-code-tab{position:absolute;left:-3px;bottom:calc(100% + 5px);
  display:none;align-items:center;gap:5px;padding:1px 2px 1px 6px;
  background:var(--chrome-1,#0e1926);color:var(--chrome-ink,#cdd9e3);
  border:1px solid var(--cyan);border-radius:6px;
  font:600 11px/1.2 var(--sans);white-space:nowrap;z-index:5;
  cursor:default;box-shadow:0 1px 5px #0004;}
.an-code.sel .an-code-tab,.an-code.an-editing .an-code-tab{display:flex;}
/* T736: Edit in Present -- in the show the box takes the pointer (the
   layer does not) and wears its label all the time */
.an-code.an-code-live{pointer-events:auto;cursor:text;}
.an-code.an-code-live .an-code-tab{display:flex;}
/* the label holds the top edge, so the rotate grip goes under the box: on
   top, centred, it sat on the label of any narrow box (2026-10-31) */
.an-code .an-rotate{top:auto;bottom:-30px;}
.an-code .an-rotate::after{top:auto;bottom:100%;}
.an-code-ic{display:inline-flex;color:var(--cyan);}
.an-code-ic svg{width:13px;height:13px;}
/* T728: Run (Stop while running), a word and an icon, after the language */
.an-code-run{display:inline-flex;align-items:center;gap:3px;
  padding:1px 6px 1px 4px;font:inherit;color:inherit;cursor:pointer;
  background:color-mix(in srgb,var(--cyan) 14%,transparent);
  border:1px solid color-mix(in srgb,var(--cyan) 55%,transparent);
  border-radius:4px;}
.an-code-run:hover,.an-code-run:focus-visible{outline:none;
  background:color-mix(in srgb,var(--cyan) 30%,transparent);}
.an-code-run.busy,#cb-run.busy{border-color:#e8a33d;
  background:color-mix(in srgb,#e8a33d 18%,transparent);}
.an-code-run svg{width:11px;height:11px;}
/* T748: RUN, DOWN THE BOX'S SIDE -- outside its left edge, level with its
   first line, the word under the icon; always there in the editor, not
   only while selected. On the right when the box is against the page's
   left edge. Chrome-sized, so it does not grow with the code's type. */
.an-code-run.an-code-side{position:absolute;right:calc(100% + 6px);top:0;
  flex-direction:column;justify-content:center;gap:2px;width:38px;
  padding:5px 0 4px;font:600 10.5px/1.1 var(--sans);
  background:var(--chrome-1,#0e1926);color:var(--chrome-ink,#cdd9e3);
  border:1px solid color-mix(in srgb,var(--cyan) 70%,transparent);
  border-radius:6px;box-shadow:0 1px 4px #0004;z-index:5;}
.an-code-run.an-code-side:hover,.an-code-run.an-code-side:focus-visible{
  background:color-mix(in srgb,var(--cyan) 26%,var(--chrome-1,#0e1926));}
.an-code-run.an-code-side svg{width:14px;height:14px;color:var(--cyan);}
.an-code-run.an-code-side.busy svg{color:var(--warning);}
.an-code-run.an-code-side.an-code-side-r{right:auto;left:calc(100% + 6px);}
/* T732: WHAT IT PRINTED, INSIDE THE BOX, as a notebook draws a cell's
   output: under the source, a rule between, in the box's own colours
   and font a step smaller; an error in the error colour. It is part of
   the slide (it is kept with the deck), so it prints and shows. */
.an-code-out{border-top:1px solid var(--cb-edge);
  border-radius:0 0 var(--tk-rad,8px) var(--tk-rad,8px);cursor:auto;}
.an-code-out-tx{margin:0;padding:.45em .8em .6em;font:inherit;
  font-size:.9em;line-height:1.4;color:inherit;background:none;
  white-space:pre-wrap;overflow-wrap:anywhere;tab-size:4;user-select:text;}
.an-code-out.bad .an-code-out-tx{color:var(--cb-err);}
/* T735: a plot the run drew, as wide as the box at most, its own shape */
.an-code-fig{display:block;max-width:calc(100% - 1.6em);height:auto;
  margin:.45em .8em .6em;border-radius:3px;}
.an-code-out-tx+.an-code-fig{margin-top:0;}
.an-code-out.busy .an-code-out-tx,.an-code-out.empty .an-code-out-tx{
  opacity:.6;font-style:italic;}
/* ---- T732: the Code tab's own controls: a caption over each field, and
   the deck's colours as swatches ---- */
/* one ribbon row each, the caption before the control: a caption over
   it made each field two rows, and the group taller than the ribbon */
.cb-field{display:inline-flex;align-items:center;gap:6px;margin:0 4px;}
.cb-field[hidden]{display:none;}
.cb-cap{font:600 11px/1.2 var(--sans);opacity:.85;min-width:5.6em;}
.cb-field select{max-width:13em;}
.cb-sws{display:inline-flex;gap:3px;align-items:center;}
.cb-sw{width:18px;height:18px;padding:0;border-radius:4px;cursor:pointer;
  border:1px solid #ffffff40;background:transparent;}
.cb-sw[aria-pressed="true"]{outline:2px solid var(--cyan);outline-offset:1px;}
.cb-sw-own{background-image:linear-gradient(135deg,transparent 46%,
  #ffffff70 46%,#ffffff70 54%,transparent 54%);}
.cb-sw-none{background:repeating-linear-gradient(45deg,transparent 0 3px,
  #ff6b5780 3px 4px);}
#cb-bdwrap select{margin-left:2px;}
/* T738: a box of HTML. The frame is laid out at the box's size on a
   720-tall page and scaled to the slide (53d-html-box.js), so it is
   positioned and scaled from its top-left corner. Transparent, so the
   slide shows through wherever the HTML paints nothing: an iframe whose
   colour scheme differs from its page's paints an opaque backdrop, so
   it asks for the same scheme its page has (none). */
.an-html{position:absolute;}
.deck.editing .an-html{cursor:move;}
.an-html.an-editing{cursor:text;}
.an-htmlframe{position:absolute;left:0;top:0;border:0;display:block;
  transform-origin:0 0;background:transparent;color-scheme:normal;}
/* The editor picks the box up by its face. Everywhere else -- the show,
   the scrolling page, a standalone export -- a click goes through a box
   to the next build unless its scripts run, when the box takes it (T546's
   rule: what takes a click while presenting is named). Even then its
   FRAME takes no pointer until the box is woken by a press on it
   (hbKeyGuard): a frame given the pointer can be given the keyboard. The
   scrolling page and an export have no .deck round them, so this is not
   scoped to one (found in review: a box there took no click at all). */
.an-htmlframe{pointer-events:none;}
.an-html.an-html-live{pointer-events:auto;cursor:pointer;}
.an-html.an-html-live.an-awake .an-htmlframe{pointer-events:auto;}
.deck.editing .an-htmlframe{pointer-events:none;}
/* a box whose scripts or internet loading arrived from somewhere else
   and are held here: said on its face, in the editor only, with the
   button that allows them */
.an-html-held{position:absolute;left:4px;right:4px;bottom:4px;z-index:3;
  display:none;flex-wrap:wrap;align-items:center;gap:4px 8px;
  padding:5px 8px;border-radius:5px;background:var(--chrome-1,#0e1926);
  color:var(--chrome-ink,#cdd9e3);border:1.5px solid var(--amber,#e0a84b);
  font:600 11px/1.3 var(--sans);cursor:default;box-shadow:0 2px 8px #0005;}
.deck.editing .an-html-held{display:flex;}
.an-html.an-editing .an-html-held{display:none;}
.an-html-held button{display:inline-flex;align-items:center;gap:4px;
  font:inherit;color:inherit;background:color-mix(in srgb,var(--cyan) 22%,
  transparent);border:1px solid var(--cyan);border-radius:4px;
  padding:3px 7px;cursor:pointer;text-align:left;}
.an-html-held button svg{width:12px;height:12px;flex:none;}
.an-html-held button:hover,.an-html-held button:focus-visible{
  background:color-mix(in srgb,var(--cyan) 38%,transparent);outline:none;}
.an-html-ph{position:absolute;inset:0;display:none;align-items:center;
  justify-content:center;text-align:center;padding:6px;
  font:12px/1.3 var(--sans);color:var(--tk-ink,#cdd9e3);opacity:.65;
  border:1px dashed currentColor;border-radius:4px;}
.deck.editing .an-html.an-html-empty .an-html-ph{display:flex;}
.an-html.an-editing .an-htmlframe,.an-html.an-editing .an-html-ph{
  visibility:hidden;}
/* its source, typed: the code box's textarea over a coloured <pre>,
   in a box that keeps its size, so the source scrolls in it. The two
   keep the same gutter for a scroll bar, or they would wrap at two
   widths and the caret would drift off its letter. */
.an-html-src{position:absolute;inset:0;z-index:2;overflow:hidden;
  border:1px solid transparent;border-radius:4px;font-family:var(--mono);
  line-height:1.45;cursor:text;}
.an-html-pre,.an-html-ta{position:absolute;inset:0;width:100%;
  height:100%;margin:0;padding:.6em .8em;font:inherit;
  line-height:inherit;letter-spacing:0;white-space:pre-wrap;
  overflow-wrap:anywhere;tab-size:4;-moz-tab-size:4;border:0;
  box-sizing:border-box;text-rendering:auto;font-variant-ligatures:none;
  font-kerning:none;scrollbar-gutter:stable;}
.an-html-pre{overflow:hidden;background:none;color:inherit;}
.an-html-pre code{font:inherit;background:none;color:inherit;padding:0;}
.an-html-ta{resize:none;overflow:auto;background:transparent;
  color:transparent;outline:none;z-index:1;}
.an-html-ta::selection{background:var(--cb-sel);color:transparent;}
.an-html-ta::placeholder{color:var(--cb-ink);opacity:.5;font-style:italic;}
/* a long source is coloured when typing pauses: until then the
   textarea shows its own words and the coloured copy waits */
.an-html-src.an-src-raw .an-html-ta{color:var(--cb-ink);}
.an-html-src.an-src-raw .an-html-pre{visibility:hidden;}
/* its tab is the code box's, shown the same way */
.an-html.sel .an-code-tab,.an-html.an-editing .an-code-tab{display:flex;}
/* by the slide's right edge the tab lines up with the box's right edge
   (hbTabFit), a code box's as an HTML box's */
.an-tab-end>.an-code-tab{left:auto;right:-3px;}
.an-html .an-rotate{top:auto;bottom:-30px;}
.an-html .an-rotate::after{top:auto;bottom:100%;}
/* the code box's label is slim since T732 (its gap 5px, for an icon, a
   name and Run); an HTML box's tab holds three controls with their own
   padding, so it keeps the tight gap it was reviewed at */
.an-html-tab{gap:1px;}
.an-html-name{margin-right:6px;}
.an-html-tab button,.an-html-opt{display:inline-flex;align-items:center;
  gap:4px;font:inherit;color:inherit;background:transparent;border:0;
  border-radius:4px;padding:3px 6px;cursor:pointer;}
.an-html-tab button svg{width:13px;height:13px;}
.an-html-tab button:hover,.an-html-tab button:focus-visible,
.an-html-opt:hover,.an-html-opt:focus-within{
  background:color-mix(in srgb,var(--cyan) 18%,transparent);outline:none;}
.an-html-opt input{margin:0;accent-color:var(--cyan);cursor:pointer;}
.an-html-tab button+.an-html-opt,.an-html-opt+.an-html-opt{margin-left:2px;}
.mini-it.is-html img{object-fit:fill;}
/* CONTAIN by default: cover let any non-proportional resize silently
   clip the picture (2026-08-19, diagnosed+verified in-browser: a 2:1
   stripe resized to 0.4:1 showed ~21% of its width). A crop must still
   FILL first or the mask would only bite letterbox — same rationale as
   the cell rule below. */
.an-image.an-cropped .an-imgel{object-fit:cover;}
/* T387: a window onto the picture -- the img is scaled and offset so
   the window fills the box, and the box clips the rest */
/* T587: the window clips in a wrapper, not the item, so the item's own
   handles (which stand outside its box) are never cut off */
.an-imgwin{position:absolute;inset:0;overflow:hidden;border-radius:inherit;}
.an-image.an-win .an-imgel{position:absolute;object-fit:fill;max-width:none;}
/* T587: while trimming, the part being cut away is still there, faint,
   so you can see what you are giving up -- as PowerPoint shows it */
.an-crop-ghost{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;opacity:.28;pointer-events:none;}
.zc-box{position:absolute;border:1.5px dashed var(--cyan);
  background:color-mix(in srgb,var(--cyan) 14%,transparent);
  pointer-events:none;}
.an-imgel{width:100%;height:100%;object-fit:contain;display:block;
  pointer-events:none;border-radius:2px;}
.deck.editing .an-image{cursor:move;}
.deck.editing .an-image.sel{outline:2px solid var(--cyan);outline-offset:1px;}
/* T321: a clip. Black behind a letterboxed film, the deck's surface
   behind a sound-only one; while editing the element takes no clicks so
   the box drags and selects like a picture. */
.an-video{position:absolute;background:#000;border-radius:2px;
  overflow:hidden;}
.an-video.an-audio{background:#16273a;}
.an-mediael{width:100%;height:100%;display:block;object-fit:contain;}
.an-audio .an-mediael{height:auto;position:absolute;left:0;right:0;
  bottom:0;width:100%;}
.deck.editing .an-mediael{pointer-events:none;}
.an-mediachip{position:absolute;left:6px;top:6px;font-size:11px;
  line-height:1.4;background:#000a;color:#fff;padding:2px 7px;
  border-radius:3px;pointer-events:none;max-width:calc(100% - 12px);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.deck.editing .an-video{cursor:move;}
.deck.editing .an-video.sel{outline:2px solid var(--cyan);outline-offset:1px;}
.md-preview{width:100%;max-height:160px;background:#000;border-radius:4px;
  display:block;margin:4px 0 8px;}
.md-preview.md-audio{max-height:40px;}
.mediapane .md-check,.chartpane .md-check{display:flex;align-items:center;
  gap:8px;
  text-transform:none;letter-spacing:0;}
.mediapane .md-btns{gap:6px;flex-wrap:wrap;}
.mediapane .md-info{opacity:.75;font-size:11px;}
.mediapane .empty > *:not(#md-name){display:none;}
/* T322: the Chart pane. Rows wrap; a series row is a colour well, its
   name, and the switches; the pressed switch wears the accent. */
.chartpane .cp-row{flex-wrap:wrap;gap:4px;align-items:center;}
.chartpane .cp-series{padding:4px 0;border-top:1px solid #ffffff12;}
.chartpane .cp-col{width:26px;height:22px;padding:0;flex:none;
  border:1px solid #ffffff26;border-radius:4px;background:none;
  cursor:pointer;}
.chartpane .cp-name,.chartpane .cp-text{flex:1 1 90px;min-width:70px;}
.chartpane .cp-btn{font-size:11px;padding:2px 7px;}
.chartpane .cp-btn.on{background:color-mix(in srgb,var(--accent) 22%,
  transparent);border-color:color-mix(in srgb,var(--accent) 55%,
  transparent);color:var(--chrome-ink);}
.chartpane .cp-tags{font-size:10px;opacity:.7;flex:1 0 100%;}
/* T324: a structured table. The group row reads as a heading above the
   heading; the footer is ruled off from the body it sums; a numeric
   column gets figures of one width so its digits stack. */
.an-tbl-grouprow th{font-weight:600;opacity:.9;
  border-bottom:1px solid color-mix(in srgb,currentColor 24%,transparent);}
.an-tbl-grouprow th.an-tbl-gapgroup{border-bottom:0;}
.an-tbl-calc td{font-weight:600;
  border-top:2px solid color-mix(in srgb,currentColor 40%,transparent);}
.an-tbl td.an-tbl-num{font-variant-numeric:tabular-nums;}
.tablepane .tp-row{flex-wrap:wrap;gap:4px;align-items:center;}
.tablepane .tp-cols{gap:3px;}
.tablepane .tp-btn{font-size:11px;padding:2px 7px;}
.tablepane .tp-btn.on{background:color-mix(in srgb,var(--accent) 22%,
  transparent);border-color:color-mix(in srgb,var(--accent) 55%,
  transparent);color:var(--chrome-ink);}
.tablepane .tp-in{flex:0 1 84px;min-width:56px;}
.tablepane .tp-in.tp-wide{flex:1 1 140px;}
.tablepane .tp-col{width:26px;height:22px;padding:0;flex:none;
  border:1px solid #ffffff26;border-radius:4px;background:none;
  cursor:pointer;}
/* T325: the citations pane. One entry a row, its number first so the
   list reads as the bibliography it will become. */
.citepane .ct-row{flex-wrap:wrap;gap:4px;align-items:baseline;}
.citepane .ct-entry{padding:5px 0;border-top:1px solid #ffffff12;}
.citepane .ct-num{flex:none;font-family:var(--mono);font-size:11px;
  opacity:.8;min-width:26px;}
.citepane .ct-ref{flex:1 1 100%;font-size:11px;line-height:1.45;}
.citepane .ct-btn{font-size:11px;padding:2px 7px;}
.citepane .ct-btn.on{background:color-mix(in srgb,var(--accent) 22%,
  transparent);border-color:color-mix(in srgb,var(--accent) 55%,
  transparent);color:var(--chrome-ink);}
.citepane .ct-hint,.citepane .ct-warn{text-transform:none;
  letter-spacing:0;font-size:11px;line-height:1.45;}
.citepane .ct-warn{color:var(--coral,#ff6b57);opacity:.95;}
/* the footnote strip a slide's citations land in */
.slide-citefoot{position:absolute;left:4%;right:4%;bottom:1.2%;
  font-size:0.9em;opacity:.7;line-height:1.35;pointer-events:none;
  text-align:left;}
.tablepane .tp-hint{opacity:.75;font-size:11px;text-transform:none;
  letter-spacing:0;line-height:1.4;}
.chartpane .cp-hint{opacity:.75;font-size:11px;text-transform:none;
  letter-spacing:0;line-height:1.4;}
/* multi-selection / group: a dashed outline, no per-item resize handles */
/* the rubber band. Percent geometry like everything else on the layer,
   so it is right at any zoom and on any page size (2026-08-20). */
.an-marquee{position:absolute;pointer-events:none;z-index:40;
  border:1px solid var(--cyan);
  background:color-mix(in srgb,var(--accent) 12%,transparent);}
/* the group you have stepped INTO: outlined as a whole, so it is obvious
   that clicks are landing on its members and not on the group */
.deck.editing .an-item.an-ingrp{outline:1px dashed
  color-mix(in srgb,var(--accent) 55%,transparent);outline-offset:3px;}
.deck.editing .an-item.grpsel{outline:1.5px dashed var(--cyan);
  outline-offset:1px;}
/* T487: a whole group selected wears ONE solid frame round the union
   of its members (paintSel draws it); the members' own dashes go */
.deck.editing .an-item.grpsel.an-grouped{outline:none;}
.deck.editing .an-grpframe{position:absolute;pointer-events:none;
  outline:2px solid var(--cyan);outline-offset:3px;border-radius:3px;
  z-index:5;}
.deck.editing .an-item.grpsel .an-resize,
.deck.editing .an-item.grpsel .an-handle,
.deck.editing .an-item.grpsel .an-cellbtn,
.deck.editing .an-item.grpsel .cellparts{display:none!important;}
/* build animations: staged items hide until revealed, then animate in */
.an-prebuild{opacity:0!important;pointer-events:none!important;}
/* TWO RULES, BOTH LEARNED FROM BUGS THESE KEYFRAMES USED TO HAVE (T156).

   1. NEVER THE `transform` SHORTHAND. applyCommon writes a rotated item's
      rotate() into style.transform, and the shorthand REPLACED it for the
      animation's duration -- an object would un-rotate, animate, and snap
      back. The render path papered over it by silently swapping a rotated
      Rise or Zoom for a Fade (JVC-03): the model said rise, the ribbon
      said rise, the pane chip said rise, and a fade played. The
      individual `translate` and `scale` properties are applied BEFORE
      `transform` in the computed value, so they COMPOSE with that
      rotate() instead of replacing it, and the substitution is deleted.

   2. NEVER END AT A LITERAL OPACITY. `to{opacity:1}` fought a.op, which
      applyCommon also writes inline: a 40%-opacity object animated up to
      FULL and then snapped back to 40% at the end of every build. An
      omitted `to` keyframe means "the value this element already has", so
      the fade now lands exactly where the author put it. Same reason the
      transform keyframes have no `to`. */
@keyframes anIn-fade{from{opacity:0}}
@keyframes anIn-rise{from{opacity:0;translate:0 22px}}
@keyframes anIn-zoom{from{opacity:0;scale:.85}}
.an-anim-fade{animation:anIn-fade .45s ease;}
.an-anim-rise{animation:anIn-rise .5s cubic-bezier(.2,.7,.2,1);}
.an-anim-zoom{animation:anIn-zoom .45s ease;}
/* T385: three more, by the same two rules. Fly in comes from the left;
   Page turn is a squash from the left edge, which reads as a page
   swinging open without a perspective on the layer (a perspective
   there would change the stacking of every item on it); Typewriter is
   done in JS (typeInto) and only borrows a caret from here. */
@keyframes anIn-slide{from{opacity:0;translate:-60px 0}}
@keyframes anIn-turn{from{opacity:.2;scale:.05 1}}
.an-anim-slide{animation:anIn-slide .5s cubic-bezier(.2,.7,.2,1);}
.an-anim-turn{animation:anIn-turn .55s cubic-bezier(.2,.7,.2,1);
  transform-origin:left center;}
.an-typing .an-tx::after{content:"\258D";opacity:.8;
  animation:an-caret .7s steps(1) infinite;}
@keyframes an-caret{50%{opacity:0}}
/* T385: HIGHLIGHT, DON'T HIDE. The lit piece takes the accent and a
   little size from its left edge; the pieces still to come sit quiet.
   Left origin so a bullet grows away from its dot, not over it. */
/* T493: the colour and the size are the box's own (--hl-col and
   --hl-scale, set by the reveal pass from anim.hlcol / anim.hlsize);
   the accent and 4% are what a box that says nothing gets */
.an-part.an-hl{color:var(--hl-col,var(--sl-accent,#39a9c0));
  scale:var(--hl-scale,1.04);
  transform-origin:left center;transition:scale .25s ease,color .25s ease;}
/* T578: inline-block ONLY for an inline run, which needs it to take a
   scale at all. A promoted piece IS the <li> (17-text-builds.js), and
   inline-block took its list-item display away -- so the lit bullet lost
   its dot (2026-09-30, user: "they don't appear with the dot points
   when doing the highlight animation"). A block already scales. */
.an-part.an-hl:not(.an-blk){display:inline-block;}
.an-part.an-hl-wait{opacity:.45;transition:opacity .25s ease;}
/* ---- T473: A FIGURE IN PANELS. The covers sit over the item in the
   page's colour and lift one per click; in the editor they are faint
   numbered outlines so the grid reads and the figure is still seen. */
.an-covers{position:absolute;inset:0;pointer-events:none;z-index:2;}
.an-cover{position:absolute;box-sizing:border-box;display:none;
  align-items:center;justify-content:center;}
.an-cover.on{display:flex;}
.an-cover>b{display:none;font:600 11px var(--mono);color:var(--sl-accent);
  background:#0b141dcc;border-radius:4px;padding:1px 5px;}
.an-cover.an-cover-edit{display:flex;background:transparent!important;
  border:1px dashed color-mix(in srgb,var(--cyan) 55%,transparent);}
.an-cover.an-cover-edit>b{display:block;}
.an-cover.on.an-cover-edit{background:transparent!important;}
.panel-ico{display:grid;gap:1.5px;width:22px;height:16px;
  margin:0 auto 2px;}
.panel-ico>i{display:block;background:currentColor;opacity:.75;
  border-radius:1px;}
/* T471: THE HIGHLIGHT, CONFIGURED. data-hlfx says what the lit piece
   does (both = the T385 look above; grow = bigger only; colour =
   coloured only) and data-hlrest what every other piece does (dim =
   the T385 look, the ones still to come sit quiet; blur = all the
   others soften; plain = they are left alone). T493: keyed on the
   attribute alone, so the Configure pane's sample (.cfg-hlprev) wears
   the same rules as the box on the slide. */
[data-hlfx="grow"] .an-part.an-hl{color:inherit;}
[data-hlfx="colour"] .an-part.an-hl{scale:1;}
[data-hlrest="blur"] .an-part.an-hl-wait{opacity:1;}
[data-hlrest="blur"] .an-part.an-hl-rest{filter:blur(2.5px);
  opacity:.7;transition:filter .3s ease,opacity .3s ease;}
[data-hlrest="plain"] .an-part.an-hl-wait{opacity:1;}
/* T578: APPEAR + HIGHLIGHT. The pieces to come are hidden, so the ones
   already said are "the rest" -- dimmed is theirs. Blurred already acts
   on every other piece, and as-they-are needs nothing. */
[data-hlin="1"][data-hlrest="dim"] .an-part.an-hl-rest{opacity:.45;
  transition:opacity .25s ease;}
/* T493: THE SAMPLE. Three bullets in the Configure pane, the middle
   one lit, drawn by the same classes and variables as the slide -- so
   a colour or a size chosen here is seen before the show. */
.cfg-hlprev{display:flex;flex-direction:column;gap:3px;margin:0 2px 8px;
  padding:8px 10px;border-radius:7px;background:var(--chrome-2,#16273a);
  font-family:var(--sans);font-size:12.5px;color:var(--chrome-ink);
  line-height:1.35;}
.cfg-hlprev .an-part{display:inline-block;}
.cfg-hlprev .an-part::before{content:"\2022\00a0";opacity:.7;}
.cfg-hlcol{display:inline-flex;align-items:center;gap:4px;}
.cfg-hlcol .cfg-dot{width:12px;height:12px;border-radius:50%;flex:none;
  border:1px solid #ffffff44;}
.cfg-hlcol input[type="color"]{width:26px;height:22px;padding:0;
  border:1px solid var(--chrome-line,#ffffff1f);border-radius:6px;
  background:none;cursor:pointer;}
body.light .cfg-hlprev{background:#fff;color:var(--ink);}
/* T385: MOTION THAT KEEPS GOING -- individual properties again, so a
   rotated item wobbles about its own rotation instead of losing it */
/* T445: HOW FAR IS A NUMBER (2026-09-14, user: "it would be cool to
   have more configurations on these, like speed, and how far they
   wobble"). Every keyframe multiplies its own travel by --mo-amp, so
   one rule per movement covers every amount of it; speed, easing,
   delay, repeat and direction are the shorthand's own terms and are
   written onto the element by motionPaint (48b-motion.js). The class
   rules below are the defaults, for an element nothing has painted. */
@keyframes an-wobble{0%,100%{rotate:calc(-2.5deg * var(--mo-amp,1))}
  50%{rotate:calc(2.5deg * var(--mo-amp,1))}}
@keyframes an-bob{0%,100%{translate:0 0}
  50%{translate:0 calc(-8px * var(--mo-amp,1))}}
@keyframes an-pulse{0%,100%{scale:1}
  50%{scale:calc(1 + .05 * var(--mo-amp,1))}}
@keyframes an-sway{0%,100%{translate:calc(-10px * var(--mo-amp,1)) 0}
  50%{translate:calc(10px * var(--mo-amp,1)) 0}}
@keyframes an-shake{0%,100%{translate:0 0}
  20%{translate:calc(-4px * var(--mo-amp,1)) 0}
  40%{translate:calc(4px * var(--mo-amp,1)) 0}
  60%{translate:calc(-3px * var(--mo-amp,1)) 0}
  80%{translate:calc(3px * var(--mo-amp,1)) 0}}
@keyframes an-spin{from{rotate:0deg}to{rotate:360deg}}
@keyframes an-swing{0%,100%{rotate:calc(-6deg * var(--mo-amp,1))}
  50%{rotate:calc(6deg * var(--mo-amp,1))}}
@keyframes an-breathe{0%,100%{opacity:1}
  50%{opacity:calc(1 - .45 * var(--mo-amp,1))}}
@keyframes an-jelly{0%,100%{scale:1 1}
  30%{scale:calc(1 + .08 * var(--mo-amp,1)) calc(1 - .08 * var(--mo-amp,1))}
  60%{scale:calc(1 - .06 * var(--mo-amp,1)) calc(1 + .06 * var(--mo-amp,1))}}
@keyframes an-drift{0%,100%{translate:0 0}
  25%{translate:calc(9px * var(--mo-amp,1)) calc(-6px * var(--mo-amp,1))}
  50%{translate:calc(12px * var(--mo-amp,1)) calc(5px * var(--mo-amp,1))}
  75%{translate:calc(-6px * var(--mo-amp,1)) calc(7px * var(--mo-amp,1))}}
@keyframes an-glow{0%,100%{filter:drop-shadow(0 0 0 transparent)}
  50%{filter:drop-shadow(0 0 calc(10px * var(--mo-amp,1))
    var(--accent,#39a9c0))}}
@keyframes an-tilt{0%,100%{rotate:0deg}
  50%{rotate:calc(4deg * var(--mo-amp,1))}}
@keyframes an-flicker{0%,40%,48%,55%,100%{opacity:1}
  45%{opacity:calc(1 - .7 * var(--mo-amp,1))}
  52%{opacity:calc(1 - .5 * var(--mo-amp,1))}}
.an-move-wobble{animation:an-wobble 1.6s ease-in-out infinite;}
.an-move-bob{animation:an-bob 2.6s ease-in-out infinite;}
.an-move-pulse{animation:an-pulse 1.8s ease-in-out infinite;}
.an-move-sway{animation:an-sway 3s ease-in-out infinite;}
.an-move-shake{animation:an-shake .6s ease-in-out infinite;}
.an-move-spin{animation:an-spin 6s linear infinite;}
.an-move-swing{animation:an-swing 2.4s ease-in-out infinite;
  transform-origin:top center;}
.an-move-breathe{animation:an-breathe 3.4s ease-in-out infinite;}
.an-move-jelly{animation:an-jelly 1.4s ease-in-out infinite;}
.an-move-drift{animation:an-drift 9s linear infinite;}
.an-move-glow{animation:an-glow 2.2s ease-in-out infinite;}
.an-move-tilt{animation:an-tilt 2.8s ease-in-out infinite;}
.an-move-flicker{animation:an-flicker 2.4s linear infinite;}
/* T446: the selected item stays still in the editor, so it can be
   grabbed; everything else moves as it will in the show.
   T445: !important, because motionPaint writes the movement into the
   element's own `animation` and an inline style would otherwise beat
   this -- and :not(.an-mo-preview), because the one time you DO want
   the selected item to move is when you are previewing a movement on
   it, which is what that class marks. */
body.slide-editing .an-item.sel[class*="an-move-"]:not(.an-mo-preview){
  animation:none!important;}
/* ---- TEXT BUILDS: the pieces one box arrives in ----------------------
   `.an-part` is a RENDER-TIME wrapper (17-text-builds.js). It never
   reaches the model -- sanitizeRich unwraps it, the caret never enters
   one -- it is inline so it cannot change a single line break, and it is
   positioned only so a build badge has something to hang off.
   The hidden state is the SAME .an-prebuild the whole-item builds use:
   opacity, never display. A text box auto-heights from its words, so
   display:none would make it grow line by line and, with a bottom or
   centre anchor, walk up the slide while it built. */
.an-part{position:relative;}
/* A BULLET THAT COULD NOT BE PROMOTED still has to lose its marker while
   its words are held back. Promotion is refused for a bullet that has
   SUB-bullets, because hiding it would take them with it -- so the dot
   is dropped here instead, for exactly as long as the bullet's own words
   are still to come. A dot sitting on its own in front of nothing reads
   as a rendering fault, not as a build. */
/* (T623: a piece is held back by its visibility, set by the reveal
   pass, which never added the .an-prebuild this rule once looked for --
   so it read nothing. The reveal pass marks the paragraph or item whose
   FIRST piece is still to come, and its marker waits with it; it is a
   class and not a :has(), so typing never asks the style engine.) */
.an-text .an-mk-wait::marker{color:transparent;}
/* one badge per piece; it borrows .an-buildno wholesale, including the
   CSS gate that shows it only while the Timeline pane is open (T76) */
.an-partno{top:-8px;left:-10px;z-index:6;}
/* REDUCED MOTION. The entrance is decoration; WHAT is on screen is not,
   so the builds still hold items back and only the movement goes. This
   was a real gap -- the query below only ever covered .slide -- and a
   sentence-by-sentence slide made it impossible to ignore: thirty
   separate animations for a reader who asked the operating system for
   none. */
@media (prefers-reduced-motion:reduce){
  .an-anim-fade,.an-anim-rise,.an-anim-zoom,.an-anim-slide,.an-anim-turn,
  [class*="an-move-"]{animation:none!important;}
}
/* ...AND THE MACHINE'S ANSWER TO MOTION IS FINAL (T157 / JVC-02). The
   guard sits HERE, beside what it guards, rather than with the unrelated
   .slide rule far below: reduced motion cleared slide TRANSITIONS and
   left every entrance running, so a reader who had asked the OS for less
   motion still got each build flying in. Builds themselves are
   untouched, which is the point -- .an-prebuild still holds an item back
   and still releases it on the click, so the deck reveals in exactly the
   same steps. It cuts instead of animating, which is what the preference
   asks for and not one thing more. */
@media (prefers-reduced-motion:reduce){
  .an-anim-fade,.an-anim-rise,.an-anim-zoom,.an-anim-slide,.an-anim-turn,
  [class*="an-move-"]{animation:none!important;}
}
/* T446 shipped fifteen rules here, one per entrance-and-movement
   pair, because two classes cannot compose one `animation` property.
   T445 made the movement's numbers per-object, which would have made
   sixty-five of them -- so motionPaint writes BOTH layers into the
   element's own `animation` instead, entrance first and the movement
   delayed to where it ends. The reduced-motion guards above still win:
   !important beats an inline style. */
/* the build-order badge shown in the editor — and ONLY while the Timeline
   pane is open (T76, user: "the animation bubbles that appear are the
   worst, like you can't get rid of them").
   GATED IN CSS, not in the renderer. Seven places close #animpane and only
   one of them re-renders the annot layer: `set(false)` in the pane's own
   block does, while six others just assign .hidden=true (showObjHist,
   showTidyPane, the Standards pane, the Notes pane, showProvPane,
   showSizePane, showFlipPane). A JS gate would therefore have left the
   bubbles standing in six cases out of seven until some unrelated edit
   forced a redraw — which is the complaint all over again. As a selector
   it is simply always right, and opening the pane costs no re-render
   because the badges are still built on every render.
   What says a slide is animated when the pane is shut is the filmstrip's
   ▸N mark, which wears this same amber on purpose.
   The `>` matters: #animpane is a CHILD of the stage wrapper, and
   without it every change anywhere under the stage (a keystroke, a
   drag step) made the browser walk all of it again to answer this
   (2026-10-09, speed). */
.an-buildno{position:absolute;top:-9px;left:-9px;z-index:5;min-width:16px;
  height:16px;border-radius:8px;background:#cf9a4e;color:#241a05;
  font-family:var(--mono);font-size:10px;font-weight:700;display:none;
  align-items:center;justify-content:center;padding:0 3px;pointer-events:none;
  white-space:nowrap;}
.deck-stagewrap:has(>#animpane:not([hidden])) .an-buildno{display:flex;}
/* T750: pointing at a row of the Order list lights its object */
.an-item.an-rowhot,.an-arrow-line.an-rowhot{
  outline:2px solid #cf9a4e;outline-offset:3px;}
/* optional per-deck slide numbers (bottom-right, part of the slide) */
/* T626 review: the slide number, the header and the footer are the
   deck's Quiet once a theme names one (--tk-quiet, written only when it
   differs from the default, so an untouched deck draws as before) */
.slide-pageno{position:absolute;right:2.6%;bottom:3.2%;z-index:4;
  font-family:var(--mono);font-size:2.4vh;line-height:1;
  color:var(--tk-quiet,var(--chrome-ink-2));pointer-events:none;}
.vpage .slide-pageno{color:var(--tk-quiet,var(--chrome-ink-2));}
/* the toolbar icons share the app ribbon's 16-grid stroke style; inside
   a .dbtn they sit inline beside the label */
.dbtn .bic{display:inline-block;vertical-align:-2px;width:13px;
  height:13px;margin-right:4px;}
/* WHILE EDITING, the page gets the window — and from 2026-08-07 that was
   read as "hide the strip", for a deck as much as a poster ("presentation
   mode still has the slides as a prominent feature"). Half right. A DECK
   IS A SEQUENCE and you steer it by seeing the sequence, so its strip is
   there by default again; a POSTER is one page, its other pages are rare
   drafts, and there the strip stays optional and opens from Versions
   (2026-08-17, user: "in the presentation maker, the thumbnail for the
   slides should be there by default. It is just the poster where it
   should be optional").
   Only the strip: the panel's head has moved into the ribbon and would
   otherwise draw an empty bar, and the layout catalogue lives in the
   Layouts dropdown. */
/* while editing the head STAYS: File, Save, undo/redo and the save
   readout live here, under Notebooks, above the thumbnails (2026-08-19,
   user). Only the builder-specific controls row hides. */
.deck.editing .dc-controls{display:none;}
/* the way BACK, above the thumbnails: with the editor full-width the
   presentations rail (and its Notebooks button) is covered, and the way
   out has to be visible or it does not exist (2026-08-19, user: "the
   notebooks button is really important — it needs to sit above the slide
   thumbnail part") */
/* the notebooks content at the column top: pane rows reused verbatim */
/* a POSTER keeps the column too now — it is where Notebooks, File and
   Save live; only the slide film is deck-only (hidden for posters by the
   .poster-page .dc-film rule) */
/* ...and putting it away is still one click, for a deck too: Slides
   toggles the strip rather than opening a pane */
/* putting the strip away hides the THUMBNAILS, not the column — the
   way back and the document actions must survive the toggle */
.deck.editing.strip-off .dc-film{display:none!important;}
/* ...and a poster's other pages live in a floating pane instead, the same
   shell the Objects list uses, so the two read as siblings (2026-08-10). */
.verpane .selpane-list{display:flex;flex-direction:column;gap:6px;}
#verpane .film-list{display:flex;flex-direction:column;gap:6px;
  overflow:visible;flex:none;padding:0;}
#verpane .film-row{width:100%;}
/* a version carries a name you chose, so it must not be clipped — unlike
   an Objects row, whose label is derived from what is on the page */
#verpane .film-t{overflow:visible;text-overflow:clip;white-space:normal;
  overflow-wrap:anywhere;}
#verpane .addslide{width:100%;margin-top:2px;}
/* A POSTER IS ONE PAGE. It has no slides, so it gets none of the slide
   machinery in ANY mode — the strip of thumbnails and "+ Add slide" were
   still there in the builder, hidden only while editing (2026-08-07,
   user). The layout catalogue stays: those are poster templates. */
.deck.poster-page .dc-film{display:none!important;}
.deck.poster-page .deck-count{display:none!important;}
.deck.poster-page .deck-arrow{display:none!important;}
/* the colour popups: a pad of roomy hit targets, headed by name */
.sh-menu.sw-menu{display:flex;flex-wrap:wrap;align-items:center;
  gap:7px;width:198px;padding:10px 11px;}
/* the two that hold the picker are wider by its hex box. Scoped to
   them by id because .sw-menu is also the line panel's stroke-WIDTH
   menu -- one class, two meanings, since long before T232. */
#fmt-txcol-menu,#fmt-fillcol-menu{box-sizing:border-box;
  width:min(264px,calc(100vw - 12px));}
.sw-menu .fmt-lab{display:block;flex:0 0 100%;margin:2px 0 -1px;}
.sw-menu>.sw-tokrow,.sw-menu>.sw-recrow{flex:0 0 100%;}
/* ---- T237: WHAT CHANGED, IN THREE READINGS ---------------------------
   By slide ("Slide 14 - Title: colour red -> yellow, picture added"), by
   type ("title colour red -> yellow - slides 13, 14, 15") and the
   pictures, which now show only the slides that differ unless you ask
   for every one. The compare-with picker reads one version against
   another instead of always against the deck you are editing. */
.dh-h2t{display:block;font-size:12.5px;color:#dbe7ef;}
.dh-h2note{display:block;font-family:var(--sans);font-size:11px;
  color:var(--chrome-ink-2);margin-top:3px;}
.dh-tools{display:flex;align-items:center;flex-wrap:wrap;gap:8px;
  margin:0 0 12px;}
.dh-vs{display:inline-flex;align-items:center;gap:6px;margin-left:auto;}
.dh-vslab{font-family:var(--sans);font-size:11px;color:var(--chrome-ink-2);}
.dh-vssel{max-width:230px;font:12px var(--sans);padding:4px 6px;
  border-radius:6px;color:var(--chrome-ink);background:var(--input-bg);
  border:1px solid var(--chrome-line);}
.dh-tabs{display:flex;align-items:center;gap:6px;margin:0 0 10px;
  border-bottom:1px solid #ffffff14;padding-bottom:9px;}
.dh-tab[aria-pressed="true"]{border-color:var(--cyan);
  background:color-mix(in srgb,var(--cyan) 18%,transparent);
  color:var(--chrome-ink);}   /* T465: an 18% wash keeps the theme's ink */
.dh-every{display:inline-flex;align-items:center;gap:5px;margin-left:auto;
  font-family:var(--sans);font-size:11.5px;color:var(--chrome-ink-2);cursor:pointer;}
.dh-chlist{display:flex;flex-direction:column;}
.dh-ch{display:grid;grid-template-columns:190px minmax(0,1fr);gap:12px;
  align-items:baseline;padding:7px 2px;
  border-bottom:1px solid #ffffff10;}
.dh-chslide{font-family:var(--sans);font-size:11.5px;color:var(--chrome-ink-2);}
.dh-chwhat{font-family:var(--sans);font-size:12.5px;color:#dbe7ef;
  line-height:1.5;}
.dh-chlead{font-weight:600;}
body.light .dh-h2t,body.light .dh-chwhat{color:var(--ink);}
body.light .dh-ch{border-bottom-color:var(--line);}

/* ---- T232: THE PICKER, AS THE BOTTOM OF THE MENU ---------------------
   Same element as the floating popup, restyled to be a section: no
   card of its own, just a rule and the controls under it. It carries
   hex, rgb and the transparency slider, which is what used to be one
   click further in behind a rainbow chip. */
.sw-menu>.color-pop.cp-inline{box-sizing:border-box;flex:0 0 100%;
  min-width:0;position:static;width:auto;
  background:none;border:none;border-top:1px solid #ffffff1c;
  border-radius:0;box-shadow:none;padding:9px 0 0;margin:3px 0 0;
  gap:7px;}
.cp-inline .cp-native{height:30px;}
.cp-inline .cp-lab{width:34px;}
.cp-inline .cp-in{padding:5px 7px;font-size:11.5px;}
.cp-inline .cp-preview{width:24px;height:24px;}
.cp-recent[hidden]{display:none!important;}
body.light .sw-menu>.color-pop.cp-inline{border-top-color:var(--chrome-line);}
.sw-tokrow{display:flex;flex-wrap:wrap;align-items:center;gap:7px;}
.sw-tokrow>.fmt-lab{flex:0 0 100%;}
/* hidden still means hidden, whatever display the rows above ask for */
.sw-menu [hidden]{display:none!important;}
/* ---- page background + LIGHT pages (2026-08-04): pres.pageBg sets
   --page-bg on the deck; a light colour flips .page-light, which
   recolours the DEFAULT chrome (text boxes, frames, page numbers) for
   dark-on-light reading. Explicit per-item colours always win — these
   rules only replace the dark-theme defaults. White is the default for
   NEW posters: posters exist to be printed. ---- */
.deck .deck-stage .slide{background:var(--page-bg,transparent);}
/* ---- T626: A SLIDE IS ITS OWN COLOUR CONTEXT ------------------------
   (2026-10-11, user: "themes sometimes don't apply to all things".)
   The slide had no colour of its own, so whatever on it had none either
   -- a table's words and rules, a notebook output -- inherited its
   HOST's: the editor's chrome ink (.deck{color:var(--chrome-ink)}), the
   app scheme's reader palette (pre.stream on --paper-2 and --ink-2), the
   print page's body ink. Under the Light app scheme a dark slide's table
   went #16202b on navy and its output frame an #eef2f6 box.
   So every picture of a slide -- .slide on the canvas, in the show, the
   print root, the presenter and the story strip, and .mini-diagram in
   every strip, sorter and gallery -- carries its colours with it:
   the words from the deck's Body text (--tk-ink, written by
   slideContext) and the page's own default; the face from the deck's
   body style (--tk-font); and the reader and chrome palette the
   notebook frames and on-page widgets are drawn with, PINNED to the
   page's own -- the built-in dark values, or the light ones on a light
   page -- so the app scheme stops at the slide's edge. The accent the
   AUDIENCE sees (an eyebrow, a frame's edge, a highlight, a flip book's
   page pips) is the deck's (--sl-accent); the editor's own handles and
   selection keep the app's. A thumbnail pins only the two faces its
   panes read (--chrome-0 and --chrome-4): every custom property declared
   on an element is a copy for its whole subtree, and the strip has sixty
   of them. The one notebook printout a thumbnail draws is given its
   colours by its own rule, below. */
.slide{
  --paper:#101c28;--paper-2:#0b141d;--paper-3:#1a2a38;--line:#ffffff1f;
  --ink:#e7edf3;--ink-2:#c4d0da;--ink-3:#91a3b2;
  --chrome-0:#0b141d;--chrome-1:#0e1926;--chrome-2:#162735;
  --chrome-3:#101c28;--chrome-4:#172838;--chrome-line:#ffffff1f;
  --chrome-ink:#d7e3ec;--chrome-ink-2:#a8b7c4;--chrome-ink-3:#8195a6;
  --sl-accent:var(--tk-accent,#58c4db);}
.mini-diagram{--chrome-0:#0b141d;--chrome-4:#172838;}
.slide.page-light{
  --paper:#fbfcfd;--paper-2:#eef2f6;--paper-3:#e2e8ee;--line:#d8e0e8;
  --ink:#16202b;--ink-2:#465767;--ink-3:#596b7d;
  --sl-accent:var(--tk-accent,#1d7a90);}
.slide{color:var(--tk-ink,#fff);font-family:var(--tk-font,var(--sans));}
.slide.page-light{color:var(--tk-ink,#1b2733);}
.mini-diagram{color:var(--tk-ink,#dbe6ee);}
.mini-diagram.page-light{color:var(--tk-ink,#1b2733);}
/* a notebook's printout on a slide is the PAGE's, never the app's: the
   reader's rules for it are keyed on body.light / body:not(.light) */
.slide pre.result,.slide pre.stream{
  background:var(--paper-2);border-color:var(--paper-3);color:var(--ink-2);}
/* ...and in a thumbnail, which DOES draw a frame's printout (miniCell
   puts framePart's output in it): the dark page's own, as literals, so
   only the cell boxes pay for it and not every one of the strip's
   thumbnails (T626 review: under the light schemes a thumbnail's output
   was #dbe6ee on #eef2f6, 1.15:1). The light page's rule below wins. */
.mini-it.is-cell pre.result,.mini-it.is-cell pre.stream{
  background:#0b141d;border-color:#1a2a38;color:#c4d0da;}
/* T465: the light page's defaults are the FALLBACK of the same
   tokens the dark page reads, so Body text, Box background and Lines
   and edges govern a white page too -- they were plain literals here,
   which outranked the token rules and made three of the five deck
   colours dead on every poster (2026-09-15 review) */
.page-light .an-text{color:var(--tk-ink,#1b2733);
  background:var(--tk-surface,#ffffffd9);
  border-color:var(--tk-line,#00000024);}
.page-light .an-cell{background:var(--tk-surface,#fff);
  border-color:var(--tk-line,#00000030);}
.page-light .an-cell pre.result,.page-light .an-cell pre.stream{
  background:#fff;color:#1b2733;border-color:#00000018;}
.page-light .an-handle{color:#5a6b78;}
.page-light .slide-pageno{color:var(--tk-quiet,#5a6b78);}
/* needs the .slide-titlefree qualifier to OUTRANK the later dark rule of
   equal specificity — without it this was dead CSS (2026-08-05 review) */
.page-light .slide-titlefree .ttl-eyebrow{color:var(--sl-accent);}
.page-light .an-title{color:var(--tk-heading,#16222c);}
/* T366: a placeholder's words. Faint enough to read as a hint about
   the slide's shape rather than as something written, and never
   selectable -- the caret arrives in an empty box, so there is nothing
   here to select. Only ever drawn while editing. */
.an-ph{opacity:.38;user-select:none;}
/* the on-page chrome the first pass missed: figure captions and slide
   meta were dark-theme greys on a white page (the empty-slide hint was
   the third; T366 took it off the slide entirely) */
.page-light .an-cellcap{color:#4a5a66;}
.page-light .slide-meta{color:#5a6b78;}
/* the File-menu page background swatches */
.dc-pagebg{display:flex;align-items:center;gap:6px;cursor:default;}
/* the background chips are built from PAGE_BGS in deck.js, so their
   colours live in ONE place instead of being restated here (2026-08-20) */
.pgbg-row{display:flex;flex-wrap:wrap;gap:5px;margin-left:auto;
  max-width:150px;justify-content:flex-end;}
.sh-menu .bg-sw{flex-wrap:wrap;}
.bg-chip{width:20px;height:20px;padding:0;border-radius:5px;flex:none;
  border:1px solid #ffffff33;cursor:pointer;}
/* a light chip needs a darker edge or it disappears into a light menu */
.bg-chip.is-light{border-color:#00000033;}
.bg-chip:hover{border-color:var(--cyan);}
.bg-chip[aria-pressed="true"]{border-color:var(--cyan);
  box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 45%,transparent);}
.bg-auto{flex:none;}
/* ---- print-resolution warning chip on poster figures ---- */
.dpi-warn{position:absolute;top:6px;right:6px;z-index:5;
  font-family:var(--mono);font-size:10px;line-height:1;
  padding:3px 7px;border-radius:5px;background:#3a2a10ee;
  color:#f0a848;border:1px solid #f0a84855;pointer-events:auto;}
.page-light .dpi-warn{background:#fff3e0ee;color:#7d5410;
  border-color:#9a610833;}
/* ---- the crop menu's Trim row ---- */
/* the row is a grid ITEM of the 3-column .sh-menu: unless it spans the
   whole row its ~330px min-content width inflated the auto tracks and
   pushed the shape options clean off the 210px panel — at laptop widths
   off the VIEWPORT, which read as "the crop menu is broken" (2026-08-20
   diagnosis, reproduced: Ellipse/Diamond/Star painted outside the panel) */
#fmt-crop-menu .crop-inset,#fmt-crop-menu .ci-trim{
  grid-column:1/-1;min-width:0;}
.crop-inset{display:flex;align-items:center;gap:4px;margin-top:6px;
  padding-top:6px;border-top:1px solid #ffffff1a;}
/* T387: the frame's shape, as a row of ratios */
.crop-aspect{flex-wrap:wrap;}
.crop-aspect .dbtn{font-family:var(--mono);font-size:10.5px;padding:2px 7px;}
.crop-inset .ci-lab{font-family:var(--mono);font-size:9px;
  letter-spacing:.08em;text-transform:uppercase;color:var(--chrome-ink-2);
  flex:none;margin-right:2px;}
.crop-inset input{width:44px;background:var(--chrome-0,#0b141d);color:var(--chrome-ink);
  border:1px solid #ffffff26;border-radius:5px;font-size:11px;
  padding:3px 4px;font-family:var(--mono);}
.crop-inset input:focus{border-color:var(--cyan);outline:none;}
.crop-inset .ci-reset{background:none;border:1px solid #ffffff26;
  color:var(--chrome-ink-2);border-radius:5px;font-size:10px;padding:3px 7px;
  cursor:pointer;}
.crop-inset .ci-reset:hover{border-color:var(--cyan);color:var(--chrome-ink);}
/* ---- PDF / print export: one fixed-size 16:9 slide per page ---- */
#print-root{position:fixed;left:-99999px;top:0;width:1280px;z-index:-1;}
.print-page{width:1280px;height:720px;position:relative;overflow:hidden;
  background:var(--chrome-0,#0b141d);}
.print-page .slide{position:absolute;inset:0;background:#0b141d;}
.print-page .annot-layer{pointer-events:none;}
@media print{
  @page{size:1280px 720px;margin:0;}
  html,body{background:var(--chrome-0,#0b141d);}
  body.printing>*{display:none!important;}
  body.printing #print-root{display:block!important;position:static;
    left:0;top:0;width:auto;z-index:auto;}
  .print-page{page-break-after:always;break-after:page;}
  .print-page:last-child{page-break-after:auto;break-after:auto;}
}

/* T556: handouts and notes pages -- A4 sheets of the same pages */
#print-root.ho-mode{width:794px;}
.ho-sheet{width:794px;height:1123px;box-sizing:border-box;
  padding:36px 44px;background:#fff;color:#111;overflow:hidden;
  font-family:var(--sans,system-ui);display:flex;flex-direction:column;}
.ho-head{display:flex;justify-content:space-between;font-size:11px;
  color:#555;border-bottom:1px solid #ccc;padding-bottom:6px;
  margin-bottom:18px;}
.ho-body{flex:1;display:flex;flex-direction:column;gap:26px;}
.ho-k-ho6 .ho-body{display:grid;grid-template-columns:1fr 1fr;
  grid-auto-rows:min-content;gap:30px 26px;align-content:space-evenly;}
/* the slides spread down the sheet, as PowerPoint's handouts do */
.ho-k-ho3 .ho-body{justify-content:space-evenly;}
.ho-row{display:flex;gap:22px;align-items:flex-start;}
.ho-k-notes .ho-row{flex-direction:column;
  align-items:center;}
.ho-slot{flex:none;overflow:hidden;position:relative;
  box-shadow:0 0 0 1px #bbb;}
.ho-slot .print-page{position:absolute;left:0;top:0;}
.ho-lines{flex:1;display:flex;flex-direction:column;gap:20px;
  padding-top:8px;}
.ho-line{border-bottom:1px solid #bbb;height:1px;}
.ho-sheet .ho-notes{width:600px;font-size:13px;line-height:1.5;color:#111;}
.ho-sheet .ho-notes.ho-nonotes{color:#666;font-style:italic;}
@media print{
  .ho-sheet{page-break-after:always;break-after:page;}
  .ho-sheet:last-child{page-break-after:auto;break-after:auto;}
  .ho-sheet .print-page{page-break-after:auto;break-after:auto;}
}
/* a frame LOCKED to a git commit */
.an-lockchip{position:absolute;top:5px;left:5px;z-index:3;
  font-family:var(--mono);font-size:9px;letter-spacing:.04em;
  background:#46a89222;border:1px solid #46a89266;color:#7fd0b8;
  border-radius:5px;padding:2px 6px;pointer-events:auto;cursor:help;}
.an-lockchip.warn{background:#ff6b5722;border-color:#ff6b5766;
  color:#ff9d8e;}
.deck:not(.editing) .an-lockchip{display:none;}
.an-verwait{flex:1;display:flex;align-items:center;justify-content:center;
  font-family:var(--mono);font-size:11px;color:var(--chrome-ink-2);padding:16px;
  text-align:center;}

/* a frame reverted to its pre-refresh figure */
.deck.editing .an-cell.an-frozen{outline:1.5px dashed #f0a848;
  outline-offset:2px;}
.an-frozenchip{position:absolute;top:5px;left:5px;z-index:3;
  font-family:var(--mono);font-size:9px;letter-spacing:.06em;
  background:#f0a84822;border:1px solid #f0a84866;color:#f0c078;
  border-radius:5px;padding:2px 6px;pointer-events:none;}

/* a frame showing the copy saved inside the deck (notebook not open) —
   quiet slate, not amber: nothing is wrong, the deck is self-reliant */
.an-embchip{position:absolute;top:5px;left:5px;z-index:3;
  font-family:var(--mono);font-size:9px;letter-spacing:.06em;
  background:#5d748822;border:1px solid #5d748866;color:var(--chrome-ink-2);
  border-radius:5px;padding:2px 6px;pointer-events:auto;cursor:help;}
.deck:not(.editing) .an-embchip{display:none;}

/* snap-to-align guide lines (drawn only mid-drag). Solid and glowing
   rather than a 1.5px dash: on an A0 poster zoomed to fit, a hairline
   dashed rule was there but read as nothing, which is what made careful
   placement feel like guesswork (2026-08-07, user: "everything is
   floating in space"). */
.snapline{position:absolute;z-index:45;pointer-events:none;}
.snapline.snap-v{top:0;bottom:0;width:0;border-left:2px solid #ff6b57;
  box-shadow:0 0 0 1px #ff6b5733,0 0 7px #ff6b5788;}
.snapline.snap-h{left:0;right:0;height:0;border-top:2px solid #ff6b57;
  box-shadow:0 0 0 1px #ff6b5733,0 0 7px #ff6b5788;}
/* a snap onto the PAGE's own centre/edge is a different fact from a snap
   onto another item — cyan for the page, coral for its contents */
.snapline.snap-page{border-color:var(--cyan);
  box-shadow:0 0 0 1px color-mix(in srgb,var(--accent) 20%,transparent),0 0 7px color-mix(in srgb,var(--accent) 53%,transparent);}
/* equal-gap markers: shown when the dragged item sits at the same
   distance from its neighbours as they are from each other */
.snapgap{position:absolute;z-index:45;pointer-events:none;
  background:#f0a84855;border:1px solid #f0a848;border-radius:2px;}
/* the gap being MADE is solid; the gap it matched is evidence, so it is
   drawn faint — two equally loud bars read as two instructions */
.snapgap.snapgap-ref{background:#f0a84826;border-style:dashed;
  border-color:#f0a84899;}
/* the number, centred on its bar. translate rather than margins so the
   percentage positions above stay the anchor point. */
.snapgap-lab{transform:translate(-50%,-50%);
  border-color:#f0a84899;color:color-mix(in srgb,#f0a848 40%,var(--chrome-ink));}
.snapgap-lab.snapgap-lab-ref{opacity:.72;}
/* live position/size readout, pinned to the dragged item */
.dragtag{position:absolute;z-index:46;pointer-events:none;
  font-family:var(--mono);font-size:10px;line-height:1;white-space:nowrap;
  background:color-mix(in srgb,var(--chrome-0,#0b141d) 85%,transparent);border:1px solid #ffffff2b;border-radius:5px;
  padding:3px 6px;color:var(--chrome-ink);}

/* ---------- page guides: margin box + grid (never printed) ---------- */
.pgrid{position:absolute;inset:0;z-index:4;pointer-events:none;
  overflow:hidden;}
.pgrid-lines{position:absolute;inset:0;}
.pgrid-margin{position:absolute;border:1px dashed color-mix(in srgb,var(--accent) 48%,transparent);}
.page-light .pgrid-margin{border-color:#1f6f8a8c;}
.pgrid-col{position:absolute;top:0;bottom:0;background:color-mix(in srgb,var(--accent) 6%,transparent);}
.page-light .pgrid-col{background:color-mix(in srgb,var(--accent) 8%,transparent);}
/* the grid's own lines — faint, so they guide without competing with the
   work sitting on top of them */
.pgrid-rule{position:absolute;height:0;border-top:1px solid color-mix(in srgb,var(--accent) 14%,transparent);}
.pgrid-vrule{position:absolute;width:0;border-left:1px solid color-mix(in srgb,var(--accent) 14%,transparent);}
.page-light .pgrid-rule{border-top-color:#1f6f8a2e;}
.page-light .pgrid-vrule{border-left-color:#1f6f8a2e;}
/* A RUN OF ROWS THAT CAN BE LONG. The figure-reference list used to be
   capped at eight with no way to reach the rest; a deck can hold thirty
   figures and every one of them has to be referable. Only the run
   scrolls, so the rows above and below it stay put. */
.menu-scroll{max-height:210px;overflow-y:auto;overscroll-behavior:contain;}
/* guides you drag off the rulers yourself; they belong to the poster and
   are saved with it, but are still guides — never ink */
/* ABOVE THE ANNOTATION LAYER, not under it (T643). While editing, that
   layer takes the pointer over the whole page (z-index 6, and its svg
   after it), so guides at 5 were drawn but never reachable: a real press
   on a guide line or on a box's edge, corner or grip landed on the layer,
   and the stage's guide handler -- which asks what was pressed -- never
   saw it. Found driving a real mouse in Chromium, which hit-tests; an
   event dispatched at the guide itself does not. The container still
   takes nothing: only the lines and the box handles do, and Lock (L)
   takes those away. */
.cguides{position:absolute;inset:0;z-index:7;pointer-events:none;}
.cguide{position:absolute;pointer-events:auto;}
.cguide.cg-v{top:0;bottom:0;width:0;border-left:1px solid #46a892cc;
  cursor:col-resize;padding:0 3px;margin-left:-3px;}
.cguide.cg-h{left:0;right:0;height:0;border-top:1px solid #46a892cc;
  cursor:row-resize;padding:3px 0;margin-top:-3px;}
.cguide:hover{border-color:#46a892;box-shadow:0 0 6px #46a89299;}
/* LOCKED (T643): the lines go on drawing and snapping and stop taking the
   pointer, so a press that lands on one lands on the page under it. A
   locked box has no handles in its markup at all. */
.cguides.cg-locked .cguide{pointer-events:none;}
/* a guide BOX: an area to lay out inside. Dashed, so it never reads as a
   drawn rectangle, and click-through except on its four edge strips —
   the middle of one covers most of the page and must not take clicks
   away from the canvas underneath. */
.cg-box{position:absolute;pointer-events:none;
  border:1px dashed #46a892aa;
  background:color-mix(in srgb,#46a892 4%,transparent);}
/* EACH STRIP RESIZES ITS OWN SIDE. All four used to run the same move
   handler, and one `cursor:move` on the lot was the tell: a guide box
   could be dragged anywhere and never made bigger (2026-08-29). The
   cursors now say which way each one goes, corners take the two sides
   they touch, and the corners come AFTER the edges in the markup so the
   overlap at a corner resizes both rather than whichever the browser
   hit-tested first. */
.cg-edge{position:absolute;pointer-events:auto;}
.cg-e-t{left:0;right:0;top:-4px;height:8px;cursor:ns-resize;}
.cg-e-b{left:0;right:0;bottom:-4px;height:8px;cursor:ns-resize;}
.cg-e-l{top:0;bottom:0;left:-4px;width:8px;cursor:ew-resize;}
.cg-e-r{top:0;bottom:0;right:-4px;width:8px;cursor:ew-resize;}
.cg-corner{position:absolute;pointer-events:auto;width:11px;height:11px;}
.cg-c-tl{left:-5px;top:-5px;cursor:nwse-resize;}
.cg-c-tr{right:-5px;top:-5px;cursor:nesw-resize;}
.cg-c-bl{left:-5px;bottom:-5px;cursor:nesw-resize;}
.cg-c-br{right:-5px;bottom:-5px;cursor:nwse-resize;}
/* THE MOVE GRIP, because resizing took the edges. A visible handle beats
   a modifier nobody is told about (the modifier stays as the shortcut).
   Above the top edge rather than inside it: the middle of a guide box is
   the area you are laying out INSIDE, and must go on taking clicks for
   whatever is under it. */
.cg-grip{position:absolute;pointer-events:auto;cursor:move;
  left:50%;margin-left:-9px;top:-11px;width:18px;height:9px;
  border:1px solid #46a892aa;border-bottom:0;border-radius:3px 3px 0 0;
  background:color-mix(in srgb,#46a892 30%,transparent);}
/* a box sitting against the top of the page has no room above it */
.cg-box.cg-lowgrip>.cg-grip{top:1px;border-bottom:1px solid #46a892aa;
  border-radius:0 0 3px 3px;}
.cg-box:hover{border-color:#46a892;}
.cg-box:hover>.cg-grip,.cg-box.cg-live>.cg-grip{background:#46a892;}
/* WHAT YOU ARE ACTUALLY MAKING, while you make it: a poster's guide box
   is a physical area ("the figure well is 380mm"), and that number was
   only knowable by drawing the box and then measuring it against the
   ruler. Inside the box, so it is never clipped off the page, and
   pointer-events:none so it never eats the drag it is describing. */
.cg-box.cg-live{border-style:solid;border-color:#46a892;}
.cg-tip{position:absolute;left:2px;top:2px;pointer-events:none;
  padding:1px 5px;border-radius:3px;white-space:nowrap;
  font:600 11px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;
  color:#04231e;background:#46a892;}
/* guides are an editing aid: never in print, export or playback */
.deck:not(.editing) .pgrid,.deck:not(.editing) .rulers,
.deck:not(.editing) .cguides{display:none;}
@media print{.pgrid,.rulers,.cguides{display:none!important;}}
#print-root .pgrid,#print-root .rulers,
#print-root .cguides{display:none!important;}

/* ---------- rulers ---------- */
.rulers{position:absolute;inset:0;z-index:7;pointer-events:none;
  font-family:var(--mono);}
/* the ruler bars themselves DO take clicks — that is where a guide is
   pulled from — while the rest of the overlay stays transparent to them */
.ruler{position:absolute;
  background:color-mix(in srgb,var(--chrome-1) 95%,transparent);
  color:var(--chrome-ink-2);border:1px solid var(--chrome-line);overflow:hidden;pointer-events:auto;}
.ruler-h{cursor:row-resize;}
.ruler-v{cursor:col-resize;}
.ruler-h{height:19px;}
.ruler-v{width:19px;}
/* the corner takes clicks too: it arms the guide BOX, the way the two
   ruler bars beside it lay down guide lines */
.ruler-corner{position:absolute;width:19px;height:19px;
  background:color-mix(in srgb,var(--chrome-1) 95%,transparent);
  border:1px solid var(--chrome-line);font-size:7.5px;
  display:flex;align-items:center;justify-content:center;color:var(--chrome-ink-3);
  pointer-events:auto;cursor:crosshair;}
.ruler-corner:hover{color:var(--accent);}
.rtick{position:absolute;
  background:color-mix(in srgb,var(--chrome-ink-2) 45%,transparent);}
.ruler-h .rtick{top:auto;bottom:0;width:1px;height:4px;}
.ruler-h .rtick.major{height:8px;background:var(--chrome-ink-2);}
.ruler-v .rtick{left:auto;right:0;height:1px;width:4px;}
.ruler-v .rtick.major{width:8px;background:var(--chrome-ink-2);}
.rlab{position:absolute;font-size:8px;color:var(--chrome-ink-2);white-space:nowrap;}
.ruler-h .rlab{top:1px;transform:translateX(2px);}
.ruler-v .rlab{left:1px;transform:translateY(1px) rotate(-90deg);
  transform-origin:left top;}
/* where the pointer is, on both rulers */
.rcursor{position:absolute;background:var(--cyan);}
.ruler-h .rcursor{top:0;bottom:0;width:1px;}
.ruler-v .rcursor{left:0;right:0;height:1px;}
/* the selected item's extent, shaded on the rulers — the quickest way to
   see how far a block reaches on a page too big to take in at once */
.rspan{position:absolute;background:color-mix(in srgb,var(--accent) 22%,transparent);}
.ruler-h .rspan{top:0;bottom:0;}
.ruler-v .rspan{left:0;right:0;}

/* ---------- text on a curved baseline ---------- */
/* the flat span still holds the text, the selection and the caret; it is
   just not what you look at while the curve is showing */
.an-text.an-arced>.an-tx{visibility:hidden;}
.an-text.an-arced{background:none;border-color:transparent;}
.an-arcsvg{position:absolute;left:0;top:0;width:100%;height:100%;
  overflow:visible;pointer-events:none;}
/* typing un-curves it, because a caret cannot live on a <textPath> */
.an-text.an-arced:focus-within>.an-tx{visibility:visible;}
.an-text.an-arced:focus-within .an-arcsvg{display:none;}

/* ---------- crop / trim marks (export only) ---------- */
/* hairlines in the bleed, clear of the artwork: a printer trims where
   they point. Always black — they are instructions to a machine, not
   part of the design, and they must survive a white page. */
.print-page.has-crop{position:relative;overflow:visible;}
.cropmark{position:absolute;pointer-events:none;}
.cropmark::before,.cropmark::after{content:"";position:absolute;
  background:#000;}
.cropmark::before{width:1px;height:14px;}
.cropmark::after{height:1px;width:14px;}
.cm-tl{left:0;top:0;}
.cm-tl::before{left:-1px;top:-19px;}
.cm-tl::after{left:-19px;top:-1px;}
.cm-tr{right:0;top:0;}
.cm-tr::before{right:-1px;top:-19px;}
.cm-tr::after{right:-19px;top:-1px;}
.cm-bl{left:0;bottom:0;}
.cm-bl::before{left:-1px;bottom:-19px;}
.cm-bl::after{left:-19px;bottom:-1px;}
.cm-br{right:0;bottom:0;}
.cm-br::before{right:-1px;bottom:-19px;}
.cm-br::after{right:-19px;bottom:-1px;}

/* ---------- pre-print check ---------- */
.pf-count{font-family:var(--sans);font-size:11.5px;font-weight:600;
  letter-spacing:0;color:var(--chrome-ink-2);padding:2px 12px 8px;}
.pf-row{display:flex;flex-direction:column;gap:3px;width:100%;
  text-align:left;background:none;border:none;border-left:3px solid #f0a848;
  border-radius:0;color:inherit;cursor:pointer;padding:8px 12px;
  font:inherit;}
.pf-row:hover{background:#ffffff0d;}
.pf-row.pf-err{border-left-color:#ff6b57;}
.pf-what{font-size:12.5px;color:#dbe7ef;font-weight:600;}
.pf-why{font-size:11px;color:var(--chrome-ink-2);line-height:1.4;}
.pf-ok{font-size:12px;color:var(--chrome-ink-2);line-height:1.5;padding:10px 12px;}
body.light .pf-row:hover{background:var(--surface-hover);}
body.light .pf-what{color:var(--ink);}
body.light .pf-why,body.light .pf-ok,body.light .pf-count{color:var(--ink-3);}

/* ---------- the flip book ----------
   One box, many figures, one showing. The stage LETTERBOXES each frame
   into a box that never changes size: frames differ in shape (a plot,
   then the same plot with a legend), and a box that hugged each one would
   move every caption tied to it on every click -- which is exactly the
   jitter people duplicate slides to avoid (2026-08-22). */
.an-flip{position:absolute;display:flex;flex-direction:column;
  align-items:stretch;justify-content:center;}
.deck.editing .an-flip{cursor:move;}
.an-flipstage{flex:1;min-height:0;display:flex;align-items:center;
  justify-content:center;overflow:hidden;}
.an-flipstage>*{max-width:100%;max-height:100%;}
.an-flipimg{max-width:100%;max-height:100%;object-fit:contain;
  display:block;}
.an-flipempty{font-size:11.5px;line-height:1.5;color:var(--chrome-ink-2);
  text-align:center;padding:10px 14px;}
.deck.editing .an-flip.empty{outline:1px dashed #ffffff33;
  outline-offset:-1px;}
/* the arrows are real buttons, which is what makes them safe in playback:
   the click-to-advance handler already skips button/a/input/select, so
   stepping a figure cannot also advance the slide */
.an-flipbar{flex:none;display:flex;align-items:center;justify-content:center;
  gap:8px;padding:3px 0 1px;}
.an-flipnav{background:#00000059;border:1px solid #ffffff2e;color:#e6eef4;
  border-radius:50%;width:22px;height:22px;line-height:1;cursor:pointer;
  font-size:13px;padding:0;display:flex;align-items:center;
  justify-content:center;}
.an-flipnav:hover:not([disabled]){border-color:var(--cyan);
  background:#0000008c;}
.an-flipnav[disabled]{opacity:.3;cursor:default;}
.an-flipn{font-family:var(--mono);font-size:10px;color:var(--chrome-ink-2);
  letter-spacing:.06em;}
.page-light .an-flipnav{background:#ffffffb3;border-color:#00000026;
  color:#16202b;}
.page-light .an-flipn{color:#44525c;}
/* ONE BUTTON PER FIGURE: the arrows are a walk, these are a menu. They
   wrap on purpose — a nine-figure book is a row of nine names, and a nav
   bar that scrolled sideways on a slide would be worse than two lines of
   buttons (T86). */
/* ---------- a flip book made of words ----------
   The same bar as a figure book's, with PIPS instead of a counter: a
   reader has to be able to tell at a glance whether the arrows below
   turn a figure or a paragraph, and dots under words is the one idiom
   everybody already reads as "there is more text here". They also cost
   no width, which matters on a box the words have already claimed. The
   arrows are the flip book's own .an-flipnav, deliberately -- the two
   books step with the same control, they only count differently. */
.an-pgbar{gap:6px;padding:2px 0 0;}
.an-pgpips{display:flex;align-items:center;gap:4px;}
.an-pgpip{width:6px;height:6px;padding:0;border-radius:50%;cursor:pointer;
  background:#ffffff3d;border:1px solid transparent;}
.an-pgpip:hover:not([disabled]){background:#ffffff70;}
.an-pgpip.on{background:var(--sl-accent);}
.an-pgpip[disabled]{cursor:default;}
.page-light .an-pgpip{background:#0000002e;}
.page-light .an-pgpip:hover:not([disabled]){background:#00000059;}
.page-light .an-pgpip.on{background:var(--sl-accent);}
.an-flipbtns{flex-wrap:wrap;gap:4px;}
.an-flipbtn{background:#00000059;border:1px solid #ffffff2e;color:#e6eef4;
  border-radius:11px;min-width:22px;height:22px;line-height:1;cursor:pointer;
  font-size:11px;font-family:var(--sans);padding:0 8px;display:flex;
  align-items:center;justify-content:center;}
.an-flipbtn:hover:not([disabled]){border-color:var(--cyan);
  background:#0000008c;}
.an-flipbtn.on{border-color:var(--sl-accent);
  background:color-mix(in srgb,var(--accent) 34%,#00000059);}
.an-flipbtn[disabled]{cursor:default;}
.page-light .an-flipbtn{background:#ffffffb3;border-color:#00000026;
  color:#16202b;}
.page-light .an-flipbtn.on{background:color-mix(in srgb,var(--sl-accent) 26%,#fff);}
/* the stepping chooser, above the frame list it describes */
.fp-opt{display:flex;flex-direction:column;gap:4px;padding:0 12px 8px;}
/* an item belonging to another figure. Dimmed rather than hidden while
   editing: you have to be able to see and click the caption you are about
   to tie to figure 4 while you are standing on figure 1. In playback it
   is removed outright. */
.deck.editing .an-item.an-fbother{opacity:.24;}
.deck.editing .an-item.an-fbother.sel{opacity:.65;}

/* the frames pane: the slide strip's shape, because a flip book is a
   little deck inside a slide */
.fp-adds{display:flex;gap:5px;padding:0 12px 8px;}
.fp-adds .dbtn{flex:1;white-space:nowrap;font-size:11px;padding:5px 6px;}
.fp-row{display:flex;align-items:center;gap:5px;padding:3px 12px;
  border-radius:7px;cursor:pointer;}
.fp-row:hover{background:#ffffff0d;}
.fp-row.current{background:color-mix(in srgb,var(--accent) 11%,transparent);
  outline:1px solid color-mix(in srgb,var(--accent) 33%,transparent);
  outline-offset:-1px;}
.fp-n{font-family:var(--mono);font-size:9.5px;color:var(--chrome-ink-3);width:14px;
  flex:none;text-align:right;}
.fp-t{flex:1;min-width:0;background:none;border:1px solid transparent;
  color:var(--chrome-ink);font-size:11.5px;font-family:var(--sans);border-radius:5px;
  padding:2px 5px;outline:none;}
.fp-t:hover{border-color:#ffffff1f;}
.fp-t:focus{border-color:var(--cyan);background:var(--chrome-0,#0b141d);}
.fp-ctr{display:none;gap:1px;flex:none;}
.fp-row:hover .fp-ctr,.fp-row.current .fp-ctr{display:flex;}
/* T403: a page that is its own object -- its number says so, and the
   row's verb has words on it, because "take it out of the book" is
   not a glyph anyone would guess */
.fp-row.own .fp-n{color:var(--accent);}
.film-mini.fp-own{white-space:nowrap;}
.deck.editing .an-flipown{opacity:.7;}
/* tying an item to a figure lives in this pane rather than the ribbon,
   because it needs the frame LIST visible to mean anything */
.fp-tie{border-top:1px solid #ffffff14;padding:9px 12px;
  display:flex;flex-direction:column;gap:5px;}
.fp-tielab{font-size:11px;color:var(--chrome-ink-2);line-height:1.4;}
.fp-tiesel{width:100%;box-sizing:border-box;font-size:11.5px;
  padding:4px 6px;border-radius:6px;background:var(--chrome-1,#0e1926);
  border:1px solid #ffffff26;color:#dce6ee;font-family:var(--sans);}
.fp-tiesel:disabled{opacity:.45;}
body.light .fp-t{color:var(--ink);}
body.light .fp-t:focus{background:var(--input-bg);}
body.light .fp-tiesel{background:var(--input-bg);
  border-color:var(--border-strong);
  color:var(--ink);}
body.light .fp-row:hover{background:var(--surface-hover);}
body.light .fp-tielab{color:var(--ink-3);}
/* the film-strip thumbnail's chip for a flip book */
.mini-pane.is-flip{background:#243b52;}
.sp-kind.k-flip{background:#2a4761;}

/* a tab with nothing on it: out of the strip, not merely dimmed. A
   contextual tab (every object control on its own tab) is empty until
   something is selected, and a button that does nothing when clicked is
   worse than no button. */
.rbn-tab.rbn-tab-off{display:none;}

/* ---------- the ribbon-layout gallery ----------
   NOT a full-screen overlay, unlike every other panel here: the thing
   you are choosing is the ribbon, so the ribbon has to stay visible.
   `top` is set in JS from the row's measured bottom, because a layout
   changes how tall the row is. */
.rbn-gallery{position:fixed;left:0;right:0;bottom:0;z-index:360;
  display:flex;flex-direction:column;background:var(--chrome-0,#0b141d);
  border-top:1px solid #ffffff1f;font-family:var(--sans);
  box-shadow:0 -18px 40px #0006;}
.rbn-gh{display:flex;align-items:center;gap:10px;padding:9px 16px;
  border-bottom:1px solid #ffffff14;}
.rbn-gt{font-size:13px;color:#dbe7ef;}
.rbn-gwarn{margin:8px 16px 0;padding:7px 10px;border-radius:6px;
  border:1px solid #ef9f2766;background:#ef9f2714;color:#e8c88f;
  font-size:11px;line-height:1.45;display:flex;align-items:center;gap:10px;}
.rbn-gwarn[hidden]{display:none!important;}
.rbn-gwarn b{color:#f0d39f;font-weight:650;}
.rbn-gwarn .dbtn{margin-left:auto;flex:none;}
.rbn-gal{flex:1;min-height:0;overflow-y:auto;padding:8px 16px 20px;}
.rbn-ggrid{display:grid;gap:10px;margin-bottom:6px;
  grid-template-columns:repeat(auto-fill,minmax(250px,1fr));}
/* a family heading. A hundred cards without them is a wall; with them
   it is a list you can skim to the part you care about. */
.rbn-gfam{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--chrome-ink-2);margin:12px 0 6px 2px;}
.rbn-gcount{font-family:var(--mono);font-size:10px;color:var(--chrome-ink-2);}
.rbn-gfind{font-family:var(--sans);font-size:12px;padding:5px 9px;
  border-radius:6px;background:#ffffff0d;color:#dbe7ef;
  border:1px solid #ffffff2b;width:190px;}
.rbn-gfind:focus{outline:none;border-color:var(--cyan);}
.rbn-gnone{color:var(--chrome-ink-2);font-size:12px;padding:14px 2px;}
body.light .rbn-gfind{background:var(--input-bg);color:var(--ink);
  border-color:var(--border-strong);}
.rbn-card{text-align:left;background:#ffffff08;border:1px solid #ffffff1c;
  border-radius:9px;padding:10px 12px;cursor:pointer;display:flex;
  flex-direction:column;gap:5px;color:#dce6ee;}
.rbn-card:hover{border-color:var(--cyan);background:#ffffff12;}
.rbn-card.on{border-color:var(--cyan);
  box-shadow:0 0 0 1px var(--cyan) inset;}
/* the tick as a CHARACTER. A CSS hex escape with nothing after it
   to terminate the run collapsed to a control character here, and
   the card printed garbage beside its name (2026-08-25). */
.rbn-card.on .rbn-cname::after{content:" ✓";color:var(--cyan);}
.rbn-cname{font-size:12.5px;font-weight:600;}
.rbn-cblurb{font-size:10.5px;line-height:1.5;color:var(--chrome-ink-2);}
/* THE PREVIEW IS THE POINT: a name tells you nothing about an
   arrangement, so the card draws the tabs and the groups on each. */
.rbn-cprev{display:flex;flex-direction:column;gap:3px;margin-top:3px;}
.rbn-ctab{display:flex;flex-wrap:wrap;gap:3px;align-items:center;}
.rbn-ctabl{font-family:var(--mono);font-size:8.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--chrome-ink-2);min-width:52px;}
.rbn-cgrp{font-size:9.5px;background:#ffffff14;border-radius:4px;
  padding:1px 5px;color:#b9cad8;white-space:nowrap;}
body.light .rbn-gallery{background:var(--chrome-2);}
body.light .rbn-gt,body.light .rbn-card{color:var(--ink);}
body.light .rbn-card{background:var(--chrome-3);
  border-color:var(--chrome-line);}
body.light .rbn-cgrp{background:var(--chrome-1);color:var(--ink-2);}
body.light .rbn-gwarn{
  background:color-mix(in srgb,var(--warning) 10%,var(--chrome-2));
  color:var(--warning);
  border-color:color-mix(in srgb,var(--warning) 55%,var(--chrome-line));}
body.light .rbn-gwarn b{color:var(--warning);}

/* ---------- what the deck says, in words ----------
   The lints on the left, the text on the right, both at once: having to
   switch between them to check one against the other is the whole
   problem with a separate report. */
.deck-review{position:fixed;inset:0;z-index:400;display:flex;
  flex-direction:column;background:var(--chrome-0,#0b141d);
  font-family:var(--sans);}
.rv-head{display:flex;align-items:center;gap:10px;padding:10px 16px;
  border-bottom:1px solid #ffffff1a;}
/* AN OBJECT THAT IS A LINK (T118). Only while presenting: in the
   editor a click selects it, and a pointer cursor would promise
   otherwise. The underline is on hover and focus rather than always,
   because a figure is not a word and a permanent rule under a picture
   reads as a border. */
.deck:not(.editing) .an-linked{cursor:pointer;}
.deck:not(.editing) .an-linked:hover,
.deck:not(.editing) .an-linked:focus-visible{
  outline:2px solid var(--accent,#39a9c0);outline-offset:3px;}
/* the TITLE gives way, never the buttons: compacting rather than
   wrapping is the house rule for every control row, and T121 put a
   fourth button here (deck.css) */
.rv-t{font-size:13px;color:#dbe7ef;min-width:0;overflow:hidden;
  white-space:nowrap;text-overflow:ellipsis;}
.rv-head .dbtn{flex:0 0 auto;}
.rv-main{flex:1;min-height:0;display:grid;
  grid-template-columns:minmax(280px,1fr) 1.2fr;gap:14px;
  padding:12px 16px 18px;}
.rv-lints{overflow-y:auto;display:flex;flex-direction:column;gap:6px;}
.rv-lhead{font-size:12px;color:#dbe7ef;}
.rv-lint{text-align:left;background:#ffffff08;border:1px solid #ffffff17;
  border-left-width:3px;border-radius:7px;padding:7px 10px;
  cursor:pointer;display:flex;flex-direction:column;gap:3px;}
.rv-lint:hover{border-color:var(--cyan);}
.rv-lint.nogo{cursor:default;}
.rv-lint.sev-warn{border-left-color:#f0a848;}
.rv-lint.sev-err{border-left-color:#ff8a7a;}
.rv-lh{font-size:12px;color:#dbe7ef;}
.rv-lw{font-size:10.5px;line-height:1.5;color:var(--chrome-ink-2);}
.rv-textwrap{display:flex;flex-direction:column;gap:6px;min-height:0;}
.rv-lab{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--chrome-ink-2);}
.rv-text{flex:1;min-height:0;resize:none;font-family:var(--mono);
  font-size:11.5px;line-height:1.6;padding:12px 14px;border-radius:8px;
  background:#0e1926;color:#dce6ee;border:1px solid #ffffff1f;
  white-space:pre;overflow:auto;}
body.light .deck-review{background:var(--chrome-0);}
body.light .rv-t,body.light .rv-lh,body.light .rv-lhead{color:var(--ink);}
body.light .rv-text{background:var(--input-bg);color:var(--ink);
  border-color:var(--border-strong);}

/* ---------- what this deck used to be ----------
   The snapshots on the left, what is different on the right. Only the
   rows that DIFFER are coloured: an unchanged row still has to be
   there (you are reading a deck, and a gap in it reads as a deletion)
   but it must not compete with the four that matter. */
.deck-history{position:fixed;inset:0;z-index:400;display:flex;
  flex-direction:column;background:var(--chrome-0,#0b141d);
  font-family:var(--sans);}
.dh-head{display:flex;align-items:center;gap:10px;padding:10px 16px;
  border-bottom:1px solid #ffffff1a;}
.dh-t{font-size:13px;color:#dbe7ef;}
.dh-main{flex:1;min-height:0;display:grid;
  grid-template-columns:minmax(230px,290px) 1fr;}
.dh-rail{overflow-y:auto;border-right:1px solid #ffffff14;
  padding:10px 8px;display:flex;flex-direction:column;gap:3px;}
/* EXACTLY one row high (T237): the graph in the gutter beside it is
   drawn 46px tall, so a row that wrapped to three lines broke its own
   lane into segments. The whole line is in the tooltip. */
.dh-snap{height:46px;text-align:left;background:transparent;
  border:1px solid
  transparent;border-radius:6px;padding:7px 9px;cursor:pointer;
  display:flex;flex-direction:column;gap:2px;color:#b9cad8;}
.dh-snap:hover{background:#ffffff0d;}
.dh-snap.on{background:#ffffff12;border-color:var(--cyan);
  color:#dbe7ef;}
.dh-when,.dh-why{white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;display:block;max-width:100%;}
.dh-when{font-size:12px;}
.dh-why{font-family:var(--mono);font-size:9px;color:var(--chrome-ink-2);}
.dh-body{overflow-y:auto;padding:12px 16px 24px;}
.dh-head2{font-size:12px;color:#b9cad8;margin-bottom:10px;
  line-height:1.5;}
.dh-all{margin-bottom:14px;}
.dh-row{display:grid;grid-template-columns:76px 1fr 1fr 150px;gap:12px;
  align-items:center;padding:8px 6px;border-top:1px solid #ffffff12;}
.dh-st{font-family:var(--mono);font-size:9px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--chrome-ink-2);}
.dh-row.st-changed .dh-st{color:var(--warning);}
.dh-row.st-added .dh-st{color:var(--success);}
.dh-row.st-removed .dh-st{color:var(--danger);}
.dh-row.st-moved .dh-st{color:var(--cyan);}
.dh-row.st-same{opacity:.5;}
.dh-row.st-same.dh-open{opacity:1;}
.dh-cell{display:flex;flex-direction:column;gap:4px;min-width:0;}
.dh-cap{font-family:var(--mono);font-size:9px;color:var(--chrome-ink-2);}
.dh-cell .mini-diagram{width:100%;height:74px;}
.dh-acts{display:flex;flex-direction:column;align-items:stretch;gap:5px;
  justify-content:center;}
.dh-full{grid-column:2/4;display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;
  padding:2px 0 8px;min-width:0;}
.dh-fullcell{display:flex;flex-direction:column;gap:5px;min-width:0;}
.dh-fullframe,.dh-fullmissing{position:relative;width:100%;aspect-ratio:16/9;
  overflow:hidden;background:#050a0f;border:1px solid #ffffff1f;
  border-radius:5px;}
.dh-fullframe .slide{position:absolute!important;left:0;top:0;
  transform-origin:top left;pointer-events:none;}
.dh-fullmissing{display:grid;place-items:center;color:var(--chrome-ink-2);
  font-family:var(--mono);font-size:10px;}
body.light .deck-history{background:var(--chrome-0);}
body.light .dh-t,body.light .dh-snap.on{color:var(--ink);}
body.light .dh-snap,body.light .dh-head2{color:var(--ink-2);}
body.light .dh-fullframe,body.light .dh-fullmissing{
  background:var(--chrome-1);border-color:var(--chrome-line);}

/* ---------- things only you can see ----------
   Marked in BOTH places a private item is drawn -- the editor and the
   presenter view -- because the whole question it answers is "can the
   audience see this", and an unmarked one looks exactly like a slide
   that is about to embarrass you. A dashed amber edge and a corner tag:
   loud enough to read at a glance, quiet enough to work under. */
.an-item.an-priv{outline:1.5px dashed #f0a848;outline-offset:2px;}
.an-item.an-priv::after{content:"only me";position:absolute;top:-9px;
  right:0;font-family:var(--mono);font-size:8px;letter-spacing:.06em;
  color:#0b141d;background:#f0a848;border-radius:3px;padding:0 3px;
  pointer-events:none;z-index:3;}
/* SVG paths cannot draw the ::after tag above. Keep the arrow's chosen
   colour/dash and give its visible stroke the same unmistakable amber
   signal instead (T49). */
.an-arrow-line.an-priv{filter:drop-shadow(0 0 2px #f0a848)
  drop-shadow(0 0 4px #f0a848);}
.an-arrow-line.an-priv.sel{filter:
  drop-shadow(0 0 5px color-mix(in srgb,var(--accent) 80%,transparent))
  drop-shadow(0 0 2px #f0a848) drop-shadow(0 0 4px #f0a848);}

/* ---------- what a rehearsal left behind ----------
   Per slide and per section. The section rows are the ones you act on,
   so they carry the weight; a row that ran over its target is the only
   thing coloured, because colouring everything says nothing. */
.np-reh{font-size:11px;line-height:1.45;color:var(--chrome-ink-2);margin:2px 0 4px;}
.np-reh.over{color:var(--warning);}
.np-rehhead{font-family:var(--mono);font-size:10px;letter-spacing:.06em;
  color:var(--chrome-ink-2);margin:2px 0 8px;}
.np-rehrow{display:flex;align-items:baseline;gap:8px;padding:4px 6px;
  border-radius:5px;font-size:11.5px;color:#b9cad8;cursor:pointer;}
.np-rehrow:hover{background:#ffffff0d;}
.np-rehrow.sec{margin-top:7px;color:#dbe7ef;cursor:default;
  border-top:1px solid #ffffff14;padding-top:7px;}
.np-rehrow.sec .np-rehlab{font-family:var(--mono);font-size:9.5px;
  letter-spacing:.12em;text-transform:uppercase;}
.np-rehlab{flex:1;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
.np-rehnum{font-family:var(--mono);font-size:11px;}
.np-rehex{font-family:var(--mono);font-size:9px;color:var(--chrome-ink-2);
  min-width:62px;text-align:right;}
.np-rehrow.over .np-rehnum,.np-rehrow.over .np-rehex{color:var(--warning);}
body.light .np-rehrow{color:var(--ink-2);}
body.light .np-rehrow.sec{color:var(--ink);border-top-color:var(--rule);}

/* ---------- the roomy notes editor ----------
   An OVERLAY, like the spotlight, the presenter view and the overview
   map: it wants the whole screen while you are writing and none of it
   afterwards. Three columns, because a note is about a slide (left),
   is typed (middle) and is read back (right). */
.deck-notesed{position:fixed;inset:0;z-index:400;display:flex;
  flex-direction:column;background:var(--chrome-0,#0b141d);
  font-family:var(--sans);}
.nse-head{display:flex;align-items:center;gap:10px;padding:10px 16px;
  border-bottom:1px solid #ffffff1a;}
.nse-t{font-size:13px;color:#dbe7ef;}
.nse-body{flex:1;min-height:0;display:grid;
  grid-template-columns:minmax(240px,1fr) 1.25fr 1.25fr;gap:14px;
  padding:14px 16px 18px;}
.nse-left,.nse-write,.nse-read{display:flex;flex-direction:column;gap:6px;
  min-height:0;}
.nse-lab{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--chrome-ink-2);}
.nse-slide{background:#000;border-radius:8px;overflow:hidden;
  display:flex;align-items:center;justify-content:center;
  flex:0 0 auto;height:min(30vh,260px);}
.nse-slide .slide{transform-origin:center center;}
.nse-help{font-size:11.5px;line-height:1.65;color:var(--chrome-ink-2);
  background:#ffffff08;border:1px solid #ffffff17;border-radius:8px;
  padding:9px 11px;overflow:auto;}
.nse-help code{font-family:var(--mono);font-size:10.5px;
  background:#ffffff14;padding:.1em .35em;border-radius:4px;
  color:#cfe0ec;}
.nse-ta{flex:1;min-height:0;resize:none;font-family:var(--sans);
  font-size:15px;line-height:1.55;padding:12px 14px;border-radius:8px;
  background:#0e1926;color:#e4eef6;border:1px solid #ffffff1f;}
.nse-ta:focus{outline:none;border-color:var(--cyan);}
.nse-prev{flex:1;min-height:0;overflow:auto;font-size:15px;
  line-height:1.55;padding:12px 14px;border-radius:8px;
  background:#ffffff08;border:1px solid #ffffff17;color:#dce6ee;}
.nse-none{color:var(--chrome-ink-3);}
/* the small markdown, wherever it is read back */
.jvn-md p{margin:0 0 .6em;}
.jvn-md h3,.jvn-md h4,.jvn-md h5{margin:.2em 0 .4em;font-size:1.05em;}
.jvn-md ul,.jvn-md ol{margin:.2em 0 .6em;padding-left:1.3em;}
.jvn-md li{margin:.15em 0;}
.jvn-md code{font-family:var(--mono);font-size:.85em;background:#ffffff14;
  padding:.1em .35em;border-radius:4px;}
.jvn-md blockquote{margin:.3em 0 .6em;padding-left:.8em;
  border-left:3px solid #ffffff2b;color:var(--chrome-ink-2);}
.jvn-md hr{border:0;border-top:1px solid #ffffff26;margin:.7em 0;}
.jvn-md a{color:var(--cyan);}
.jvn-md .jvn-goto{cursor:pointer;text-decoration:underline dotted;}
.np-bigbtn{align-self:flex-start;margin:2px 0 6px;}
body.light .deck-notesed{background:var(--chrome-0);}
body.light .nse-t{color:var(--ink);}
body.light .nse-ta{background:var(--input-bg);color:var(--ink);
  border-color:var(--border-strong);}
body.light .nse-prev{background:var(--chrome-3);color:var(--ink);
  border-color:var(--chrome-line);}
body.light .nse-help{background:var(--chrome-3);color:var(--ink-2);
  border-color:var(--chrome-line);}
body.light .jvn-md code,body.light .nse-help code{background:var(--chrome-1);
  color:var(--ink);}

/* ---------- the overview map ----------
   An OVERLAY, not a pane: it wants all the room there is for as long as
   you are looking and none afterwards, which is the shape the spotlight
   and the presenter view already have. */
.deck-overview{position:fixed;inset:0;z-index:400;display:flex;
  flex-direction:column;background:var(--chrome-0,#0b141d);
  font-family:var(--sans);}
.ovw-head{display:flex;align-items:center;gap:10px;
  padding:10px 16px;border-bottom:1px solid #ffffff1a;}
.ovw-t{font-size:13px;color:#dbe7ef;}
.ovw-body{flex:1;overflow:auto;padding:14px 16px 26px;}
.ovw-grp{margin-bottom:18px;}
.ovw-gh{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--chrome-ink-2);margin:0 0 7px 2px;}
.ovw-tiles{display:flex;flex-wrap:wrap;gap:10px;}
.ovw-tile{width:150px;background:#ffffff08;border:1px solid #ffffff1f;
  border-radius:7px;padding:6px;cursor:pointer;text-align:left;
  display:flex;flex-direction:column;gap:4px;position:relative;}
.ovw-tile:hover{border-color:var(--cyan);background:#ffffff12;}
.ovw-tile.cur{border-color:var(--cyan);
  box-shadow:0 0 0 1px var(--cyan) inset;}
/* an optional slide, and one the current version leaves out: the map is
   a zoom-out of the strip, so it says the same things the strip does */
.ovw-tile.opt::after{content:"optional";position:absolute;top:5px;
  right:6px;font-family:var(--mono);font-size:8px;color:var(--warning);}
.ovw-tile.cut{opacity:.42;}
/* a search hit: the tile is already the answer, so the only thing added
   is WHY it matched -- and where, when the word is only in the notes */
.ovw-tile.hit{border-color:var(--cyan);}
.ovw-why{font-size:9.5px;line-height:1.35;color:var(--chrome-ink-2);
  border-top:1px solid #ffffff17;padding-top:4px;margin-top:1px;}
.ovw-find{font-family:var(--sans);font-size:12px;padding:5px 9px;
  border-radius:6px;background:#ffffff0d;color:#dbe7ef;
  border:1px solid #ffffff2b;width:210px;}
.ovw-find:focus{outline:none;border-color:var(--cyan);}
.ovw-fn{font-family:var(--mono);font-size:9.5px;color:var(--chrome-ink-2);
  min-width:62px;}
body.light .ovw-find{background:var(--input-bg);color:var(--ink);
  border-color:var(--border-strong);}
.ovw-n{font-family:var(--mono);font-size:9px;color:var(--chrome-ink-2);}
.ovw-tile .mini-diagram{width:100%;height:76px;}
/* T557: the sorter's picked slides, its drop marks and its tools */
.deck-overview.sorting .ovw-tiles{gap:14px;}
.ovw-tile.pick{border-color:var(--accent);background:color-mix(in srgb,
  var(--accent) 16%,transparent);box-shadow:0 0 0 2px var(--accent);}
.ovw-tile.drop-before{box-shadow:-5px 0 0 -1px var(--accent);}
.ovw-tile.drop-after{box-shadow:5px 0 0 -1px var(--accent);}
.ovw-tile.hid .ovw-n{text-decoration:line-through;}
.ovw-tools{display:flex;gap:6px;margin-left:8px;}
.ovw-tools .dbtn{height:28px;}
/* T607: the TITLE gives way, never the buttons (the house rule .rv-head
   keeps). At 1366px the sorter's head ran out of room and every button
   shrank: Open, Duplicate, New section, Delete and Close each broke into
   an icon over a word that hung below the button's box, and the title
   took two lines. */
.ovw-head .dbtn{flex:none;white-space:nowrap;}
.ovw-head .ovw-t{flex:0 1 auto;min-width:0;overflow:hidden;
  white-space:nowrap;text-overflow:ellipsis;}
.ovw-head .ovw-find{flex:0 1 210px;min-width:120px;}
.ovw-lab{font-size:10.5px;color:#b9cad8;line-height:1.25;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
body.light .deck-overview{background:var(--chrome-0);}
body.light .ovw-t{color:var(--ink);}
body.light .ovw-lab{color:var(--ink-2);}

/* ---------- T601: the Parts view ----------
   The overview map's overlay and grouping, one group per part or section
   in the talk's order; a part's header says what it shows, whether that
   is up to date, and carries what can be done with it. */
.deck-parts .prt-head{flex-wrap:wrap;row-gap:6px;}
.deck-parts .dbtn[hidden]{display:none;}
/* T660: its buttons, its own. They wore the ribbon's .rbn-sm, whose
   padding and gap are tokens on .deck -- and the view is on the page,
   outside it, so they came to nothing: no gap, no padding, the words
   against the edge. */
.deck-overview .dbtn.prt-b,.deck-parts .dbtn.prt-b{display:inline-flex;align-items:center;gap:5px;
  padding:4px 10px;font-family:var(--sans);font-size:12px;line-height:1.4;
  white-space:nowrap;}
.deck-overview .dbtn.prt-b .bic,.deck-parts .dbtn.prt-b .bic{width:14px;height:14px;margin-right:0;
  flex:none;vertical-align:0;}
.deck-overview .dbtn.prt-b:disabled,.deck-parts .dbtn.prt-b:disabled{opacity:.45;cursor:default;}
.prt-say{margin:8px 16px 0;padding:6px 10px;border-radius:6px;font-size:12px;
  color:#dbe7ef;background:color-mix(in srgb,var(--cyan) 12%,transparent);
  border:1px solid color-mix(in srgb,var(--cyan) 40%,transparent);}
.prt-say.warn{background:color-mix(in srgb,var(--warning) 14%,transparent);
  border-color:color-mix(in srgb,var(--warning) 50%,transparent);}
.prt-say[hidden]{display:none;}
.prt-grp{border:1px solid #ffffff17;border-radius:9px;padding:10px 12px 12px;}
.prt-grp.linked{border-color:color-mix(in srgb,var(--accent) 50%,transparent);
  background:color-mix(in srgb,var(--accent) 6%,transparent);}
.prt-gh{display:flex;align-items:center;gap:10px;margin-bottom:9px;
  flex-wrap:wrap;}
.prt-ic{display:inline-flex;color:var(--chrome-ink-2);}
.prt-grp.linked .prt-ic{color:var(--accent);}
.prt-tx{flex:1;min-width:200px;}
.prt-name{font-size:13.5px;font-weight:600;color:#dbe7ef;}
.prt-from{font-weight:400;color:var(--chrome-ink-2);}
.prt-sub{font-size:11.5px;color:var(--chrome-ink-2);margin-top:2px;}
.prt-sub.warn{color:var(--warning);}
.prt-acts{display:flex;gap:5px;flex-wrap:wrap;}
.prt-acts .dbtn:disabled{opacity:.4;cursor:default;}
/* the chevrons turned to point where the part goes */
.prt-up .bic,.prt-dn .bic{transform:rotate(90deg);}
.prt-none{color:var(--chrome-ink-2);font-size:12.5px;margin:0 0 14px;}
.prt-pick{display:grid;grid-template-columns:minmax(220px,340px) 1fr;gap:16px;}
.prt-pick-list{display:flex;flex-direction:column;gap:4px;}
.prt-row{display:flex;flex-direction:column;align-items:flex-start;gap:2px;
  text-align:left;background:#ffffff08;border:1px solid #ffffff1f;
  border-radius:7px;padding:7px 10px;cursor:pointer;color:#dbe7ef;
  font-family:var(--sans);}
.prt-row:hover,.prt-row:focus-visible{border-color:var(--cyan);
  background:#ffffff12;outline:none;}
.prt-row.off{opacity:.55;}
.prt-row-name{font-size:13px;font-weight:600;}
.prt-row-sub{font-size:11px;color:var(--chrome-ink-2);}
.prt-pick-pv{min-width:0;}
@media (max-width:720px){.prt-pick{grid-template-columns:1fr;}}
body.light .prt-name,body.light .prt-row,body.light .prt-say{color:var(--ink);}
body.light .prt-grp{border-color:var(--chrome-line);}
body.light .prt-row{background:var(--chrome-1);border-color:var(--chrome-line);}
/* the corner's second button: a part's slide says where it comes from */
.deck-where{gap:4px;}
.deck-where .where-part.from{border-color:color-mix(in srgb,var(--accent) 60%,transparent);
  color:var(--accent);}
.deck-where .where-part[hidden]{display:none;}
/* T676: the two on one line in the slide column ("Edit in “work-and-f"
   was cut off beside "Slide 1 of 21 · …"). The chip says "Edit
   original" and never gives way; the count beside it is the number
   alone -- "1 of 21", the film icon says what it counts and the whole
   phrase is its tip. Its word went as it does beside a collection's
   chip, and the live copy's name after it too: in a laptop's 171px
   column it was only ever "· …", and the name heads the slides just
   under it. A state class, written by partChipSync. */
.film-head .deck-where.part-on .dbtn.rbn-sm{padding:4px 6px;gap:4px;}
.deck-where.part-on #where-btn{flex:0 1 auto;min-width:0;}
.deck-where.part-on .where-w,.deck-where.part-on .where-s{display:none;}
.deck-where.part-on #where-t{display:flex;min-width:0;}
.deck-where.part-on .where-n{flex:none;}
.deck-where.part-on .where-part{flex:none;}
/* T614: the way back to the collection a deck was made from -- a quiet
   accent border like a part's chip; a collection that has gone says so
   in the warning colour */
.deck-where .where-col{flex:none;
  border-color:color-mix(in srgb,var(--accent) 45%,transparent);}
/* ...on the slide count's own line, as a part's chip is: one word, and
   both a little narrower while it shows, so the corner stays ONE line
   in the 171px column of a laptop (it took a line of its own, and the
   strip 28px). The count drops its word -- "2 of 14", the film icon
   says what it counts, the whole phrase is its tip -- so the count is
   never what gives way (fix round 2: it read "Slide 2 …" on every linked
   deck); only what follows it (a version, a section) ellipsizes. A state
   class, written by cpsChipSync, rather than a :has rule. */
.film-head .deck-where.has-col .dbtn.rbn-sm{padding:4px 6px;}
.deck-where.has-col #where-btn{flex:0 1 auto;min-width:0;}
.deck-where.has-col .where-w{display:none;}
.deck-where.has-col #where-t{display:flex;min-width:0;}
.deck-where.has-col .where-n{flex:none;}
.deck-where.has-col .where-s{min-width:0;overflow:hidden;
  text-overflow:ellipsis;}
.deck-where .where-col.gone{border-color:var(--danger);color:var(--danger);}
.deck-where .where-col[hidden]{display:none;}
/* ...and a part's chip as well (T601's "From …" or "Part of …"): the three
   do not fit one 171px line, where the part's words ran over this chip
   and the count was cut to "1." (2026-10-13 review). The part's chip
   takes the line under the count and this one, as wide as the column,
   and its name ellipsizes inside it; the count takes what this chip
   leaves of the first line (its own width would push this chip down a
   line too). has-part: a state class written by cpsChipSync. */
.deck-where.has-col.has-part{flex-wrap:wrap;}
.deck-where.has-col.has-part #where-btn{flex:1 1 0;}
.deck-where.has-col.has-part .where-part{order:1;flex:1 1 100%;}
.deck-where.has-col .where-part #where-part-t{min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;}

/* ---------- one object's history ----------
   A row is a schematic of a past state, a sentence about what changed,
   and (for anything but the current state) a button. Not a .pf-row for
   the reason .std-find is not one: a preflight row is one big button. */
.oh-row{display:flex;align-items:center;gap:9px;padding:7px 12px;
  border-left:3px solid transparent;}
.oh-row.oh-now{border-left-color:var(--cyan);}
.oh-body{flex:1;min-width:0;}
.oh-h{font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--chrome-ink-2);}
.oh-what{font-size:11.5px;color:var(--chrome-ink);line-height:1.35;
  overflow:hidden;text-overflow:ellipsis;}
.oh-do{font-size:10.5px;padding:3px 8px;flex:none;}
.oh-thumb{flex:none;width:38px;max-height:34px;border-radius:3px;
  border:1px solid #ffffff2b;background:#ffffff08;overflow:hidden;
  font-size:7px;line-height:1.15;padding:2px;color:var(--chrome-ink-2);
  display:flex;align-items:center;justify-content:center;
  text-align:center;word-break:break-word;}
.oh-thumb.oh-line{max-height:0;height:0;border-width:0 0 2px 0;
  border-radius:0;align-self:center;}
.oh-thumb.oh-block{font-family:var(--mono);font-size:6.5px;}
body.light .oh-what{color:var(--ink-2);}
body.light .oh-h{color:var(--ink-3);}

/* ---------- standardise text ----------
   Not a .pf-row: a preflight row is one big button that takes you to the
   thing, and a finding here carries several boxes AND an action, so the
   row is a block with buttons inside it. Amber for a drift with a
   majority to fix towards, quiet blue for an offer — and never the red
   preflight uses, because nothing this finds is broken. */
.std-find{display:flex;flex-direction:column;gap:5px;padding:9px 12px;
  border-left:3px solid #f0a848;}
.std-find.std-info{border-left-color:#39a9c0;}
.std-h{font-size:12.5px;color:#dbe7ef;font-weight:600;}
.std-why{font-size:11px;color:var(--chrome-ink-2);line-height:1.45;}
.std-who{display:flex;flex-wrap:wrap;gap:3px;}
.std-chip{background:#ffffff10;border:1px solid #ffffff1f;color:var(--chrome-ink-2);
  border-radius:10px;font-family:var(--sans);font-size:11.5px;
  padding:2px 8px;cursor:pointer;max-width:100%;overflow:hidden;
  white-space:nowrap;display:flex;align-items:center;
  min-width:0;flex:1 1 190px;text-align:left;}
.std-chip:hover{border-color:var(--cyan);color:var(--chrome-ink);}
/* T368: the chip is a specimen of its box. The slide number keeps its
   own quiet mono lane so the words are the thing you read, and the
   words elide rather than stretch the card. */
.std-chipn{flex:none;font-family:var(--mono);font-size:9.5px;
  opacity:.7;padding-right:7px;}
.std-chiptx{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;border-radius:3px;padding:0 3px;}
.std-chiptx.std-chipempty{opacity:.55;font-style:italic;}
/* T279: WHICH ONE DISAGREES. A band card lists the whole band, because
   the fix moves all of it -- so the ones that differ have to be told
   apart from the ones that do not, and they lead. Weight and a badge,
   NOT a new hue: the note at the top of this section records that this
   screen never uses the red preflight uses, because nothing it finds is
   broken. Amber is already this screen's word for "look at this". */
.std-chip.std-odd{border-color:#f0a848;color:#f7d9a8;
  background:color-mix(in srgb,#f0a848 16%,transparent);font-weight:600;}
.std-chip.std-odd::before{content:"! ";font-weight:700;}
/* T383: a group that was compared and matches -- a quieter card, no
   button, so the screen shows its working without offering a fix */
.std-find.std-checked{border-left-color:#46c08a;opacity:.8;}
.std-find.std-checked .std-chip.std-ok{opacity:.75;}
.std-more{font-size:11px;color:var(--chrome-ink-2);align-self:center;}
.std-chip.std-ok{opacity:.5;}
.std-chip.std-ok:hover{opacity:1;}
body.light .std-chip.std-odd{color:#7a4b00;
  background:color-mix(in srgb,#f0a848 22%,transparent);}
.std-do{align-self:flex-start;font-size:11px;padding:3px 9px;}
.std-do2{opacity:.8;}
body.light .std-h{color:var(--ink);}
body.light .std-why{color:var(--ink-3);}
body.light .std-chip{background:var(--surface-hover);border-color:var(--line);
  color:var(--ink-3);}

/* ---------- toolbar down the right-hand edge (tall pages) ---------- */
/* A0 portrait is 1.4x taller than wide: on a laptop the horizontal ribbon
   costs ~122px of the scarce dimension. Moved to the side it costs width,
   which a portrait poster has to spare. Absolute rather than a flex
   sibling so the stage, its arrows and the Objects pane keep their
   existing layout untouched. */
/* The horizontal ribbon is a fixed-height row of two-row grids. NONE of
   that survives being stood on its end, so side mode has to undo each
   piece explicitly — the height, the row grid and the clipping. It did
   not, so the toggle appeared to do nothing (2026-08-07, user: "the
   ribbon stays fucking horizontal"). */
/* ONE width for the rail, so the stage's padding, the rulers, the next
   arrow and the Objects pane cannot drift apart — they were four separate
   numbers that all meant "however wide the rail is". 226px is the width at
   which Print check and Present sit side by side instead of stacking: 12px
   of a dimension a portrait poster has to spare, for a line back
   (2026-08-16). */
.deck.rbn-side{--rbn-side-w:226px;}
.deck.rbn-side .edit-tools.ribbon{position:absolute;top:0;right:0;bottom:0;
  width:var(--rbn-side-w);height:auto;flex-direction:column;flex-wrap:nowrap;
  align-items:stretch;align-content:flex-start;min-height:0;
  overflow-y:auto;overflow-x:hidden;
  padding:10px 10px 16px;row-gap:2px;
  border-bottom:none;border-left:1px solid #ffffff14;z-index:8;}
.deck.rbn-side .rbn-grp{align-items:stretch;padding:8px 2px;flex:none;
  border-right:none;border-bottom:1px solid #ffffff1c;width:100%;}
/* The same little CLUSTERS the horizontal ribbon has, stood on end. One
   control per line made Insert seven rows deep and turned the rail back
   into the list of rows the ribbon had just stopped being (2026-08-16,
   user: "I hate how everything is just in rows it makes it so uncompact
   ... poster layout should be the same as well").
   flex-wrap does the pairing with NO measuring: every control keeps its
   natural width, two share a line when both fit, and a long one takes the
   line to itself. flex-shrink stays 0 for the reason it always does here
   — a squeezed button is a truncated word, and no rung of this toolbar
   has ever been allowed to hide one. Grow fills the leftover so the rail
   keeps a clean edge instead of a ragged one. */
.deck.rbn-side .rbn-row{display:flex;flex-flow:row wrap;
  align-items:stretch;align-content:flex-start;height:auto;gap:3px;}
.deck.rbn-side .rbn-row>*{flex:1 0 auto;}
/* a cell is ONE flex item and holds no wrap of its own, so the zoom
   stepper and the undo/redo pair each stay whole wherever they land —
   without claiming a whole line the way a `flex-basis:100%` would */
.deck.rbn-side .rbn-cell{height:auto;}
.deck.rbn-side .rbn-cell .dbtn.rbn-sm{flex:1 0 auto;justify-content:center;}
/* the group divider is a vertical rule in the horizontal ribbon and has no
   business on a stacked one; the ORDER still applies, so View and Output
   fall to the bottom of the column */
.deck.rbn-side .rbn-view{border-left:none;}
/* T679: View's pairs after its tiles in the rail. A 24px button that
   wraps onto a tile's line sits at its own height and leaves a hole
   under it; after the tiles they pair up two to a line, as During the
   talk's do */
.deck.rbn-side .rbn-view .view-sm{order:1;}
/* ...on a line of their own, so the last tile never takes the first of
   a pair beside it (a line break: the first of the order-1 items) */
.deck.rbn-side .rbn-view>.rbn-row::before{content:"";order:1;
  flex:0 0 100%;height:0;}
/* File over Save is a two-row stack only where there are two rows: in the
   rail's wrapping flow it pairs across like every other control, rather
   than standing one item twice as tall as its neighbours */
.deck.rbn-side .rbn-stack{flex-direction:row;}
.deck.rbn-side .et-hint{display:none;}
/* A section heading belongs ABOVE its section in a vertical list — that
   is how every sidebar reads. Below is right for the horizontal ribbon,
   where the label sits under the group like PowerPoint's
   (2026-08-07, user: "put the titles above the section not below"). */
.deck.rbn-side .rbn-lab{order:-1;padding:0 2px 2px;text-align:left;}
/* the group divider turns from a vertical rule into a horizontal one */
.deck.rbn-side .deck-stage{padding-right:calc(var(--rbn-side-w) + 12px);}
.deck.rbn-side .rulers{right:var(--rbn-side-w);}
.deck.rbn-side .deck-arrow.next{right:calc(var(--rbn-side-w) + 8px);}
.deck.rbn-side .selpane{right:var(--rbn-side-w);}
/* T470: A STRIP IS AS WIDE AS THE RAIL. The frames keep their
   horizontal widths -- three or four tiles -- which is wider than the
   rail's column, so the Airy tile ran under the scrollbar with its
   right edge cut (2026-09-15 review). In the rail a frame is the
   column's width and its tiles wrap inside it; the arrows still step
   whole rows. */
.deck.rbn-side .strip-frame{width:100%;flex:1 0 100%;box-sizing:border-box;}
.deck.rbn-side .strip-frame>.fx-strip.fx-strip,
.deck.rbn-side .strip-frame>#anim-by-strip{width:auto;max-width:none;
  flex:1 1 auto;min-width:0;}
.deck.rbn-side{--rbn-tile-w:54px;}
/* ...and a bare strip (Play's four tiles) wraps in the rail too, rather
   than running its last tile under the scrollbar */
.deck.rbn-side .rbn-row>.fx-strip{flex-wrap:wrap;width:100%;height:auto;}
/* ...and so does a cell frame's part picker (#fmt-parts): Figure, Code
   and Split in two are one nowrap row wider than the rail, and Split in
   two ran past its edge, cut off (2026-10-11 review). In the rail the
   picker is a line of its own and its pills pair up like every other
   control there -- each keeps its word and its icon. */
.deck.rbn-side .rbn-partslot:not([hidden]){display:flex;flex:1 0 100%;
  width:100%;height:auto;align-items:flex-start;}
.deck.rbn-side #fmt-parts .cellparts{display:flex;flex-wrap:wrap;
  width:100%;gap:3px;}
.deck.rbn-side #fmt-parts .cellpartbtn{flex:1 0 auto;
  justify-content:center;}
/* Justify (2026-10-30 review) made Left, Centre, Right, Justify one run
   49px wider than the rail; there the four sit two to a line in the one
   box, a rule between the lines as between the words */
.deck.rbn-side #tx-run-align{display:grid;grid-template-columns:1fr 1fr;
  height:auto;}
.deck.rbn-side #tx-run-align>.dbtn{justify-content:center;}
.deck.rbn-side #tx-run-align>.dbtn:nth-child(3){border-left:0;}
.deck.rbn-side #tx-run-align>.dbtn:nth-child(n+3){
  border-top:1px solid var(--rbn-btn-bd);}
/* ...and Opacity's typed number took 12px the rail does not have: its
   slider is shorter there */
.deck.rbn-side #fmt-opcell .fmt-range{width:64px;}

/* ---------- full-screen EDITING (not presenting) ---------- */
/* Present hides every tool, which is wrong for a poster: there is no
   audience and nothing to step through. This keeps the whole editor and
   just takes the browser chrome away. */
.deck.editfull .deck-top{display:none;}
.deck.editfull .deck-stage{padding-top:6px;}

/* annotation layer */
.annot-layer{position:absolute;inset:0;z-index:6;pointer-events:none;}
/* the layer does not clip while EDITING, so an item nudged past the
   page edge stays visible and draggable instead of disappearing; the
   stage grows scrollbars to reach it (2026-08-20). Playback and every
   export clip to the page, which is what a page is. */
.annot-layer.an-spill{overflow:visible;}
.deck.editing .annot-layer{pointer-events:auto;cursor:crosshair;}
/* A PLACED CARD IS NOT A DOCUMENT. Its markdown, tables and code are
   never edited in place, so nothing is lost by making them unselectable
   -- and it is belt-and-braces behind startMarquee's preventDefault for
   the blue smear of T63. Deliberately NOT applied to .an-text/.an-tx:
   those ARE edited in place and must stay selectable. */
.deck.editing .an-item.an-cell{user-select:none;-webkit-user-select:none;}
.deck.editing .annot-layer.tool-select{cursor:default;}
.deck.editing .annot-layer:not(.tool-select) .an-item,
.deck.editing .annot-layer:not(.tool-select) .an-item *{
  cursor:crosshair!important;}
.annot-layer>svg{position:absolute;inset:0;width:100%;height:100%;
  overflow:visible;pointer-events:none;}
.deck.editing .annot-layer>svg{pointer-events:auto;}
.annot-layer>svg.an-svgtop{pointer-events:none!important;z-index:5;}
/* The current slide stays interactive; other slides are a tracing aid only.
   Their bounds sit below the live annotation layer and never intercept a
   click, so turning the aid on cannot steal an edit gesture. */
.deck-ghost-layer{position:absolute;inset:0;z-index:2;pointer-events:none;}
.deck-ghost-slide{position:absolute;inset:0;opacity:.7;
  color:var(--ghost,#55b7ff);}
.deck-ghost-slide::before{content:attr(data-slide);position:absolute;
  left:4px;top:4px;z-index:20;padding:2px 4px;border-radius:3px;
  background:#08111ccc;color:var(--ghost,#55b7ff);
  font:600 9px/1 var(--mono);}
.deck-ghost-slide:not(.is-content) .an-item{background:transparent!important;
  box-shadow:inset 0 0 0 1px var(--ghost,#55b7ff)!important;}
.deck-ghost-slide:not(.is-content) .an-item>*{visibility:hidden!important;}
.deck-ghost-slide:not(.is-content)>svg{opacity:.75;filter:saturate(0) brightness(1.7);}
.deck-ghost-slide.is-content{opacity:.14;filter:saturate(.8);}
.deck-ghost-box{position:absolute;border:1px dashed currentColor;
  border-radius:4px;opacity:.72;box-sizing:border-box;}
.deck-ghost-box.is-filled{opacity:.18;}
.deck-ghost-box::after{content:attr(data-slide);position:absolute;left:3px;
  top:2px;font:600 9px/1 var(--mono);color:inherit;opacity:.9;}
.an-item{pointer-events:none;}
.deck.editing .an-item{pointer-events:auto;}
/* T546: WHAT A CLICK MEANS SOMETHING ON, WHILE PRESENTING. An item takes
   no pointer so a click anywhere advances -- and so the four things the
   playback click handler claims were never reached by a mouse: a linked
   object (T118), linked words, a clip (T321) and, with tap-to-enlarge
   on, any item. Found driving T546: a click on a link moved the talk on. */
.deck:not(.editing) .an-linked,
.deck:not(.editing) .an-tx a,
.deck:not(.editing) .an-video,
.deck:not(.editing) .slide.tapzoom .an-item{pointer-events:auto;}
/* the corner is a DECK TOKEN (T12): one value, written onto the slide
   as --tk-rad, so every drawn box follows it and none of them stores a
   radius of its own. The literal is the fallback for anything rendered
   outside a slide (a thumbnail, a menu chip). */
/* T455: the literal is the DEFAULT, --tk-line is the deck's answer when
   somebody has changed it. Same bargain as --tk-rad above. */
.an-rect{position:absolute;border:3px solid var(--tk-line,#ff6b57);
  border-radius:var(--tk-rad,4px);}
.deck.editing .an-rect{cursor:move;}
.an-rect.sel,.an-text.sel,.an-title.sel,.an-cell.sel,.an-code.sel,
.an-html.sel{
  outline:2px dashed var(--cyan);outline-offset:3px;}
/* T623: the box's fill is the DECK's surface, or the dark one its white
   words were made for -- never the editor's own chrome colour, which the
   light editor theme turns pale: every default box drew white words on
   pale grey there, in the editor and in the show, while the exported
   page (no theme) drew them dark. A slide does not follow the app. */
.an-text{position:absolute;max-width:60%;font-family:var(--sans);
  line-height:1.35;color:var(--tk-ink,#fff);
  background:color-mix(in srgb,
    var(--tk-surface,#0e1926) 85%,transparent);
  border:1px solid var(--tk-line,#ffffff2e);border-radius:var(--tk-rad,8px);padding:.35em .55em;
  display:flex;align-items:flex-start;gap:.35em;}
/* no text-shadow: it was meant to keep bare text legible on any page but
   read as a smudge on every one (2026-08-19, user: "why is there a shadow
   on the text — that's weird") */
.an-text.nobg{background:none;border:none;}
/* fill the box (minus the move handle) so text-align actually positions the
   text — a content-sized flex item can't be aligned */
.an-tx{white-space:pre-wrap;min-width:14px;outline:none;flex:1;
  padding-left:var(--an-ind,0);}
/* THE BULLET GUTTER IS 1.7em (T195): an outside marker sits about 1em
   left of its words, so at 1.15em it was drawn on the box's edge, under
   the dashed selection line (2026-09-02, user: "the dot points appear
   where the dashed selection line is"). Until T623 it was a root list's
   padding, added to the box indent in a calc() whose unitless zero
   fallback voided the whole declaration (2026-09-09, user: "bullet
   points still don't sit in right place"). It is each paragraph's own
   margin now (paraPos), and the box indent is still .an-tx's padding, so
   the two add up with no calc() at all. */
/* ---- T623: THE PARAGRAPH -------------------------------------------------
   A text box is its paragraphs, one <p class="an-p"> each, drawn the same
   in the editor, the show, the strip and every export (parasDraw in
   20-notes-and-tables.js). paraDecorate puts each one where it goes -- a
   margin for its level, so the box indent (.an-tx's padding, --an-ind)
   composes with it -- and gives one with a marker its kind and number
   (list-style-type and counter-set: the browser's own dots and counters,
   so a bullet is the shape every list here has always had). The marker
   is the paragraph's ::marker, OUTSIDE it, in the margin: 1.7em at the
   first level, the gutter T195 settled on. A margin and not a padding,
   because an outside marker sits outside the box it marks -- and because
   each paragraph carries its own, each column of a two-column box has
   its gutter (the show's single list had one, for the first column). */
.an-p{margin:0;}
.an-p[data-list]{display:list-item;margin-top:.18em;margin-bottom:.18em;}
/* T571: a marker's own colour and size (the words keep theirs) */
.an-p::marker{color:var(--an-lc,currentColor);
  font-size:calc(var(--an-ls,1) * 1em);}
/* a closing bracket is the one shape the built-in list styles cannot
   say: a counter style of its own, so 1) 2) 3) counts on paragraph by
   paragraph as 1. 2. 3. does (a ::marker's counter() only showed the
   number a paragraph carried, so every paragraph had to carry one) */
@counter-style jv-paren{system:extends decimal;suffix:") ";}
/* a line break INSIDE a paragraph (Shift+Enter) is only a line break --
   the gap between paragraphs is theirs (.an-tx br, below, is a Markdown
   box's) */
.an-tx .an-p br{display:inline;margin-top:0;}
/* columns break between paragraphs, and a margin at a break is cut off:
   the first column's first paragraph would start .18em below the next
   column's */
.an-cols>.an-p:first-child{margin-top:0;}
/* T231: the slide column picks slides, so it gets the same two buttons
   the table has, and says how many are picked. */
.dg-picks{display:flex;align-items:center;gap:6px;flex-wrap:wrap;
  margin:8px 0 4px;}
.dg-pickn{font-family:var(--sans);font-size:11px;color:var(--chrome-ink-2);}

/* ---- T230: THE BOARD SHOWS THE REAL BOXES -----------------------------
   The dragged rectangle is the default this style stamps -- thicker,
   amber, and glowing. Behind it, every box that actually wears the
   style, and on request everything else, one colour per kind. */
.dg-real{position:absolute;border:1px solid rgba(240,168,72,.55);
  border-radius:3px;background:rgba(240,168,72,.07);pointer-events:none;
  overflow:hidden;}
/* T279: a box that WEARS this style and no longer keeps to it. Two
   channels, not one -- double-weight border and a corner badge -- so it
   survives a colour-blind reader and the light theme. (T367 removed the
   amber-dashed prototype it also had to differ from.) */
.dg-real.dg-off{border-width:2px;border-style:solid;
  border-color:rgba(240,168,72,.95);
  background:color-mix(in srgb,#f0a848 16%,transparent);}
.dg-real.dg-off::after{content:"!";position:absolute;top:-1px;right:2px;
  font:700 9px var(--sans);color:var(--warning);line-height:1;}
.dg-offnote{margin-top:6px;font-family:var(--mono);font-size:10px;
  letter-spacing:.06em;color:var(--warning);}
.dg-offnote[hidden]{display:none!important;}
.dg-other{position:absolute;border:1px dashed currentColor;
  border-radius:3px;opacity:.55;pointer-events:none;
  border-color:#8aa0b0;overflow:hidden;}
.dg-key{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin:0 0 12px;font-family:var(--sans);font-size:11.5px;
  color:var(--chrome-ink-2);}
.dg-keyck{display:inline-flex;align-items:center;gap:6px;cursor:pointer;}
.dg-keyit{display:inline-flex;align-items:center;gap:5px;}
.dg-keyit::before{content:"";width:11px;height:11px;border-radius:3px;
  border:1px dashed var(--dg-kc,#8aa0b0);}
/* WHERE THEY ARE, GROUPED (2026-09-07). One row per place, its count,
   and the slides in it as chips you can press. */
.dg-place{flex:1 0 100%;display:flex;flex-wrap:wrap;align-items:baseline;
  gap:4px 8px;padding:4px 0;border-top:1px solid #ffffff12;}
/* T367: the group you picked, and the rows it owns */
.dg-place.on{border-color:var(--cyan);
  background:color-mix(in srgb,var(--accent) 10%,transparent);}
.dg-placehead.on{color:var(--cyan);}
.dgt-c.dgt-inplace{background:color-mix(in srgb,var(--accent) 12%,transparent);}
.dg-placehead{font-size:11px;opacity:.85;flex:0 0 auto;}
.dg-placeslides{display:flex;align-items:center;flex-wrap:wrap;gap:3px;}
.dg-placeslides-label{margin-right:3px;color:var(--chrome-ink-3);}
.dg-slidechip{font-family:var(--mono);font-size:10px;line-height:1;
  padding:2px 5px;border-radius:4px;cursor:pointer;color:var(--chrome-ink-2);
  background:none;border:1px solid var(--border-strong,#ffffff26);}
.dg-slidechip:hover{border-color:color-mix(in srgb,var(--accent) 55%,
  transparent);background:color-mix(in srgb,var(--accent) 14%,
  transparent);color:var(--chrome-ink);}
/* the board's own bubble: what is under the pointer, and a way there */
.dg-bub{position:absolute;z-index:30;min-width:120px;max-width:230px;
  display:flex;flex-direction:column;gap:2px;padding:4px;
  background:var(--chrome-2,#16273a);border:1px solid #ffffff2e;
  border-radius:7px;box-shadow:0 10px 26px #0009;}
/* display:flex was beating the hidden attribute, so an EMPTY bubble sat
   over the key's checkbox from the moment the board was drawn (the
   "Show everything else" label had a box through it, 2026-09-12) */
.dg-bub[hidden]{display:none!important;}
.dg-bubline{text-align:left;font-family:var(--sans);font-size:11px;
  line-height:1.25;padding:3px 6px;border-radius:4px;cursor:pointer;
  color:var(--chrome-ink);background:none;border:1px solid transparent;}
.dg-bubline:hover{background:color-mix(in srgb,var(--accent) 18%,
  transparent);border-color:color-mix(in srgb,var(--accent) 45%,
  transparent);color:var(--chrome-ink);}
.dg-bubmore{font-size:10px;opacity:.7;padding:0 6px 2px;}
.dg-keyit.dg-keymine::before{border:2px solid var(--amber,#f0a848);
  background:rgba(240,168,72,.18);}
/* the table's boxes were as wide as their column; a percentage never
   needs five digits */
.dgt-n{max-width:74px;}
.dgt-tx{width:100%;min-width:0;height:24px;padding:0 6px;
  box-sizing:border-box;font-family:var(--sans);font-size:12px;
  color:#e8f1f8;background:#ffffff0d;border:1px solid #ffffff22;
  border-radius:5px;}
.dgt-tx:focus{border-color:var(--cyan);outline:none;}
.dgt-lab{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  color:var(--chrome-ink-2);}
body.light .dgt-tx{background:var(--input-bg);border-color:var(--border-strong);
  color:var(--ink);}
body.light .dg-grp{background:var(--surface-hover);
  border-color:var(--line);}

/* ---- T229: THE OBJECT'S HISTORY IS A TABLE ----------------------------
   Four columns -- when, what changed, what it looked like, and the way
   back -- because a stack of cards made every state look like an event
   rather than a row you compare against its neighbours. A big object's
   preview is a button: a 38px schematic of a table says nothing. */
.oh-head,.oh-row{display:grid;
  grid-template-columns:96px minmax(0,1fr) 76px 78px;
  align-items:center;gap:9px;padding:6px 12px;}
.oh-head{font-family:var(--sans);font-size:11px;font-weight:600;
  color:var(--chrome-ink-2);border-bottom:1px solid #ffffff1c;position:sticky;top:0;
  background:var(--chrome-2,#16273a);z-index:1;}
.oh-row{border-left:3px solid transparent;border-bottom:1px solid #ffffff10;}
.oh-row.oh-open{grid-template-rows:auto auto;}
.oh-c{min-width:0;}
.oh-when{font-family:var(--sans);font-size:11.5px;color:var(--chrome-ink-2);}
.oh-look{display:flex;align-items:center;}
.oh-act{display:flex;justify-content:flex-end;}
.oh-prev{font-size:11px;padding:3px 8px;}
.oh-big{grid-column:1/-1;width:100%;max-height:none;height:150px;
  margin-top:6px;}
.img-ov .oh-head,.img-ov .oh-row{grid-template-columns:130px minmax(0,1fr)
  96px 96px;}
.img-ov .oh-list{display:block;}
body.light .oh-head{background:var(--chrome-2);}

/* ---- T228: THUMBNAILS MEANS THUMBNAILS ---------------------------------
   The strip's Thumbnails view still printed every slide's title beside
   the picture, which is what "Thumbnails and headings" is for
   (2026-09-03, user: "I don't know why the thumbnails only view for a
   slide has the title still"). */
#film-list[data-fv="thumb"] .film-t{display:none;}
/* ...and the current slide keeps its name, because that row is the
   inline editor and the name is its heading */
#film-list[data-fv="thumb"] .film-row.current .film-t{display:block;}

/* ---- T227: KINDS OF BULLET, KINDS OF NUMBERING ----------------------
   A text box's markers are its paragraphs' (T623, above). These are the
   levels of a list in a MARKDOWN box, which notesHtml draws as ul/ol. */
.an-tx.an-md li{margin:.18em 0;white-space:pre-wrap;}
/* (descendants, not children) */
.an-tx.an-md ul ul,
.an-tx.an-md ol ul{list-style:circle;margin:0;padding-left:1.5em;}
.an-tx.an-md ul ul ul,
.an-tx.an-md ol ul ul{list-style:square;}
.an-tx.an-md ol ol,
.an-tx.an-md ul ol{list-style:lower-alpha;margin:0;
  padding-left:1.25em;}
.an-tx.an-md ol ol ol,
.an-tx.an-md ul ol ol{list-style:lower-roman;}
/* text reads as draggable, and only turns into a text cursor once you are
   actually typing in it */
.deck.editing .an-text,.deck.editing .an-title{cursor:move;}
.deck.editing .an-item.an-editing{cursor:auto;}
.deck.editing .an-item.an-editing .an-tx{cursor:text;}
.an-handle{cursor:move;color:var(--chrome-ink-2);font-size:.65em;flex:none;
  user-select:none;margin-top:.3em;}
.an-handle:hover{color:#fff;}
.an-arrow-line{fill:none;}
.an-arrow-line.sel{filter:drop-shadow(0 0 5px color-mix(in srgb,var(--accent) 80%,transparent));}
.an-arrow-hit{stroke:transparent;stroke-width:16;fill:none;}
.deck.editing .an-arrow-hit{cursor:move;}
/* z-index 6, above the arrows' svg (5): while editing an arrow's grab
   path is up there (T585), and one attached at an edge would otherwise
   sit on that edge's handle */
/* the grips are the EDITOR's, so their ring and face are the app
   scheme's chrome, read on the stage -- inside a .slide the chrome
   palette is pinned to the page's (T626), and a Light-scheme grip lost
   its white ring on a navy slide */
.deck-stage{--grip-ring:var(--chrome-0,#0b141d);--grip-face:var(--chrome-1,#0e1926);}
/* ...and their colour, on a dark page under a light scheme: the light
   schemes' accents are dark (they are inks on paper), so the selection
   outline and the grips went #0e6174 on navy, 2.6:1. The same accent's
   soft tone reads there (6.6:1). And the mirror: a dark scheme's accent
   is pale, so on a white slide the outline was #58c4db, 2.0:1 (1.5:1 in
   High contrast dark); its deep tone reads there. Editing only, and the
   one slide on the stage: the show draws no marks. */
body.light .deck.editing .deck-stage .slide:not(.page-light){
  --accent:var(--accent-soft);}
body:not(.light) .deck.editing .deck-stage .slide.page-light{
  --accent:var(--accent-deep);}
.an-resize{position:absolute;width:15px;
  height:15px;border-radius:4px;background:var(--cyan);
  border:2px solid var(--grip-ring,#0b141d);display:none;z-index:6;}
.an-rs-se{right:-7px;bottom:-7px;cursor:nwse-resize;}
.an-rs-nw{left:-7px;top:-7px;cursor:nwse-resize;}
.an-rs-ne{right:-7px;top:-7px;cursor:nesw-resize;}
.an-rs-sw{left:-7px;bottom:-7px;cursor:nesw-resize;}
/* THE FOUR SIDES (T65). Drawn as BARS rather than squares so which axis
   a handle owns is readable without hovering for the cursor -- and so
   they cannot be mistaken for the corner grips at a glance. These rules
   must stay AFTER .an-resize, whose 15px square they override. */
.an-rs-n,.an-rs-s{left:50%;margin-left:-11px;width:22px;height:9px;
  cursor:ns-resize;}
.an-rs-e,.an-rs-w{top:50%;margin-top:-11px;width:9px;height:22px;
  cursor:ew-resize;}
.an-rs-n{top:-4px;}
.an-rs-s{bottom:-4px;}
.an-rs-w{left:-4px;}
.an-rs-e{right:-4px;}
.an-item.sel .an-resize{display:block;}
/* T584: a small selected thing (paintSel, under 48px) keeps its middle
   for moving: no side bars, and the corners stand clear of it */
.an-item.sel.an-small .an-rs-n,.an-item.sel.an-small .an-rs-s,
.an-item.sel.an-small .an-rs-e,.an-item.sel.an-small .an-rs-w{display:none;}
.an-item.an-small .an-rs-se{right:-16px;bottom:-16px;}
.an-item.an-small .an-rs-nw{left:-16px;top:-16px;}
.an-item.an-small .an-rs-ne{right:-16px;top:-16px;}
.an-item.an-small .an-rs-sw{left:-16px;bottom:-16px;}
/* free-rotation grip above the item (drag; Shift snaps to 15 deg) */
.an-rotate{position:absolute;top:-30px;left:50%;margin-left:-8px;
  width:16px;height:16px;border-radius:50%;background:var(--grip-face,#0e1926);
  border:2px solid var(--cyan);cursor:grab;display:none;z-index:6;}
.an-rotate::after{content:"";position:absolute;left:50%;top:100%;
  width:2px;height:11px;background:var(--cyan);margin-left:-1px;}
.an-item.sel .an-rotate{display:block;}
/* T697: a corner's rotate zone, outside its resize grip, the cursor a
   turning arrow */
.an-rotz{position:absolute;width:18px;height:18px;display:none;z-index:5;
  cursor:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 22 22'><path d='M5 12a6.5 6.5 0 1 1 6.5 6.5' fill='none' stroke='black' stroke-width='3.6' stroke-linecap='round'/><path d='M5 12a6.5 6.5 0 1 1 6.5 6.5' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'/><path d='M1.6 9.6 5 14.2 8.4 9.6z' fill='white' stroke='black' stroke-width='1'/></svg>") 11 11,alias;}
.an-item.sel .an-rotz{display:block;}
.an-rotz-nw{left:-24px;top:-24px;}
.an-rotz-ne{right:-24px;top:-24px;}
.an-rotz-se{right:-24px;bottom:-24px;}
.an-rotz-sw{left:-24px;bottom:-24px;}
.an-item.an-small .an-rotz-nw{left:-34px;top:-34px;}
.an-item.an-small .an-rotz-ne{right:-34px;top:-34px;}
.an-item.an-small .an-rotz-se{right:-34px;bottom:-34px;}
.an-item.an-small .an-rotz-sw{left:-34px;bottom:-34px;}
.annot-layer.an-fitting .an-rotz,
.deck.editing .an-item.grpsel .an-rotz{display:none!important;}
/* T717: two rows of three tiles wide enough for "Rotate right 90°" on a
   line, and the angle row across all three columns under them */
#fmt-rot-menu{width:300px;}
.rot-deg{grid-column:1/-1;display:flex;align-items:center;gap:8px;
  padding:7px 4px 3px 6px;
  margin-top:3px;border-top:1px solid var(--chrome-line,#ffffff1a);
  font-size:12.5px;color:var(--chrome-ink);white-space:nowrap;}
.rot-deg-l{display:flex;align-items:center;gap:6px;}
.rot-deg-0{margin-left:auto;gap:5px;}
.rot-deg-n{width:64px;font:inherit;font-size:12.5px;padding:2px 4px 2px 6px;
  border:1px solid var(--chrome-line);border-radius:5px;
  background:var(--chrome-1,#0f1b26);color:var(--chrome-ink);}
/* T-review 2026-10-08: never measured as part of a box (fitTexts) */
.annot-layer.an-fitting .an-resize,
.annot-layer.an-fitting .an-rotate{display:none!important;}
.deck.editing .an-item.grpsel .an-rotate{display:none!important;}
.an-endpt{position:absolute;width:15px;height:15px;
  margin:-7.5px 0 0 -7.5px;border-radius:50%;background:var(--cyan);
  border:2px solid var(--grip-ring,#0b141d);display:none;z-index:6;
  pointer-events:none;}
.deck.editing .an-endpt.sel{display:block;pointer-events:auto;
  cursor:grab;}

/* movable title / subtitle on title slides */
.an-title{color:var(--tk-heading,#f0f6fa);}
/* T480: a text box wearing a heading style reads the same token */
.an-text.an-head{color:var(--tk-heading,#f0f6fa);}
.page-light .an-text.an-head{color:var(--tk-heading,#16222c);}
   /* default lives HERE so .page-light can win; T455 lets the deck's
      Heading text colour override it when one has been chosen */
.an-title{position:absolute;transform:translate(-50%,-50%);
  max-width:88%;text-align:center;display:flex;gap:.4em;
  align-items:flex-start;justify-content:center;
  font-family:var(--tk-sfont,var(--sans));line-height:1.2;}
/* T626: a title slide's title wears the Title style's face, and its
   subtitle the Subtitle's (--tk-tfont / --tk-sfont, slideContext) */
.an-title.t-main{font-family:var(--tk-tfont,var(--sans));}
/* A TITLE'S DESIGNED WEIGHT, and no more than that. This rule sits on
   the inner span, so it beat the weight the renderer writes on the .an-
   title div — Bold changed the model and nothing on screen, and a title
   looked bold whatever you did (2026-08-29, user: "text always seems to
   revert to bold"). 600 is still what a title looks like when nobody has
   said otherwise; --ttl-w is set only once you have touched Bold. */
.an-title.t-main .an-tx{font-weight:var(--ttl-w,600);
  letter-spacing:-.018em;}
.slide-titlefree .ttl-eyebrow{position:absolute;top:7%;left:0;right:0;
  text-align:center;font-family:var(--mono);font-size:11px;
  letter-spacing:.24em;text-transform:uppercase;color:var(--sl-accent);}

/* notebook-cell frames */
/* T456: a notebook frame is a BOX, and "Box background" is the deck
   colour for one -- it governed the text box and not this, which is the
   most box-shaped thing on a slide. Same bargain as T455: the chrome
   colour stays the default, --tk-surface answers when one is chosen. */
/* T465: the frame's edge, like the text box's, is "Lines and edges"
   once that is chosen; the accent tint stays its default */
.an-cell{position:absolute;
  background:var(--tk-surface,var(--chrome-1,#0e1926));
  border:1.5px solid var(--tk-line,color-mix(in srgb,var(--sl-accent,var(--accent)) 36%,transparent));border-radius:var(--tk-rad,10px);overflow:hidden;
  display:flex;flex-direction:column;}
/* edit mode: an UNSELECTED frame is just its content — transparent (so it
   never blocks what's behind), no border, no title header. The border, title,
   Replace and part-picker all return only when the frame is SELECTED, so you
   can read the slide as it will present. */
.deck.editing .an-cell{cursor:move;background:none;border-color:transparent;}
.deck.editing .an-cell.sel{border-color:var(--cyan);background:color-mix(in srgb,var(--chrome-0,#0b141d) 53%,transparent);}
/* light pages: the placeholder/selected frame washes must flip too —
   these outrank the dark rules above by the extra .page-light class
   (2026-08-05: white posters showed navy placeholder boxes) */
.deck.editing .page-light .an-cell.sel{background:#ffffffd0;}
.deck.editing .page-light .an-cell.empty{background:#00000008;
  border-color:#00000030;}
/* an EMPTY frame keeps its dashed dark placeholder box (a card goes here) */
.deck.editing .an-cell.empty{background:color-mix(in srgb,var(--chrome-1,#0e1926) 60%,transparent);border-color:color-mix(in srgb,var(--accent) 36%,transparent);}
/* the title header is an OVERLAY (out of flow) shown only when selected, so
   selecting a frame never reflows/shrinks the figure underneath it */
.deck.editing .an-cell .an-cellhead,
.pane.filled .an-cellhead{position:absolute;top:0;left:0;right:0;z-index:2;
  display:none;padding:7px 30px 10px 12px;
  background:linear-gradient(color-mix(in srgb,var(--chrome-0,#0b141d) 88%,transparent),color-mix(in srgb,var(--chrome-0,#0b141d) 0%,transparent));}
.deck.editing .an-cell.sel .an-cellhead,
.pane.filled.active .an-cellhead{display:flex;}
.deck:not(.editing) .an-cell.empty{display:none;}
/* clean playback: a frame is just its content — no header title, no
   badge, no frame border (the editor/builder keep them for orientation) */
.vpage .an-cell{border:none;background:none;}
.vpage .an-cellhead{display:none;}
/* playback: a framed cell is just its content (no dark card box / cyan border),
   so a shape-crop reads as the shape even on slides without a code trace */
.deck:not(.editing) .deck-stage .an-cell{border:none;background:none;}
.deck:not(.editing) .deck-stage .an-cellhead{display:none;}
.an-cellhead{flex:none;display:flex;align-items:center;gap:8px;
  padding:8px 30px 0 12px;min-width:0;}
.an-cellhead-t{font-size:13px;font-weight:600;color:#dbe7ef;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;
  min-width:0;}
.an-cellcap{flex:none;font-family:var(--serif);font-size:12.5px;
  color:var(--chrome-ink);padding:0 12px 9px;margin:0;overflow:hidden;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;}
.an-cell .cardbody{flex:1;min-height:0;display:flex;
  flex-direction:column;padding:8px;}
/* the .cb-fig figure-part wrapper must pass the flex height through in slide
   frames, else .figframe's flex:1 fit-to-frame sizing is inert and plots clip */
.an-cell .cb-fig,.spane .cb-fig,.slide-fig .cb-fig{flex:1;min-height:0;
  display:flex;flex-direction:column;}
.an-cell .figframe{flex:1;min-height:0;display:flex;
  align-items:center;justify-content:center;overflow:hidden;
  border:none;padding:6px;}
/* a frame wider/taller than its figure shows TRANSPARENT space around
   the plot, not a white box (the plot keeps its own background) */
.an-cell .figframe,.spane .figframe{background:none;}
.an-cell .figframe+.figframe{border-top:1px solid #ffffff10;}
.an-cell .figpager{flex:1;min-height:0;display:flex;
  flex-direction:column;}
.an-cell .figpager .figpage{display:none;}
.an-cell .figpager .figpage.current{flex:1;min-height:0;display:flex;
  flex-direction:column;}
.an-cell .fp-btn{background:transparent;border-color:#ffffff22;
  color:#cdd9e3;}
.an-cell .fp-count{color:var(--chrome-ink-2);}
.an-cell .cardbody.mdclamp,.spane .cardbody.mdclamp{max-height:none;}
.an-cell .cardbody.mdclamp::after,
.spane .cardbody.mdclamp::after{display:none;}
.spane .figpager{flex:1;min-height:0;display:flex;
  flex-direction:column;}
.spane .figpager .figpage.current{flex:1;min-height:0;display:flex;
  flex-direction:column;}
.an-cell .figframe img{max-width:100%;max-height:100%;width:auto;
  height:auto;object-fit:contain;margin:0;}
/* a FIGURE frame is just the plot: no inner padding, and after render the
   frame snaps to the image's aspect ratio (snapFigAspect) — so the selection
   outline and resize handle sit exactly on the plot, with no letterbox gap
   and no title header (the tooltip + Locate in notebook carry its name) */
.an-cell.an-figonly{border-radius:4px;}
.an-cell.an-figonly .cardbody{padding:0;}
.an-cell.an-figonly .figframe{padding:0;}
/* the frame already matches the plot's aspect, so filling it (up- OR
   down-scaling) keeps the plot edge-to-edge under the outline */
.an-cell.an-figonly .figframe img{width:100%;height:100%;
  max-width:none;max-height:none;object-fit:contain;}
.an-cell .note{flex:1;min-height:0;overflow:auto;
  background:var(--nb-bg,var(--output-paper));
  color:var(--nb-tx,var(--output-ink-2));border-radius:6px;padding:10px 14px;
  font-size:13px;}
/* Auto-generated decks are for presenting prose, not inspecting notebook
   cards. At the 1280x720 reference 28px is 21pt: the same Body default as
   a new text box. Remove the notebook-card paper, padding and scroll frame
   so a markdown cell reads as slide copy; its measured box is chosen by
   autoDeckBuild at this line height. Selection chrome still wins in edit. */
.an-cell.an-auto-note{background:transparent;border-color:transparent;}
.an-auto-note .cardbody{padding:0;}
.an-auto-note .note{overflow:hidden;background:transparent;color:#fff;
  border-radius:0;padding:0 4px;font-size:28px;line-height:1.35;}
.an-auto-note .note *{color:inherit;}
/* a recoloured markdown card carries its text colour to every child
   (headings, lists, bold) so the whole note reads in the chosen colour */
.an-cell[style*="--nb-tx"] .note,
.an-cell[style*="--nb-tx"] .note *{color:var(--nb-tx);}
/* T626 review: A NOTE ON A SLIDE IS THE SLIDE'S, NEVER THE READER'S.
   app.css keeps body:not(.light) .note (0,2,1) for custom views, and it
   outranked every note rule here: under the Dark app scheme a note frame
   was the reader's #c4d0da on its white paper (1.5:1), and a markdown
   cell placed as slide copy ignored Body text. A frame's words are its
   paper's ink (#1b2733 on a light page, as before); slide copy is the
   deck's Body text, on either page. A table in a note takes its rules
   from its words, for the same reason (the reader's dark rule made them
   white on the white frame). */
.slide :is(.an-cell,.slide-fig,.spane) .note,.mini-diagram .an-cell .note{
  color:var(--nb-tx,var(--output-ink-2));}
.page-light .an-cell .note{color:var(--nb-tx,#1b2733);}
.slide .an-auto-note .note,.mini-diagram .an-auto-note .note{
  color:var(--nb-tx,var(--tk-ink,#fff));}
.page-light .an-auto-note .note{color:var(--nb-tx,var(--tk-ink,#1b2733));}
/* ...and a caption in it is the note's words (body:not(.light) .note
   .caption, 0,3,1, gave it the reader's ink as well) */
.slide :is(.an-cell,.slide-fig,.spane) .note .caption,
.mini-diagram .an-cell .note .caption{color:inherit;}
.slide :is(.an-cell,.slide-fig,.spane) .note :is(th,td),
.mini-diagram .an-cell .note :is(th,td){
  border-color:color-mix(in srgb,currentColor 22%,transparent);}
.slide :is(.an-cell,.slide-fig,.spane) .note th,
.mini-diagram .an-cell .note th{
  background:color-mix(in srgb,currentColor 6%,transparent);}
.an-cell .jv-xr,.an-cell pre.result,.an-cell pre.stream{
  overflow:auto;min-height:0;}
.an-cell.empty{align-items:center;justify-content:center;
  border-style:dashed;background:color-mix(in srgb,var(--chrome-1,#0e1926) 60%,transparent);}
.an-cellpick{background:none;border:none;color:#7fb6c6;
  font-family:var(--mono);font-size:11px;letter-spacing:.05em;
  cursor:pointer;padding:14px;text-align:center;line-height:1.5;}
.an-cellpick:hover{color:#fff;}
.an-cellbtn{position:absolute;top:5px;right:5px;z-index:3;display:none;
  background:color-mix(in srgb,var(--chrome-1,#0e1926) 93%,transparent);border:1px solid color-mix(in srgb,var(--accent) 40%,transparent);border-radius:6px;
  color:#7fd0e0;font-family:var(--sans);font-size:11px;padding:4px 9px;
  cursor:pointer;}
/* Replace shows only for the SELECTED frame (not on hover) — declutter */
.deck.editing .an-cell.sel .an-cellbtn{display:block;}
.an-cellbtn:hover{color:#fff;border-color:var(--cyan);}
/* which part of a cell a frame shows: code / figure / output */
.an-cellpart{font-family:var(--mono);font-size:9px;letter-spacing:.08em;
  text-transform:uppercase;color:#7fb6c6;background:color-mix(in srgb,var(--accent) 13%,transparent);
  border-radius:4px;padding:1px 6px;flex:none;}
/* the code/figure/output picker sits along the BOTTOM of the frame so
   it never covers the title header or the part badge at the top */
.cellparts{position:absolute;bottom:5px;left:5px;right:5px;z-index:5;
  display:none;gap:3px;flex-wrap:wrap;justify-content:center;}
/* the part-picker shows only for the SELECTED frame (not on hover) */
.deck.editing .an-cell.sel .cellparts,
.pane.filled.active .cellparts{display:flex;}
.cellpartbtn{font-family:var(--sans);font-size:11px;letter-spacing:0;
  background:color-mix(in srgb,var(--chrome-1,#0e1926) 93%,transparent);border:1px solid #ffffff2b;border-radius:5px;
  color:var(--chrome-ink);padding:3px 7px;cursor:pointer;line-height:1;}
.cellpartbtn.on{background:var(--cyan-deep);border-color:var(--cyan-deep);
  color:var(--on-accent-deep,#fff);}
.cellpartbtn:hover{border-color:var(--cyan);color:var(--chrome-ink);}
.cellpartbtn.split{color:var(--chrome-ink-2);}
/* the same part-picker, hosted in the top ribbon's Object group */
.rbn-partslot{display:inline-flex;align-items:center;}
.rbn-partslot[hidden]{display:none;}
#fmt-parts .cellparts{position:static;display:inline-flex;gap:6px;
  flex-wrap:nowrap;bottom:auto;left:auto;right:auto;z-index:auto;}
/* in the ribbon the figure/code/output/split pills dress like every other
   ribbon button — same face, same size */
#fmt-parts .cellpartbtn{font-family:var(--sans);font-size:12px;
  letter-spacing:normal;background:var(--rbn-btn,#ffffff0a);
  border:1px solid var(--rbn-btn-bd,#ffffff22);
  border-radius:6px;color:var(--chrome-ink,#cdd9e3);padding:0 9px;
  height:var(--rbn-btn-h,26px);line-height:normal;
  display:inline-flex;align-items:center;gap:5px;}
#fmt-parts .cellpartbtn .bic{width:14px;height:14px;vertical-align:0;}
#fmt-parts .cellpartbtn:hover{border-color:var(--cyan);color:var(--chrome-ink);}
#fmt-parts .cellpartbtn.on{background:var(--cyan-deep);
  border-color:var(--cyan-deep);color:var(--on-accent-deep,#fff);}
/* the Layouts dropdown: the whole template catalog, off the panel and
   into a ribbon menu */
/* T212: the Change layout gallery is the one tile, wrapped, no scrollbar */
.sh-menu.lay-menu{display:block;width:580px;max-height:none;
  overflow:visible;padding:8px;}
.lay-menu .lay-picker{margin:0;display:flex;flex-wrap:wrap;gap:6px;
  max-height:none;overflow:visible;}
.lay-menu .lay-picker .dbtn.lay{flex:0 0 var(--rbn-tile-w);
  width:var(--rbn-tile-w);height:var(--rbn-tile-h);
  padding:3px 3px;align-items:center;}
.lay-menu .lay-picker .layico2{width:calc(var(--rbn-tile-w) - 22px);}
/* catalog section headings (Slide layouts / Poster layouts) */
.lay-sec{grid-column:1/-1;font-family:var(--mono);font-size:9px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--chrome-ink-3);
  padding:7px 2px 1px;}
.lay-sec:first-child{padding-top:1px;}

/* picking a card for a cell frame */
.pickbar{position:fixed;top:var(--chrome-h);left:var(--presrail-w);
  right:0;z-index:99;background:var(--cyan-deep);
  color:var(--on-accent-deep,#fff);
  padding:9px 16px;font-size:13px;display:flex;gap:12px;
  align-items:center;box-shadow:0 6px 24px #00000055;}
.pickbar[hidden]{display:none;}
.pickbar .dbtn{border-color:#ffffff55;color:var(--on-accent-deep);}
body.picking .card{cursor:copy;}
body.picking .card:hover{outline:2px solid #fff;outline-offset:2px;}
/* the armed-match bar is a SIBLING of .deck, like the pickbar and every
   other overlay here — and .deck is fixed at z-index 100, so this has to
   be fixed and above it or it renders underneath the editor it is
   describing. It covers the thin top bar for the duration, which is
   honest: you are standing in a mode. */
.matchbar{position:fixed;top:0;left:0;right:0;z-index:150;}
.matchbar .dc-menu{max-height:min(64vh,460px);overflow-y:auto;
  min-width:230px;right:0;left:auto;}
.mp-head{display:flex;gap:5px;padding:2px 4px 6px;}
.mp-b{padding:2px 8px;font-size:10.5px;}
.mp-menu .find-ck{padding:2px 5px;border-radius:5px;color:var(--chrome-ink);}
.mp-menu .find-ck:hover{background:#ffffff0d;}
/* while a match is armed the canvas is a PICKER: say so with the cursor,
   and light up whatever is under the pointer so it is obvious what the
   next click will take */
.deck.matching .annot-layer{cursor:copy;}
.deck.matching .an-item:hover{outline:2px solid var(--cyan);
  outline-offset:2px;}
.ms-box{width:min(560px,94vw);}

/* the three spacing presets are a segmented run in the ribbon (T219):
   a three-column grid had put the caption in a column of its own and
   wrapped Airy under it */

/* ---------- arrangements ----------
   Each row shows what it would arrange TO, drawn by the same miniDiagram
   the film strip uses, so the preview cannot drift from the canvas. */
.ar-box{width:min(880px,95vw);}
/* the one thing you can do with an empty library sits under it, as a
   button the width of the column (T219) */
.ar-savebtn{display:flex;align-items:center;justify-content:center;gap:7px;
  margin-top:6px;}
.ar-lib,.ar-sug{overflow-y:auto;max-height:52vh;padding-right:3px;}
.ar-row{display:flex;align-items:center;gap:8px;padding:5px 4px;
  border-radius:7px;}
.ar-row:hover{background:#ffffff0d;}
.ar-th{flex:none;width:92px;}
.ar-th .mini-diagram{width:92px;height:52px;min-height:0;}
.ar-mid{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;}
.ar-name{background:none;border:1px solid transparent;color:#dce6ee;
  font-size:12px;font-family:var(--sans);border-radius:5px;padding:2px 5px;
  outline:none;width:100%;box-sizing:border-box;}
.ar-name:hover{border-color:#ffffff1f;}
.ar-name:focus{border-color:var(--cyan);background:var(--chrome-0,#0b141d);}
.ar-sub{font-family:var(--sans);font-size:11px;color:var(--chrome-ink-2);
  padding-left:6px;}
.ar-row:hover .fp-ctr{display:flex;}
.ar-srow{display:flex;align-items:center;gap:6px;padding:3px 4px;
  border-radius:5px;}
.ar-srow:hover{background:#ffffff0d;}
.ar-st{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
.ar-ssel{flex:none;max-width:46%;font-size:11px;padding:2px 4px;
  border-radius:5px;background:var(--chrome-1,#0e1926);
  border:1px solid #ffffff26;color:#dce6ee;font-family:var(--sans);}
body.light .ar-name{color:var(--ink);}
body.light .ar-name:focus{background:var(--input-bg);}
body.light .ar-ssel{background:var(--input-bg);
  border-color:var(--border-strong);
  color:var(--ink);}
body.light .ar-row:hover,body.light .ar-srow:hover{
  background:var(--surface-hover);}

/* ---------- style sets ----------
   A gallery, not a menu: every card is SET IN the type it offers, because
   a look is chosen by looking (2026-08-22). */
.ss-box{width:min(880px,95vw);}
/* T317: a ready-made look reads as an offer, not a thing you already
   have -- dotted edge, and the note where the point size would be */
.jv-preset{border-style:dashed;opacity:.92;}
.jv-preset:hover{opacity:1;}
/* T315: the two bands of the gallery, and a theme card's palette */
.ss-band{font-family:var(--sans);font-size:11px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--chrome-ink-3);margin:10px 0 4px;}
/* T595: the colour band's own switch, under its label */
.ss-bgck{margin:0 0 7px;width:max-content;gap:6px;cursor:pointer;
  font-size:12px;}
.ss-chips{display:flex;gap:4px;padding:6px;border-radius:6px;margin:6px 0;}
.ss-chip{flex:1 1 0;height:14px;border-radius:3px;
  border:1px solid #00000033;}
.ss-tspec{padding:6px 8px;border-radius:6px;font-family:var(--sans);
  font-size:12px;line-height:1.5;}
.ss-grid{display:grid;gap:9px;overflow-y:auto;max-height:62vh;
  grid-template-columns:repeat(auto-fill,minmax(200px,1fr));
  padding:1px;}
.ss-card{position:relative;text-align:left;display:flex;
  flex-direction:column;gap:7px;padding:11px 12px 10px;cursor:pointer;
  background:var(--chrome-0,#0b141d);border:1px solid #ffffff1f;
  border-radius:9px;color:#dce6ee;font-family:var(--sans);}
.ss-card:hover{border-color:var(--cyan);
  background:color-mix(in srgb,var(--accent) 8%,var(--chrome-0,#0b141d));}
.ss-name{font-family:var(--mono);font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent);display:flex;
  align-items:center;gap:6px;}
.ss-mine{font-size:10px;letter-spacing:.06em;padding:1px 6px;
  border-radius:8px;background:#ffffff14;color:var(--chrome-ink-2);}
/* T470: the card just saved, lit for a moment */
.ss-card.ss-new{border-color:var(--accent,var(--cyan));
  box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 45%,transparent);
  transition:box-shadow .5s,border-color .5s;}
.ss-spec{display:flex;flex-direction:column;gap:3px;min-height:82px;
  overflow:hidden;}
.ss-line{line-height:1.2;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
.ss-note{font-size:10.5px;line-height:1.4;color:var(--chrome-ink-2);}
.ss-del{position:absolute;top:6px;right:7px;font-size:10px;color:var(--chrome-ink-2);
  padding:2px 4px;border-radius:4px;}
.ss-del:hover{background:var(--surface-active);color:var(--chrome-ink);}
body.light .ss-card{background:var(--chrome-1,#f4f7fa);
  border-color:var(--line);color:var(--ink);}
body.light .ss-note{color:var(--ink-3);}
body.light .mp-menu .find-ck{color:var(--ink);}
body.light .mp-menu .find-ck:hover{background:var(--surface-hover);}

/* pane editor: the current slide as clickable regions */
/* the current slide's interactive editor — the single big view in the
   merged slides list (fills the width; drag the panel edge to resize) */
.pane-editor{aspect-ratio:var(--page-ar,16/9);display:grid;gap:6px;
  background:var(--chrome-0,#0b141d);
  border:1px solid #ffffff22;border-radius:8px;padding:6px;
  margin:0;width:100%;overflow:hidden;}
.pane-editor.full{grid-template-columns:1fr;grid-template-rows:1fr;}
.pane-editor.halves{grid-template-columns:1fr 1fr;grid-template-rows:1fr;}
.pane-editor.quarters{grid-template-columns:1fr 1fr;
  grid-template-rows:1fr 1fr;}
.pane{position:relative;background:var(--chrome-4,#12202e);border:1px dashed #ffffff26;
  border-radius:6px;cursor:pointer;display:flex;align-items:center;
  justify-content:center;padding:6px 18px 6px 8px;overflow:hidden;
  transition:border-color .15s,background .15s;}
/* a filled frame shows the ACTUAL slide content (an .an-cell fills it),
   so the builder preview is exactly what will be presented */
.pane.filled{padding:0;background:none;border:none;overflow:visible;}
.pane.filled .an-cell{position:absolute;inset:0;width:auto;height:auto;
  cursor:pointer;pointer-events:none;}
.pane.active{outline:2px solid var(--cyan);outline-offset:1px;}
.pane.empty.active{border-color:var(--cyan);border-style:solid;
  background:color-mix(in srgb,var(--accent) 9%,transparent);box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 30%,transparent) inset;}
.pane.empty.active .pane-t{color:var(--cyan);}
.pane-t{font-size:10.5px;line-height:1.35;color:var(--chrome-ink);text-align:center;
  overflow:hidden;display:-webkit-box;-webkit-line-clamp:3;
  -webkit-box-orient:vertical;}
.pane.empty .pane-t{color:var(--chrome-ink-3);font-family:var(--mono);font-size:9.5px;
  letter-spacing:.1em;text-transform:uppercase;}
.pane-x{position:absolute;top:3px;right:3px;z-index:4;background:color-mix(in srgb,var(--chrome-1,#0e1926) 80%,transparent);
  border:1px solid #ffffff22;border-radius:5px;color:var(--chrome-ink);
  cursor:pointer;font-size:11px;padding:2px 6px;line-height:1;}
.pane-x:hover{color:var(--chrome-ink);border-color:var(--cyan);}

/* filmstrip: mini slide thumbnails */
.film-list{flex:1;overflow-y:auto;min-height:60px;margin:0 -4px;
  padding:0 4px;}
.film-row{display:flex;align-items:center;gap:4px;border-radius:7px;
  margin-bottom:3px;cursor:grab;}
.film-row.current{background:color-mix(in srgb,var(--accent) 11%,transparent);outline:1px solid color-mix(in srgb,var(--accent) 33%,transparent);
  align-items:flex-start;}
.film-row.dragging{opacity:.45;}
.film-row.drop-above{box-shadow:0 -2px 0 var(--cyan);}
.film-row.drop-below{box-shadow:0 2px 0 var(--cyan);}
.film-label{flex:1;display:flex;align-items:center;gap:9px;background:none;
  border:none;color:var(--chrome-ink);font-size:11.5px;padding:5px 6px;cursor:pointer;
  text-align:left;min-width:0;font-family:var(--sans);}
.film-label .film-t{overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
/* T228: a slide number you can read. It was 9.5px in the mono face
   (2026-09-03, user: "the slide numbers are way too small"). */
.film-label .film-n{font-family:var(--mono);font-size:12.5px;
  color:var(--chrome-ink-2);width:22px;flex:none;text-align:right;}
/* Optional and omitted are words in the strip, not secret state in a
   context menu. Only the thumbnail/title dim: controls and the current
   inline editor stay fully usable (T50). */
.film-marks{display:flex;align-items:center;gap:3px;margin-left:auto;
  flex:none;}
.film-mark{font-family:var(--mono);font-size:7.5px;letter-spacing:.04em;
  line-height:1;padding:2px 4px;border:1px solid currentColor;
  border-radius:8px;white-space:nowrap;}
.film-row.opt .film-mark.opt{color:var(--warning);}
.film-mark.cut{color:var(--chrome-ink-2);}
/* ▸N — this slide has N builds. Deliberately the SAME amber as
   .an-buildno: the strip mark and the on-slide bubbles are one fact
   shown at two zoom levels, and the colour is the only thing tying them
   together once the bubbles are gated behind the pane (T76). */
.film-mark.anim{color:var(--amber);}
.film-row.cut:not(.current) .mini-diagram,
.film-row.cut:not(.current) .film-t,
.film-row.cut:not(.current) .film-n{opacity:.42;}
.film-row.cut{background-image:linear-gradient(90deg,#71879a 0 2px,
  transparent 2px);}
/* T549: FLIPPED CONTENT. The item's box, handles and grip never flip;
   what is drawn inside does -- the picture (or the window onto it), the
   shape, a notebook figure's picture, a book's page, a clip. A text
   box's words are never mirrored (nor are they given the flag). */
.an-item{--an-sx:1;--an-sy:1;}
.an-item.an-flh{--an-sx:-1;}
.an-item.an-flv{--an-sy:-1;}
.an-item.an-flh>.an-imgel,.an-item.an-flv>.an-imgel,
.an-item.an-flh>.an-imgwin,.an-item.an-flv>.an-imgwin,
.an-item.an-flh>.an-shape-svg,.an-item.an-flv>.an-shape-svg,
.an-item.an-flh .cardbody img,.an-item.an-flv .cardbody img,
.an-item.an-flh.an-flip img,.an-item.an-flv.an-flip img,
.an-item.an-flh video,.an-item.an-flv video{
  transform:scale(var(--an-sx),var(--an-sy));}
/* T550: the Corrections window's rows are short; keep them on a line */
.pic-panel .opt-row{flex-wrap:nowrap;}
/* T565: an accessibility finding, and its fix beside it */
.a11y-row{display:flex;flex-direction:column;align-items:stretch;gap:6px;}
.a11y-go{all:unset;cursor:pointer;display:flex;flex-direction:column;
  gap:2px;}
.a11y-fix{align-self:flex-start;height:24px;font-size:12px;}
/* T575: a finger on the editing canvas edits it rather than scrolling
   or zooming the page; presenting, only a sideways swipe is the show's */
.deck.editing .annot-layer{touch-action:none;}
.deck:not(.editing) .deck-stage{touch-action:pan-y pinch-zoom;}
/* T573: the Shapes window's search, in its header */
.strip-all-h{display:flex;align-items:center;gap:8px;}
.strip-find{flex:1;min-width:0;max-width:260px;margin-left:auto;
  font:inherit;font-size:12px;text-transform:none;letter-spacing:0;
  padding:4px 8px;border-radius:6px;border:1px solid var(--line);
  background:var(--chrome-1,#0f1b26);color:var(--chrome-ink,#d7e3ec);}
.strip-find-none{padding:6px 10px;font-size:12px;
  color:var(--chrome-ink-2,#93a8ba);}
/* T553: the Duration box beside the transitions */
.trans-dur{flex:none;width:52px;align-self:stretch;font:inherit;
  font-size:12px;padding:0 2px 0 6px;border:0;border-left:1px solid
  var(--line);border-radius:0;background:transparent;
  color:var(--chrome-ink,#d7e3ec);}
.trans-dur:disabled{opacity:.45;}
/* T672: THE COMBINE TAB'S SETTINGS (#pz-dlg) -- a choice a line, a
   sentence under it saying what it does, in sections */
.aa-box.pz-box{width:min(600px,94vw);}
/* T682: sections under a heading and a rule, not boxes whose legend
   cut through their border (the owner: "comes out weirdly spaced") */
.pz-body{overflow:auto;display:flex;flex-direction:column;gap:0;
  padding:0 2px 4px;}
.pz-set{margin:0;padding:12px 0 14px;border:0;
  border-top:1px solid var(--chrome-line,#ffffff1a);
  display:flex;flex-direction:column;gap:8px;min-width:0;}
.pz-set:first-child{border-top:0;padding-top:4px;}
.pz-set[hidden]{display:none;}
.pz-set>legend{float:left;width:100%;padding:0;margin:0 0 2px;
  font-size:12px;font-weight:600;color:var(--chrome-ink-2,#93a8ba);}
.pz-set>legend+*{clear:both;}
.pz-opt{display:flex;gap:9px;align-items:flex-start;cursor:pointer;
  font-size:13px;line-height:1.4;color:var(--chrome-ink);}
.pz-opt>input{flex:none;margin:2px 0 0;width:15px;height:15px;
  accent-color:var(--cyan);cursor:pointer;}
.pz-opt b{font-weight:600;}
.pz-opt:has(>input:disabled){cursor:default;opacity:.55;}
.pz-why{display:block;margin:0;font-size:12px;line-height:1.45;
  color:var(--chrome-ink-2,#93a8ba);}
.pz-why[hidden]{display:none;}
/* Close only big ones' two limits, under it and in line with its words */
.pz-lims{display:flex;align-items:center;flex-wrap:wrap;gap:5px;
  margin:-2px 0 0 24px;font-size:12px;color:var(--chrome-ink-2,#93a8ba);}
.pz-num{flex:none;width:56px;font:inherit;font-size:12px;
  padding:2px 4px 2px 6px;border:1px solid var(--chrome-line);
  border-radius:5px;background:var(--chrome-1,#0f1b26);
  color:var(--chrome-ink,#d7e3ec);}
.pz-num:disabled{opacity:.45;}
.pz-acts{display:flex;flex-wrap:wrap;gap:6px;}
.pz-acts[hidden]{display:none;}
/* T715: SPLIT (#spl-dlg) -- the Combine dialog's sections; what it will
   make, a line each: the name, then where its slides are and its size */
.aa-box.spl-box{width:min(460px,94vw);}
.spl-box .pz-sel{align-self:flex-start;max-width:100%;}
.spl-list{margin:0;padding:0 0 0 22px;max-height:220px;overflow:auto;
  display:flex;flex-direction:column;gap:3px;font-size:13px;
  color:var(--chrome-ink);}
.spl-list:empty{display:none;}
.spl-list b{font-weight:600;}
.spl-meta{margin-left:8px;font-size:12px;color:var(--chrome-ink-2,#93a8ba);}
.cell-unit{flex:none;padding:0 7px 0 1px;font-size:11px;
  color:var(--chrome-ink-2,#93a8ba);}
/* T548: the Shadow menu's rows show their shadow on a small card */
.shd-sw{display:inline-block;width:18px;height:14px;border-radius:2px;
  background:var(--chrome-ink-2,#9fb0c0);margin:2px 4px 6px 0;flex:none;}
/* T554: a hidden slide, as PowerPoint draws one -- its number struck
   through, the picture dimmed (by .cut, since the show skips it), and
   the current slide dimmed too, so hiding the slide you are on shows */
.film-row.hid .film-n{text-decoration:line-through;}
.film-row.hid.current .mini-diagram{opacity:.55;}
.film-mark.hid{color:var(--chrome-ink-2);}
/* the selected slide expands: number on top, big editor, title below */
.film-row.current .film-label{flex-direction:column;align-items:stretch;
  gap:6px;cursor:default;}
.film-row.current .film-n{align-self:flex-start;text-align:left;
  color:var(--cyan);}
.film-row.current .film-marks{align-self:flex-start;margin-left:0;}
.film-view{width:100%;min-width:0;}
.film-view .pane-editor{width:100%;margin:0;}
/* --mini-h is read back in JS (MINI_H in deck.js) to size thumbnail type
   and stroke: both are page percentages and have to become real pixels
   somewhere. Change one, change the other. */
.mini-diagram{--mini-h:66px;width:116px;height:var(--mini-h);flex:none;
  display:grid;gap:2px;
  background:var(--page-bg,var(--chrome-0,#0b141d));border:1px solid #ffffff22;border-radius:4px;
  padding:2px;overflow:hidden;}
.mini-diagram.full{grid-template-columns:1fr;}
.mini-diagram.halves{grid-template-columns:1fr 1fr;}
.mini-diagram.quarters{grid-template-columns:1fr 1fr;
  grid-template-rows:1fr 1fr;}
.mini-pane{position:relative;overflow:hidden;border-radius:2px;
  background:#1b2c3e;display:flex;align-items:center;
  justify-content:center;}
.mini-pane img{width:100%;height:100%;object-fit:contain;display:block;
  background:#fff;}
.mini-pane.is-note{background:#eef2f6 repeating-linear-gradient(180deg,
  #eef2f6 0,#eef2f6 4px,#b9c8d4 4px,#b9c8d4 5px);
  background-clip:padding-box;border:2px solid #eef2f6;}
.mini-pane.is-code{font-family:var(--mono);font-size:8.5px;
  color:#6f8ba3;background:#101d2a;}
.mini-pane.is-fig{background:#2a4761;}
.mini-pane.empty{background:var(--tk-surface,var(--chrome-4));}
.page-light .mini-pane.empty,.page-light .mini-pane.is-title{
  background:var(--tk-surface,#0000000d);}

/* pane editor: faint live preview behind the title */
.pane-img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;opacity:.4;}
.pane.filled .pane-t{position:relative;z-index:1;color:#eef4f8;
  text-shadow:0 1px 3px #000c,0 0 8px #0008;}
.film-ctr{display:none;gap:1px;padding-right:5px;flex:none;}
.film-row:hover .film-ctr,.film-row.current .film-ctr{display:flex;}
.film-mini{background:none;border:none;color:var(--chrome-ink-2);cursor:pointer;
  font-size:11px;padding:2px 4px;border-radius:4px;}
.film-mini:hover{background:#ffffff14;color:#fff;}
.addslide{margin-top:8px;}
/* Add slide takes the room; Section is the narrower, rarer verb beside
   it. One row, so the strip loses no height to gaining a second button. */
.film-adds{display:flex;gap:4px;margin-top:8px;}
.film-adds .addslide{flex:1;margin-top:0;}
.film-adds .addsec{flex:none;}
/* both labels on one line at the column's resting 200px. Letting them
   wrap inside the button is the same sin as an ellipsis: the words are
   all still there but the control stops reading as one thing. */
.film-adds .dbtn{white-space:nowrap;padding:5px 7px;font-size:11px;}

/* ---- section dividers in the strip -----------------------------------
   A divider reads as a LABEL over the slides beneath it rather than as
   another row in the list: no thumbnail, no number, and a rule under it
   so the eye can see where one run stops and the next starts. */
.film-sec{display:flex;align-items:center;gap:5px;cursor:grab;
  padding:6px 4px 4px;margin:6px 0 3px;border-radius:6px;
  border-bottom:1px solid color-mix(in srgb,var(--accent) 30%,transparent);}
.film-sec:first-child{margin-top:0;}
/* T699: where the next presentation begins, with no heading to say so */
.film-pzline{display:flex;align-items:center;gap:6px;margin:8px 2px 5px;
  font:600 10.5px var(--sans);color:var(--chrome-ink-2);
  pointer-events:none;}
.film-pzline::before,.film-pzline::after{content:"";height:2px;
  border-radius:1px;background:var(--pzl,var(--accent));}
.film-pzline::before{flex:none;width:10px;}
.film-pzline::after{flex:1;min-width:12px;}
.film-pzline-t{flex:0 1 auto;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;}
.film-sec.dragging{opacity:.45;}
.film-sec.drop-above{box-shadow:0 -2px 0 var(--cyan);}
.film-sec.drop-below{box-shadow:0 2px 0 var(--cyan);}
.film-sec-fold{background:none;border:none;color:var(--chrome-ink-2);cursor:pointer;
  font-size:10px;padding:1px 3px;border-radius:4px;flex:none;line-height:1;}
.film-sec-fold:hover{background:var(--surface-active);color:var(--chrome-ink);}
/* T316: the section's colour, on its divider */
.film-sec-dot{flex:none;width:10px;height:10px;border-radius:50%;
  border:1px solid #ffffff55;padding:0;cursor:pointer;}
.film-sec-dot:hover{transform:scale(1.25);}
.sw.sw-sec{outline:1px dashed #ffffff66;outline-offset:1px;}
/* T681: a section's name as you typed it, in the sans -- as a part's
   heading (below) and the sheet tabs already show it; it was spaced
   capitals, so "Introduction" read INTRODUCTION over its slides */
.film-sec-t{flex:1;min-width:0;font-family:var(--sans);font-size:11.5px;
  font-weight:600;letter-spacing:0;color:var(--accent);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.film-sec-n{flex:none;font-family:var(--mono);font-size:9px;color:var(--chrome-ink-3);}
.film-sec:hover .film-ctr{display:flex;}
/* T601: a divider that is a PART says so -- a tinted rule, and the word
   "part" as the door to the Parts view */
/* T653: ...and is a heading of its own, not a section's label: a band
   of its colour down the left, a tinted box, the presentation's mark,
   its name in the sentence's case over where it lives */
/* T675: the colour and the name, the whole line its own; under it, what
   it is in two quiet words, and the count (owner: "a bit crowded, and a
   bit confusing what some of the things like refresh are") */
.film-sec.linked{display:grid;position:relative;
  grid-template-columns:16px 12px minmax(0,1fr) auto;
  grid-template-areas:"fold dot name name" ". . kind n";
  align-items:center;column-gap:4px;row-gap:1px;
  padding:6px 5px 6px 4px;margin:8px 0 4px;
  border:1px solid color-mix(in srgb,var(--part-c,var(--accent)) 40%,transparent);
  border-left:3px solid var(--part-c,var(--accent));
  background:color-mix(in srgb,var(--part-c,var(--accent)) 12%,transparent);}
.film-sec.linked .film-sec-fold{grid-area:fold;}
.film-sec.linked .film-sec-t{grid-area:name;}
.film-sec.linked .film-sec-n{grid-area:n;justify-self:end;}
.film-sec.linked .film-sec-dot{grid-area:dot;justify-self:center;}
.film-sec.linked .film-part-kind{grid-area:kind;}
/* T660: a heading is a door to its run -- it lights as a row does */
.film-sec:hover{background:var(--surface-hover);}
.film-sec.linked:hover{
  background:color-mix(in srgb,var(--part-c,var(--accent)) 20%,transparent);}
/* its rename / remove sit over the top right on hover, never taking a
   column the name needs */
.film-sec.linked .film-ctr{position:absolute;top:3px;right:3px;
  padding:1px;border-radius:5px;background:var(--chrome-1,#0e1926);}
.film-sec.linked .film-sec-t{font-family:var(--sans);font-size:11.5px;
  font-weight:600;letter-spacing:0;text-transform:none;
  color:var(--chrome-ink);}
.film-part-kind{min-width:0;font:10.5px var(--sans);
  color:var(--chrome-ink-3);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
/* T669: the talk's own slides head themselves in a talk of parts -- the
   same block, in the chrome's ink rather than a section's colour; it is
   not a section, so it does not drag */
.film-sec.film-talk{--part-c:var(--chrome-ink-3);cursor:pointer;
  grid-template-columns:16px minmax(0,1fr) auto;
  grid-template-areas:"fold name name" ". kind n";}
/* the rule the strip folds parts by, in the Parts view (57-parts.js) */
.pf-rule{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;
  margin:8px 16px 0;font-size:12px;color:var(--chrome-ink-2);}
.pf-rule-sel,.pf-rule-n{font:inherit;font-size:12px;padding:3px 6px;
  border-radius:6px;border:1px solid var(--border-strong);
  background:var(--input-bg);color:var(--chrome-ink);}
.pf-rule-n{width:64px;}
.pf-rule-lim[hidden]{display:none;}
body.light .pf-rule{color:var(--ink-2);}

/* ---- T654: THE SHEET TABS, along the foot of the slide ---------------
   A workbook's sheets: a thin bar under the page, its tabs hanging from
   the bar's top edge, the one on screen lifted, a part wearing its
   colour and the link mark. Only while editing a deck (a poster has
   none), and folded away with the ribbon. Auto-hide lays the bar over
   the page's foot, slid down until it is pointed at (.sheets-peek). */
.deck{--sht-h:30px;}
.deck-sheets{display:none;}
.deck.editing .deck-sheets:not([hidden]){display:flex;}
.deck-sheets{position:relative;flex:none;align-items:stretch;gap:6px;
  height:var(--sht-h);padding:0 8px 0 6px;border-top:1px solid #ffffff1c;
  background:var(--chrome-1,#0e1926);}
.sht-tabs{display:flex;align-items:stretch;gap:2px;min-width:0;
  overflow-x:auto;overflow-y:hidden;scrollbar-width:none;}
.sht-tabs::-webkit-scrollbar{display:none;}
/* T659: a tab keeps its whole name, as a workbook's sheet does. Squeezed
   to fit, twelve sections read "Topic 2:...", "Topic 3:..." -- the part
   that tells them apart was the part cut off. Past the bar's end they
   are counted, and listed, by "N more". */
.sht-tab{flex:none;display:inline-flex;align-items:center;
  gap:5px;max-width:220px;padding:0 12px;margin-top:-1px;
  border:1px solid transparent;border-top:none;border-radius:0 0 7px 7px;
  background:none;color:var(--chrome-ink-2);font:inherit;
  font-family:var(--sans);font-size:12px;white-space:nowrap;
  cursor:pointer;box-shadow:inset 0 -2px 0 transparent;}
.sht-tab:hover{background:var(--surface-hover);color:var(--chrome-ink);}
.sht-tab.on{background:var(--chrome-0,#0b141d);color:var(--chrome-ink);
  font-weight:600;border-color:#ffffff1c;
  box-shadow:inset 0 -2px 0 var(--sht-c,var(--accent));}
.sht-tab.part{box-shadow:inset 0 -2px 0 var(--sht-c,var(--accent));}
.sht-tab.part.on{box-shadow:inset 0 -3px 0 var(--sht-c,var(--accent));}
/* the row clips: a ring outside the tab would be cut off */
.sht-tab:focus-visible{outline:2px solid var(--focus);outline-offset:-2px;}
.sht-nm{min-width:0;overflow:hidden;text-overflow:ellipsis;}
.sht-ic{flex:none;display:inline-flex;color:var(--sht-c,var(--accent));}
.sht-ic .bic{width:12px;height:12px;}
.sht-dot{flex:none;width:7px;height:7px;border-radius:50%;
  background:var(--sht-c);}
.deck-sheets .sht-btn{align-self:center;flex:none;display:inline-flex;
  align-items:center;gap:4px;padding:3px 8px;font-size:11.5px;
  white-space:nowrap;}
.deck-sheets .sht-btn[hidden]{display:none;}
.deck-sheets .sht-btn .bic{width:12px;height:12px;}
/* a drag: the tab picked up dims, a line shows where it will land */
.sht-tab.sht-dragging{opacity:.5;}
body.sht-drag-on,body.sht-drag-on *{cursor:grabbing!important;
  user-select:none!important;}
.sht-mark{position:absolute;top:4px;bottom:4px;width:2px;z-index:2;
  background:var(--accent);border-radius:1px;pointer-events:none;}
.sht-mark[hidden]{display:none;}
/* every tab, listed: its mark, its name, its slides */
.sht-more-menu .vw-opt{display:flex;align-items:center;gap:6px;}
.sht-more-menu .sht-ic{color:var(--sht-c,var(--accent));}
.sht-more-nm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
.sht-more-n{flex:none;font:10px var(--mono);color:var(--chrome-ink-3);}
.sht-more-menu .vw-opt.on{font-weight:600;
  box-shadow:inset 3px 0 0 var(--sht-c,var(--accent));}
body.light .deck-sheets{border-top-color:#0000001f;}
body.light .sht-tab.on{border-color:#0000001f;}
/* a pane docked on the right stops above the bar */
.deck.editing.sheets-on:not(.sheets-auto) .selpane{
  bottom:calc(var(--sht-h) + 8px);}
/* T699: hiding the ribbon (Ctrl+F1) leaves the bottom tabs where they
   are -- the presentations are no tool (the owner, 2026-10-30) */
.sht-hot{display:none;}
.deck.editing.sheets-auto.sheets-on .sht-hot{display:block;position:absolute;
  left:0;right:0;bottom:0;height:10px;z-index:69;}
.deck.editing.sheets-auto .deck-sheets{position:absolute;left:0;right:0;
  bottom:0;z-index:70;transform:translateY(100%);
  transition:transform .16s ease;box-shadow:0 -6px 18px #00000055;}
.deck.editing.sheets-auto.sheets-peek .deck-sheets{transform:none;}
/* its settings, and its menus: rows down, as the strip's menu has them
   (.sh-menu is a grid of swatches by default) */
.sht-menu{display:block;width:250px;min-width:0;max-width:min(340px,92vw);
  max-height:72vh;overflow-y:auto;overflow-x:hidden;}
.sht-menu .hd-lab{margin-top:6px;}
.sht-menu .hd-lab:first-child{margin-top:0;}
.sht-menu .vw-opt{width:100%;text-align:left;}
.sht-check{display:flex;align-items:flex-start;gap:6px;padding:4px 10px 8px;
  font-size:12px;line-height:1.4;color:var(--chrome-ink-2);cursor:pointer;}
body.light .sht-check{color:var(--ink-2);}
/* T655: the keys' switch, under the fold rule in the Parts view; T665:
   its words short, the rest behind the "?" after them */
.pk-keys{display:flex;align-items:center;padding:4px 10px 8px;}
.pk-keys>.sht-check{padding:0;}
.deck-parts .pk-keys{margin:6px 16px 0;padding:0;max-width:760px;}

/* ---- T656: A BINDER IN THE STRIP AND ON THE TABS ----------------------
   Each presentation of the binder is a heading of its own -- the
   binder's mark, its name over where it is from, its count -- the one
   on screen lit over its own slides, the others above and below it, an
   open one with its slides as the library's pictures. */
.bnd-block{margin:8px 0 4px;}
.bnd-head{display:grid;grid-template-columns:16px 15px minmax(0,1fr) auto;
  grid-template-areas:"fold ic name n" ". . from from";align-items:center;
  column-gap:4px;row-gap:2px;padding:6px 5px 6px 4px;cursor:pointer;
  border:1px solid #ffffff22;border-left:3px solid var(--chrome-ink-3);
  border-radius:6px;background:#ffffff08;color:var(--chrome-ink-2);}
.bnd-head:hover{background:var(--surface-hover);color:var(--chrome-ink);}
.bnd-head.on{cursor:default;border-left-color:var(--accent);
  background:color-mix(in srgb,var(--accent) 12%,transparent);
  color:var(--chrome-ink);}
.bnd-fold{grid-area:fold;background:none;border:none;color:inherit;
  font-size:10px;padding:1px 3px;border-radius:4px;cursor:pointer;}
.bnd-fold:disabled{cursor:default;opacity:.7;}
.bnd-ic{grid-area:ic;display:inline-flex;}
.bnd-ic .bic{width:13px;height:13px;}
.bnd-t{grid-area:name;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font-family:var(--sans);font-size:11.5px;
  font-weight:600;}
.bnd-n{grid-area:n;justify-self:end;font-family:var(--mono);font-size:9px;
  color:var(--chrome-ink-3);}
.bnd-from{grid-area:from;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font-family:var(--mono);font-size:9px;
  color:var(--chrome-ink-3);}
.bnd-pv{margin:4px 0 0 2px;}
.bnd-pv .pv-head{display:none;}
.bnd-pv .pv-list{display:flex;flex-direction:column;gap:6px;}
/* T661: another presentation's slides read as the strip's own rows --
   the number beside the picture, no heading under it (they read as a
   different list, captioned) */
.bnd-pv .pv-slide{margin:0;cursor:pointer;opacity:.85;flex-direction:row-reverse;
  justify-content:flex-end;align-items:flex-start;gap:6px;}
.bnd-pv .pv-slide figcaption{flex:none;width:18px;font-size:0;
  text-align:right;padding-top:3px;}
.bnd-pv .pv-slide figcaption b{font:10px var(--mono);color:var(--chrome-ink-3);}
.bnd-pv .pv-slide:hover{opacity:1;}
.bnd-pv .pv-slide:hover .mini-diagram{outline:1px solid var(--accent);
  outline-offset:1px;}
/* ---- T661: THE PICKER -- your presentations to tick, by folder, with
   their slides beside the list, and both ways in at the foot ---------- */
.bnd-pick .bp-body{flex:1;min-height:0;display:grid;
  grid-template-columns:minmax(260px,380px) 1fr;gap:16px;padding:12px 16px 0;}
.bp-col{display:flex;flex-direction:column;min-height:0;gap:8px;}
.bp-find{font:13px var(--sans);padding:6px 10px;border-radius:7px;
  border:1px solid var(--border-strong);background:var(--input-bg);
  color:var(--chrome-ink);}
.bp-list{flex:1;min-height:0;overflow:auto;display:flex;flex-direction:column;
  gap:3px;padding:2px;}
.bp-dir{display:flex;align-items:center;gap:6px;margin:8px 0 2px 2px;
  font:600 11px var(--sans);color:var(--chrome-ink-2);}
.bp-dir .bic{width:13px;height:13px;}
.bp-dir[hidden],.bp-row[hidden],.bp-none[hidden]{display:none;}
.bp-row{display:flex;align-items:center;gap:8px;padding:6px 9px;
  border:1px solid #ffffff1a;border-radius:7px;background:#ffffff06;
  color:var(--chrome-ink);cursor:pointer;}
.bp-row:hover{background:#ffffff10;border-color:#ffffff33;}
.bp-row:focus-visible{outline:2px solid var(--focus);outline-offset:-1px;}
.bp-row[aria-selected="true"]{border-color:var(--accent);
  background:color-mix(in srgb,var(--accent) 14%,transparent);}
/* the tick box: a box, and a tick when chosen */
.bp-box{flex:none;width:15px;height:15px;border-radius:4px;
  border:1.5px solid var(--chrome-ink-3);position:relative;}
.bp-row[aria-selected="true"] .bp-box{background:var(--accent);
  border-color:var(--accent);}
.bp-row[aria-selected="true"] .bp-box::after{content:"";position:absolute;
  left:4px;top:1px;width:4px;height:8px;border:solid var(--on-accent,#06121b);
  border-width:0 2px 2px 0;transform:rotate(45deg);}
.bp-ic{flex:none;display:inline-flex;color:var(--chrome-ink-2);}
.bp-ic .bic{width:14px;height:14px;}
.bp-tx{min-width:0;display:flex;flex-direction:column;gap:1px;}
.bp-nm{font:600 12.5px var(--sans);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
.bp-sub{font:11px var(--sans);color:var(--chrome-ink-2);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;}
.bp-none{margin:6px 2px;font:12px var(--sans);color:var(--chrome-ink-2);}
.bp-pv{min-width:0;min-height:0;overflow:auto;padding-bottom:12px;}
.bp-foot{display:flex;align-items:center;gap:8px;padding:10px 16px;
  border-top:1px solid #ffffff1a;}
.bp-count{font:12px var(--sans);color:var(--chrome-ink-2);}
@media (max-width:720px){
  .bnd-pick .bp-body{grid-template-columns:1fr;}
  .bp-pv{display:none;}
}
body.light .bp-row{background:var(--chrome-1);border-color:var(--chrome-line);
  color:var(--ink);}
body.light .bp-row:hover{border-color:#0000003a;}
body.light .bp-row[aria-selected="true"]{border-color:var(--accent);
  background:color-mix(in srgb,var(--accent) 12%,var(--chrome-1));}
body.light .bp-foot,body.light .bnd-pick .ovw-head{border-color:var(--chrome-line);}
/* a binder's own preview: its presentations, one picture each */
.pv-binder .pv-mem figcaption b{font:600 11px var(--sans);}
.sht-tab.member .sht-ic{color:var(--accent);}
.sht-tab.missing{opacity:.5;text-decoration:line-through;}
body.light .bnd-head{background:#00000006;border-color:#00000022;}
/* slides inside a section step in, so the run is visible without having
   to read the divider each time */
.film-row.in-sec{margin-left:7px;}
/* T318: a version sits under its main, one step further in and dimmed;
   the one you are editing is full strength. The main's pill is the fold
   toggle, drawn as a mark so it is never over the thumbnail. */
.film-row.alt{margin-left:18px;opacity:.72;}
.film-row.alt.current{opacity:1;}
.film-row.alt .film-n{color:var(--chrome-ink-3);}
.film-mark.alt-pill{cursor:pointer;background:none;border:1px solid
  var(--chrome-line);color:var(--chrome-ink-2);font:inherit;padding:0 5px;}
.film-mark.alt-pill:hover{color:var(--chrome-ink);}
.film-mark.alt{color:var(--accent);}
/* The current slide remains in a collapsed section so its live thumbnail
   can refresh. It is a real, readable row -- dimming it made the current
   slide look disabled and its controls needlessly hard to hit. */
.film-row.peek{opacity:1;box-shadow:inset 3px 0 0 var(--accent);}
/* T399: ONE readable column, like the canvas menu below it. The strip's
   menu inherited .sh-menu's three-column icon grid, so "New version of
   this slide" and "Move matching objects" wrapped word by word into
   tiles beside their headings (2026-09-13, user: "the right click
   options on a slide look cursed"). */
.film-menu{display:block;width:300px;min-width:0;
  max-width:min(340px,92vw);max-height:72vh;
  overflow-y:auto;overflow-x:hidden;}
.film-menu .hd-lab{margin-top:6px;}
.film-menu>.hd-lab:first-child{margin-top:0;}
.film-menu .vw-opt{width:100%;text-align:left;}
.film-menu .vw-opt.on{background:color-mix(in srgb,var(--accent) 22%,
  transparent);color:#fff;}
.film-menu .vw-opt.on::after{content:"on";margin-left:auto;
  font-family:var(--mono);font-size:9px;opacity:.75;}
body.light .film-menu .vw-opt.on{color:var(--ink);}
/* the canvas right-click menu: the film strip's menu is the other
   context menu in the app, so it gets the same width and the same
   left-aligned rows. The one addition is a dead row -- "Nothing copied
   yet" -- which has to read as unavailable rather than broken. */
/* five sections deep with a rich selection, so it scrolls rather than
   running off the bottom of the window */
/* T137 / JVUX-01: .sh-menu's 3-column 210px grid is for icon
   galleries; on a WORD menu it wrapped 31 labels character by
   character into thin columns with both scrollbars. One readable
   column, and the long tail folds behind "More" (cmFold). */
.canvas-menu{display:block;width:308px;min-width:0;
  max-width:min(340px,92vw);max-height:72vh;
  overflow-y:auto;overflow-x:hidden;}
.canvas-menu .hd-lab{margin-top:6px;}
/* [hidden] must actually hide: a bare display rule on the class would
   beat the attribute's UA default, which is exactly how the fold shipped
   open in its first screenshot */
.cm-more[hidden]{display:none;}
.cm-moret{width:100%;text-align:left;margin-top:6px;
  border-top:1px solid #ffffff1a;border-radius:0;padding-top:8px;}
.canvas-menu .vw-opt{width:100%;text-align:left;}
.canvas-menu .vw-opt[disabled]{opacity:.45;pointer-events:none;}
/* A BUTTON YOU HAVE PUT AWAY. display:none, not [hidden]: showFmt owns
   the attribute and turns controls on and off by kind, so a customiser
   writing the same one would fight it on every click. This composes
   with it instead — and costs the fit ladder nothing, because
   display:none takes no width. */
#edit-tools .rbn-hid{display:none!important;}
.rbn-cust{max-height:74vh;}
.rbn-cust .rbn-crow{gap:3px;}
.rbn-cust .rbn-move{font-size:11px;line-height:1;padding:2px 6px;
  flex:none;}
/* which lock the selection is in now. Same treatment the View menu's
   toggles use, so "on" reads the same way everywhere. */
.canvas-menu .vw-opt.on{background:color-mix(in srgb,var(--accent) 22%,
  transparent);color:#fff;}
.canvas-menu .vw-opt.on::after{content:"on";margin-left:auto;
  font-family:var(--mono);font-size:9px;opacity:.75;}
body.light .canvas-menu .vw-opt.on{color:var(--ink);}

/* ---- the strip's own resize handle ------------------------------------
   position:fixed, not absolute: .deck-create scrolls, and an absolutely
   positioned child would scroll away from the edge it is supposed to be
   sitting on. The shared rail remains live in the editor, so the handle
   begins after its width rather than at the window's left edge. */
.film-resize{display:none;position:fixed;top:0;bottom:0;width:6px;
  z-index:130;cursor:col-resize;
  left:calc(var(--deck-left,var(--presrail-w)) + clamp(150px,var(--film-w,min(var(--dc-w),200px)),
    var(--film-max,46vw)) - 3px);}
.deck.editing .film-resize{display:block;}
.deck.editing.strip-off .film-resize,
.deck.editing.poster-page .film-resize{display:none;}
/* the handle sits at the column's rendered edge, so it goes where the
   column goes: gone while it is parked, back while it is peeking */
.deck.editing.film-auto .film-resize{display:none;}
.deck.editing.film-auto.film-peek .film-resize{display:block;}
.film-resize:hover,.film-resize.on{
  background:color-mix(in srgb,var(--accent) 40%,transparent);}
/* A GRIP YOU CAN SEE. The handle was six transparent pixels that only
   appeared once the pointer was already on them, so a feature asked for
   by name (2026-08-22, "the thumbnail part should be dragable to make
   bigger or smaller") could only be found by accident. Two pixels of
   hairline at mid height is the affordance every panel splitter uses,
   and it costs the column no width. */
.film-resize::before{content:"";position:absolute;left:2px;top:50%;
  width:2px;height:26px;margin-top:-13px;border-radius:1px;
  background:#ffffff2e;}
.film-resize:hover::before,.film-resize.on::before{background:#fff;}
/* ...and the handle stops at the COLUMN. top:0/bottom:0 is what keeps it
   glued to the edge while .deck-create scrolls, but it also laid a 6px
   dead stripe up through the top bar and the tab row -- at the resting
   200px that is a slice of the save readout, at another rung a slice of
   a button, and it moves with every drag. Those two rows outrank it in
   their own bands. 131 clears the handle's 130 and stays under .vfull
   (135) and .matchbar (150), so nothing that used to paint over the bar
   stops doing so. */
.deck-qat,.deck-top,.rbn-tabs{position:relative;z-index:131;}
/* ...and the top bar OUTRANKS the tab strip (T397). Its menus float at
   z-index 240 -- inside its own stacking context, which at an equal 131
   lost to the later tab strip, so the first row of the Help menu sat
   under Auto-hide and Ribbon layouts. Still under .vfull (135). */
.deck-qat{z-index:132;}
@media(max-width:860px){.film-resize{display:none!important;}}

/* ---- how the slides are listed ---------------------------------------
   The chooser is one line and carries no second copy of anything. It is
   stamped on the LIST rather than on the body or the deck, because
   filmToPane MOVES #film-list into the Versions pane and a body class
   would then be styling a list that is somewhere else. */
.film-head{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:6px;}
/* never narrower than its own word (T619): the readout beside it is
   what wraps, never "Thumbnails ▾" into three lines */
.film-head .dc-menuwrap{flex:1 0 auto;}
.film-view-btn{width:100%;text-align:left;font-size:11px;padding:4px 8px;
  white-space:nowrap;}
/* headings mode: no picture at all, so the row is one line of text and
   forty slides fit on a laptop screen */
#film-list[data-fv="head"] .film-t{white-space:normal;
  text-overflow:clip;overflow:visible;}
#film-list[data-fv="head"] .film-row.current .film-label{
  flex-direction:row;align-items:center;}
#film-list[data-fv="head"] .film-label{padding:3px 6px;}
/* the outline steps in by heading level, so a deck with sections and
   headings reads as a real table of contents */
#film-list[data-fv="head"] .film-row[data-lvl="1"] .film-t{
  padding-left:9px;}
#film-list[data-fv="head"] .film-row[data-lvl="2"] .film-t{
  padding-left:18px;}
#film-list[data-fv="head"] .film-row[data-lvl="3"] .film-t{
  padding-left:27px;}
/* both: the caption sits UNDER the thumbnail and is allowed to wrap,
   because the point of asking for both is being able to read it */
#film-list[data-fv="both"] .film-label{flex-wrap:wrap;}
#film-list[data-fv="both"] .film-t{white-space:normal;
  text-overflow:clip;overflow:visible;flex-basis:100%;
  line-height:1.35;}
/* the thumbnail follows the column: it is a scale model of the slide, so
   it has the slide's shape and grows with the room it is given */
/* WIDTH:100% IS ONLY TRUE OF THE ROW THAT STACKS (T153). The CURRENT
   row's .film-label turns column, so there the thumbnail really does own
   the full width. Every OTHER row is a horizontal flex line -- number,
   thumbnail, title -- where 100% is a promise the row cannot keep: at
   flex:none the thumbnail took the whole line, pushed the title to zero
   width and the row's own controls to zero, overflowed the row by the
   number's width, and .film-list (overflow-y:auto, so the x axis
   computes to auto as well) grew a horizontal scrollbar inside a
   vertical list. Measured at a 200px column: row 171px, content 189px,
   title 0px. Sharing rows shrink to fit instead. */
.film-list .film-row.current .mini-diagram{width:100%;height:auto;
  aspect-ratio:116/66;min-height:var(--mini-h);}
.film-list .film-row:not(.current) .mini-diagram{flex:1 1 auto;
  min-width:0;width:auto;height:auto;aspect-ratio:116/66;
  min-height:var(--mini-h);}
/* ...and the list never scrolls sideways: it is a vertical list, and a
   horizontal scrollbar in it is always a fitting bug, never a feature */
.film-list{overflow-x:hidden;}

/* the sans, as every other control (T679: one type for the chrome) --
   the reader's toast already was; the mono made a sentence read as code
   (2026-10-30 review) */
.deck-toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);
  background:var(--chrome-2,#16273a);border:1px solid var(--cyan);color:var(--chrome-ink);
  font-size:12.5px;font-family:var(--sans);padding:9px 16px;border-radius:8px;
  z-index:120;box-shadow:0 8px 30px #00000066;max-width:80vw;}
/* T607 lifted the editor's toasts to 58px, above the status and zoom
   row they sat on; T619 took that row off the canvas, so they keep the
   ordinary 24px and only their width is the editor's own */
.deck.editing .deck-toast{max-width:min(80vw,760px);}
/* the light themes' toast is their own white chrome, so its words are
   their chrome ink -- the dark theme's pale words were all but invisible
   on it (T614: its Undo and Update replies live here) */
body.light .deck-toast{color:var(--chrome-ink);}
/* T686: live share. The pill sits in the title row beside the save
   readout; the File row wears its "prototype" tag */
.live-pill{font-size:12px;padding:2px 10px;border-radius:999px;
  white-space:nowrap;flex:none;}
.live-pill::before{content:"";display:inline-block;width:7px;height:7px;
  border-radius:50%;background:#3fb950;margin-right:6px;vertical-align:1px;}
.live-pill.live-off::before{background:#d29922;}
/* T698: the live panel -- People, Links, Changes, Chat. Docked at the
   right under the title row, above the stage (the z ladder: past the
   column's 120) */
.live-panel{position:fixed;right:12px;top:76px;width:340px;z-index:140;
  max-height:calc(100vh - 100px);display:flex;flex-direction:column;
  background:var(--chrome-2,#16273a);color:var(--chrome-ink);
  border:1px solid color-mix(in srgb,var(--chrome-ink) 22%,transparent);
  border-radius:10px;box-shadow:0 16px 48px #0008;font-size:12.5px;}
.live-panel[hidden]{display:none;}
.live-head{display:flex;align-items:center;gap:6px;padding:8px 10px 4px;}
.live-title{font-weight:600;font-size:13px;}
.live-tabs{display:flex;gap:4px;padding:4px 10px 8px;flex-wrap:nowrap;}
.live-tabs .dbtn.on{outline:2px solid var(--cyan);}
.live-body{overflow:auto;padding:0 10px 10px;display:flex;
  flex-direction:column;gap:8px;}
.live-row{display:flex;align-items:center;gap:6px;flex-wrap:wrap;}
.live-row .ask-in{flex:1;min-width:0;}
.live-note{opacity:.8;line-height:1.4;}
.live-who{font-weight:600;}
.live-link,.live-log,.live-msg{border-radius:8px;padding:8px;
  background:color-mix(in srgb,var(--chrome-ink) 7%,transparent);
  display:flex;flex-direction:column;gap:6px;}
.live-msg.mine{background:color-mix(in srgb,var(--cyan) 14%,transparent);}
.live-what{text-align:left;}
.live-chat{display:flex;flex-direction:column;gap:6px;max-height:46vh;
  overflow:auto;}
.live-check{cursor:pointer;}
/* the link this admin came in by (2026-10-30 review) */
.live-mine{font-size:11px;font-weight:600;padding:1px 6px;
  border-radius:999px;border:1px solid currentColor;opacity:.85;}
/* T698: copies off -- no Download, no Export, while the live deck is on
   screen for someone who is not an admin */
.deck.live-nocopy #mi-dl,.deck.live-nocopy #mi-pdf,
.deck.live-nocopy #mi-pptx,.deck.live-nocopy #mi-html,
.deck.live-nocopy #mi-review,.deck.live-nocopy #mi-bdl,
.deck.live-nocopy #mi-tocol,.deck.live-nocopy #mi-unlinked{display:none;}
/* T696: the initials of whoever else is on a slide, on its thumbnail */
.film-row.live-on{position:relative;}
.live-here{position:absolute;top:4px;right:6px;z-index:2;font-size:10px;
  font-weight:600;line-height:1;padding:3px 5px;border-radius:999px;
  background:#3fb950;color:#04140a;pointer-events:auto;
  box-shadow:0 1px 3px #0006;}
.live-proto{font-size:10px;text-transform:uppercase;letter-spacing:.04em;
  border:1px solid currentColor;border-radius:4px;padding:0 4px;
  margin-left:6px;opacity:.75;}
/* ...and the editor's questions: their title kept the dark theme's
   near-white over the light box, 1.07:1 (T614's Update and Make as
   collection ask through it; so does every askText) */
body.light .eq-t,body.light .aa-head .eq-t,
body.light .eq-head .eq-t{color:var(--chrome-ink);}

@media (max-width:860px){
  .deck-stage{padding:16px 52px 4px;}
  .deck-drawer{padding:12px 20px 18px;}
  .slide-grid.halves,.slide-grid.quarters{grid-template-columns:1fr;
    grid-template-rows:none;grid-auto-rows:1fr;}
}
@media (prefers-reduced-motion:reduce){.slide{animation:none;}}

/* drag-to-trim: four accent edge handles; the live clip is the preview */
.an-crop-h{position:absolute;background:var(--accent);border:1px solid
  #00000055;border-radius:4px;z-index:8;}
.an-crop-t,.an-crop-b{left:50%;margin-left:-16px;width:32px;height:9px;
  cursor:ns-resize;}
.an-crop-l,.an-crop-r{top:50%;margin-top:-16px;width:9px;height:32px;
  cursor:ew-resize;}
.ci-trim{display:block;width:100%;text-align:left;background:none;
  border:1px solid color-mix(in srgb,var(--accent) 45%,transparent);
  color:var(--accent);border-radius:7px;padding:7px 10px;cursor:pointer;
  font-family:var(--sans);font-size:12px;margin-bottom:6px;}
.ci-trim:hover{background:color-mix(in srgb,var(--accent) 14%,transparent);}

/* a table in a thumbnail: the words are a smudge at 116px but the SHAPE
   of a table is unmistakable, which is what a thumbnail is for */
.mini-tbl{width:100%;height:100%;border-collapse:collapse;
  table-layout:fixed;line-height:1.05;}
/* T626: its rules are the slide's (--tbl-line, from tableLine, as the
   canvas sets it) and its words the thumbnail's own ink -- the literal
   #dbe6ee it wore here drew every table in the default whatever the
   theme said */
.mini-tbl td,.mini-tbl th{border:.5px solid var(--tbl-line,currentColor);
  padding:0 .2em;
  overflow:hidden;white-space:nowrap;text-align:left;font-weight:inherit;}
.mini-tbl th{font-weight:700;
  background:color-mix(in srgb,currentColor 18%,transparent);}
.mini-tbl.nogrid td,.mini-tbl.nogrid th{border-color:transparent;}

/* ---- repeated page furniture ---------------------------------------
   Sized in PERCENT OF PAGE HEIGHT, like text items are, so a watermark
   reads the same on a 16:9 slide and on an A0 poster (2026-08-20). */
.slide-wmark{position:absolute;left:50%;top:50%;z-index:0;
  pointer-events:none;user-select:none;white-space:nowrap;
  font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  line-height:1;color:currentColor;}
.slide-head,.slide-foot{position:absolute;left:4%;right:4%;
  pointer-events:none;color:var(--tk-quiet,var(--chrome-ink-2));
  line-height:1.2;}
.slide-head{top:2.4%;}
.slide-foot{bottom:2.4%;}
.page-light .slide-head,.page-light .slide-foot{
  color:var(--tk-quiet,#5b6b78);}
/* the number sits at the corner, so a footer spanning the page must not
   run underneath it */
.slide-foot{padding-right:3.5%;}
/* T699: the name of the presentation the slide is in, in a corner */
.slide-pzlabel{position:absolute;z-index:4;max-width:44%;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;line-height:1.2;
  pointer-events:none;color:var(--tk-quiet,var(--chrome-ink-2));}
.page-light .slide-pzlabel{color:var(--tk-quiet,#5b6b78);}
.slide-pzlabel.at-bl,.slide-pzlabel.at-tl{left:4%;}
.slide-pzlabel.at-br,.slide-pzlabel.at-tr{right:4%;text-align:right;}
.slide-pzlabel.at-bl,.slide-pzlabel.at-br{bottom:2.4%;}
.slide-pzlabel.at-tl,.slide-pzlabel.at-tr{top:2.4%;}
/* the page number has the bottom-right corner: the name stands left of it */
.slide-pzlabel.at-br{right:9%;}

/* ---- the Styles menu: each row is a SPECIMEN of the style it names, so
   you pick by looking rather than by reading a number (2026-08-20) */
/* T293: it SCROLLS now. The list was seven rows and a fixed height was
   fine; with a family under each heading it can pass the viewport, and
   floatMenu clamps a menu's top edge without ever scrolling it -- so the
   bottom rows were lost with no scrollbar and no error. */
.sh-menu.style-tx-menu{display:block;width:380px;padding:5px;
  max-height:min(68vh,520px);overflow-y:auto;}
/* a variation sits under the type it varies, and says so by sitting in */
.style-tx-menu .jv-styleopt.jv-stylevar{padding-left:20px;position:relative;}
.style-tx-menu .jv-styleopt.jv-stylevar::before{content:"";position:absolute;
  left:9px;top:50%;width:5px;height:1px;background:var(--chrome-ink-3);}
.jv-styleopt{display:flex!important;align-items:baseline;
  justify-content:space-between;gap:10px;width:100%;text-align:left;}
.jv-stylename{line-height:1.15;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
.jv-stylesz{font-family:var(--mono);font-size:9.5px;color:var(--chrome-ink-2);
  flex:none;}
.style-tx-menu .vw-opt[disabled]{opacity:.4;pointer-events:none;}

/* ---- SPOTLIGHT: one item, blown up mid-talk -------------------------
   A FLIP, not a fade: the clone starts exactly over the original and is
   transformed to the centre, so it grows out of where it was and the
   original never moves (2026-08-20). */
.jv-spot-wrap{position:fixed;inset:0;z-index:400;
  background:#000000;opacity:0;transition:opacity .2s ease;
  cursor:zoom-out;}
.jv-spot-wrap.on{opacity:.93;}
.jv-spot-inner{position:fixed;transform-origin:50% 50%;
  transition:transform .26s cubic-bezier(.22,.8,.3,1);
  will-change:transform;}
/* the clone paints above the backdrop, which is the whole point */
.jv-spot-wrap .jv-spot-inner{z-index:1;}
.jv-spot-x{position:fixed;top:16px;right:18px;z-index:2;
  background:#ffffff14;border-color:#ffffff3d;color:#eaf2f8;}
.jv-spot-x:hover{background:#ffffff26;border-color:var(--cyan);}
/* while a spotlight is up, the deck underneath must not react to
   anything - the click that closes it is the only one that counts */
body.jv-spot .deck-stage{pointer-events:none;}
/* an item you can blow up says so on hover, and only while presenting */
.deck:not(.editing) .an-item{transition:filter .12s;}

/* ---- the FILL panel: pick by looking, not by reading -----------------
   Every chip is drawn with the shape's own colours, so the preview is the
   answer rather than an illustration of one (2026-08-20). */
.sh-menu.fill-panel{display:block;width:268px;padding:6px 7px 8px;}
.fill-row{display:flex;flex-wrap:wrap;gap:5px;margin:3px 0 7px;}
.fill-chip{padding:0;background:none;border:1px solid transparent;
  border-radius:5px;cursor:pointer;line-height:0;display:block;}
.fill-chip:hover{border-color:var(--cyan);}
.fill-chip.on{border-color:var(--cyan);
  box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 45%,transparent);}
.fill-chip svg{display:block;border-radius:4px;}
.fill-dot{width:20px;height:20px;border-radius:5px;display:block;
  border:1px solid #ffffff33;}
/* the custom-colour dot is the spectrum, so it reads as "anything else" */
.fill-custom{background:conic-gradient(#e5484d,#f0a848,#46a892,#39a9c0,
  #6b9bff,#a586e8,#e5484d);}

/* rename a layer in place, like the group folders above it */
.sp-rename{flex:1;min-width:0;font-family:var(--sans);font-size:11.5px;
  background:var(--chrome-0,#0b141d);color:var(--chrome-ink);
  border:1px solid var(--cyan);border-radius:5px;padding:1px 5px;
  outline:none;}

/* the "match another slide" picker: one row per other slide, numbered */
.sh-menu.match-menu{position:fixed;z-index:220;display:block;
  width:236px;padding:5px;max-height:60vh;overflow-y:auto;}
.match-menu .vw-opt{width:100%;text-align:left;}
/* T381: the Update menu is a LIST, not .sh-menu's three-column grid.
   Its rows are phrases ("The whole presentation", "Load locked
   versions"), and in a 210px grid each wrapped into a four-line cell
   (2026-09-12, user: "the options in the button look poor"). One per
   row, full width, left aligned -- the rule the lock trio has always
   needed, now on the menu they live in. Both class names, because
   .sh-menu's grid comes later in this file. */
.sh-menu.upd-menu{display:block;width:250px;padding:5px;}
.upd-menu .dbtn{display:flex;width:100%;text-align:left;
  white-space:normal;margin-top:3px;}
.upd-menu .dbtn[disabled]{opacity:.45;}
/* the folded View group's menu. A row stands in for a toggle button, so
   it has to show the toggle's state — otherwise folding the group would
   lose the one thing a visible toggle was chosen for (2026-08-22). */
/* T679: a LIST, one row per control. It was laid out by .sh-menu's
   three-column grid, so the rows were squeezed into 60px cells, their
   "on" spilled out of them and the headings took a cell each. */
.sh-menu.vw-more-menu{display:flex;flex-direction:column;gap:3px;
  width:auto;min-width:200px;max-height:calc(100vh - 140px);overflow-y:auto;}
.vw-more-menu .vw-opt{width:100%;text-align:left;}
/* T681: Overlay options -- three short lists, a row a choice */
.sh-menu.opt-panel.ovl-panel{min-width:250px;}
.ovl-opt{display:flex;align-items:center;gap:7px;padding:4px 2px;
  font:12.5px var(--sans);color:var(--chrome-ink);cursor:pointer;
  white-space:nowrap;}
.ovl-opt>input{margin:0;flex:none;accent-color:var(--accent);}
.ovl-kinds{display:grid;grid-template-columns:auto auto;column-gap:14px;
  justify-content:start;}
.ovl-num,.ovl-sec{flex:none;font:inherit;font-size:12px;
  padding:2px 4px 2px 6px;border:1px solid var(--chrome-line);
  border-radius:5px;background:var(--chrome-1,#0f1b26);
  color:var(--chrome-ink,#d7e3ec);}
.ovl-num{width:52px;}
.ovl-sec{max-width:190px;}
.vw-more-menu .vw-opt.on{background:color-mix(in srgb,var(--accent) 22%,
  transparent);border-color:var(--accent);color:#fff;}
.vw-more-menu .vw-opt.on::after{content:"On";margin-left:auto;
  font:600 10.5px var(--sans);opacity:.85;}
body.light .vw-more-menu .vw-opt.on{color:var(--ink);}

/* ---- the equation editor -------------------------------------------
   Type on the left, see it set on the right. The palette is the half
   that was missing: "insert equation" used to drop $$ E = mc^2 $$ and
   leave you to remember every command yourself (2026-08-20). */
.eq-dlg{position:fixed;inset:0;z-index:260;display:flex;
  align-items:center;justify-content:center;background:var(--overlay);}
.eq-dlg[hidden]{display:none!important;}
.eq-box{width:min(820px,94vw);max-height:88vh;display:flex;
  flex-direction:column;gap:8px;padding:12px 13px 11px;
  background:var(--chrome-2);border:1px solid var(--chrome-line);
  border-radius:12px;box-shadow:0 24px 70px var(--shadow);
  font-family:var(--sans);}
.eq-head{display:flex;align-items:center;gap:8px;}
/* T219: a dialog's title is a title; a column's heading is a heading */
.eq-t{font-family:var(--sans);font-size:12.5px;font-weight:600;letter-spacing:0;
  text-transform:none;color:var(--chrome-ink);}
.aa-head .eq-t,.eq-head .eq-t{font-size:15px;color:var(--chrome-ink);}
.aa-box .dbtn,.eq-box .dbtn{font-family:var(--sans);font-size:12.5px;}
.eq-main{display:flex;gap:10px;min-height:0;flex:1;}
.eq-left{flex:1.15;min-width:0;display:flex;flex-direction:column;gap:7px;}
.eq-right{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px;}
.eq-src{height:92px;resize:vertical;font-family:var(--mono);
  font-size:12.5px;line-height:1.5;background:var(--chrome-0,#0b141d);
  color:#eaf2f8;border:1px solid #ffffff26;border-radius:7px;
  padding:7px 9px;outline:none;}
.eq-src:focus{border-color:var(--cyan);}
.eq-pal{flex:1;min-height:0;overflow-y:auto;padding-right:2px;}
.eq-palh{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--chrome-ink-2);margin:7px 0 3px;}
.eq-palrow{display:flex;flex-wrap:wrap;gap:3px;}
/* BIG ENOUGH TO READ THE GLYPH. These keys are set in maths precisely
   so you can find sigma by looking for a sigma -- at 11px in a 24px box
   a sigma and a summation sign are the same smudge (2026-08-29, user:
   "the text options in the insert text have boxes too small and can't
   see symbols"). */
.eq-key{font-family:var(--mono);font-size:12.5px;padding:4px 8px;
  min-width:34px;background:var(--btn-bg,#ffffff0a);
  border:1px solid var(--btn-border,#ffffff22);border-radius:5px;
  color:var(--btn-ink,#cdd9e3);cursor:pointer;}
.eq-key:hover{border-color:var(--cyan);color:var(--chrome-ink);}
.eq-plab{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--chrome-ink-2);}
.eq-prev{flex:1;min-height:120px;overflow:auto;display:flex;
  align-items:center;justify-content:center;text-align:center;
  background:var(--chrome-0,#0b141d);border:1px solid #ffffff1f;
  border-radius:7px;padding:10px;color:#eaf2f8;font-size:17px;}
.eq-warn{font-size:11px;line-height:1.4;
  color:color-mix(in srgb,#cf9a4e 40%,var(--chrome-ink));background:#cf9a4e1f;border:1px solid #cf9a4e4d;border-radius:6px;
  padding:6px 8px;}
.eq-foot{display:flex;align-items:center;gap:8px;}
body.light .eq-box{background:var(--chrome-2);
  border-color:var(--chrome-line);}

/* ---- the Apply dialog -------------------------------------------------
   Same shell as the equation editor, two columns wide instead of one. */
.aa-dlg{position:fixed;inset:0;z-index:260;display:flex;
  align-items:center;justify-content:center;background:var(--overlay);}
.aa-dlg[hidden]{display:none!important;}
/* T640: the question is asked from the page body while the editor is
   hidden (askHost), out of reach of `.deck [hidden]` -- so a question
   with no `what` showed an empty .aa-what box (display:flex beats the
   browser's own [hidden]) from the reader and the library */
.ask-dlg [hidden]{display:none!important;}
/* T470: the Style sets picker opened from the Style system sits over
   that screen (z-index 400), not under it */
.aa-dlg.over-design{z-index:410;}
/* T475: the editor's own question sits over every other dialog and
   menu (the apply dialog, the masters panel, the library) */
.aa-dlg.ask-dlg{z-index:300;}
.aa-dlg.ask-dlg.over-design{z-index:420;}
.ask-box{width:min(440px,94vw);}
.ask-lab{font-family:var(--sans);font-size:12.5px;color:var(--chrome-ink-2);}
.ask-in{width:100%;box-sizing:border-box;font:13.5px var(--sans);
  padding:7px 9px;border-radius:7px;color:var(--chrome-ink);
  background:var(--chrome-0,#0b141d);border:1px solid var(--chrome-line);}
.ask-in:focus{outline:none;border-color:var(--accent,var(--cyan));}
.ask-area{resize:vertical;min-height:84px;font:12.5px var(--mono);
  line-height:1.45;}
/* T488: the small form -- label column, field column, a note under a
   row spanning both */
.ask-rows{display:grid;grid-template-columns:auto minmax(0,1fr);
  gap:8px 12px;align-items:center;}
.ask-rows[hidden]{display:none;}
/* a row shown only for some answers (askRowsBuild's `when`): its cell is
   a flex box, which [hidden] alone does not hide */
.ask-rows>[hidden]{display:none;}
.ask-row-lab{font-family:var(--sans);font-size:12.5px;
  color:var(--chrome-ink-2);white-space:nowrap;}
.ask-row-cell{display:flex;align-items:center;gap:8px;min-width:0;}
.ask-rows .ask-in{flex:1 1 auto;}
.ask-rows .ask-num{flex:0 0 84px;width:84px;}
.ask-rows .ask-sel{flex:0 0 auto;width:auto;min-width:120px;padding:5px 8px;
  max-width:100%;}
.ask-rows .ask-range{flex:1 1 auto;min-width:0;accent-color:var(--cyan);}
.ask-rows .ask-check{width:16px;height:16px;accent-color:var(--cyan);
  margin:0;}
.ask-rows .ask-color{width:40px;height:26px;padding:0;border:1px solid
  var(--chrome-line);border-radius:6px;background:none;cursor:pointer;}
.ask-rows .ask-clear{font-size:11px;padding:4px 8px;}
.ask-rows .ask-clear[aria-pressed="true"]{border-color:var(--cyan);
  color:var(--chrome-ink);}
.ask-rows .ask-color:has(+.ask-clear[aria-pressed="true"]){opacity:.35;}
.ask-unit{font-family:var(--sans);font-size:11.5px;color:var(--chrome-ink-3);
  white-space:nowrap;}
.ask-row-note{grid-column:1/-1;font-family:var(--sans);font-size:11.5px;
  color:var(--chrome-ink-3);line-height:1.45;margin-top:-4px;}
.ask-dlg.ask-form .ask-box{width:min(520px,94vw);}
/* T527: a yes/no or a notice keeps the paragraph breaks and bullets of
   what it is asking about ("this will not come across: • …") */
.ask-dlg.ask-yes .aa-what{white-space:pre-line;}
/* the question's own width: `.aa-box` (760px, declared later at the same
   weight) had been winning over `.ask-box` since T475, so a one-line
   name field sat in a box the width of the Apply dialog (T527) */
.aa-box.ask-box{width:min(460px,94vw);}
.ask-dlg.ask-form .aa-box.ask-box{width:min(520px,94vw);}
/* ...and a verb that destroys is red, filled, so "Delete presentation"
   never wears the same cyan as "Save and close" */
.ask-dlg .dbtn.primary.dbtn-warn{background:var(--danger);
  border-color:var(--danger);color:var(--on-accent);
  box-shadow:0 0 0 1px color-mix(in srgb,var(--danger) 40%,transparent),
    0 2px 12px color-mix(in srgb,var(--danger) 35%,transparent);}
.ask-dlg .dbtn.primary.dbtn-warn:hover{
  background:color-mix(in srgb,var(--danger) 86%,black);color:var(--on-accent);}
.aa-box{width:min(760px,94vw);max-height:88vh;display:flex;
  flex-direction:column;gap:9px;padding:12px 13px 11px;
  background:var(--chrome-2);border:1px solid var(--chrome-line);
  border-radius:12px;box-shadow:0 24px 70px var(--shadow);
  font-family:var(--sans);}
.aa-head{display:flex;align-items:center;gap:8px;}
/* positioned, so the type menu (.sh-menu, absolute) opens under the
   chip and not 5px below the bottom of the window (2026-10-08 review) */
.aa-what{position:relative;font-size:13px;color:var(--chrome-ink);line-height:1.5;
  background:var(--chrome-0,#0b141d);border:1px solid #ffffff1a;
  border-radius:8px;padding:8px 10px;display:flex;align-items:center;
  gap:7px;flex-wrap:wrap;}
/* the type chip borrows the treatment a pressed option already has, so a
   highlight the app has never used before does not have to be invented */
.aa-chip{font-family:var(--mono);font-size:11px;letter-spacing:.05em;
  padding:2px 8px;border-radius:11px;
  background:color-mix(in srgb,var(--accent) 14%,transparent);
  border:1px solid color-mix(in srgb,var(--accent) 55%,transparent);
  color:var(--accent);}
.aa-chipbtn{cursor:pointer;font-family:var(--mono);}
.aa-chipbtn:hover{border-color:var(--accent);
  background:color-mix(in srgb,var(--accent) 32%,transparent);}
.aa-typemenu{min-width:250px;}
.aa-n{margin-left:auto;font-family:var(--mono);font-size:11px;
  color:var(--chrome-ink-2);}
.aa-main{display:flex;gap:11px;min-height:0;flex:1;}
.aa-col{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px;}
.aa-colh{display:flex;align-items:center;gap:6px;padding-bottom:5px;
  border-bottom:1px solid #ffffff14;}
.aa-b{padding:3px 9px;font-size:11.5px;}
.aa-props{max-height:52vh;overflow-y:auto;padding-right:3px;}
.aa-scope{max-height:52vh;overflow-y:auto;padding-right:3px;}
.aa-props .find-ck,.aa-scope .find-ck{padding:2px 3px;border-radius:5px;}
.aa-props .find-ck:hover,.aa-scope .find-ck:hover{background:#ffffff0d;}
/* a row that does not fit the selected item is GREYED and explained, not
   hidden: a list that reshuffles itself when you click a different object
   is a list you have to re-read every time */
.aa-props .find-ck.aa-no{opacity:.42;}
.aa-props .find-ck.aa-no input{cursor:not-allowed;}
.aa-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));
  gap:0 9px;}
.aa-sech{display:flex;align-items:center;gap:5px;margin:5px 0 2px;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--accent);}
.aa-slide-n{font-family:var(--mono);font-size:9.5px;color:var(--chrome-ink-3);
  width:16px;flex:none;text-align:right;}
.aa-slide-t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  min-width:0;}
.aa-foot{display:flex;align-items:center;gap:8px;}
/* T558: a dialog's verbs keep their words on one line; the note beside
   them is what wraps ("Keep ink" broke into "Keep / ink" under a
   three-line note at 1366px) */
.aa-foot>.dbtn{flex:none;white-space:nowrap;}
.aa-tie{display:inline-flex;align-items:center;gap:6px;
  font-family:var(--sans);font-size:11.5px;color:var(--chrome-ink-2);
  cursor:pointer;white-space:nowrap;}
.aa-tie[hidden]{display:none!important;}
.aa-tie input{margin:0;cursor:pointer;}
.aa-tie:hover{color:var(--chrome-ink);}
.aa-count{font-family:var(--sans);font-size:12px;color:var(--chrome-ink-2);}
/* the matching items on the slide behind, outlined while you hover the
   headline — a pure class toggle over nodes that are already rendered */
.an-typematch{outline:2px dashed var(--accent)!important;
  outline-offset:2px;}
body.light .aa-box{background:var(--chrome-2);
  border-color:var(--chrome-line);}
/* T625: a dialog's title in the light theme is the theme's ink -- it was
   the dark theme's near-white on a light box, in every dialog */
body.light .aa-head .eq-t,body.light .eq-head .eq-t{color:var(--chrome-ink);}
body.light .aa-what{background:var(--chrome-1,#f4f7fa);
  border-color:var(--line);color:var(--ink);}
body.light .aa-props .find-ck:hover,
body.light .aa-scope .find-ck:hover{background:var(--surface-hover);}
body.light .eq-src,body.light .eq-prev{background:var(--paper-2);
  color:var(--ink);border-color:var(--line);}
/* a typeset key needs room for a fraction without growing the whole row */
.eq-key-tex{font-size:15.5px;padding:4px 8px;min-height:32px;
  display:inline-flex;align-items:center;justify-content:center;}
.eq-key-tex mjx-container{margin:0!important;}

/* ---- the style manager: a specimen per style, sized by its own rule --- */
/* seven rows fitted; seven plus a dozen types of your own plus an open
   editor will not, and floatMenu clamps a menu's top edge without ever
   scrolling it (2026-08-22) */
.sh-menu.style-mgr{display:block;width:292px;padding:6px;
  max-height:min(70vh,520px);overflow-y:auto;}
.stm-arrow{font-size:9px;padding:1px 5px;}
/* the arrow's expander: one at a time, inline, indented under its row so
   it reads as belonging to it rather than as another style */
.stm-edit{margin:2px 3px 7px 10px;padding:7px 8px;border-radius:7px;
  background:var(--chrome-0,#0b141d);border:1px solid #ffffff14;
  display:flex;flex-direction:column;gap:6px;}
.stm-erow{display:flex;gap:4px;flex-wrap:wrap;}
.stm-tg{flex:none;padding:2px 8px;font-size:11px;line-height:1.4;}
.stm-tg[aria-pressed="true"]{border-color:var(--cyan);color:var(--chrome-ink);
  background:color-mix(in srgb,var(--accent) 22%,transparent);}
.stm-ren{width:100%;box-sizing:border-box;font-size:11.5px;
  padding:4px 7px;border-radius:6px;background:var(--chrome-1,#0e1926);
  border:1px solid #ffffff26;color:#eaf2f8;outline:none;
  font-family:var(--sans);}
.stm-ren:focus{border-color:var(--cyan);}
.style-mgr .stm-edit .vw-opt{margin-top:0;}
body.light .stm-edit{background:var(--chrome-1,#f4f7fa);
  border-color:var(--line);}
body.light .stm-ren{background:var(--input-bg);
  border-color:var(--border-strong);color:var(--ink);}
.stm-row{display:flex;align-items:center;gap:6px;padding:2px 3px;}
.stm-empty{padding:7px 4px;color:var(--chrome-ink-2);font-size:11.5px;
  line-height:1.4;}
.stm-spec{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;line-height:1.15;}
.stm-sz{font-family:var(--mono);font-size:9.5px;color:var(--chrome-ink-2);flex:none;}
.stm-b{flex:none;padding:1px 7px;font-size:11px;line-height:1.4;}
.style-mgr .vw-opt{width:100%;margin-top:5px;}

/* ---- notes & timing pane -------------------------------------------- */
.notespane .selpane-list{display:flex;flex-direction:column;gap:5px;
  padding:9px 10px;}
.np-lab{font-family:var(--sans);font-size:11px;font-weight:600;
  letter-spacing:0;color:var(--chrome-ink-2);margin-top:4px;}
.np-notes{min-height:150px;resize:vertical;font-family:var(--sans);
  font-size:12.5px;line-height:1.5;background:var(--chrome-0,#0b141d);
  color:#eaf2f8;border:1px solid #ffffff26;border-radius:7px;
  padding:7px 8px;outline:none;}
.np-notes:focus{border-color:var(--cyan);}
.np-row{display:flex;align-items:center;gap:6px;}
.np-goal{width:74px;font-family:var(--mono);font-size:12px;
  background:var(--chrome-0,#0b141d);color:#eaf2f8;
  border:1px solid #ffffff26;border-radius:6px;padding:4px 6px;
  outline:none;}
.np-goal:focus{border-color:var(--cyan);}
.np-unit{font-family:var(--mono);font-size:10.5px;color:var(--chrome-ink-2);}
.np-clear{padding:2px 7px;font-size:10px;}
.np-tot{font-family:var(--mono);font-size:10.5px;line-height:1.45;
  color:var(--chrome-ink-2);background:#ffffff0a;border-radius:6px;padding:6px 8px;}
.np-tot:empty{display:none;}
/* over your slot is the one thing here worth alarming about */
.np-tot.over{color:color-mix(in srgb,#cf9a4e 40%,var(--chrome-ink));
  background:#cf9a4e1f;}
body.light .np-notes,body.light .np-goal{background:var(--paper-2);
  color:var(--ink);border-color:var(--line);}
/* the Present split button */
.qat-playgrp{display:inline-flex;align-items:stretch;flex:none;}
.qat-playgrp #dc-playmore{padding:4px 7px;}

/* T544: Change case -- five worded rows, each written in the case it
   makes, and the key that steps through them */
.sh-menu.case-menu{display:flex;flex-direction:column;width:224px;
  padding:6px;gap:3px;}
.case-menu .case-key{font-size:11px;line-height:1.35;
  color:var(--chrome-ink-2);padding:6px 4px 2px;}
/* line + paragraph spacing */
.sh-menu.lh-menu{display:block;width:186px;padding:5px;}
.lh-menu .vw-opt{width:100%;text-align:left;}
#hm-upd-menu .vw-opt{width:100%;text-align:left;}
/* paragraph spacing is the gap BETWEEN paragraphs, so it lands on every
   paragraph but the first -- a bullet or a plain line alike (T623: it
   reached only a whole-box list in the show, never the editor's, a list
   in a box with other lines, or lines typed with Enter). Between two
   bullets it replaces their .18em; next to one it is never less. */
.an-p+.an-p{margin-top:var(--an-pspace,0px);}
/* the space after a paragraph (a.paft): padding, so it adds to the next
   one's space before as PowerPoint's does, where margins would merge */
.an-p{padding-bottom:var(--an-paft,0px);}
.an-p[data-list]+.an-p[data-list]{margin-top:var(--an-pspace,.18em);}
.an-p+.an-p[data-list]{margin-top:max(.18em,var(--an-pspace,0px));}
.an-tx br{content:"";display:block;margin-top:var(--an-pspace,0);}

/* ---- the notes pane's three tabs + the scratchpad -------------------- */
/* T470: ONE TAB GRAMMAR PER PANE SHELL. These were 9.5px mono text
   with a class for "on" while the Animation pane's tabs, in the same
   shell, were 11.5px sans with role=tab (2026-09-15 review). They wear
   .anim-tab now; five of them in a 272px pane means the words are set
   a step smaller than Animation's two. */
.np-tabs .anim-tab{font-size:10.5px;padding:6px 3px 5px;letter-spacing:0;}
/* T607: the five words came to 278px in a 270px row, so Rehearsals
   ran into the pane's edge; the row's own gutters are what gives */
.anim-tabs.np-tabs{padding:0 4px;gap:0;}
.np-tall{min-height:230px;}
.np-padbar{display:flex;gap:5px;}
.np-padb{padding:3px 9px;font-size:10.5px;}
.np-padlist{display:flex;flex-direction:column;gap:6px;margin-top:6px;}
.np-fold{border:1px solid #ffffff1f;border-radius:8px;padding:5px;
  display:flex;flex-direction:column;gap:5px;
  background:color-mix(in srgb,var(--accent) 5%,transparent);}
.np-fhead,.np-nhead{display:flex;align-items:center;gap:4px;}
.np-ftitle,.np-ntitle{flex:1;min-width:0;font-family:var(--sans);
  background:none;border:1px solid transparent;border-radius:5px;
  color:#eaf2f8;padding:2px 5px;outline:none;}
.np-ftitle{font-weight:600;font-size:11.5px;}
.np-ntitle{font-size:11.5px;}
.np-ftitle:hover,.np-ntitle:hover,.np-ftitle:focus,.np-ntitle:focus{
  border-color:#ffffff2b;}
.np-nfold{font-family:var(--mono);font-size:9.5px;max-width:84px;
  background:var(--chrome-0,#0b141d);color:#bcccd8;
  border:1px solid #ffffff26;border-radius:5px;padding:1px 3px;}
.np-nx{padding:0 6px;font-size:11px;opacity:.55;}
.np-nx:hover{opacity:1;}
.np-note{border:1px solid #ffffff14;border-radius:7px;padding:4px;
  display:flex;flex-direction:column;gap:3px;}
.np-nbody{min-height:52px;resize:vertical;font-family:var(--sans);
  font-size:11.5px;line-height:1.45;background:var(--chrome-0,#0b141d);
  color:#dbe6ee;border:1px solid #ffffff1f;border-radius:6px;
  padding:4px 6px;outline:none;}
.np-nbody:focus{border-color:var(--cyan);}
body.light .np-nbody,body.light .np-nfold{background:var(--paper-2);
  color:var(--ink);border-color:var(--line);}
body.light .np-ftitle,body.light .np-ntitle{color:var(--ink);}

/* a named FOLDER in the Layers pane. Not a group: filing only, so it gets
   a neutral outline rather than a group's colour bar (2026-08-20). */
.sp-fold2{border-left:3px solid #ffffff33;}
.sp-fico{flex:none;opacity:.65;font-size:11px;}
.sp-row.sp-infold{padding-left:16px;border-left:3px solid #ffffff1f;}

/* a dragged CORNER on a line, and the faint handle that makes one */
.an-endpt.an-mid{background:var(--accent);border-color:#fff;
  width:11px;height:11px;margin:-5.5px 0 0 -5.5px;}
.an-endpt.an-addpt{width:9px;height:9px;margin:-4.5px 0 0 -4.5px;
  background:transparent;border:1.5px dashed
  color-mix(in srgb,var(--accent) 70%,transparent);opacity:.5;}
.an-endpt.an-addpt:hover{opacity:1;background:var(--accent);
  border-style:solid;}
/* ---- icon sizing where JS-built editor chrome swapped an emoji or a
   raw glyph for a .bic svg (2026-08-23). Same rule as app.css: only
   the tight little buttons are clamped below the 14px default. ---- */
.sp-act .bic,.sp-fico .bic{width:12px;height:12px;vertical-align:-2px;}
.vo-eye .bic,.vo-full .bic{width:12px;height:12px;vertical-align:-2px;}
.vo-xall .bic{width:11px;height:11px;vertical-align:-2px;}
.film-mini .bic{width:10px;height:10px;vertical-align:-1px;}
.pane-x .bic,.ss-del .bic{width:10px;height:10px;vertical-align:-1px;}
.an-lockchip .bic{width:10px;height:10px;vertical-align:-2px;}
.an-verwait .bic{width:12px;height:12px;vertical-align:-2px;}
.pickbar .bic{width:13px;height:13px;vertical-align:-2px;}
.dc-mi .bic{width:12px;height:12px;vertical-align:-2px;}
.cellpartbtn .bic{width:10px;height:10px;vertical-align:-1px;}

/* T66: while a slide match is armed every thumbnail is a target, and
   says so the way the canvas says it during an object match. The strip
   is the picker now, so it has to look like one. */
.deck.slide-matching #film-list .film-row{cursor:copy;}
.deck.slide-matching #film-list .film-row .film-label{
  outline:2px dashed var(--accent,#2f6f9f);outline-offset:-2px;
  border-radius:4px;}
.deck.slide-matching #film-list .film-row:hover .film-label{
  outline-style:solid;background:rgba(47,111,159,.10);}
.deck.slide-matching #film-list .film-ctr{opacity:.35;}

/* T74: a markdown box on a slide. Everything is in em of the BOX's own
   type size, the rule a.lh, a.pspace and a.ind already follow, so a
   markdown box means the same thing on a 16:9 slide and an A0 poster. */
.an-md{display:block;text-align:inherit;}
.an-md>:first-child{margin-top:0;}
.an-md>:last-child{margin-bottom:0;}
.an-md h3,.an-md h4,.an-md h5{
  margin:.5em 0 .25em;line-height:1.15;font-weight:700;}
.an-md h3{font-size:1.45em;}
.an-md h4{font-size:1.2em;}
.an-md h5{font-size:1.05em;}
.an-md p{margin:.35em 0;}
.an-md ul,.an-md ol{margin:.35em 0;padding-left:1.3em;}
.an-md li{margin:.12em 0;}
.an-md blockquote{margin:.4em 0;padding-left:.7em;
  border-left:.16em solid currentColor;opacity:.82;}
.an-md code{font-family:var(--mono,ui-monospace,Consolas,monospace);
  font-size:.9em;padding:0 .2em;border-radius:.2em;
  background:rgba(127,127,127,.18);}
/* T467: a fenced block is a block */
.an-md pre{margin:.4em 0;padding:.4em .55em;border-radius:.3em;
  background:rgba(127,127,127,.18);white-space:pre-wrap;
  overflow-wrap:anywhere;font-size:.9em;line-height:1.3;}
.an-md pre code{padding:0;background:none;font-size:1em;}
.an-md h6{margin:.5em 0 .25em;line-height:1.15;font-weight:700;font-size:1em;}
.an-md hr{border:0;border-top:.08em solid currentColor;opacity:.4;
  margin:.5em 0;}
.an-md a{color:inherit;text-decoration:underline;}
/* T546: linked words wear their box's colour, underlined, as a Markdown
   box's links do; a pointer only where a click follows them */
.an-tx a{color:inherit;text-decoration:underline;}
.deck:not(.editing) .an-tx a{cursor:pointer;}
/* the editor's cheat sheet, under the source box */
.md-help{font-size:11px;line-height:1.7;color:var(--chrome-ink-3);padding:8px 2px 0;}
.md-help b{font-weight:600;color:var(--chrome-ink-2);}
/* the preview is a block of the slide text as it will read, left to right
   and top to bottom. It wears .eq-prev for the panel's look, whose flex row
   centred every block side by side: the heading, a sentence and a list
   came out as three narrow centred columns (T737 review) */
.md-prev{overflow:auto;display:block;text-align:left;}

/* T88: the talk panel. Present mode only -- .deck is neither .creating
   nor .editing then, the same test .deck-count already uses one line up
   from here. Never printed: it is chrome, and chrome does not export. */
.talkbtn{position:absolute;right:18px;bottom:38px;z-index:8;
  opacity:.35;transition:opacity .15s ease;}
.talkbtn:hover,.talkbtn[aria-expanded="true"]{opacity:1;}
.deck.creating .talkbtn,.deck.editing .talkbtn,
.deck.creating .talkpane,.deck.editing .talkpane{display:none;}
/* T624: as wide as its widest row (the Ink row's three tools), never
   narrower than it was -- at 266px fixed, Eraser ran out of the pane */
.talkpane{position:absolute;right:18px;bottom:74px;z-index:9;
  width:max-content;min-width:266px;max-width:calc(100% - 58px);
  background:var(--chrome-2,#16273a);border:1px solid #ffffff26;
  border-radius:10px;padding:10px;box-shadow:0 18px 44px #000a;
  display:flex;flex-direction:column;gap:8px;}
.talkpane[hidden]{display:none;}
.tk-h{display:flex;align-items:center;justify-content:space-between;
  font-family:var(--mono);font-size:9px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--cyan-deep);}
.tk-row{display:flex;align-items:center;gap:8px;
  justify-content:space-between;}
.tk-lab{font-size:11px;color:var(--chrome-ink-2);flex:none;}
.tk-grp{display:flex;align-items:center;gap:3px;}
.tk-b{display:flex;align-items:center;gap:6px;font-size:11px;}
.tk-b[aria-pressed="true"]{background:var(--amber);color:var(--on-accent);
  border-color:transparent;}
/* T624: the state IS the button's word now (the row's label names the
   thing), so it reads as one */
.tk-state{font:inherit;letter-spacing:normal;text-transform:none;}
/* the heading's "?" sits beside "This talk", not mid-row */
.tk-h>button.jv-q{margin-right:auto;}
/* T660: a talk's parts -- shown only where it has them */
.tk-row[hidden]{display:none;}
.tk-sel{min-width:0;max-width:220px;font:12px var(--sans);
  padding:4px 6px;border-radius:6px;border:1px solid var(--border-strong);
  background:var(--input-bg);color:var(--chrome-ink);}
@media print{.talkbtn,.talkpane{display:none !important;}}
/* ---- T391: THE ANIMATION STORY -----------------------------------------
   A strip between the ribbon and the stage. Each stop is a real render
   of the slide at that stop, scaled with zoom; the one the stage is
   showing is lit. An object off the stage at this stop is display:none,
   not opacity 0, so nothing invisible can be picked up by mistake. */
/* T580: the head is a COLUMN at the left and the cards take the rest,
   so the strip is one card tall and nothing in its head can end up
   under a pane docked over the right of the stage */
.story-strip{flex:none;border-bottom:1px solid var(--chrome-line);
  background:var(--chrome-1);padding:6px 12px 6px;display:flex;gap:10px;
  align-items:flex-start;}
.story-head{flex:none;width:92px;display:flex;flex-direction:column;
  align-items:flex-start;gap:5px;padding-top:2px;}
.story-lab{font:600 10px/1.25 var(--mono);letter-spacing:.1em;
  text-transform:uppercase;color:var(--chrome-ink-2);}
.story-n{font:11px var(--sans);color:var(--chrome-ink-2);}
.story-x{height:24px;padding:0 8px;font-size:11px;}
.story-row{flex:1;min-width:0;display:flex;gap:8px;overflow-x:auto;
  padding-bottom:4px;scrollbar-width:thin;}
.story-stop{flex:none;display:flex;flex-direction:column;gap:3px;
  padding:4px;border:1px solid var(--chrome-line);border-radius:7px;
  background:#ffffff06;cursor:pointer;color:var(--chrome-ink);
  text-align:left;width:calc(128px + 8px);}
/* the Whole slide card is not a moment of the show; dashed says so */
.story-stop.story-whole{border-style:dashed;}
/* T580: cards drag; the landing side, or the whole card for "onto" */
.story-stop[draggable="true"]{cursor:grab;}
.story-stop.dragging{opacity:.5;}
.story-stop.drop-before{box-shadow:-3px 0 0 0 var(--cyan);}
.story-stop.drop-after{box-shadow:3px 0 0 0 var(--cyan);}
.story-stop.drop-with{box-shadow:inset 0 0 0 2px var(--cyan);}
.story-stop:hover{border-color:color-mix(in srgb,var(--accent) 55%,transparent);}
.story-stop.on{border-color:var(--cyan);
  background:color-mix(in srgb,var(--accent) 14%,transparent);}
.story-pic{position:relative;overflow:hidden;border-radius:4px;
  background:#0b141d;}
.story-pic .story-slide{position:absolute;left:0;top:0;pointer-events:none;}
.story-cap{display:flex;flex-direction:column;gap:1px;
  font:10.5px/1.25 var(--sans);color:var(--chrome-ink-2);
  overflow:hidden;}
.story-cap b{color:var(--chrome-ink);font-weight:600;}
.story-cap span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.story-paint{position:fixed;left:-99999px;top:0;width:1280px;z-index:-1;}
.an-item.an-storyout,.an-arrow-line.an-storyout{display:none!important;}
/* the stage says it is showing a stop, so an empty-looking slide is
   read as "at this click" and not as "my things are gone" */
.deck.storying .deck-stage{box-shadow:inset 0 0 0 2px
  color-mix(in srgb,var(--accent) 45%,transparent);}
/* ---- T389: THE SCROLLING VERSION ---------------------------------------
   An overlay over the editor; the pages inside are buildPrintRoot's,
   given back their static flow and scaled with `zoom` to the width. An
   armed object keeps its entrance's from-state through its delay
   (fill-mode backwards), so a slide's things arrive a beat apart
   instead of all popping in before their turn. */
.deck-scroll{position:fixed;inset:0;z-index:400;display:flex;
  flex-direction:column;background:#20262c;}
.deck-scroll-bar{display:flex;align-items:center;gap:12px;padding:8px 14px;
  background:var(--chrome-1);border-bottom:1px solid var(--chrome-line);
  color:var(--chrome-ink);flex:none;}
.deck-scroll-t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font:600 13px var(--sans);}
.deck-scroll-n{font:11px var(--mono);color:var(--chrome-ink-2);}
.deck-scroll-body{flex:1 1 auto;overflow-y:auto;padding:24px 0;}
.deck-scroll .scroll-root{position:static;left:auto;top:auto;width:auto;
  z-index:auto;}
.deck-scroll .print-page{margin:0 auto 24px;box-shadow:0 8px 40px #0008;}
/* T620: between the slides. Spaced is T389's cards; the other three run
   the pages edge to edge, as one long page, and differ in the line at
   each join. The line is a zero-height element between two pages with
   its stroke drawn across the join, above both (z-index), in a
   see-through grey: lighter than a dark slide, darker than a white one,
   so "faint" is faint on either. */
.deck-scroll:not([data-sep="gap"]) .print-page{margin:0 auto;box-shadow:none;}
.deck-scroll .scroll-sep{display:none;position:relative;z-index:1;height:0;
  margin:0 auto;}
.deck-scroll[data-sep="faint"] .scroll-sep,
.deck-scroll[data-sep="strong"] .scroll-sep{display:block;}
.deck-scroll .scroll-sep::after{content:"";position:absolute;left:0;right:0;}
.deck-scroll[data-sep="faint"] .scroll-sep::after{top:0;height:1px;
  background:#8a939c80;}
.deck-scroll[data-sep="strong"] .scroll-sep::after{top:-1px;height:2px;
  background:#7a838cf2;}
/* the choice, in the bar: a label and four worded buttons, each with a
   small picture of its join */
.deck-scroll-bar{flex-wrap:wrap;row-gap:6px;}
.deck-scroll-sep{display:inline-flex;align-items:center;gap:3px;flex:none;}
.deck-scroll-seplab{font:11px var(--sans);color:var(--chrome-ink-2);
  margin-right:4px;white-space:nowrap;}
.deck-scroll-sepb{display:inline-flex;align-items:center;gap:6px;
  font-size:12px;padding:3px 9px;white-space:nowrap;}
.deck-scroll-sepb[aria-pressed="true"]{border-color:var(--cyan);
  color:var(--chrome-ink);background:color-mix(in srgb,var(--cyan) 18%,transparent);}
.deck-scroll-sw{width:12px;height:14px;flex:none;border-radius:2px;
  background:#d6dce1;}
.deck-scroll-sepb[data-sep="faint"] .deck-scroll-sw{
  background:linear-gradient(#d6dce1 0 6px,#8a939c 6px 7px,#d6dce1 7px);}
.deck-scroll-sepb[data-sep="strong"] .deck-scroll-sw{
  background:linear-gradient(#d6dce1 0 6px,#4d555c 6px 8px,#d6dce1 8px);}
.deck-scroll-sepb[data-sep="gap"] .deck-scroll-sw{
  background:linear-gradient(#d6dce1 0 5px,transparent 5px 9px,#d6dce1 9px);}
@media (max-width:760px){.deck-scroll-seplab{display:none;}}
/* ---- T622: THE SCROLL VIEW ----------------------------------------------
   The editor's stage as a column: the live page (always its first child,
   see 54b-scroll-view.js) and a picture of every other slide, put in
   deck order by `order`. The stage scrolls; its gutter is kept so the
   page measured before the pictures arrive is the page that fits after.
   `safe center`: a page zoomed wider than the stage starts at its left
   edge instead of being cut off there. */
.deck.editing .deck-stage.sv{flex-direction:column;justify-content:flex-start;
  align-items:safe center;overflow:auto;scrollbar-gutter:stable;}
.deck-stage.sv>.slide,.deck-stage.sv>.sv-pic{flex:none;}
/* the pages meet edge to edge: no frame of their own, no entrance (the
   swap from a picture to the live page must not be seen) */
.deck.editing .deck-stage.sv>.slide{border:none;border-radius:0;
  animation:none;}
.deck.editing .deck-stage.sv:not([data-sep="gap"])>.slide{box-shadow:none;}
/* each page lit for itself (applyPageBg): the class sits ON the live
   page, where `.page-light .slide` cannot see it, so its two rules that
   key on the page or the deck are said again for it */
.deck-stage.sv>.slide.page-light{color:var(--tk-ink,#1b2733);}
.deck.editing .deck-stage.sv>.slide.page-light .an-cell.sel{
  background:#ffffffd0;}
.deck.editing .deck-stage.sv>.slide.page-light .an-cell.empty{
  background:#00000008;border-color:#00000030;}
/* above the pictures, so a handle or a box hanging off the page's edge
   is drawn over the next slide rather than under it */
.deck-stage.sv>.sv-live{position:relative;z-index:2;}
.deck-stage.sv>.sv-pic{position:relative;overflow:hidden;margin:0 auto;
  background:var(--page-bg,#0b141d);cursor:pointer;}
.deck-stage.sv>.sv-pic:hover{outline:2px solid
  color-mix(in srgb,var(--cyan) 45%,transparent);outline-offset:-2px;}
.deck-stage.sv>.sv-pic>.print-page{position:absolute;left:0;top:0;
  pointer-events:none;}
.deck-stage.sv .sv-pic .slide{border:none;border-radius:0;box-shadow:none;
  margin:0;width:auto;max-height:none;aspect-ratio:auto;animation:none;}
/* Spaced: cards a gap apart, each with the editor's own shadow */
.deck-stage.sv[data-sep="gap"]>.slide,
.deck-stage.sv[data-sep="gap"]>.sv-pic{margin-bottom:22px;}
.deck-stage.sv[data-sep="gap"]>.sv-pic{box-shadow:0 14px 60px #00000066;}
/* the lines, as the scrolling page draws them (T620): zero height,
   stroked across the join, above both pages */
.deck-stage.sv>.sv-sep{display:none;flex:none;position:relative;z-index:3;
  height:0;margin:0 auto;pointer-events:none;}
.deck-stage.sv[data-sep="faint"]>.sv-sep,
.deck-stage.sv[data-sep="strong"]>.sv-sep{display:block;}
.deck-stage.sv>.sv-sep::after{content:"";position:absolute;left:0;right:0;}
.deck-stage.sv[data-sep="faint"]>.sv-sep::after{top:0;height:1px;
  background:#8a939c80;}
.deck-stage.sv[data-sep="strong"]>.sv-sep::after{top:-1px;height:2px;
  background:#7a838cf2;}
/* T699: where the next presentation begins, whatever the lines are: a
   band of its own, the presentations a gap apart, with the next one's
   name over its line */
.deck-stage.sv>.sv-sep.pz{display:flex;align-items:flex-end;height:34px;
  padding-bottom:6px;box-sizing:border-box;}
.deck-stage.sv>.sv-sep.pz::after{top:auto;bottom:0;height:3px;
  border-radius:2px;background:var(--pzl,var(--accent));}
.deck-stage.sv>.sv-sep.pz::before{content:attr(data-name);
  font:600 12px var(--sans);color:var(--chrome-ink-2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;}
.deck-stage.sv[data-dir="across"]>.sv-sep.pz{width:34px;height:auto;
  align-items:center;justify-content:flex-end;padding:0 6px 0 0;
  writing-mode:vertical-rl;}
.deck-stage.sv[data-dir="across"]>.sv-sep.pz::after{left:auto;right:0;
  top:0;bottom:0;width:3px;height:auto;}
/* ---- T678: ACROSS --------------------------------------------------------
   The column laid on its side (54b-scroll-view.js): the pages in a row,
   each as tall as the view, the row centred while it fits. Every margin
   that spaced the column down spaces the row along -- the live page's
   inline margin:auto included, which in a row would push its neighbours
   to the ends of the view. The line between two pages stands up between
   them. Under the thumbnails (54c) the stage keeps no scrollbar of its
   own: they are the row's. Without them, a scrollbar always there, so
   the page measured before the pictures arrive is the page that fits
   after -- the column's stable gutter, turned. */
.deck.editing .deck-stage.sv[data-dir="across"]{flex-direction:row;
  justify-content:safe center;overflow:auto;scrollbar-gutter:auto;}
.deck.editing .deck-stage.sv[data-dir="across"]:not([data-bar]){
  scrollbar-width:none;}
.deck.editing .deck-stage.sv[data-dir="across"][data-bar]{overflow-x:scroll;}
.deck.editing .deck-stage.sv[data-dir="across"]>.slide{margin:auto 0!important;}
.deck-stage.sv[data-dir="across"]>.sv-pic{margin:auto 0;}
.deck.editing .deck-stage.sv[data-dir="across"][data-sep="gap"]>.slide{
  margin:auto 22px auto 0!important;}
.deck-stage.sv[data-dir="across"][data-sep="gap"]>.sv-pic{
  margin:auto 22px auto 0;}
.deck-stage.sv[data-dir="across"]>.sv-sep{width:0;margin:auto 0;}
.deck-stage.sv[data-dir="across"]>.sv-sep::after{top:0;bottom:0;right:auto;}
.deck-stage.sv[data-dir="across"][data-sep="faint"]>.sv-sep::after{
  left:0;width:1px;height:auto;}
.deck-stage.sv[data-dir="across"][data-sep="strong"]>.sv-sep::after{
  top:0;left:-1px;width:2px;height:auto;}
/* the scrolling page, across: a row of pages as tall as the window */
.deck-scroll[data-dir="across"] .deck-scroll-body{display:flex;
  overflow-x:auto;overflow-y:hidden;padding:24px;}
.deck-scroll[data-dir="across"] .scroll-root{display:flex;align-items:center;
  width:max-content;margin:auto;}
.deck-scroll[data-dir="across"].svr-on .deck-scroll-body{scrollbar-width:none;}
.deck-scroll[data-dir="across"] .print-page{flex:none;margin:0 24px 0 0;}
.deck-scroll[data-dir="across"]:not([data-sep="gap"]) .print-page{margin:0;}
.deck-scroll[data-dir="across"] .scroll-sep{flex:none;width:0;margin:0;}
.deck-scroll[data-dir="across"] .scroll-sep::after{top:0;bottom:0;right:auto;}
.deck-scroll[data-dir="across"][data-sep="faint"] .scroll-sep::after{
  left:0;width:1px;height:auto;}
.deck-scroll[data-dir="across"][data-sep="strong"] .scroll-sep::after{
  top:0;left:-1px;width:2px;height:auto;}
.deck-scroll-railb[hidden]{display:none;}
.deck-scroll-sepb .bic{width:12px;height:12px;}
/* ---- T678: THE THUMBNAILS ALONG THE BOTTOM (54c-thumb-rail.js) -----------
   A bar the sheet tabs' height and look (T654), a row of small slides in
   it and its pin at the end. Kept, it is in the layout, under the page
   and above the tabs; otherwise it waits below the view, faded out, and
   comes up over the page's foot when the strip under it is pointed at,
   as the auto-hidden tabs come up over it. Kept, a docked pane stops
   above it, as it stops above the tabs; either way it stops short of
   the side toolbar. */
.deck,.deck-scroll{--svr-h:76px;--svr-th-h:54px;--svr-right:0px;}
.deck.rbn-side{--svr-right:var(--rbn-side-w);}
.deck.editing.svr-on.svr-kept .selpane{bottom:calc(var(--svr-h) + 8px);}
.deck.editing.svr-on.svr-kept.sheets-on:not(.sheets-auto) .selpane{
  bottom:calc(var(--svr-h) + var(--sht-h) + 8px);}
.sv-rail{display:flex;align-items:center;gap:6px;height:var(--svr-h);
  box-sizing:border-box;padding:0 8px 0 6px;border-top:1px solid #ffffff1c;
  background:var(--chrome-1,#0e1926);color:var(--chrome-ink);}
.sv-rail[hidden],.sv-rail-hot[hidden]{display:none;}
.svr-list{flex:1;min-width:0;height:100%;display:flex;align-items:center;
  gap:6px;padding:0 2px;position:relative;overflow-x:auto;overflow-y:hidden;
  scrollbar-width:thin;}
.svr-th{flex:none;position:relative;padding:0;line-height:0;cursor:pointer;
  border:2px solid transparent;border-radius:6px;background:none;}
.svr-th .svr-mini{width:var(--svr-th-w,96px);height:var(--svr-th-h);
  border-radius:3px;overflow:hidden;pointer-events:none;}
.svr-th:hover{border-color:color-mix(in srgb,var(--cyan) 45%,transparent);}
.svr-th.on{border-color:var(--accent);}
.svr-th.hid .svr-mini{opacity:.45;}
.svr-th:focus-visible{outline:2px solid var(--focus);outline-offset:1px;}
.svr-n{position:absolute;left:4px;bottom:4px;padding:2px 4px;border-radius:3px;
  font:600 9.5px/1 var(--mono);background:#000000a6;color:#fff;
  pointer-events:none;}
.svr-run{flex:none;align-self:stretch;display:flex;align-items:center;
  max-width:130px;margin-left:6px;padding:0 6px 0 8px;
  border-left:3px solid var(--run-c,var(--chrome-ink-3));
  font:11px var(--sans);color:var(--chrome-ink-2);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;}
.svr-run:first-child{margin-left:0;}
.svr-pin{flex:none;display:inline-flex;align-items:center;gap:4px;
  padding:3px 8px;font-size:11.5px;white-space:nowrap;}
.svr-pin .bic{width:12px;height:12px;}
.svr-pin[aria-pressed="true"]{border-color:var(--cyan);
  background:color-mix(in srgb,var(--cyan) 18%,transparent);}
body.light .sv-rail{border-top-color:#0000001f;}
/* kept: in the layout (the page is fitted to what is left above it) */
.sv-rail.kept{position:relative;flex:none;}
.deck-stagewrap>.sv-rail.kept{margin-right:var(--svr-right);}
/* waiting: over the foot of the view, faded and let through */
.sv-rail.auto{position:absolute;left:0;bottom:0;z-index:66;
  opacity:0;visibility:hidden;transform:translateY(10px);pointer-events:none;
  box-shadow:0 -6px 18px #00000055;
  transition:opacity .16s ease,transform .16s ease,bottom .16s ease,
    visibility 0s linear .16s;}
.deck-stagewrap>.sv-rail.auto{right:var(--svr-right);}
.deck-scroll>.sv-rail.auto{right:0;z-index:3;}
.sv-rail.auto.peek{opacity:1;visibility:visible;transform:none;
  pointer-events:auto;
  transition:opacity .16s ease,transform .16s ease,bottom .16s ease,
    visibility 0s;}
.sv-rail-hot{position:absolute;left:0;right:0;bottom:0;height:10px;z-index:65;}
.deck-scroll>.sv-rail-hot{z-index:2;}
/* above the sheet tabs while they are in the layout; with them hidden
   as well, the one bottom edge is theirs and raises both (shtPeek) */
.deck.editing.sheets-on:not(.sheets-auto) .deck-stagewrap>.sv-rail.auto,
.deck.editing.sheets-on:not(.sheets-auto) .deck-stagewrap>.sv-rail-hot{
  bottom:var(--sht-h);}
.deck.editing.sheets-auto.sheets-peek .deck-stagewrap>.sv-rail.auto{
  bottom:var(--sht-h);}
.deck.editing.sheets-auto.sheets-on .deck-stagewrap>.sv-rail-hot{
  display:none;}
@media (prefers-reduced-motion:reduce){
  .sv-rail.auto,.sv-rail.auto.peek{transition:none;}}
/* belt and braces: a deferred re-render (text fitting runs a tick
   later) can put the editor's ring back on a page after buildPrintRoot
   has stripped it, so no page ever draws one */
.print-page .sel{outline:none!important;}
.an-scrollin{animation-fill-mode:backwards!important;}
/* ---- T386: THE TALK'S TOOLS --------------------------------------------
   All three sit above the deck (z 100) and the spotlight (400) but
   under the drawer's library dialog; none of them take the pointer, so
   a click still lands on the slide and advances. */
.jv-laserdot{position:fixed;z-index:420;width:16px;height:16px;
  margin:-8px 0 0 -8px;border-radius:50%;pointer-events:none;
  background:#ff3b30;box-shadow:0 0 6px 2px #ff3b30aa,0 0 22px 8px #ff3b3055;}
body.jv-laser .deck-stage{cursor:none;}
/* T465: the lens ELEMENT is .jv-lensbox; .jv-lens is the BODY flag
   (talkSync toggles it, the rule below reads it). They were one name,
   so the body itself was position:fixed and pointer-events:none while
   the magnifier was up -- every click in the show died, including the
   Magnifier and Close buttons that would have ended it (2026-09-15
   review). tests/test_talk_tools.py now refuses a body flag that is
   also a bare element selector. */
.jv-lensbox{position:fixed;z-index:420;border-radius:50%;overflow:hidden;
  pointer-events:none;border:3px solid #ffffffcc;
  box-shadow:0 0 0 1px #0008,0 18px 48px #000a;background:#000;}
.jv-lens-in{position:absolute;inset:0;}
body.jv-lens .deck-stage{cursor:crosshair;}
.jv-black{position:fixed;inset:0;z-index:430;background:#000;cursor:pointer;}
.tk-grp .tk-b{flex:1 1 auto;}

/* T64: the free-crop lasso. An overlay over the annot layer, so the
   canvas mousedown handler -- gatekeeper for selection, marquee, resize,
   rotate, group entry and eight tools -- never learns about it. */
.crop-lasso{position:absolute;inset:0;z-index:40;cursor:crosshair;
  background:#0006;touch-action:none;}
.cl-ink{position:absolute;inset:0;width:100%;height:100%;
  pointer-events:none;overflow:visible;}
.cl-poly{fill:#ffffff1f;stroke:var(--amber,#f0a848);stroke-width:.5;
  vector-effect:non-scaling-stroke;stroke-dasharray:3 2;}
.cl-hint{position:absolute;left:50%;top:8px;transform:translateX(-50%);
  background:var(--chrome-2,#16273a);color:var(--chrome-ink);font-size:11px;
  padding:4px 9px;border-radius:6px;white-space:nowrap;
  pointer-events:none;box-shadow:0 6px 18px #0008;}

/* T90: the history rail is a tree now. Depth is an indent and a rule
   rather than a drawn graph -- twenty snapshots four deep is a list with
   steps in it, and a canvas would be a second way of drawing what the
   rail already draws. */
/* ---- T237: THE GRAPH REPLACED THE INDENT ---------------------------
   T90 drew the shape of the tree by indenting each row by its depth
   and heading each run with its branch name, because "the shape reads
   without drawing a graph". It does not, past two branches
   (2026-09-04, user: "like how you can see the git history thing
   where you can just see the little lines with the dots for versions
   and then can see branches as different colours from that. I really
   like that design"). Each row now carries an SVG gutter: one lane
   per branch, in its own colour, with the dot on the lane the version
   belongs to and an elbow where a branch leaves its parent. */
.dh-r{display:grid;
  grid-template-columns:var(--dh-gutter,18px) minmax(0,1fr) 26px;
  align-items:stretch;gap:0;}
.dh-gutter{display:block;line-height:0;}
.dh-gsvg{display:block;}
.dh-ren{padding:0;width:22px;align-self:center;justify-self:center;
  opacity:0;font-size:11px;}
.dh-r:hover .dh-ren,.dh-ren:focus-visible{opacity:1;}
.dh-ren svg{width:11px;height:11px;}
.dh-brlab{display:flex;align-items:center;gap:6px;
  font-family:var(--mono);font-size:8.5px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--cyan-deep);padding:10px 8px 4px;}
.dh-brlab svg{width:11px;height:11px;}
.dh-snap{border-left:3px solid var(--dh-lane,transparent);
  border-left:2px solid transparent;}
.dh-snap.head{border-left-color:var(--amber,#f0a848);}
.dh-snap.head .dh-when{color:var(--warning,#f0a848);}   /* T465: per-scheme */
.dh-snap.forked .dh-why{color:var(--cyan);}
.dh-onbr{display:inline-flex;align-items:center;gap:5px;margin-left:10px;
  font-family:var(--mono);font-size:10px;color:var(--cyan);
  border:1px solid #ffffff26;border-radius:999px;padding:2px 9px;}
.dh-onbr svg{width:11px;height:11px;}
.dh-branch{margin-left:8px;}

/* T87: the design surface. Deliberately the history overlay's shape --
   full screen, a rail of things on the left, one of them open on the
   right -- because it is the same kind of screen and a second layout for
   it would be a second idea about what a full-screen view is. */
.deck-design{position:fixed;inset:0;z-index:400;display:flex;
  flex-direction:column;background:var(--chrome-0,#0b141d);
  font-family:var(--sans);}
.dg-main{display:flex;flex:1 1 auto;min-height:0;}
/* T443: the count table in the rail -- T490: the loose bands only,
   after the style rows; a style's own count and its odd wearers sit on
   its row */
.dg-counts{margin-top:8px;padding-top:6px;
  border-top:1px solid var(--chrome-line);}
.dg-cnt.dg-rownote{margin:-3px 7px 4px;padding:2px 3px 3px;cursor:default;
  flex-wrap:nowrap;border-top:1px solid #ffffff12;border-radius:0;}
.dg-cnt.dg-rownote:hover{background:none;}
.dg-cnt.dg-rownote .dg-cnt-note,.dg-cnt.dg-rownote .dg-cnt-fix{
  margin-left:0;}
.dg-cnt.dg-rownote .dg-cnt-note{flex:1 1 auto;}
.dg-cnt.dg-rownote .dg-cnt-fix{flex:none;width:auto;padding:2px 8px;}
.dg-cnt{display:flex;flex-wrap:wrap;align-items:center;gap:4px 6px;
  padding:4px 6px;border-radius:6px;font:12px var(--sans);
  color:var(--chrome-ink);cursor:pointer;}
.dg-cnt:hover{background:#ffffff0c;}
.dg-cnt-n{font:600 13px var(--mono);min-width:22px;text-align:right;
  color:var(--cyan);}
.dg-cnt-l{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}
.dg-cnt-odd .dg-cnt-l{color:var(--amber);}
.dg-cnt-note{flex:1 0 calc(100% - 28px);margin-left:28px;min-width:0;
  font-size:11px;color:var(--amber);}
.dg-cnt-loose .dg-cnt-l{color:var(--chrome-ink-2);}
/* the fix on its own line under the words, so neither is squeezed */
.dg-cnt .dg-cnt-fix{font-size:10.5px;padding:2px 6px;
  flex:1 0 calc(100% - 28px);min-width:0;box-sizing:border-box;
  margin-left:28px;width:auto;justify-content:center;}
/* T444: the deck colours panel's preview */
.tok-preview{margin:4px 0 8px;}
.tok-pv-page{border-radius:6px;padding:8px 10px;font:12px var(--sans);
  border:1px solid var(--chrome-line);}
.tok-pv-h{font-weight:700;font-size:14px;margin-bottom:2px;}
.tok-pv-box{margin-top:6px;padding:4px 8px;border-radius:5px;
  border:1px solid;font-size:11px;}
.dg-rail{width:216px;flex:none;overflow-y:auto;padding:8px;
  border-right:1px solid #ffffff14;display:flex;flex-direction:column;
  gap:3px;}
.dg-body{flex:1 1 auto;min-width:0;overflow-y:auto;padding:16px 22px 40px;}
.dg-row{display:flex;align-items:baseline;justify-content:space-between;
  gap:8px;text-align:left;background:transparent;border:1px solid
  transparent;border-radius:7px;padding:7px 9px;color:inherit;
  cursor:pointer;width:100%;}
.dg-row:hover{background:#ffffff0d;}
.dg-row.on{background:#ffffff14;border-color:#ffffff2b;}
.dg-name{line-height:1.15;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;font-size:15px;font-weight:500;
  font-style:normal;font-family:var(--sans);}
/* T295: a variation sits under the type it varies, and its colour
   rides on a chip -- the NAME is deliberately left uncoloured, because
   a style whose ink is the page's would vanish against this chrome. */
.dg-row.dg-rowvar{padding-left:22px;position:relative;}
.dg-row.dg-rowvar::before{content:"";position:absolute;left:10px;top:50%;
  width:6px;height:1px;background:var(--chrome-ink-3);}
.dg-swatch{flex:none;width:11px;height:11px;border-radius:3px;
  border:1px solid #ffffff33;margin-left:6px;}
body.light .dg-swatch{border-color:#00000026;}
.dg-count{font-family:var(--sans);font-size:11.5px;color:var(--chrome-ink-2);
  flex:none;}
/* T230: a heading, in words. It was 10px spaced capitals -- the very
   thing the ribbon gave up in T219 -- with three other type sizes
   stacked under it (2026-09-03, user: "all the text is a bit
   confusing here. There is text of heaps of different sizes and
   different width everywhere"). */
/* T465: the screen's ink is the theme's (three headings, the slide
   chips and the scope select were dark-only literals, invisible or an
   island in Light -- 2026-09-15 review) */
.dg-h{font-family:var(--sans);font-size:15px;font-weight:600;
  letter-spacing:0;text-transform:none;color:var(--chrome-ink);margin:26px 0 5px;}
.dg-h:first-child{margin-top:0;}
.dg-sub{margin:0 0 10px;font-size:12.5px;line-height:1.55;color:var(--chrome-ink);
  max-width:62ch;}
.dg-spec{padding:12px 14px;border:1px solid #ffffff1a;border-radius:8px;
  /* the ACTUAL page colour, not chrome: a dark style meant for a light
     slide was unreadable in its own preview (JVUX-10) */
  background:var(--page-bg,#ffffff08);line-height:1.3;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;}
/* T519: one job at a time. The old screen showed the style editor,
   placement board, instance table and slide navigator simultaneously. */
.dg-navrow{display:flex;align-items:flex-start;gap:8px;margin:8px 0 16px;
  border-bottom:1px solid var(--chrome-line,#ffffff1f);}
.dg-tabs{display:flex;flex:1 1 auto;gap:4px;margin:0;padding-bottom:10px;
  overflow-x:auto;}
.dg-tab{min-width:128px;justify-content:center;white-space:nowrap;}
.dg-tab[aria-selected="true"]{background:var(--accent-deep,var(--cyan-deep));
  border-color:var(--accent-deep,var(--cyan-deep));
  color:var(--on-accent-deep,#fff);}
.dg-sheet-toggle{flex:none;margin-left:auto;white-space:nowrap;}
.dg-viewhead{display:flex;align-items:center;justify-content:space-between;
  gap:12px;margin-bottom:8px;}
.dg-viewhead .dg-h{margin:0;}
/* T519: a property sheet, not differently sized islands. Two regular
   columns keep labels and controls aligned; Colours needs the whole row. */
.dg-ctrls{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:0 18px;margin-top:12px;padding:4px 12px;
  border:1px solid #ffffff1c;border-radius:8px;background:#ffffff04;}
.dg-grp{display:flex;align-items:center;gap:4px;min-width:0;padding:8px 0;
  border:0;border-bottom:1px solid #ffffff14;background:none;}
.dg-grp[data-group="colours"],.dg-grp[data-group="reset"]{
  grid-column:1/-1;}
.dg-grp[data-group="reset"]{justify-content:flex-end;border-bottom:0;}
.dg-grplab{font-family:var(--sans);font-size:11px;color:var(--chrome-ink-2);
  width:72px;flex:none;margin-right:3px;white-space:nowrap;}
.dg-grplab:empty{display:none;}
.dg-b{min-width:30px;}
.dg-size{font-family:var(--mono);font-size:11px;color:var(--chrome-ink);
  min-width:112px;text-align:center;white-space:nowrap;}
.dg-family-name{margin:7px 8px 1px;color:var(--muted);font-size:10px;
  font-weight:700;letter-spacing:.08em;text-transform:uppercase;}
.jv-style-family{display:block;border:1px solid #ffffff14;
  border-radius:7px;margin:4px 0;background:#ffffff04;}
.jv-style-family-head{display:flex;align-items:stretch;gap:5px;padding:5px;}
.jv-style-family-head>.jv-styleopt{flex:1 1 auto;width:auto;min-width:0;
  margin:0;}
.jv-style-expand{flex:none;width:58px;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:2px;padding:3px;
  font:10px/1.1 var(--sans);color:var(--chrome-ink-2);}
.jv-style-expand .bic{width:14px;height:14px;}
.jv-style-expand.on{background:var(--accent-deep,var(--cyan-deep));
  border-color:var(--accent-deep,var(--cyan-deep));
  color:var(--on-accent-deep,#fff);}
.jv-style-family-children{border-top:1px solid #ffffff14;padding:5px;}
.jv-style-family-children[hidden]{display:none!important;}
.jv-style-family-children>.jv-styleopt{margin:0 0 4px;width:100%;}
.jv-style-family-children>.jv-styleopt:last-child{margin-bottom:0;}
.dg-col{width:30px;height:26px;padding:0;border:1px solid #ffffff26;
  border-radius:6px;background:transparent;cursor:pointer;}
/* the board: a slide, and a rectangle you drag on it */
/* T368: the looks a type comes in, on the type's own page */
.dg-looks{display:flex;flex-wrap:wrap;align-items:center;gap:6px;
  margin:2px 0 10px;}
.dg-lookslab{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--chrome-ink-3,#8ea2b3);
  padding-right:4px;}
.dg-look{font-size:12.5px;padding:3px 10px;border-radius:7px;}
.dg-look.on{border-color:var(--cyan);}
.dg-lookmore{position:relative;}
.dg-lookmore>summary{list-style:none;cursor:pointer;border-style:dashed;}
.dg-lookmore>summary::-webkit-details-marker{display:none;}
.dg-lookoffers{position:absolute;z-index:5;top:calc(100% + 5px);left:0;
  display:flex;gap:6px;padding:7px;background:var(--chrome-1,#13202c);
  border:1px solid var(--chrome-line,#ffffff26);border-radius:8px;
  box-shadow:0 10px 28px #0008;white-space:nowrap;}
.dg-slotpick{font-family:var(--sans);font-size:12px;
  background:var(--btn-bg,#ffffff0e);color:var(--chrome-ink);
  border:1px solid var(--chrome-line,#ffffff26);border-radius:6px;
  padding:3px 6px;}
/* Look and Position now share the same calm single-column canvas; the tabs
   say which question it answers, so duplicate all-caps column labels are gone. */
.dg-top{display:block;width:100%;max-width:980px;margin-top:2px;}
.dg-typecol .dg-ctrls{margin-top:12px;}
.dg-typecol .dg-spec{white-space:normal;line-height:1.2;}
.dg-boardwrap{position:relative;}
/* the board is a slide: the page's own colour, and a size container so
   the words on it are set in percent of ITS height (cqh), the same
   currency a style's size is written in */
.dg-board{position:relative;width:100%;container-type:size;
  background:var(--page-bg,#ffffff0a);border:1px solid #ffffff2b;
  border-radius:6px;margin:0 0 8px;overflow:hidden;}
.dg-realtx{display:block;width:100%;line-height:1.15;overflow:hidden;
  padding:.5cqh .6cqw;box-sizing:border-box;pointer-events:none;
  word-break:break-word;}
.dg-realtx.dg-realempty{opacity:.45;font-style:italic;}
.dg-other .dg-realtx{opacity:.4;}
.dg-put{margin-bottom:6px;}
/* the contact sheet */
/* the contact sheet, a column down the right-hand side */
.dg-sheetcol{width:250px;flex:none;overflow-y:auto;
  padding:14px 12px 40px;border-left:1px solid #ffffff14;
  background:#ffffff04;}
.dg-sheetcol[hidden]{display:none!important;}
.dg-sheetcol .dg-h{font-size:13.5px;margin:0 0 4px;}
.dg-sheetcol .dg-sub{font-size:11.5px;margin-bottom:8px;max-width:none;}
.dg-sheetcol .dg-putrow{flex-wrap:wrap;}
.dg-sheetcol .dg-scope{max-width:100%;}
.dg-sheet{display:grid;gap:10px;margin-top:10px;
  grid-template-columns:1fr;}
/* ABOVE THE EDITOR IT IS DESCRIBING (T170). .pickbar's own z-index is
   99, which is right for the notebook card picker -- that bar appears
   when the deck is NOT covering the screen. .deck is fixed at 100, so a
   sequencing bar left at 99 rendered underneath the very editor it was
   talking about: the DOM reported it visible, at the right size, in the
   right place, and the screen showed nothing. .matchbar solved this at
   150 for exactly the same reason; this joins it rather than inventing
   a third number. */
/* T180: setting the order happens IN THE RIBBON, as a group of the
   Animation tab that appears while the mode is armed. It was a bar
   fixed across the top of the window (z-index 150, over the ribbon it
   stood in for); the tint and the rule on its left are what say
   "mode" now that it is a group like any other. */
.seq-cell{display:flex;flex-direction:column;justify-content:center;
  font-size:10px;line-height:1.3;white-space:nowrap;color:#c9d6e2;
  padding:0 4px;}
.seq-cell b{color:#fff;}
body.light .seq-cell{color:var(--ink-2);}
body.light .seq-cell b{color:var(--ink);}
/* the modifier hints are the first words to go when the row is
   tight -- they explain, the tooltips repeat them, and nothing acts
   on them; the count stays */
.deck.erc-tight .seq-cell:not(.fmt-path) span+span{display:none;}
/* T171: the effect gallery. Cards are .sh-opt, which is already
   icon-over-word, so this only lays them out and gives the popover its
   heading, its scroller and its footer. The strip shows five and a half
   cards on purpose: a card CUT at the edge is the scroll affordance,
   taken from the film strip rather than from PowerPoint's spinners. */
.anim-gal{display:block;width:392px;max-width:92vw;padding:8px;}
.anim-galh{font-family:var(--mono);font-size:9px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--chrome-ink-2);padding:0 2px 6px;}
.anim-galrow{display:flex;gap:6px;overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x mandatory;padding-bottom:4px;}
.anim-galrow .anim-card{flex:0 0 66px;scroll-snap-align:start;
  display:flex;flex-direction:column;align-items:center;gap:5px;
  padding:9px 4px;text-align:center;font-size:10.5px;line-height:1.15;}
.anim-galrow .anim-card .bic{width:20px;height:20px;}
.anim-galrow .anim-card.on{background:var(--cyan-deep);
  color:var(--on-accent-deep,#fff);
  border-color:var(--cyan-deep);}
/* the SCOPE, said before you click: picking with nothing selected is a
   large edit and it must never be a silent one */
.anim-galfoot{margin-top:7px;padding-top:7px;border-top:1px solid #ffffff14;
  font-size:11px;color:var(--chrome-ink-2);}
/* T170: the bar's own furniture. The NAME first, so the mode is a
   thing you can remember afterwards rather than a sentence you were
   reading at the time; then the running state; then the chooser. */
.seq-fx{display:inline-flex;align-items:center;gap:4px;flex-wrap:nowrap;}
.seq-fxb{padding:2px 7px;font-size:10.5px;display:inline-flex;
  align-items:center;gap:5px;white-space:nowrap;}
.seq-fxb.on{background:var(--cyan-deep);color:var(--on-accent-deep,#fff);
  border-color:var(--cyan-deep);}
/* a key looks like a key, on the button and not only in the tooltip:
   a mode whose shortcuts are invisible has no shortcuts */
.seq-fxb kbd{font-family:var(--mono);font-size:9px;line-height:1;
  padding:1px 3px;border:1px solid currentColor;border-radius:3px;
  opacity:.75;}
.seq-fxb.on kbd{opacity:1;}
/* T168: sequencing by pointing. The bar is .pickbar, so it inherits
   the one picking-mode look; only the armed SLIDE needs saying. Every
   object advertises that it is clickable, and the selection chrome goes
   away because a resize handle is a claim about a click this mode does
   not make. */
.deck.seqing .annot-layer{cursor:cell;}
.deck.seqing .an-item{outline:1px dashed color-mix(in srgb,
  var(--cyan) 55%,transparent);outline-offset:2px;}
.deck.seqing .an-item:hover{outline:2px solid var(--cyan);}
.deck.seqing .an-resize,.deck.seqing .an-rotate,
.deck.seqing .an-handle,.deck.seqing .an-endpt{display:none!important;}
.deck.seqing .an-buildno{display:flex;}
/* T142: the Review centre's category rows */
.rv-cat{padding:8px 2px;border-bottom:1px solid #ffffff12;}
.rv-cat:last-child{border-bottom:none;}
.rv-cat-h{display:flex;align-items:center;gap:8px;}
.rv-cat-nm{flex:1;font-size:11.5px;color:var(--chrome-ink);}
.rv-cat-n{font-family:var(--mono);font-size:9.5px;color:var(--success);
  border:1px solid color-mix(in srgb,var(--success) 27%,transparent);border-radius:8px;padding:1px 7px;}
.rv-cat-n.has{color:var(--amber,#f0a848);
  border-color:#f0a84855;}
.rv-cat-scope{font-family:var(--sans);font-size:11px;
  letter-spacing:0;color:var(--chrome-ink-2);margin:2px 0 6px;}
.rv-cat-scope::first-letter{text-transform:uppercase;}
.rv-cat-open{display:block;width:100%;text-align:left;font-size:11px;
  padding:4px 7px;}
/* T143: autosave is a SETTING with a countdown, not a second primary
   action beside Save — pressed stops painting it accent (JVUX-07) */
.deck-qat .qat-auto[aria-pressed="true"]{background:none;
  border-color:#ffffff2e;color:var(--chrome-ink,#c9d6e2);}
/* T143: the File menu's named sections, and its dangerous tail */
/* T679: the scheme's own danger ink. --warn was never defined, so the
   red was a fallback that body.light .dc-mi / .dc-mhead outranked: in
   Light, Discard changes and Delete presentation were plain grey rows */
.dc-mhead-warn,body.light .dc-mhead-warn{color:var(--danger,#ff6b57);}
.dc-mi-warn,body.light .dc-mi-warn{color:var(--danger,#ff6b57);}
.dc-mi-warn:hover{background:color-mix(in srgb,var(--danger,#ff6b57) 14%,
  transparent);}
/* T139: the tab wrapper is semantic only */
.rbn-tabset{display:contents;}
/* T144: the empty notebook column's worded door */
/* T115: masters — the inherited layer, inert behind everything */
.slide-mast{position:absolute;inset:0;pointer-events:none;z-index:0;}
/* T215: a PANEL -- block layout (the .sh-menu grid had spread its note
   over three columns), wide enough to read, on the overlay stack */
.sh-menu.mast-panel{display:block;position:fixed;left:auto;right:16px;top:110px;
  z-index:420;width:320px;max-height:70vh;overflow-y:auto;
  padding:10px 12px 14px;}
.mast-panel .rd-note{font-size:12px;line-height:1.5;}
.mast-panel .rd-state{font-size:11px;margin:6px 0;}
.mast-name{font-family:var(--mono);font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--cyan);margin:10px 0 4px;}
.mast-row{display:block;width:100%;text-align:left;font-family:var(--sans);
  font-size:12.5px;
  padding:4px 7px;margin:2px 0;}
.mast-new{display:block;width:100%;text-align:left;margin-top:10px;}
/* T478: the master's choices as swatches and pressed runs */
.mast-lab{font-family:var(--sans);font-size:11px;color:var(--chrome-ink-2);
  margin:8px 0 3px;}
.mast-chips{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:4px;}
.mast-chips .bg-chip{width:22px;height:22px;border-radius:5px;padding:0;
  border:1px solid #ffffff2a;}
.mast-chips .bg-chip[aria-pressed="true"],.mast-chips .bg-auto[aria-pressed="true"]{
  outline:2px solid var(--accent,var(--cyan));outline-offset:1px;}
.mast-chips .bg-auto{font-size:11px;padding:2px 8px;}
.mast-run{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:4px;}
.mast-opt{font-size:12px;padding:3px 8px;}
/* T117: charts — the SVG fills its box; the dialog is the numbers */
/* POSITIONED, like every other kind (T164). Charts shipped in T117
   without a `position`, and every other annotation declares its own
   (.an-table, .an-image, .an-flip...). Two consequences, both bad and
   both invisible in a screenshot of a slide with one chart on it:
   the inline left/top drawChart writes were INERT, so a chart always
   rendered at the slide's top-left however you placed it; and an
   unpositioned element stacks below the arrow hit-layer -- an absolute
   <svg> covering the whole canvas -- so a chart could not be clicked,
   which is why it could not be selected and why its right-click menu
   (Edit data, chart type, and T160's series build) was unreachable. */
.an-chart{position:absolute;overflow:hidden;}
.an-chartsvg{width:100%;height:100%;display:block;
  font-family:var(--tk-font,var(--sans,system-ui));}   /* T626 */
.chart-data{position:fixed;left:50%;top:20%;transform:translateX(-50%);
  z-index:420;width:min(440px,92vw);padding:10px 12px 12px;}
/* T283: the first-run "where should this be kept?" prompt. Centred and
   unanchored -- it is a question about the deck, not about a button --
   so it goes on the overlay stack with a null owner. */
.save-ask{position:fixed;left:50%;top:26%;transform:translateX(-50%);
  z-index:430;width:min(430px,92vw);padding:10px 12px 12px;
  display:flex;flex-direction:column;gap:4px;}
.save-ask .sa-opt{width:100%;text-align:left;align-items:flex-start;
  flex-direction:column;gap:2px;padding:9px 11px;height:auto;}
.sa-t{font-family:var(--sans);font-size:13px;font-weight:600;
  color:var(--chrome-ink);}
.sa-n{font-family:var(--sans);font-size:11.5px;font-weight:400;
  line-height:1.45;color:var(--chrome-ink-3);white-space:normal;}
.save-ask .sa-opt:hover .sa-n{color:var(--chrome-ink-2);}
/* T296: the one answer that can lose your work reads as the fallback it
   is. Amber, not red: choosing it is a reasonable thing to do and
   nothing is broken -- it is the same distinction the style check makes
   (T279), and the same token. */
.save-ask .sa-opt.sa-warn{border-left:2px solid var(--warning);}
.save-ask .sa-opt.sa-warn .sa-t{color:var(--warning);}
.chart-ta{width:100%;min-height:150px;resize:vertical;
  font-family:var(--mono);font-size:11.5px;line-height:1.5;
  color:#dbe7ef;background:#0d1722;border:1px solid #ffffff22;
  border-radius:5px;padding:7px 9px;}
.chart-btns{display:flex;gap:8px;margin-top:9px;justify-content:flex-end;}
/* T562: the numbers as a grid */
.chart-data{width:min(620px,94vw);display:flex;flex-direction:column;
  align-items:stretch;}
.chart-data .chart-btns{align-self:flex-end;}
.cd-modes{display:flex;gap:4px;margin:2px 0 6px;}
.cd-mode{height:24px;padding:0 10px;font-size:12px;}
.cd-mode[aria-pressed="true"]{background:color-mix(in srgb,var(--accent)
  22%,transparent);border-color:var(--accent);}
.cd-host{max-height:min(46vh,380px);overflow:auto;margin-top:6px;}
.cd-grid{border-collapse:collapse;font-size:12px;}
.cd-grid th,.cd-grid td{padding:0;border:1px solid #ffffff1f;
  position:relative;}
.cd-grid td.cd-rowx{border:0;padding-left:3px;}
.cd-in{width:86px;height:24px;box-sizing:border-box;padding:2px 6px;
  font:inherit;font-variant-numeric:tabular-nums;text-align:right;
  color:#dbe7ef;background:#0d1722;border:0;border-radius:0;}
.cd-in.cd-cat{text-align:left;width:110px;}
.cd-in.cd-head{font-weight:600;text-align:left;background:#132131;}
.cd-in:disabled{background:#132131;}
.cd-in:focus{outline:2px solid var(--accent);outline-offset:-2px;}
.cd-x{position:absolute;right:1px;top:3px;width:16px;height:16px;
  padding:0;border:0;border-radius:3px;background:transparent;
  color:var(--chrome-ink-2,#93a8ba);font-size:12px;line-height:16px;
  cursor:pointer;opacity:.55;}
.cd-rowx .cd-x{position:static;}
.cd-x:hover{opacity:1;color:var(--warning,#e8a33d);}
.cd-adds{display:flex;gap:6px;margin-top:6px;}
.cd-adds .dbtn{height:24px;font-size:12px;}
/* T106: the reading-order panel and its on-slide numbers */
/* left:auto, or .sh-menu's left:0 wins the over-constrained box and the
   panel opens on the LEFT over the slide (T184; the screenshot showed
   it there) */
.rd-order{position:fixed;left:auto;right:16px;top:110px;z-index:420;
  width:252px;
  max-height:64vh;overflow-y:auto;padding:8px 10px 12px;}
.rd-order .hd-lab{position:relative;padding-right:26px;}
.rd-close{position:absolute;right:0;top:-4px;}
.rd-note{font-size:10.5px;color:var(--chrome-ink-2);margin:2px 0 8px;
  line-height:1.35;text-transform:none;letter-spacing:normal;}
.rd-state{font-family:var(--mono);font-size:9.5px;color:var(--chrome-ink-2);
  margin:0 0 6px;}
.rd-row{display:flex;align-items:center;gap:6px;padding:3px 2px;}
.rd-num{flex:none;min-width:16px;height:16px;border-radius:8px;
  background:var(--cyan);color:var(--on-accent);font-family:var(--mono);
  font-size:10px;font-weight:700;display:flex;align-items:center;
  justify-content:center;padding:0 3px;}
.rd-lab{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font-size:11.5px;color:var(--chrome-ink);}
.rd-reset{margin-top:8px;}
/* the number badges: gated exactly like .an-buildno above — always
   built, shown only while the panel is open. The panel lives in body,
   so the gate is body.rd-order-on, set by openReadingOrder and cleared
   by rdClose, the panel's only maker and remover: a body:has(#rd-order)
   was re-checked over the whole document on every DOM change
   (2026-10-09, speed). */
.an-readno{position:absolute;top:-9px;right:-9px;z-index:5;min-width:16px;
  height:16px;border-radius:8px;background:var(--cyan);color:var(--on-accent);
  font-family:var(--mono);font-size:10px;font-weight:700;display:none;
  align-items:center;justify-content:center;padding:0 3px;
  pointer-events:none;}
body.rd-order-on .an-readno{display:flex;}
/* T131: the layout-ideas chooser — live previews of THIS slide */
/* T209: full screen, like All images; the cards a third of the window
   wide so a layout can actually be read */
.sh-menu.lay-ideas{display:block;position:fixed;inset:0;left:0;top:0;
  transform:none;width:auto;max-width:none;max-height:none;z-index:400;
  padding:16px 28px 40px;overflow:auto;border:0;border-radius:0;
  box-shadow:none;background:var(--chrome-0,#0b141d);}
body.light .sh-menu.lay-ideas{background:var(--chrome-2);}
.li-grid{display:flex;flex-wrap:wrap;gap:10px;}
.li-card{display:flex;flex-direction:column;align-items:center;gap:5px;
  padding:7px;}
.li-card .mini-diagram{pointer-events:none;background:#0d1722;
  border:1px solid #ffffff22;border-radius:3px;}
/* T490: a candidate's text boxes show their BOX, hairline, so two
   layouts that differ only in where the words go can be told apart */
.li-card .mini-tx{outline:1px solid #ffffff2e;outline-offset:1px;
  border-radius:1px;}
.li-lab{font-size:10.5px;color:var(--chrome-ink);}
/* T130: the put button and its slide scope, side by side */
.dg-putrow{display:flex;align-items:center;gap:8px;flex-wrap:nowrap;}
.dg-scope{background:var(--input-bg);color:var(--chrome-ink);
  border:1px solid var(--border-strong);
  border-radius:6px;padding:4px 6px;font:inherit;font-size:11px;
  max-width:180px;}
/* the drag proxies live inside the miniature at page percentages;
   they exist only while outlines are on, so the sheet stays a plain
   navigator otherwise */
.dg-drag{position:absolute;display:none;cursor:grab;z-index:3;
  border-radius:2px;}
.dg-sheet.outlined .dg-drag{display:block;}
.dg-sheet.outlined .dg-drag:hover{outline:2px solid #f0a848;
  background:#f0a84822;}
/* an arrow's proxy is the bounding box of a LINE, so it can be large and
   almost entirely empty: it yields to the box proxies it overlaps rather
   than swallowing their drags. The canvas answers this with a per-pixel
   distance test (arrowAt); a 116x66px thumbnail cannot. */
.dg-drag.is-arrow{z-index:2;}
.dg-cell{position:relative;background:#ffffff08;border:1px solid #ffffff1a;
  border-radius:6px;padding:5px;cursor:pointer;}
.dg-cell:hover{border-color:#ffffff3d;}
.dg-celln{position:absolute;left:6px;bottom:4px;font-family:var(--mono);
  font-size:9px;color:var(--chrome-ink-3);}
/* EVERY object outlined, on every slide -- the third thing T87 asked
   for. miniDiagram already draws one element per object, so this is a
   class over the sheet rather than a second renderer. */
.dg-sheet.outlined .mini-it,
.dg-sheet.outlined .mini-tx,
.dg-sheet.outlined .mini-pane{
  outline:1px solid rgba(240,168,72,.85);outline-offset:0;}
.dg-sheet.outlined .mini-diagram{background:#0e1a26;}

/* ---- T203/T207: THE STRIP FRAME ---------------------------------------
   A tile strip is a gallery the PowerPoint way: one row of tiles in
   sight, the rest wrapped beneath it out of view, and a column at the
   right with up, down and "show all". No scrollbar anywhere (2026-09-02,
   user: "bit messy with the bottom scroll bar"). The frame is a box
   with an edge, the tiles inside it are the one 72x56 tile. */
.strip-frame{display:flex;align-items:stretch;height:var(--rbn-band);
  border:1px solid #ffffff24;border-radius:8px;background:#ffffff06;
  overflow:hidden;}
/* the STRIP is the scroll box (a fixed height, overflow hidden), so the
   arrows can move scrollTop; the frame only draws the edge */
.strip-frame>.fx-strip{height:calc(var(--rbn-band) - 2px);
  padding:2px 4px 0;box-sizing:border-box;
  flex-wrap:wrap;align-content:flex-start;overflow:hidden;
  scroll-behavior:smooth;scroll-snap-type:none;}
.strip-frame .fx-tile,.strip-frame .dbtn.lay{
  height:var(--rbn-tile-h);flex:0 0 var(--rbn-tile-w);
  scroll-snap-align:none;}
/* a strip's width is a whole number of tiles: four, or three for the
   page sizes, so no tile is ever cut at the edge */
.strip-frame>.fx-strip,.strip-frame>.fx-strip.lay-strip,
.strip-frame>.fx-strip.shape-strip{
  width:calc(4 * var(--rbn-tile-w) + 3 * var(--rbn-tile-gap) + 8px);}
/* the text tiles are as wide as their NAMES (T463), so a whole number
   of tiles does not describe this strip: it is as wide as what is in
   it, up to the ceiling the ladder sets, and past that it scrolls. */
.strip-frame>.fx-strip.tx-strip{width:max-content;
  max-width:var(--rbn-txstrip-max);}
/* the three-tile strips: page sizes, and T372's transition and timing
   choices, which have three answers each and no fourth to scroll to */
.strip-frame>.fx-strip.page-strip,
.strip-frame>.fx-strip.trans-strip{
  width:calc(3 * var(--rbn-tile-w) + 2 * var(--rbn-tile-gap) + 8px);}
/* T518: the text-step mode has two choices; T472 keeps four ways to be
   the point. The three-unit text sequence uses the standard width above. */
.strip-frame>#anim-textmode-strip.trans-strip{
  width:calc(2 * var(--rbn-tile-w) + var(--rbn-tile-gap) + 8px);}
.strip-frame>#anim-focus-strip.trans-strip{
  width:calc(4 * var(--rbn-tile-w) + 3 * var(--rbn-tile-gap) + 8px);}
/* the group caption wears the click, like a folded door's readout */
.rbn-focus .rbn-lab .rbn-foldval{display:inline;margin-left:4px;
  font-size:10px;color:var(--chrome-ink-3);max-width:none;}
.strip-nav{flex:none;width:18px;display:flex;flex-direction:column;
  border-left:1px solid #ffffff24;background:#ffffff0a;}
.strip-nav>button{flex:1 1 0;min-height:0;padding:0;border:0;
  background:none;color:#c9d6e2;cursor:pointer;font-size:8px;line-height:1;
  display:flex;align-items:center;justify-content:center;}
.strip-nav>button+button{border-top:1px solid #ffffff14;}
.strip-nav>.strip-more{font-size:12px;}
.strip-nav>button:hover:not(:disabled){
  background:color-mix(in srgb,var(--accent) 18%,transparent);color:var(--chrome-ink);}
.strip-nav>button[aria-disabled="true"]{opacity:.3;}
.strip-more[aria-expanded="true"]{
  background:var(--accent-deep,var(--cyan-deep));
  color:var(--on-accent-deep,#fff);}
body.light .strip-frame{border-color:var(--line);
  background:var(--surface-hover);}
body.light .strip-nav{border-left-color:var(--line);
  background:var(--surface-hover);}
body.light .strip-nav>button{color:var(--ink-2);}
/* the window with every tile in it: the strip itself, moved in and
   wrapped, so every tile keeps its wiring; moved back on close */
/* block, not the menu grid: the strip must have the whole width to wrap in */
.sh-menu.strip-all{display:block;position:fixed;z-index:60;left:0;top:0;padding:8px;
  border-radius:10px;background:var(--chrome-1,#111c26);
  border:1px solid #ffffff24;box-shadow:0 12px 32px #0009;
  width:560px;max-width:calc(100vw - 16px);max-height:calc(100vh - 120px);
  overflow:auto;}
.sh-menu.strip-all .strip-all-h{font-family:var(--sans);font-size:11px;
  color:var(--chrome-ink-2);margin:0 2px 6px;}
.sh-menu.strip-all .fx-strip{display:flex;flex-wrap:wrap;gap:6px;
  height:auto;width:100%;max-width:none;overflow:visible;padding:0;
  scroll-snap-type:none;}
.sh-menu.strip-all .fx-strip>*{flex:0 0 auto;height:var(--rbn-tile-h);}
.sh-menu.strip-all .fx-strip>.hd-lab,.sh-menu.strip-all .fx-strip>.lay-sec{
  display:none;}
body.light .sh-menu.strip-all{background:var(--chrome-2);
  border-color:var(--line);}

/* ---- T204: NEW SLIDE AS A TILE, AND ALL IMAGES FULL SCREEN ------------
   The New slide button is a tall tile at the left of its strip, the
   shape of the layout tiles it stands beside (2026-09-02, user: "put
   the new slide on the left hand side and make it a full button"). The
   full-screen view is every slide's images under a heading each, the
   headings folding. */
/* T383: the check's tile is the fold tile's width -- three words on a
   64px tile broke into three lines and spilled out */
.rbn-row>#dsg-std.big-tile{width:82px;
  height:var(--rbn-tile-h);align-self:center;}
.rbn-row>#dsg-std.big-tile>span{white-space:normal;text-align:center;
  line-height:1.15;}
.img-ov{position:fixed;inset:0;z-index:400;
  background:var(--chrome-0,#0b141d);color:#c9d6e2;overflow:auto;
  padding:16px 28px 40px;font-family:var(--sans);}
.img-ov[hidden]{display:none;}
.img-ov-h{display:flex;align-items:center;gap:10px;margin-bottom:12px;}
.img-ov-t{font-size:18px;font-weight:600;}
.img-ov-sub{flex:1;color:var(--chrome-ink-2);font-size:12px;}
.img-sec{border:1px solid #ffffff1c;border-radius:9px;margin:0 0 8px;
  background:#ffffff05;}
.img-sec>summary{cursor:pointer;padding:9px 12px;font-size:13px;
  list-style:none;display:flex;align-items:center;gap:8px;}
.img-sec>summary::-webkit-details-marker{display:none;}
.img-sec>summary::before{content:"\25B8";color:var(--chrome-ink-2);font-size:11px;}
.img-sec[open]>summary::before{content:"\25BE";}
.img-rows{display:grid;gap:6px;padding:0 10px 10px;
  grid-template-columns:repeat(auto-fill,minmax(320px,1fr));}
.img-ov .img-row{border:1px solid #ffffff12;}
.img-ov .img-th{width:72px;height:50px;}
body.light .img-ov{background:var(--chrome-2);color:var(--ink-2);}
body.light .img-sec{border-color:var(--line);
  background:var(--surface-hover);}
body.light .img-ov .img-row{border-color:var(--line);}

/* ---- T328: LOOK BEFORE A FIGURE REFRESH WRITES ------------------------
   The deck's kept rendering and the source's current rendering get equal
   space. The choice stays worded: these are destructive source updates,
   not a mystery pair of tick/cross icons. */
.fig-review{box-sizing:border-box;width:min(1120px,calc(100vw - 32px));
  max-width:none;max-height:calc(100vh - 32px);padding:18px 20px 22px;
  color:#c9d6e2;background:var(--chrome-0,#0b141d);
  border:1px solid #ffffff2b;border-radius:12px;box-shadow:0 24px 70px #000c;
  font-family:var(--sans);overflow:auto;}
.fig-review::backdrop{background:#02060bd9;backdrop-filter:blur(2px);}
.fig-review-h{display:flex;align-items:center;gap:9px;position:sticky;top:-18px;
  z-index:2;margin:-18px -20px 0;padding:16px 20px 12px;
  background:var(--chrome-0,#0b141d);border-bottom:1px solid #ffffff18;}
.fig-review-t{font-size:18px;font-weight:650;white-space:nowrap;}
.fig-review-sub{flex:1;color:var(--chrome-ink-2);font-size:12px;}
.fig-review-note{font-size:12px;line-height:1.5;color:var(--chrome-ink-2);
  margin:13px 0;}
.fig-review-list{display:flex;flex-direction:column;gap:14px;}
.fig-review-item{border:1px solid #ffffff1c;border-radius:9px;
  background:#ffffff05;padding:10px;}
.fig-review-label{font-family:var(--mono);font-size:10px;color:var(--chrome-ink-2);
  margin:0 2px 8px;}
.fig-review-pair{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:10px;}
.fig-review-col{min-width:0;display:flex;flex-direction:column;gap:5px;}
.fig-review-cap{font-size:11px;font-weight:600;color:#dbe7ef;}
.fig-review-frame{height:290px;box-sizing:border-box;overflow:auto;
  display:flex;align-items:center;justify-content:center;padding:10px;
  background:#fff;color:#18232d;border:1px solid #ffffff26;border-radius:7px;}
.fig-review-frame>.cardbody{width:100%;max-height:100%;}
.fig-review-frame img,.fig-review-frame svg{max-width:100%;max-height:100%;}
.fig-review-frame>.an-chartsvg{width:100%;height:100%;}
.fig-review-empty{font-family:var(--mono);font-size:11px;color:var(--chrome-ink-3);}
body.light .fig-review{color:var(--ink-2);background:var(--chrome-2);
  border-color:var(--line);}
body.light .fig-review-h{background:var(--chrome-2);border-color:var(--line);}
body.light .fig-review-item{border-color:var(--line);
  background:var(--surface-hover);}
body.light .fig-review-cap{color:var(--ink);}
@media(max-width:760px){
  .fig-review-h{flex-wrap:wrap;}
  .fig-review-sub{flex-basis:100%;order:3;}
  .fig-review-pair{grid-template-columns:1fr;}
  .fig-review-frame{height:230px;}
}

/* the two galleries: three lines with the marker they would draw */
.sh-menu.ls-menu{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:4px;width:250px;padding:7px;}
.ls-opt{gap:5px;}
.ls-prev{display:flex;flex-direction:column;gap:3px;width:100%;}
.ls-row{display:flex;align-items:center;gap:4px;}
.ls-mark{font-family:var(--mono);font-size:9px;color:var(--chrome-ink-2);
  min-width:13px;text-align:right;}
.ls-bar{flex:1;height:2px;border-radius:1px;background:#ffffff33;}
.ls-opt[aria-pressed="true"] .ls-bar{background:var(--accent,#39a9c0);}
.ls-opt[aria-pressed="true"] .ls-mark{color:var(--chrome-ink);}
body.light .ls-bar{background:var(--border-strong);}

/* ---- T226: MAKING A LAYOUT --------------------------------------------
   The board is the page and the slots are what a layout is made of, so
   they are drawn at page percentages exactly as the design screen's
   ghost is. Nothing here renders content: a layout is a shape. */
.lb-bar{display:flex;flex-wrap:wrap;align-items:center;gap:8px;
  margin:2px 0 12px;}
.lb-board{position:relative;width:min(100%,760px);margin:0 0 14px;
  background:var(--chrome-0,#0b141d);border:1px solid #ffffff22;
  border-radius:10px;overflow:hidden;}
.lb-slot{position:absolute;box-sizing:border-box;border-radius:6px;
  cursor:move;display:flex;align-items:flex-start;padding:5px 7px;
  border:1.5px dashed color-mix(in srgb,var(--chrome-ink) 30%,transparent);
  background:var(--surface-hover);color:var(--chrome-ink-2);
  font-family:var(--sans);font-size:12px;}
.lb-slot.lb-cell{border-style:solid;
  border-color:color-mix(in srgb,var(--accent) 55%,transparent);
  background:color-mix(in srgb,var(--accent) 10%,transparent);}
.lb-slot.on{border-color:var(--accent);
  box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 45%,transparent);}
.lb-lab{pointer-events:none;overflow:hidden;white-space:nowrap;
  text-overflow:ellipsis;}
.lb-grip{position:absolute;right:-4px;bottom:-4px;width:12px;height:12px;
  border-radius:3px;background:var(--accent,#39a9c0);cursor:nwse-resize;}
.lb-foot{display:flex;align-items:center;gap:10px;margin:14px 0 6px;}
.lb-name{flex:0 1 280px;height:30px;padding:0 9px;box-sizing:border-box;
  font-family:var(--sans);font-size:13px;color:#e8f1f8;
  background:#ffffff0a;border:1px solid #ffffff26;border-radius:7px;}
.lb-mine{margin-top:14px;max-width:620px;}
.lb-row{display:flex;align-items:center;gap:8px;padding:5px 2px;
  border-top:1px solid #ffffff14;}
.lb-rowt{flex:1;min-width:0;font-family:var(--sans);font-size:13px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
body.light .lb-board{background:var(--paper-2);border-color:var(--line);}
body.light .lb-name{background:var(--input-bg);
  border-color:var(--border-strong);
  color:var(--ink);}

/* ---- T225: a checkpoint reads as one ----------------------------------
   Every other snapshot is something that happened to you; this is one
   you chose, so it is marked in the rail and never evicted. */
.dh-snap.checkpoint{border-left:3px solid var(--accent,#39a9c0);}
.dh-snap.checkpoint .dh-why{color:var(--cyan);}

/* ---- T224: EVERY BOX OF A KIND, IN A TABLE ----------------------------
   One row per box, wherever it is: tick several, then Match style of and
   click the one they should follow. The grid's column count comes from
   the header row it was built with, so the text and object views can
   have different columns without two stylesheets. */
.dgt{margin:6px 0 18px;}
.dgt-bar{display:flex;flex-wrap:wrap;align-items:center;gap:8px;
  margin-bottom:8px;}
/* T411: the size box on the table's bar, and the typed size between a
   named type's steppers */
.dgt-szw{display:inline-flex;align-items:center;gap:5px;margin-left:4px;}
.dgt-szlab{font-family:var(--sans);font-size:12px;color:var(--chrome-ink-2);}
.dgt-n.dgt-szin,.dgt-n.dg-sizein{width:58px;}
.dg-size{display:inline-flex;align-items:center;gap:2px;min-width:0;}
.dgt-count{font-family:var(--sans);font-size:12px;color:var(--chrome-ink-2);
  margin-left:auto;}
.dgt-grid{display:grid;
  grid-template-columns:26px 40px minmax(150px,1.7fr)
    repeat(calc(var(--dgt-cols) - 5),minmax(52px,.5fr)) 88px 74px;
  /* T490: the two colour columns hold a picker AND its Default / None */
  gap:1px;background:#ffffff12;border:1px solid #ffffff1c;
  border-radius:9px;overflow:hidden;max-height:52vh;overflow-y:auto;}
.dgt-h{background:var(--chrome-1,#0e1926);font-family:var(--sans);
  font-size:11px;font-weight:600;color:var(--chrome-ink-2);padding:7px 8px;
  position:sticky;top:0;z-index:1;}
.dgt-c{background:var(--chrome-2,#16273a);padding:5px 8px;
  font-family:var(--sans);font-size:12px;color:#dce6ee;cursor:pointer;
  display:flex;align-items:center;min-width:0;}
.dgt-c.on{background:color-mix(in srgb,var(--accent) 22%,var(--chrome-2,#16273a));}
/* the rows not drawn yet (dgtVirtual): one grid row as tall as they are */
.dgt-spacer{grid-column:1/-1;background:var(--chrome-2,#16273a);}
.dgt-c:hover{background:color-mix(in srgb,var(--accent) 12%,var(--chrome-2,#16273a));}
.dgt-what{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  display:block;line-height:1.9;}
.dgt-si{font-family:var(--mono);color:var(--chrome-ink-2);}
.dgt-n{width:100%;min-width:0;height:24px;padding:0 5px;box-sizing:border-box;
  font-family:var(--mono);font-size:11.5px;color:#e8f1f8;
  background:#ffffff0d;border:1px solid #ffffff22;border-radius:5px;}
.dgt-n:focus{border-color:var(--cyan);outline:none;}
.dgt-face{font-family:var(--mono);font-size:11px;color:var(--chrome-ink-2);}
/* T490: the editable cells -- a swatch that is a picker, with its
   Default / None beside it, and the typeface list */
.dgt-colw{display:inline-flex;align-items:center;gap:4px;}
.dgt-col{width:22px;height:20px;padding:0;border:1.5px solid #ffffff33;
  border-radius:50%;background:none;cursor:pointer;}
.dgt-col::-webkit-color-swatch-wrapper{padding:0;}
.dgt-col::-webkit-color-swatch{border:0;border-radius:50%;}
.dgt-col.dgt-unset{opacity:.45;}
.dgt-colb{font-size:10px;padding:2px 5px;line-height:1.2;}
.dgt-colb[aria-pressed="true"]{border-color:var(--cyan);color:var(--chrome-ink);}
.dgt-facesel{height:24px;padding:0 4px;max-width:96px;
  background:#ffffff0d;border:1px solid #ffffff22;border-radius:5px;
  color:#e8f1f8;}
body.light .dgt-facesel{background:var(--input-bg);
  border-color:var(--border-strong);color:var(--ink);}
.dgt-sw{width:16px;height:16px;border-radius:50%;
  border:1.5px solid #ffffff33;display:block;}
.dgt-sw.dgt-none{background:var(--chrome-0,#0b141d);position:relative;
  overflow:hidden;}
.dgt-sw.dgt-none::after{content:"";position:absolute;left:-2px;right:-2px;
  top:50%;height:1.5px;background:#ff6b57;transform:rotate(-45deg);}
.dgt-ck{cursor:pointer;}
/* the slide the strip is filtering by */
.dg-cell.dg-pick{outline:2px solid var(--cyan);outline-offset:2px;}
body.light .dgt-c{background:var(--chrome-2);color:var(--ink);}
body.light .dgt-spacer{background:var(--chrome-2);}
body.light .dgt-h{background:var(--chrome-1,#f4f7fa);}
body.light .dgt-n{background:var(--input-bg);
  border-color:var(--border-strong);
  color:var(--ink);}

/* ---- T223: A STYLE SAYS EVERYTHING ------------------------------------
   The typeface and three colours, in both places a style can be edited:
   the Text styles window's inline editor and the Style system screen.
   Each colour can also be told to be nothing at all, which is a
   different answer from having said nothing. */
.stm-erow .stm-font,.dg-ctrls .dg-font{font-family:var(--sans);
  font-size:11.5px;padding:3px 6px;border-radius:6px;
  background:var(--chrome-1,#0e1926);border:1px solid #ffffff26;
  color:#dce6ee;max-width:120px;}
.stm-col,.dg-colw{display:inline-flex;align-items:center;gap:5px;
  padding:0 2px;}
.stm-collab,.dg-collab{font-family:var(--sans);font-size:11px;
  color:var(--chrome-ink-2);}
.stm-colin,.dg-ctrls .dg-col{width:26px;height:22px;padding:0;
  border:1px solid #ffffff33;border-radius:5px;background:none;
  cursor:pointer;}
body.light .stm-erow .stm-font,body.light .dg-ctrls .dg-font{
  background:#fff;border-color:var(--line);color:var(--ink);}
/* the numbers beside the drag board */
.dg-nums{display:flex;gap:14px;align-items:center;margin:8px 0 2px;}
.dg-num{display:inline-flex;align-items:center;gap:6px;
  font-family:var(--sans);font-size:12px;color:var(--chrome-ink-2);}
.dg-num input{width:62px;height:26px;padding:0 6px;box-sizing:border-box;
  font-family:var(--mono);font-size:12px;color:#e8f1f8;
  background:#ffffff0a;border:1px solid #ffffff26;border-radius:6px;}
.dg-numpc{color:var(--chrome-ink-2);}
body.light .dg-num input{background:var(--input-bg);
  border-color:var(--border-strong);
  color:var(--ink);}

/* ---- T221: A BUTTON IS ITS OWN WIDTH ------------------------------------
   The grid stretched every cell to its column, so a lone button sharing
   a column with a three-button run was drawn that run's width -- which
   is how Tidy page ended up the size of Spacing | Tight | Normal | Airy
   (2026-09-03, user: "that layout looks hectic, why is tidy page
   huge?"). Cells start-align now, the way PowerPoint's do; the things
   that must fill their cell say so here. */
.rbn-row>.rbn-cell,.rbn-row>.sh-drop,.rbn-row>.dc-menuwrap,
.rbn-row>.strip-frame,.rbn-row>.fx-strip{justify-self:stretch;}
.rbn-row>.rbn-cell.rbn-seg{justify-self:start;}
/* ---- T365: NO HOLES, NO RAGGED COLUMNS ------------------------------
   2026-09-07, user: "there are weird gaps and spaces everywhere ... I
   have told you about this like 40 fucking times."

   TWO shapes of gap, measured on all seven tabs. Both are set by
   sizeRibbonGroups(), which is the one place that already knows how
   many cells a group has and re-runs on every path that re-fits the
   ribbon.

   .rbn-odd -- the last cell when the count is ODD. Column-major flow
   over two rows leaves it at the top of a column with 37px of nothing
   under it, fenced by the group's dividers into a visible rectangle.
   It takes the whole column and centres in it, so the space it does
   not need sits evenly above and below rather than as a notch below.

   .rbn-fit -- both halves of a column whose two members can be
   widened without looking absurd. The track is already max-content
   wide; without this the narrower button stops short and leaves a
   notch, which is the ragged right edge in twenty-two columns. It is
   set in PAIRS, and never on a pair containing a joined run: a run is
   as wide as all its segments, and stretching a plain button to that
   is exactly the "why is tidy page huge?" of 2026-09-03. */
.rbn-row>.rbn-odd{grid-row:1/span 2;align-self:center;}
.rbn-row>.rbn-fit{justify-self:stretch;}
/* List and Numbered are a two-cell column. Their text buttons, not just
   their wrappers, fill the shared width so the caret stays aligned. */
#fmt-bulletswrap.rbn-fit,#fmt-numberswrap.rbn-fit{width:100%;}
#fmt-bulletswrap.rbn-fit>#fmt-bullets,
#fmt-numberswrap.rbn-fit>#fmt-numbers{flex:1;min-width:0;}
/* Background is a tall tile now, so its menu hangs off a tile-wide door.
   T373: the transition's scope door is the third of these -- a tile that
   opens a menu, so it is the same shape as the tiles it applies. */
#bg-drop.rbn-tall,#hm-updwrap.rbn-tall,
#trans-scopewrap.rbn-tall{justify-self:start;}
/* T280: the merged Update tile is the same shape as the two it replaced
   (T463: the tile inside any tall wrapper is sized by the one
   standing-tile rule beside .fx-tile) */
/* the opacity slider inside its captioned run */
#fmt-opcell .fmt-opwrap{display:flex;align-items:center;gap:5px;
  padding:0 8px 0 4px;align-self:center;}
#fmt-opcell .fmt-range{width:84px;}
/* B I U S: four segments of one width, so the S is not the wide one */
.rbn-cell#tx-run-style .dbtn.etm{min-width:30px;justify-content:center;
  padding-left:4px;padding-right:4px;}
/* ...and A- / A+ are glyphs, so they get the same treatment */
#fmt-sizecell .dbtn.etm{min-width:30px;justify-content:center;
  padding-left:4px;padding-right:4px;}
/* History is a tall tile in a section of its own (T233; T463: it wears
   rbn-tall in the markup now, so the grid and sizeRibbonGroups agree
   that it takes a column) */
/* ---- T234: THE FLIP BOOK'S ONE BIG DOOR, AND ITS PAGE TURN ----------
   "+ Add" is the first control in the Picture group and the same
   height as History: an empty flip book is a hole, and the button that
   fills it should not be the smallest thing on the row. The turn
   itself is one keyframe on the frame that changed -- so it plays in
   the show, in an exported page, and nowhere else. */
/* History is a tile on Home too, the same size as the others (T236) */
/* ---- T239: THE WAY OUT IS ON THE BAR YOU CAN SEE ---------------------
   Two rows, like File over Save beside them: the pair is one errand
   and stacking halves the width it costs the top bar. */
.qat-way{flex:none;}
.qat-way .qat-btn{justify-content:flex-start;}
/* ---- T238: LEAVING IS AN EFFECT, NOT A CUT --------------------------
   The stop an object goes on keeps the element so the exit can play;
   from then on it is invisible and untouchable, and every later stop
   drops it for real. */
@keyframes an-out{from{opacity:1;}to{opacity:0;}}
.an-anim-out{animation:an-out .28s ease forwards;pointer-events:none;}
/* ---- T472: FOCUS, ON ITS CLICK ----------------------------------------
   spot: every other item on the layer softens; the stage zooms about the
   item and slides it to the middle (the transition is on the stage,
   which survives a re-render, so the zoom back moves too); a lens is a
   scaled clone floated over the page. */
.deck:not(.editing) .annot-layer .an-item{
  transition:filter .35s ease,opacity .35s ease;}
/* T491: NEVER ON A HIDDEN ITEM. Every render builds the items fresh
   and the reveal pass adds .an-prebuild a moment later, so with the
   transition on every item each not-yet-arrived object flashed at full
   opacity on EVERY click and faded out over 350ms (third review pass,
   measured: 1.00 -> 0.62 -> 0.22 -> 0.01). An element whose after-
   change style carries no transition starts none. */
.deck:not(.editing) .annot-layer .an-item.an-prebuild{transition:none;}
.annot-layer.an-spotlit .an-item:not(.an-spot):not(.an-lens){
  filter:blur(3px);opacity:.45;}
/* T491: the visible arrow stroke is not an .an-item (the fat hit path
   under it is), so "Blur the rest" left every arrow sharp */
.annot-layer.an-spotlit .an-arrow-line:not(.an-spot){
  filter:blur(3px);opacity:.45;}
.annot-layer.an-spotlit .an-item.an-spot{z-index:20;}
.deck-stage{transition:transform .55s cubic-bezier(.2,.7,.2,1);}
.deck.editing .deck-stage{transition:none;}
.an-item.an-lens{pointer-events:none;z-index:30;opacity:0;
  transition:opacity .3s ease,transform .45s cubic-bezier(.2,.7,.2,1);
  box-shadow:0 18px 60px #000a,0 0 0 2px #ffffff55;
  background:var(--page-bg,#0b141d);border-radius:6px;}
.an-item.an-lens.an-lens-in{opacity:1;}
@media (prefers-reduced-motion:reduce){
  .deck-stage,.an-item.an-lens,.deck:not(.editing) .annot-layer .an-item{
    transition:none;}
}
@media (prefers-reduced-motion: reduce){
  .an-anim-out{animation:none;opacity:0;}}
@keyframes fturn-fade{from{opacity:0;}to{opacity:1;}}
@keyframes fturn-rise{from{opacity:0;transform:translateY(14px);}
  to{opacity:1;transform:none;}}
@keyframes fturn-zoom{from{opacity:0;transform:scale(.93);}
  to{opacity:1;transform:none;}}
.an-flipstage.fturn-fade{animation:fturn-fade .3s ease;}
.an-flipstage.fturn-rise{animation:fturn-rise .34s
  cubic-bezier(.2,.7,.3,1);}
.an-flipstage.fturn-zoom{animation:fturn-zoom .3s
  cubic-bezier(.2,.7,.3,1);}
/* T385: a page that turns on its left edge, and one pushed in from
   the right. The stage is the inner frame, which applyCommon never
   rotates, so the transform shorthand is safe here. */
@keyframes fturn-turn{from{opacity:.3;
  transform:perspective(900px) rotateY(-85deg);}
  to{opacity:1;transform:perspective(900px) rotateY(0);}}
@keyframes fturn-push{from{transform:translateX(100%);}
  to{transform:none;}}
.an-flipstage.fturn-turn{animation:fturn-turn .45s
  cubic-bezier(.2,.7,.3,1);transform-origin:left center;}
.an-flipstage.fturn-push{animation:fturn-push .4s
  cubic-bezier(.2,.7,.3,1);}
@media (prefers-reduced-motion: reduce){
  .an-flipstage.fturn{animation:none!important;}}

/* ---- T220: QUICK COLOURS AND A VISIBLE SIZE ----------------------------
   The deck's six colours sit in the row as two segmented cells, one for
   the words and one for the box; the size is a third, holding the
   number, its unit and the two steppers. Nothing here opens a menu
   (2026-09-03, user: "DON'T HAVE EVERYTHING ALWAYS HIDDEN BEHIND
   SEVERAL CLICKS"). */
.qk-cell{align-items:center;}
.qk-sw{width:15px;height:15px;border-radius:50%;padding:0;flex:none;
  cursor:pointer;border:1.5px solid #ffffff33;margin-right:3px;}
.qk-cell>.qk-sw:last-child{margin-right:5px;}
/* T273: the caption used to give the cell its left inset; with the
   caption gone the first chip would touch the segment border. */
.qk-cell>.qk-sw:first-child{margin-left:5px;}
.qk-sw:hover{border-color:#fff;transform:scale(1.14);}
.qk-sw.on{border-color:#fff;
  box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 70%,transparent);}
body.light .qk-sw{border-color:var(--border-strong);}
.edit-tools .rbn-cell.rbn-seg#fmt-sizecell>.fmt-szwrap{display:flex;
  align-items:center;gap:3px;padding:0 6px;align-self:center;}
#fmt-sizecell .fmt-num{width:42px;}
.edit-tools .rbn-cell.rbn-seg#fmt-sizecell>.dbtn{min-width:30px;
  justify-content:center;}
/* the typeface, on the row rather than in a window */
.edit-tools select#fmt-font{min-width:150px;max-width:180px;align-self:center;
  height:var(--rbn-btn-h);}

/* ---- T220: THE HISTORY OF ONE OBJECT, FULL SCREEN ---------------------
   The rows the dock pane draws, as cards with room to read. */
.oh-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));
  gap:10px;align-content:start;}
.img-ov .oh-row{background:#ffffff05;border:1px solid #ffffff14;
  border-left:3px solid #ffffff26;border-radius:9px;padding:12px 14px;
  gap:12px;}
.img-ov .oh-row.oh-now{border-left-color:var(--cyan);}
.img-ov .oh-thumb{width:62px;max-height:52px;}
.img-ov .oh-h{font-size:11px;}
.img-ov .oh-what{font-size:13px;}
.img-ov .oh-do{font-size:12px;padding:5px 10px;}
.img-ov .pf-ok{grid-column:1/-1;}
body.light .img-ov .oh-row{background:var(--surface-hover);
  border-color:var(--line);}

/* ---- T219: A BUTTON LOOKS LIKE A BUTTON ---------------------------------
   T207 made every ribbon control flat at rest, the way PowerPoint's
   are. On this ribbon, whose icons are small and one colour, flat
   read as loose words -- "they are all just floating text with icons.
   This is a mess to look at" (2026-09-03). So every control has a
   surface again, and ONE surface: the same fill, the same 1px edge,
   the same 6px corner, at one height per kind -- a small button is a
   --rbn-track box, a tile is --rbn-tile-w by --rbn-tile-h, a run is
   one box with its segments
   divided inside it. What made boxes chaos before T207 was that the
   boxes came in every size; the sizes are settled now, so the box can
   come back. Hover lifts it; pressed fills it with the deep accent. */
.edit-tools{--rbn-btn:var(--btn-bg);--rbn-btn-bd:var(--btn-border);
  --rbn-btn-hi:var(--surface-active);}
.edit-tools .dbtn.rbn-sm,.edit-tools .dbtn.etm,.edit-tools .fx-tile,
.edit-tools .dbtn.lay,.edit-tools .rbn-cell .dbtn,.edit-tools .rbn-foldbtn{
  background:var(--rbn-btn);border:1px solid var(--rbn-btn-bd);
  border-radius:6px;box-shadow:none;}
.edit-tools .dbtn.rbn-sm:hover:not(:disabled),
.edit-tools .dbtn.etm:hover:not(:disabled),
.edit-tools .fx-tile:hover:not(:disabled),
.edit-tools .dbtn.lay:hover:not(:disabled),
.edit-tools .rbn-cell .dbtn:hover:not(:disabled),
.edit-tools .rbn-foldbtn:hover{
  background:var(--rbn-btn-hi);
  border-color:color-mix(in srgb,var(--accent) 55%,transparent);
  color:var(--chrome-ink);}
.edit-tools .dbtn[aria-pressed="true"],.edit-tools .fx-tile.on,
.edit-tools .dbtn.lay[aria-pressed="true"],
.edit-tools .fx-tile[aria-pressed="true"]{
  background:var(--accent-deep,var(--cyan-deep));
  border-color:var(--accent-deep,var(--cyan-deep));
  color:var(--on-accent-deep,#fff);}
.edit-tools .dbtn.dbtn-warn{color:var(--danger);
  border-color:color-mix(in srgb,var(--danger) 42%,transparent);}
.edit-tools .dbtn.dbtn-warn:hover:not(:disabled){
  background:color-mix(in srgb,var(--danger) 13%,transparent);
  border-color:color-mix(in srgb,var(--danger) 70%,transparent);}
/* the colourful theme tints the box's edge and its words with the tab's hue */
/* T465: ...and NEVER a pressed one -- .fx-tile excluded .on but not
   [aria-pressed="true"], which is how View's Slides and Guides, Home's
   Layers and Present's Code trail read exactly like their unlit
   neighbours in this theme (2026-09-15 review) */
body.th-colorful .edit-tools .dbtn:not([aria-pressed="true"]):not(:hover),
body.th-colorful .edit-tools .fx-tile:not(.on):not([aria-pressed="true"]):not(:hover){
  border-color:color-mix(in srgb,var(--accent) 30%,transparent);
  background:color-mix(in srgb,var(--accent) 7%,transparent);
  color:color-mix(in srgb,var(--accent) 60%,#f2f7fa);}
body.th-colorful .edit-tools .dbtn:hover:not([aria-pressed="true"]),
body.th-colorful .edit-tools .fx-tile:hover:not(.on):not([aria-pressed="true"]){
  background:color-mix(in srgb,var(--accent) 16%,transparent);
  border-color:color-mix(in srgb,var(--accent) 55%,transparent);}
/* a primary button keeps its fill (Finish in Quick animate) */
.edit-tools .dbtn.rbn-sm.primary,body.light .edit-tools .dbtn.rbn-sm.primary{
  background:var(--cyan);border-color:var(--cyan);color:var(--on-accent);}
/* A RUN is one box. Its buttons are segments divided by a hairline, and
   its caption -- Spacing -- is the first segment, inside the box, so the
   word and the choices it names are visibly one control (2026-09-03,
   user: "the spacing stuff is weird, why is that word where it is?"). */
.edit-tools .rbn-row>.rbn-cell.rbn-seg{gap:0;background:var(--rbn-btn);
  border:1px solid var(--rbn-btn-bd);border-radius:6px;overflow:hidden;}
.edit-tools .rbn-cell.rbn-seg>.dbtn{border:0;border-radius:0;
  background:transparent;border-left:1px solid var(--rbn-btn-bd);margin:0;}
.edit-tools .rbn-cell.rbn-seg>.dbtn:first-child,
.edit-tools .rbn-cell.rbn-seg>.cell-lab+.dbtn{border-left:0;}
.edit-tools .rbn-cell.rbn-seg>.dbtn:hover:not(:disabled){
  background:var(--rbn-btn-hi);border-color:var(--rbn-btn-bd);}
.edit-tools .rbn-cell.rbn-seg>.dbtn[aria-pressed="true"]{
  background:var(--accent-deep,var(--cyan-deep));
  border-color:var(--accent-deep,var(--cyan-deep));}
.edit-tools .rbn-cell.rbn-seg>.cell-lab{display:flex;align-items:center;
  align-self:stretch;padding:0 8px 0 9px;
  border-right:1px solid var(--rbn-btn-bd);}
/* ...and in the colourful theme a run is tinted as ONE box, its segments
   clear, so the box does not sit grey under three tinted buttons */
body.th-colorful .edit-tools .rbn-row>.rbn-cell.rbn-seg{
  border-color:color-mix(in srgb,var(--accent) 30%,transparent);
  background:color-mix(in srgb,var(--accent) 7%,transparent);}
body.th-colorful .edit-tools .rbn-cell.rbn-seg>.dbtn:not([aria-pressed="true"]):not(:hover){
  background:transparent;
  border-left-color:color-mix(in srgb,var(--accent) 30%,transparent);}

/* ---- T207: X Y W H on the Object tab ------------------------------------
   Two cells in one column: position over size. A label letter, a
   number in millimetres, typed straight in; Enter or leaving the field
   is one undo step. */
.rbn-cell.rbn-geom{gap:6px;padding:0 2px;}
.rbn-geom .geo{display:flex;align-items:center;gap:4px;
  font-family:var(--sans);font-size:10.5px;color:var(--chrome-ink-2);}
.rbn-geom input{width:54px;height:24px;padding:0 5px;box-sizing:border-box;
  font-family:var(--mono);font-size:11px;color:#e8f1f8;
  background:#ffffff0a;border:1px solid #ffffff22;border-radius:5px;
  -moz-appearance:textfield;}
.rbn-geom input::-webkit-outer-spin-button,
.rbn-geom input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0;}
.rbn-geom input:focus{outline:none;border-color:var(--accent);}
.rbn-geom input:disabled{opacity:.45;}
/* 2026-10-30: the angle's degree sign, tight to its number; a label the
   cell hides (a box's Length) takes no room */
.rbn-geom .geo-unit{margin-left:-2px;}
.rbn-geom .geo[hidden]{display:none;}
/* T748: Size & position as ONE grid -- W over X, H over Y, the angle over
   Rotate -- placed by hand, so a hidden lock or a longer number never
   moves one under the other. The letters share a width, so the fields
   line up as columns. A line shows only its length and angle. */
.rbn-row>.rbn-stack.rbn-geogrid{display:grid;
  grid-template-columns:auto auto;
  grid-template-rows:var(--rbn-track) var(--rbn-track);
  row-gap:var(--rbn-row-gap);column-gap:var(--rbn-col-gap);
  align-items:center;justify-items:start;}
.rbn-geogrid>#fmt-geom-wh{grid-row:1;grid-column:1;}
.rbn-geogrid>#fmt-geom-xy{grid-row:2;grid-column:1;}
.rbn-geogrid>#fmt-geom-ang{grid-row:1;grid-column:2;}
.rbn-geogrid>#fmt-rotwrap{grid-row:2;grid-column:2;}
.rbn-geogrid>.sh-drop:not([hidden]){display:flex;height:100%;}
.rbn-geogrid>.sh-drop>.dbtn{width:100%;}
.rbn-geogrid #fmt-geom-wh .geo>span:first-child,
.rbn-geogrid #fmt-geom-xy .geo>span:first-child{width:11px;
  text-align:center;}
body.light .rbn-geom input{color:var(--ink-2);background:var(--input-bg);
  border-color:var(--border-strong);}

/* ---- T208: SEGMENTED RUNS, AND A RUN WITH NOTHING SHOWING IS NOT THERE --
   B I U and Left Centre Right are one cell each, so the letters sit
   shoulder to shoulder at their own widths (a grid column had made "U"
   as wide as whatever stood under it). A cell whose every button is
   hidden takes no column. */
.rbn-cell#tx-run-style .dbtn,.rbn-cell#tx-run-align .dbtn{padding:3px 7px;}
.rbn-cell#tx-run-style .dbtn.etm{min-width:28px;justify-content:center;}
/* T465: the CHILD combinator. Without it the <b>/<i>/<u>/<s> inside
   the hidden buttons counted as "something showing", so B/I/U/S and
   Left/Centre/Right stayed as 2px slivers beside a shape or a table and
   pushed the row's first control to the bottom track (2026-09-15
   review, measured). */
.rbn-row>.rbn-cell:not(:has(>:not([hidden]))){display:none;}

/* ---- T209: THE REVIEW VIEWS, FULL SCREEN --------------------------------
   Mismatched text and Tidy page draw their cards into a grid with room
   to read, under the same header the All images view has. */
.std-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));
  gap:10px;align-content:start;}
.img-ov .std-find{margin:0;background:#ffffff05;border:1px solid #ffffff14;
  border-left:3px solid #f0a848;border-radius:9px;padding:12px 14px;}
.img-ov .std-find.std-info{border-left-color:#39a9c0;}
.img-ov .std-h{font-size:14px;}
.img-ov .std-why{font-size:12.5px;}
.img-ov .pf-ok{grid-column:1/-1;font-size:14px;max-width:760px;}
.img-ov .hd-lab{grid-column:1/-1;margin-top:6px;}
.img-ov .std-find.std-fig{grid-column:auto;}
body.light .img-ov .std-find{background:var(--surface-hover);
  border-color:var(--line);}
.lay-ideas .li-grid{gap:16px;}
.lay-ideas .li-card{padding:10px;}
.lay-ideas .li-lab{font-size:13px;}

/* ---- T212: a run says what it is ---------------------------------------
   The spacing trio wears a small caption inside its cell. */
.rbn-cell .cell-lab{align-self:center;font-family:var(--sans);font-size:11.5px;
  letter-spacing:0;text-transform:none;color:var(--chrome-ink-2);padding:0 6px 0 2px;}

/* ---- T214: Before you print, full screen --------------------------------
   The same rows the pane drew, as cards in the review grid. */
.img-ov .pf-row{display:flex;flex-direction:column;gap:4px;text-align:left;
  padding:12px 14px;border-radius:9px;border:1px solid #ffffff14;
  background:#ffffff05;font-size:13px;}
.img-ov .pf-row .pf-what{font-size:14px;font-weight:600;}
.img-ov .pf-row .pf-why{font-size:12.5px;}
body.light .img-ov .pf-row{background:var(--surface-hover);
  border-color:var(--line);}

/* ---- T215: ROOM TO READ ON A BIG SCREEN ----------------------------------
   The ribbon's sizes were set for a laptop; on a wide monitor (2026-09-03,
   user: "some of the text is maybe too small now") the words grow a step
   while the geometry stays. */
@media (min-width:1600px){
  .edit-tools .dbtn.rbn-sm,.edit-tools .dbtn.etm{font-size:12.5px;}
  .edit-tools .fx-tile{font-size:11.5px;}
  .edit-tools .rbn-lab{font-size:10.5px;}
  .edit-tools .rbn-cell .cell-lab{font-size:12px;}
  .rbn-tab{font-size:13.5px;}
}

/* ---- T216: the Present tab ---------------------------------------------- */
.rbn-play{order:1;}
.rbn-version{order:2;}    /* T477: which version, between Play and the talk */
.rbn-talk{order:3;}
/* a deck with no versions has one tile and no strip to speak of: the
   frame is as wide as that tile */
.strip-frame>#pr-version-strip.trans-strip{width:max-content;
  max-width:calc(4 * var(--rbn-tile-w) + 3 * var(--rbn-tile-gap) + 8px);}

/* ---- T218: the folded door is a tile; the delay's cell --------------------- */
.rbn-grp.rbn-folded>.rbn-foldwrap{align-items:center;}
/* T463: a door is a wider tile -- a group's name is longer than a
   verb -- and, like every tile now, never narrower than its words. A
   door with a choice on it keeps its name on one line (the tile's
   has-val rule), so "Text sequence ▾" widens the door rather than
   dropping its chevron onto a line of its own; a door without one
   wraps its name into the 82px. The readout itself is the tile's
   (.fx-tile>.rbn-foldval), shared with New slide and Send it away. */
.rbn-foldwrap .fx-tile.rbn-foldbtn{height:var(--rbn-tile-h);min-width:82px;}
.rbn-foldwrap .fx-tile.rbn-foldbtn>span{text-align:center;line-height:1.15;}
.rbn-foldwrap .fx-tile.rbn-foldbtn:not(.has-val)>span{white-space:normal;}
/* T441: the door's readout -- the current choice, under the name. T463:
   the icon stays. It used to step aside for the value, which left the
   choosers the only wordless-icon-less tiles on the bar; with the
   has-val gap the three lines fit the tile. */
.rbn-foldbtn.has-val>span:first-of-type{font-size:11px;color:var(--ink-2);}
#anim-delaycell .fmt-szwrap{display:flex;align-items:center;gap:4px;}
#anim-delaycell .cell-lab{padding-left:2px;}

/* ---- T607: A WORK VIEW IS A SHEET, NOT THE WHOLE WINDOW ----------------
   (2026-10-03, user: "make sure layouts are good and not eating up the
   entire screen which seems to be common. I think this gets missed as
   this is ok for you but not humans.") History, the Style system, the
   deck in words, the bigger notes editor, the item view and the card
   lists T209 and T214 gave room to read were each the whole window,
   edge to edge, in the page colour -- at a laptop's 1366x657 History was
   a 360px list in a black page with its two footnotes stranded in the
   middle and at the bottom, and the Style system a quarter-filled form
   with nothing of the deck in sight. A machine reading the DOM never
   notices it has lost the room; a person does. Each is now a sheet:
   centred, at most 1180px wide, as tall as what is in it (the views
   that ARE a writing surface keep the full height), over the editor
   dimmed but still there. The slide sorter and the shows stay full
   screen -- the window is what they are for. The room to read T209
   asked for is kept: the card lists are still the width of a page,
   never a 272px pane again. */
.deck-history,.deck-design,.deck-review,.deck-notesed,.img-ov,.vfull,
.sh-menu.lay-ideas{inset:24px;margin:auto;box-sizing:border-box;
  width:min(1180px,calc(100vw - 48px));height:fit-content;
  max-height:calc(100vh - 48px);
  border:1px solid var(--chrome-line,#ffffff24);border-radius:12px;
  box-shadow:0 24px 70px #000000a6,0 0 0 100vmax rgb(3 8 13 / .58);}
/* writing surfaces fill the height the sheet may have */
.deck-review,.deck-notesed,.vfull{height:calc(100vh - 48px);}
/* the dimmed editor is not clickable through the sheet: this layer is
   the sheet's own (a press on it is a press on the sheet, which
   sheetBoot reads as "close"), transparent, under everything in it */
.deck-history::before,.deck-design::before,.deck-review::before,
.deck-notesed::before,.img-ov::before,.vfull::before,
.sh-menu.lay-ideas::before{content:"";position:fixed;inset:0;z-index:-1;}
body.light .deck-history,body.light .deck-design,body.light .deck-review,
body.light .deck-notesed,body.light .img-ov,body.light .vfull{
  box-shadow:0 24px 70px #0000004d,0 0 0 100vmax rgb(20 30 40 / .34);}

/* ---- T559: New presentation -- blank, or a starting deck --------------
   A small dialog: five cards in one row at a laptop's width, each drawn
   from the deck it makes (a contact sheet of its first four slides, or
   its one page), its name and slide count, and one line on what it is
   for. Wraps to two rows below ~1000px; never a screen of its own. */
.aa-box.nt-box{width:min(980px,94vw);}
.nt-grid{display:grid;gap:10px;overflow-y:auto;min-height:0;
  grid-template-columns:repeat(auto-fill,minmax(176px,1fr));}
.nt-card{display:flex;flex-direction:column;gap:6px;text-align:left;
  padding:8px;border-radius:9px;cursor:pointer;color:var(--chrome-ink);
  background:var(--chrome-1);border:1px solid var(--chrome-line);
  font-family:var(--sans);}
.nt-card:hover,.nt-card:focus-visible{border-color:var(--accent,var(--cyan));
  background:color-mix(in srgb,var(--accent) 9%,var(--chrome-1));
  outline:none;}
.nt-sheet{display:grid;grid-template-columns:repeat(2,max-content);
  gap:4px;justify-content:center;align-content:center;height:94px;}
.nt-sheet.nt-one{grid-template-columns:max-content;}
.nt-sheet .mini-diagram{border-radius:3px;pointer-events:none;}
.nt-name{display:flex;align-items:baseline;gap:6px;font-size:13px;
  font-weight:600;}
.nt-n{margin-left:auto;font:400 10px var(--mono);color:var(--chrome-ink-3);
  white-space:nowrap;}
.nt-blurb{font-size:11px;line-height:1.4;color:var(--chrome-ink-2);}

/* ---- T551: the picked cells, the Lines look, and the table menus -------
   A picked cell is tinted and ringed in the accent, inside its own rules
   so the grid does not shift; only while editing (drawTable adds the
   class from the pick, and nothing is picked in a show or a print). */
.deck.editing .an-tbl td.tc-sel,.deck.editing .an-tbl th.tc-sel{
  box-shadow:inset 0 0 0 2px var(--accent,var(--cyan)),
    inset 0 0 0 999px color-mix(in srgb,var(--accent,#39a9c0) 16%,transparent);}
.an-table.tst-lines .an-tbl th{background:none;
  border-bottom-width:calc(var(--tbl-sw,1px) * 2.5);}
.sh-menu.tbl-menu{display:flex;flex-direction:column;gap:3px;
  width:288px;padding:8px;}
.tbl-menu .vw-opt{width:100%;text-align:left;align-items:flex-start;
  flex-direction:column;gap:2px;padding:7px 10px;height:auto;}
.tbl-menu .vw-opt[disabled]{opacity:.45;}
.tbl-note{font:11.5px var(--sans);color:var(--chrome-ink-3);
  padding:4px 4px 2px;}
.tbl-swatches{display:grid;grid-template-columns:repeat(7,1fr);gap:5px;
  padding:2px 2px 4px;}
.tbl-sw{height:24px;border-radius:5px;border:1px solid var(--chrome-line);
  cursor:pointer;padding:0;}
.tbl-sw:hover{outline:2px solid var(--accent,var(--cyan));outline-offset:1px;}
.tbl-sw[disabled]{opacity:.4;cursor:default;outline:none;}
.tbl-fill-foot{display:flex;align-items:center;gap:8px;padding:2px;}
.tbl-anylab{display:flex;align-items:center;gap:6px;font:12px var(--sans);
  color:var(--chrome-ink-2);cursor:pointer;}
.tbl-any{width:30px;height:24px;padding:0;border:1px solid var(--chrome-line);
  border-radius:5px;background:none;cursor:pointer;}
.sh-menu.tbl-style-menu{width:330px;}
.tbl-gal{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;
  padding:2px 2px 4px;}
.tbl-card{display:flex;flex-direction:column;align-items:center;gap:4px;
  padding:6px;border-radius:7px;cursor:pointer;color:var(--chrome-ink-2);
  background:var(--page-bg,var(--chrome-0));border:1px solid var(--chrome-line);
  font:11px var(--sans);}
.tbl-card:hover{border-color:var(--accent,var(--cyan));}
.tbl-card[aria-pressed="true"]{border-color:var(--accent,var(--cyan));
  box-shadow:0 0 0 1px var(--accent,var(--cyan));color:var(--chrome-ink);}
.tbl-prev{display:flex;flex-direction:column;width:84px;
  border:1px solid color-mix(in srgb,var(--chrome-ink) 30%,transparent);}
.tbl-prev-r{display:flex;}
.tbl-prev-c{flex:1;height:9px;border-right:1px solid
  color-mix(in srgb,var(--chrome-ink) 22%,transparent);
  border-bottom:1px solid color-mix(in srgb,var(--chrome-ink) 22%,transparent);}
.tbl-prev-c:last-child{border-right:0;}
.tbl-opt{display:flex;align-items:flex-start;gap:8px;padding:5px 6px;
  font:12px/1.4 var(--sans);color:var(--chrome-ink-2);cursor:pointer;
  border-radius:6px;}
.tbl-opt:hover{background:color-mix(in srgb,var(--accent) 10%,transparent);}
.tbl-opt b{color:var(--chrome-ink);font-weight:600;}
.tbl-opt input{margin:2px 0 0;accent-color:var(--accent,var(--cyan));}

/* ---- T558: ink while presenting ----------------------------------------
   The ink lies over the slide in its own percentages, above everything on
   it; it takes the pointer only while a tool is up, so a click on the
   slide still advances otherwise. The bar is small, bottom-left, and only
   there while a tool is: the room is looking at the slide. */
.jv-ink{position:absolute;inset:0;width:100%;height:100%;z-index:30;
  pointer-events:none;overflow:visible;}
.jv-ink.jv-ink-live{pointer-events:auto;cursor:crosshair;touch-action:none;}
.jv-ink.jv-ink-live.jv-ink-erase{cursor:cell;}
.jv-inkbar{position:fixed;left:14px;bottom:14px;z-index:440;display:flex;
  align-items:center;gap:4px;padding:5px;border-radius:10px;
  background:color-mix(in srgb,var(--chrome-1,#0e1926) 88%,transparent);
  border:1px solid var(--chrome-line,#ffffff24);
  box-shadow:0 8px 26px #00000066;opacity:.55;transition:opacity .2s;}
.jv-inkbar:hover,.jv-inkbar:focus-within{opacity:1;}
.jv-inkbar[hidden]{display:none;}
.jv-ink-b{white-space:nowrap;padding:4px 8px;font-size:11px;}
.jv-ink-b[aria-pressed="true"]{border-color:var(--accent,var(--cyan));
  color:var(--chrome-ink);background:color-mix(in srgb,var(--accent) 18%,
  transparent);}
.jv-ink-cols{display:flex;gap:4px;padding:0 4px;}
.jv-ink-col{width:18px;height:18px;border-radius:50%;padding:0;
  cursor:pointer;border:2px solid var(--chrome-line,#ffffff33);}
.jv-ink-col[aria-pressed="true"]{border-color:var(--chrome-ink,#fff);
  box-shadow:0 0 0 2px var(--accent,var(--cyan));}
/* on a light page a highlighter darkens what is under it, as a real one
   does, rather than laying a pale film over the words */
.slide.page-light .jv-ink .jv-hl{mix-blend-mode:multiply;}

/* ---- T563: comments ------------------------------------------------------
   A marker is a small amber speech bubble on the corner of what it is
   about -- drawn only while editing (cmtMount), never in the show, a print
   or an export -- with a count when there is more than one there. */
.cmt-pins{position:absolute;inset:0;pointer-events:none;z-index:9;}
.cmt-pin{position:absolute;transform:translate(-50%,-50%);
  pointer-events:auto;display:inline-flex;align-items:center;gap:2px;
  height:22px;min-width:22px;padding:0 5px;border-radius:11px 11px 11px 3px;
  border:1px solid color-mix(in srgb,#f0a848 70%,#000);
  background:#f0a848;color:#1a1205;cursor:pointer;
  box-shadow:0 2px 8px #0006;font:700 10.5px var(--sans);}
.cmt-pin .bic{width:12px;height:12px;}
.cmt-pin:hover{outline:2px solid var(--accent,var(--cyan));outline-offset:1px;}
.film-mark.cmt{display:inline-flex;align-items:center;gap:2px;
  color:var(--warning,#f0a848);}
.film-mark.cmt .bic{width:10px;height:10px;}
.compane .selpane-list{display:flex;flex-direction:column;gap:8px;}
.cmt-tabs{margin:-2px -10px 2px;}
.cmt-compose{display:flex;flex-direction:column;gap:5px;}
.cmt-on{font:11.5px var(--sans);color:var(--chrome-ink-2);}
.cmt-ta{min-height:54px;font:12.5px/1.45 var(--sans);}
.cmt-row{display:flex;align-items:center;justify-content:flex-end;gap:6px;}
.cmt-link{background:none;border:0;padding:0;cursor:pointer;
  color:var(--accent,var(--cyan));font:inherit;text-align:left;}
.cmt-link:hover{text-decoration:underline;}
.cmt-empty{font:12px var(--sans);color:var(--chrome-ink-3);padding:6px 2px;}
.cmt-slide{background:none;border:0;padding:6px 0 0;cursor:pointer;
  text-align:left;font:600 11px var(--sans);color:var(--chrome-ink-2);
  overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}
.cmt-card{background:var(--chrome-1);border:1px solid var(--chrome-line);
  border-left:3px solid var(--warning,#f0a848);border-radius:8px;
  padding:7px 9px;display:flex;flex-direction:column;gap:5px;}
.cmt-card.done{border-left-color:var(--chrome-line);opacity:.75;}
.cmt-card.cmt-flash{box-shadow:0 0 0 2px var(--accent,var(--cyan));}
.cmt-head{display:flex;align-items:baseline;gap:8px;font:11px var(--sans);}
.cmt-head .cmt-link{flex:1;min-width:0;overflow:hidden;white-space:nowrap;
  text-overflow:ellipsis;}
.cmt-when{font:10px var(--mono);color:var(--chrome-ink-3);white-space:nowrap;}
.cmt-text{font:12.5px/1.45 var(--sans);color:var(--chrome-ink);
  white-space:pre-wrap;overflow-wrap:anywhere;}
.cmt-re{margin-left:10px;padding-left:8px;border-left:2px solid
  var(--chrome-line);display:flex;flex-direction:column;gap:2px;}
.cmt-acts{display:flex;gap:4px;flex-wrap:wrap;}
.cmt-act{padding:3px 8px;font-size:10.5px;}
.cmt-done>summary{cursor:pointer;font:600 11px var(--sans);
  color:var(--chrome-ink-2);padding:4px 0;}
.cmt-done>.cmt-card{margin-top:6px;}

/* ---- T561: Diagram -- the kinds, the steps and the preview ----------
   A small dialog, never a screen: four kinds across the top (each drawn
   by the layout it places), the steps on the left in a fixed-width face
   so the indents read, and the preview at the slide's own shape on the
   right. One column on a phone. */
.aa-box.dgm-box{width:min(640px,94vw);}
.dgm-kinds{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;}
.dgm-kind{display:flex;flex-direction:column;align-items:center;gap:4px;
  padding:6px 6px 5px;border-radius:8px;cursor:pointer;
  background:var(--chrome-1);border:1px solid var(--chrome-line);
  color:var(--chrome-ink);font:600 12px var(--sans);}
.dgm-kind:hover,.dgm-kind:focus-visible{outline:none;
  border-color:color-mix(in srgb,var(--accent) 60%,var(--chrome-line));}
.dgm-kind.on{border-color:var(--accent);
  background:color-mix(in srgb,var(--accent) 12%,var(--chrome-1));}
.dgm-mini{display:block;width:100%;max-width:118px;height:auto;
  border-radius:4px;pointer-events:none;}
.dgm-body{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:12px;
  min-height:0;}
.dgm-col{display:flex;flex-direction:column;gap:5px;min-width:0;}
.dgm-lab{font-size:11.5px;line-height:1.35;color:var(--chrome-ink-2);}
.dgm-text{font:12.5px/1.5 var(--mono);tab-size:2;resize:vertical;
  min-height:118px;}
.dgm-preview .dgm-svg{display:block;border-radius:6px;
  border:1px solid var(--chrome-line);}
.dgm-count{font:10.5px var(--mono);color:var(--chrome-ink-3);}
@media (max-width:560px){
  .dgm-kinds{grid-template-columns:repeat(2,1fr);}
  .dgm-body{grid-template-columns:minmax(0,1fr);}
}

/* ---- T625: one animation rule for many slides ----------------------
   A row per kind of thing (its colour, its name, how many there are in
   the slides chosen, then four choices and Earlier), the current slide
   drawn small beside them with the click each thing arrives on, and
   which slides get it underneath. Every colour is the theme's own, so
   the dialog is right in every theme; the seven kind colours are the
   only colours of its own, and they sit on the slide's own page colour
   in the preview. Laid out to fit 1280x600 without a scroll. */
.aa-box.anr-box{width:min(940px,96vw);gap:8px;}
.anr-q{font:12px var(--sans);padding:3px 9px;white-space:nowrap;}
.anr-q[aria-expanded="true"]{border-color:var(--accent);color:var(--accent);}
.anr-help{margin:0;font-size:12px;line-height:1.45;color:var(--chrome-ink-2);
  background:var(--chrome-1);border:1px solid var(--chrome-line);
  border-radius:8px;padding:7px 10px;}
.anr-help[hidden]{display:none;}
.anr-body{display:flex;gap:14px;align-items:flex-start;flex-wrap:wrap;
  min-height:0;}
.anr-main{flex:1 1 560px;min-width:0;display:flex;flex-direction:column;
  gap:5px;}
.anr-side{flex:0 0 200px;display:flex;flex-direction:column;gap:6px;}
.anr-lab{font-size:11.5px;color:var(--chrome-ink-2);white-space:nowrap;}
.anr-order{display:flex;align-items:center;gap:6px;flex-wrap:wrap;}
.anr-order .cfg-chip{margin:0;}
/* the fourth choice is every kind's now (One by one / All together,
   2026-10-17): its column takes a little from the three before it, each
   of which still reads its longest choice whole */
.anr-heads,.anr-row{display:grid;align-items:center;gap:6px;
  grid-template-columns:minmax(170px,1.6fr) minmax(0,.92fr) minmax(0,1.1fr)
    minmax(0,.96fr) minmax(0,1.02fr) auto;}
.anr-heads{font-size:10.5px;color:var(--chrome-ink-3);padding:0 2px;}
.anr-rows{display:flex;flex-direction:column;gap:3px;}
.anr-row{padding:2px 2px;border-radius:6px;}
.anr-row:hover{background:var(--surface-hover);}
.anr-kind{display:flex;align-items:center;gap:6px;min-width:0;
  font-size:12.5px;color:var(--chrome-ink);}
.anr-kind .bic{width:13px;height:13px;flex:none;color:var(--chrome-ink-2);}
.anr-kn{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.anr-n{font:10.5px var(--mono);color:var(--chrome-ink-3);flex:none;}
.anr-sw{width:10px;height:10px;border-radius:3px;flex:none;
  background:var(--anr-c);}
.anr-row.anr-none .anr-kind{color:var(--chrome-ink-3);}
.anr-row.anr-off .anr-sel:not(.anr-fx){opacity:.45;}
.anr-sel{width:100%;min-width:0;box-sizing:border-box;font:12px var(--sans);
  padding:4px 6px;border-radius:6px;color:var(--chrome-ink);
  background:var(--input-bg);border:1px solid var(--border-strong);}
.anr-sel:focus-visible,.anr-range:focus-visible{outline:2px solid var(--focus);
  outline-offset:1px;}
.anr-sel:disabled{cursor:default;opacity:.55;}
.anr-up{font:11.5px var(--sans);padding:3px 8px;white-space:nowrap;}
.anr-up:disabled{opacity:.35;cursor:default;}
.anr-rows.anr-place .anr-up{visibility:hidden;}
/* the seven kinds: one hue each, the same in the legend and the preview */
.anr-k-title{--anr-c:#e0a33a;}
.anr-k-text{--anr-c:#4fb3d9;}
.anr-k-figure{--anr-c:#7cc46a;}
.anr-k-image{--anr-c:#b38cf0;}
.anr-k-shape{--anr-c:#f08a6c;}
.anr-k-table{--anr-c:#46b8a8;}
.anr-k-code{--anr-c:#9aa9b6;}
.anr-pv{position:relative;width:100%;aspect-ratio:16 / 9;overflow:hidden;
  border-radius:6px;border:1px solid var(--chrome-line);
  background:var(--chrome-0);}
.anr-o{position:absolute;box-sizing:border-box;border-radius:2px;
  background:color-mix(in srgb,var(--anr-c) 42%,transparent);
  border:1px solid var(--anr-c);}
.anr-o b{position:absolute;left:1px;top:1px;font:700 9px/1 var(--mono);
  color:#0b141d;background:var(--anr-c);border-radius:3px;padding:1px 3px;}
.anr-o.anr-wait{opacity:0;}
.anr-pvfoot{display:flex;align-items:center;gap:8px;}
.anr-pvn{font:10.5px var(--mono);color:var(--chrome-ink-3);}
.anr-opts{display:flex;align-items:center;gap:8px 16px;flex-wrap:wrap;
  padding-top:7px;border-top:1px solid var(--chrome-line);}
.anr-opt{display:flex;align-items:center;gap:6px;}
.anr-opts .anr-sel{width:auto;}
.anr-range{width:96px;box-sizing:border-box;font:12px var(--mono);
  padding:4px 6px;border-radius:6px;color:var(--chrome-ink);
  background:var(--input-bg);border:1px solid var(--border-strong);}
.anr-range[hidden]{display:none;}
.anr-sum{font-size:12px;color:var(--chrome-ink-2);}
/* Replace taking entrances off is said in the danger ink, before Apply */
.anr-sum.anr-sum-warn{color:var(--danger);}
@media (max-width:760px){
  .anr-side{flex:1 1 100%;flex-direction:row;align-items:flex-end;}
  .anr-pv{width:180px;}
}
@media (max-height:640px){
  .aa-box.anr-box{gap:6px;padding:9px 12px 9px;}
  .anr-row{padding:1px 2px;}
  .anr-sel{padding:3px 6px;}
}

/* ---- T564: narration -- the recording bar, the strip mark, the pane --
   The bar sits at the foot of the screen, centred: the ink bar has the
   left corner and the slide count the right. Faint until the pointer
   comes to it, like the ink bar, but its dot stays red: you always know
   the microphone is on. */
.jv-recbar{position:fixed;left:50%;bottom:14px;transform:translateX(-50%);
  z-index:440;display:flex;align-items:center;gap:8px;padding:5px 6px 5px 10px;
  border-radius:999px;background:rgb(11 20 29 / .86);color:#e8eef3;
  border:1px solid #ffffff22;font:12px var(--sans);opacity:.72;
  box-shadow:0 8px 26px #0007;transition:opacity .15s;}
.jv-recbar:hover{opacity:1;}
.jv-recbar[hidden]{display:none;}
.jv-recbar .rec-dot{width:10px;height:10px;border-radius:50%;flex:none;
  background:#ff3b30;box-shadow:0 0 0 3px rgb(255 59 48 / .25);}
.jv-recbar.paused .rec-dot{background:#f0a848;box-shadow:none;}
.jv-recbar .rec-t{font-variant-numeric:tabular-nums;white-space:nowrap;}
.jv-recbar .dbtn{font-size:11.5px;padding:3px 9px;white-space:nowrap;}
.film-mark.narr{color:var(--danger);}
.np-narr{display:flex;align-items:center;flex-wrap:wrap;gap:6px;
  margin-top:8px;padding-top:8px;border-top:1px solid var(--chrome-line);}
.np-narr-lab{flex:1 1 auto;font-size:12px;color:var(--chrome-ink-2);
  display:inline-flex;align-items:center;gap:5px;}
.np-narr .dbtn{font-size:11.5px;padding:3px 9px;}
/* T682: A LINKED SLIDE IS READ ONLY (57-parts partShield): a cover over
   the slide that takes every press. Above the annot layer (6) and its
   selection paint; under the deck's menus. */
.deck.editing .slide>.lk-shield{position:absolute;inset:0;z-index:8;
  cursor:not-allowed;border-radius:inherit;}
.lk-menu .lk-say{padding:4px 10px 8px;font-size:12px;line-height:1.4;
  color:var(--chrome-ink-2,#9fb0c0);}
body.light .lk-menu .lk-say{color:var(--ink-2,#555);}
/* T683, T684: CONTENTS, in the slide's place (57-parts openParts): over
   #deck-stage and nothing else -- its top and height set from the stage
   (partsFit) -- with the ribbon greyed while it is there. Above the
   slide's layers and the stage's own chrome; under the deck's menus
   (240) and its questions (300). */
.deck-parts{position:absolute;left:0;right:0;z-index:125;overflow:auto;
  background:var(--chrome-0,#0b141d);
  font-family:var(--sans);color:var(--chrome-ink,#d7e3ec);}
/* T685: one column, everything in it in line -- the title and its
   buttons, the list, the add row, the settings */
.ct-col{max-width:920px;margin:0 auto;padding:0 20px 28px;}
.deck-parts .prt-head{display:flex;align-items:center;gap:10px;
  position:sticky;top:0;z-index:2;background:var(--chrome-0,#0b141d);
  padding:14px 0 10px;}
.deck-parts .prt-head .ovw-t{font-size:16px;font-weight:600;
  color:var(--chrome-ink,#d7e3ec);}
.deck-parts .prt-body{padding:0;}
.deck.ct-open #edit-tools .rbn-grp{opacity:.38;pointer-events:none;
  filter:grayscale(1);}
/* the rows */
.ct-list{display:flex;flex-direction:column;gap:6px;}
/* T685: the columns, the same in the header, the total and every row:
   handle, arrow, name, slides, size, where its slides are */
.ct-cols,.ct-total,.ct-hd{display:grid;align-items:center;column-gap:10px;
  grid-template-columns:18px 20px minmax(0,1fr) 56px 72px 190px;
  padding:0 12px 0 7px;}
.ct-cols>.ct-c-name,.ct-total>.ct-c-name{grid-column:3;}
.ct-c-name{display:flex;align-items:center;gap:8px;min-width:0;}
.ct-c-n,.ct-c-sz{text-align:right;font-variant-numeric:tabular-nums;
  font-size:12.5px;color:var(--chrome-ink-2,#93a8ba);}
.ct-c-where{display:flex;justify-content:flex-start;min-width:0;}
.ct-cols{padding-top:4px;padding-bottom:6px;font-size:11px;font-weight:600;
  letter-spacing:.04em;text-transform:uppercase;
  color:var(--chrome-ink-3,#6f8293);}
.ct-cols .ct-c-n,.ct-cols .ct-c-sz{font-size:11px;color:inherit;}
.ct-total{min-height:40px;margin-bottom:8px;border-radius:9px;
  border:1px solid transparent;
  background:color-mix(in srgb,var(--accent) 9%,transparent);}
.ct-total .ct-c-name{font-size:13px;font-weight:700;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;}
.ct-total .ct-c-n,.ct-total .ct-c-sz{font-weight:700;
  color:var(--chrome-ink,#d7e3ec);}
.ct-total .ct-c-where{font-size:12px;color:var(--chrome-ink-2,#93a8ba);
  padding-left:10px;}
/* adding more: under the list, in line with the names */
.ct-add{display:flex;gap:8px;flex-wrap:wrap;padding:10px 0 0 55px;}
/* the settings, all on show, in two columns where there is room */
.ct-set{margin-top:26px;padding-top:14px;
  border-top:1px solid var(--chrome-line,#ffffff1a);}
.ct-set[hidden]{display:none;}
.ct-set-t{margin:0 0 10px;font-size:14px;font-weight:600;}
.ct-set .pz-body{display:grid;grid-template-columns:repeat(auto-fill,
  minmax(270px,1fr));column-gap:32px;overflow:visible;padding:0;}
.ct-set .pz-set,.ct-set .pz-set:first-child{border-top:1px solid
  var(--chrome-line,#ffffff1a);padding:12px 0 14px;}
.ct-row{border:1px solid var(--chrome-line,#ffffff1f);border-radius:9px;
  background:var(--chrome-1,#0f1b26);
  box-shadow:inset 3px 0 0 var(--ct-c,transparent);}
.ct-row.on{border-color:color-mix(in srgb,var(--accent) 45%,transparent);}
.ct-row.dragging{opacity:.45;}
.ct-row.drop-before{box-shadow:inset 3px 0 0 var(--ct-c,transparent),
  0 -3px 0 0 var(--accent);}
.ct-row.drop-after{box-shadow:inset 3px 0 0 var(--ct-c,transparent),
  0 3px 0 0 var(--accent);}
.ct-row.drop-in{border-color:var(--accent);
  background:color-mix(in srgb,var(--accent) 10%,var(--chrome-1,#0f1b26));}
.ct-hd{min-height:44px;}
.ct-grip{flex:none;width:18px;text-align:center;cursor:grab;font-size:15px;
  line-height:1;color:var(--chrome-ink-3,#6f8293);user-select:none;}
.ct-grip:hover{color:var(--chrome-ink,#d7e3ec);}
.ct-ex{all:unset;flex:none;width:20px;height:20px;display:grid;
  place-items:center;border-radius:4px;cursor:pointer;font-size:11px;
  color:var(--chrome-ink-2,#93a8ba);}
.ct-ex:hover{background:#ffffff14;color:var(--chrome-ink,#d7e3ec);}
.ct-ex:disabled{visibility:hidden;}
.ct-ex:focus-visible,.ct-go:focus-visible,.ct-chip:focus-visible{
  outline:2px solid var(--accent);}
.ct-go{all:unset;cursor:pointer;display:inline-flex;align-items:center;gap:7px;
  min-width:0;font-size:13px;font-weight:600;border-radius:5px;padding:2px 5px;}
.ct-go:hover .ct-nm{text-decoration:underline;}
.ct-go:disabled{cursor:default;opacity:.6;}
.ct-go .bic{width:14px;height:14px;flex:none;color:var(--chrome-ink-2,#93a8ba);}
.ct-nm{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.ct-from,.ct-warn{flex:none;font-size:11.5px;color:var(--chrome-ink-2,#93a8ba);}
.ct-warn{color:var(--warning,#e0b050);}
.ct-chip{all:unset;flex:none;cursor:pointer;display:inline-flex;
  align-items:center;gap:5px;height:24px;padding:0 10px;border-radius:12px;
  font-size:12px;background:#ffffff10;border:1px solid #ffffff1f;
  color:var(--chrome-ink,#d7e3ec);}
.ct-chip:hover{background:#ffffff1c;}
.ct-chip.ro{color:var(--accent);
  border-color:color-mix(in srgb,var(--accent) 45%,transparent);}
.ct-chip.ed{color:var(--warning,#e0b050);
  border-color:color-mix(in srgb,var(--warning,#e0b050) 50%,transparent);}
.ct-cv{font-size:10px;opacity:.8;}
/* its slides, opened under it */
.ct-tiles{display:flex;flex-wrap:wrap;gap:8px;padding:2px 12px 12px 62px;}
.ct-tile{all:unset;position:relative;width:112px;cursor:grab;
  border-radius:5px;outline:1px solid #ffffff1f;background:var(--chrome-0,#0b141d);}
.ct-tile[draggable="false"]{cursor:pointer;}
.ct-tile.cur{outline:2px solid var(--accent);}
.ct-tile.drop-at{box-shadow:-4px 0 0 0 var(--accent);}
.ct-tile:focus-visible{outline:2px solid var(--accent);}
.ct-tile svg{display:block;width:100%;height:auto;border-radius:5px;}
.ct-n{position:absolute;left:4px;top:3px;font-size:10px;
  color:var(--chrome-ink-2,#93a8ba);}
/* the doors: Contents at the top of the thumbnails, in the accent, and
   first along the bottom tabs */
.film-contents{display:flex;align-items:center;gap:7px;margin:8px 8px 6px;
  padding:7px 11px;font-size:12.5px;font-weight:600;border-radius:8px;
  background:color-mix(in srgb,var(--accent) 22%,transparent);
  border:1px solid color-mix(in srgb,var(--accent) 60%,transparent);
  color:var(--chrome-ink,#e8f2f8);}
.film-contents:hover{background:color-mix(in srgb,var(--accent) 32%,transparent);}
.film-contents[aria-pressed="true"]{background:var(--accent);color:var(--on-accent,#04121c);}
.film-contents[hidden]{display:none;}
.film-contents .bic{width:14px;height:14px;}
.film-contents .fc-n{margin-left:auto;font-variant-numeric:tabular-nums;
  font-weight:500;opacity:.85;}
.deck-sheets .sht-contents{margin-right:4px;}
/* the top tabs' door, before the talk's own tab */
.top-pres-tab.pz-ctab .tab-t{font-weight:600;}
body.light .deck-parts,body.light .ct-row{color:var(--ink);}
body.light .ct-row{background:#fff;}
body.light .ct-chip{background:#0000000a;border-color:#0000001f;}
body.light .deck-parts .prt-head{background:var(--chrome-0);}
body.light .ct-total .ct-c-n,body.light .ct-total .ct-c-sz{color:var(--ink);}
/* T685: one row of the settings with its control at the end */
.pz-opt.pz-row{align-items:center;justify-content:space-between;}
.pz-opt.pz-sub{margin-left:24px;}
.pz-sel{font:inherit;font-size:12.5px;padding:3px 6px;border-radius:6px;
  border:1px solid var(--chrome-line);background:var(--chrome-1,#0f1b26);
  color:var(--chrome-ink,#d7e3ec);}
/* T685: the top tabs' group -- the talk's own tab hidden behind it, a
   tab for each presentation in it, its colour on its icon */
.top-pres-tab.pz-lead{display:none!important;}
#where-btn[hidden]{display:none!important;}
.top-pres-tab.pz-rtab .tab-ico{color:var(--rt-c,currentColor);}
.top-pres-tab.pz-rtab:not(.current) .tab-b{display:none;}
/* T685: presenting, the name of the presentation just started, in the
   corner for a moment -- over the slide's layers (6) and the column
   (120) */
.pz-xcard{position:absolute;right:24px;bottom:56px;z-index:130;
  display:flex;flex-direction:column;gap:2px;padding:10px 16px 11px;
  border-radius:10px;pointer-events:none;
  background:color-mix(in srgb,var(--chrome-0,#0b141d) 88%,transparent);
  border-left:4px solid var(--xc,var(--accent));
  box-shadow:0 8px 28px #0007;color:var(--chrome-ink,#e8f2f8);
  font-family:var(--sans);opacity:0;transform:translateX(16px);
  transition:opacity .35s ease,transform .35s ease;}
.pz-xcard.in{opacity:1;transform:none;}
.pz-xk{font-size:11px;letter-spacing:.05em;text-transform:uppercase;
  color:var(--chrome-ink-2,#93a8ba);}
.pz-xn{font-size:17px;font-weight:600;}
@media (prefers-reduced-motion:reduce){.pz-xcard{transition:none;transform:none;}}
body.light .film-contents{color:var(--ink);}
/* ---- T687: ONE CONTROL FOR SAVING -------------------------------------
   The Save button says how often it saves itself and saves now; a dot
   while something is not written yet (saveMirror); its readout's pill
   shows only when it needs you -- a full browser, a file waiting on a
   click (status: those are the .unsaved states). The ▾ beside it is
   every saving choice, how often included. */
.deck-status:not(.unsaved){display:none!important;}
#dc-save{display:inline-flex;align-items:center;gap:5px;position:relative;}
#dc-save .bic{width:13px;height:13px;}
#dc-save.sv-dirty::after{content:"";width:6px;height:6px;border-radius:50%;
  background:var(--warning,#e0b050);margin-left:2px;flex:none;}
.dc-mi .dc-kbd{margin-left:auto;padding-left:18px;font-size:11px;
  color:var(--chrome-ink-3,#6f8293);}
#sv-now{display:flex;align-items:center;}
#sv-auto{display:flex;flex-direction:column;}
/* T694: where it is saved, as words; the autosave choice */
.sv-where{white-space:pre-line;padding:2px 11px 6px;font-size:12.5px;
  line-height:1.45;color:var(--chrome-ink);max-width:280px;
  overflow-wrap:anywhere;}
.sv-auto{gap:2px;padding:2px 8px 6px;}
.sv-arow{display:flex;align-items:center;gap:6px;padding:5px 4px;
  font-size:12.5px;color:var(--chrome-ink);cursor:pointer;
  border-radius:5px;white-space:nowrap;}
.sv-arow:hover{background:color-mix(in srgb,var(--accent) 10%,transparent);}
.sv-arow input[type="radio"]{margin:0;accent-color:var(--cyan);}
.sv-n{width:58px;font:inherit;font-size:12.5px;padding:2px 4px 2px 6px;
  border:1px solid var(--chrome-line);border-radius:5px;
  background:var(--chrome-1,#0f1b26);color:var(--chrome-ink);}
/* back and forward beside the zoom, a pair */
.deck-zoombar .zb-hist{display:inline-flex;gap:2px;margin-right:6px;}
.rbn-tabs .deck-zoombar .zb-hist .dbtn.rbn-ico .bic{width:13px;height:13px;}
/* ---- T689: THE TAB ROW'S RIGHT END, ONE HEIGHT AND ONE LINE ----------
   (2026-10-29, the owner: "the present button with it's drop down arrow
   isn't perfectly algineed, the back and forewards button sits too high,
   and the collapse ribbon button is tiny".) Autosave came down from the
   title row to stand beside Present; every control here is 24px high on
   the row's centre line, a split control's two halves the same box, and
   the fold a 24px square. */
.rbn-tabs .qat-savegrp,.rbn-tabs .qat-playgrp,.rbn-tabs .deck-zoombar,
.rbn-tabs .deck-zoombar .zb-hist{align-self:center;display:inline-flex;
  align-items:stretch;flex:none;height:24px;}
.rbn-tabs .qat-savegrp{margin:0 6px 0 4px;}
.rbn-tabs .qat-savegrp .dbtn,.rbn-tabs .qat-playgrp .dbtn,
.rbn-tabs .deck-zoombar .dbtn.rbn-sm,.rbn-tabs .deck-zoombar .dbtn.rbn-ico,
.rbn-tabs .rbn-fold{height:24px;min-height:0;margin:0;box-sizing:border-box;
  display:inline-flex;align-items:center;justify-content:center;
  line-height:1;font-family:var(--sans);font-size:12px;white-space:nowrap;
  vertical-align:top;}
.rbn-tabs .qat-savegrp .dbtn{padding:0 9px;gap:5px;}
.rbn-tabs .qat-savegrp .dc-menuwrap,.rbn-tabs .qat-playgrp .dc-menuwrap{
  display:inline-flex;align-items:stretch;}
.rbn-tabs .qat-savegrp .dc-target,.rbn-tabs .qat-playgrp #dc-playmore{
  width:22px;padding:0;}
.rbn-tabs .deck-zoombar .dbtn.rbn-ico{width:26px;padding:0;}
.rbn-tabs .deck-zoombar .zb-hist .dbtn.rbn-ico .bic{width:13px;height:13px;
  margin:0;}
.rbn-tabs .rbn-fold{width:26px;padding:0;margin-left:4px;font-size:13px;}
.rbn-tabs.rt-c1 .qat-savegrp .dbtn:first-child{padding:0 6px;}
.rbn-tabs .qat-short{display:none;}
.rbn-tabs.rt-c1 .qat-long{display:none;}
.rbn-tabs.rt-c1 .qat-short{display:inline;}
