/* Spotsheet SV2 — The Selection Moment (DH #655).
   Production-only adaptation: the signed native shell supplies the outer
   window, while this stylesheet owns the NOTES | SFX interior. */

.sv2-selection {
  --sv2-lime: #CCDE49;
  --sv2-lime-rgb: 204, 222, 73;
  --sv2-lime-deep: #A3B520;
  --sv2-lime-wash: rgba(var(--sv2-lime-rgb), .12);
  /* --sv2-drawer-width is TWO things, per edition (#7209):
       SV2 app  - the twin of MainWindow.sv2DrawerExpansionWidth: the native
                  window grows its right edge by exactly this, so the SFX pane
                  is born at this width. One release contract, held at 420 by
                  the native selftest (SV2-DRAWER-OK expansion-width).
       SV3 app  - ONLY the SFX pane's default flex-basis. The native window
                  opens COLUMN -> LANDSCAPE (MainWindow.sv3LandscapeFrame:
                  1440x900 content, floor 900x600, clamped to the screen;
                  founder 2026-09-03: "column to landscape window when sfx
                  stuff is open", not the 360+420 square). This interior
                  assumes NO window width: both halves carry flex-grow 1
                  (#7137 below), so every pixel the landscape brings is shared
                  and the SFX side has no dead strip at 1440. */
  --sv2-drawer-width: 420px;
  width: 100%;
  height: 100%;
  min-width: 320px;
  min-height: 380px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  color: var(--fg);
  background: var(--bg-app);
  font-family: var(--ui);
  container-type: inline-size;
}

.sv2-identity {
  height: 31px;
  flex: 0 0 31px;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 8px 0 9px;
  background: linear-gradient(180deg, #3A3B43, #31323A);
  border-bottom: 1px solid var(--line);
}

/* #6950 — the header block is THE calling card (window.SSHeaderCallingCard,
   standard /root/spotsheet-docs/HEADER-CALLING-CARD-STANDARD.md). Its
   geometry, type and colour come from ss-header-calling-card.css + shell.css
   and are NOT restated here. .sv2-mark survives only as the last-resort flat
   frame SV2CallingCard paints when the card component itself is missing. */
.sv2-mark { width: 24px; height: 24px; border-radius: 3px; flex: 0 0 auto; }
.sv2-identity .ss-hcc { flex: 0 0 auto; }
/* The standard's ONE responsive rule (>= 768 mark + wordmark + pill; below,
   mark only) is written in ss-header-calling-card.css with selectors scoped to
   .ss-app .ss-topbar, which this header is not. This is the same threshold for
   .sv2-identity and NOTHING else — raised on the board under #6950 as the copy
   to DELETE the day the card's own rule goes ancestor-generic. */
@media (max-width: 767px) {
  .sv2-identity .ss-hcc > .ss-hcc-word,
  .sv2-identity .ss-hcc > .ss-hcc-build { display: none; }
}
.sv2-spacer { flex: 1; }

.sv2-project {
  position: relative;
  min-width: 0;
  max-width: 320px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 0 7px;
  border: 1px solid transparent;
  border-radius: var(--r-1);
  color: var(--fg);
  font-size: 11.5px;
  cursor: pointer;
}
.sv2-project:hover { background: var(--bg-sub); border-color: var(--line-strong); }
.sv2-project > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sv2-project .sv2-chevron { color: var(--fg-dim); flex: 0 0 auto; }
.sv2-project select { position: absolute; inset: 0; opacity: 0; cursor: pointer; width: 100%; }

.sv2-project-settings {
  height: 21px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 8px;
  border: 1px solid transparent;
  border-radius: var(--r-1);
  background: transparent;
  color: var(--fg-dim);
  font: 11px var(--ui);
  cursor: pointer;
}
.sv2-project-settings:hover { color: var(--fg-strong); background: var(--bg-sub); border-color: var(--line-strong); }
.sv2-avatar {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid var(--as-teal);
  background: transparent;
  color: var(--as-teal);
  font: 500 8px var(--ui);
  letter-spacing: .02em;
  cursor: pointer;
}
.sv2-avatar:hover { color: var(--fg-strong); border-color: var(--fg-mute); }
.sv2-drawer-toggle {
  height: 22px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 7px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-1);
  background: var(--bg-sub);
  color: var(--fg-mute);
  font: 650 8px var(--mono);
  letter-spacing: .13em;
  cursor: pointer;
}
.sv2-drawer-toggle:hover,
.sv2-drawer-toggle[aria-expanded="true"] { color: var(--fg-strong); border-color: var(--fg-mute); }
.sv2-drawer-toggle:focus-visible { outline: 2px solid var(--sv2-lime); outline-offset: 2px; }
.sv2-drawer-toggle i { color: var(--sv2-lime); font: normal 14px/1 var(--ui); }

.sv2-rail {
  height: 33px;
  flex: 0 0 33px;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 0 9px;
  background: var(--bg-app);
  border-bottom: 1px solid var(--line);
}
.sv2-clock {
  height: 25px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0 8px;
  flex: 0 0 auto;
  border: 1px solid var(--line);
  border-radius: var(--r-1);
  background: var(--bg-deep);
  box-shadow: inset 0 1px 2px rgba(0,0,0,.5);
  color: var(--sv2-lime);
}
.sv2-clock.disabled { color: var(--fg-dim); }
.sv2-clock .sv2-kicker,
.sv2-rate,
.sv2-roll {
  font-family: var(--mono);
  font-size: 8px;
  letter-spacing: .13em;
  text-transform: uppercase;
  white-space: nowrap;
}
.sv2-clock .sv2-kicker { color: var(--fg-faint); }
.sv2-clock .ss-tcf { font-size: 13px; font-weight: 550; color: inherit; }
.sv2-clock-value { font: 550 13px var(--mono); letter-spacing: .05em; }
.sv2-roll { display: inline-flex; align-items: center; gap: 5px; color: var(--fg-dim); }
.sv2-roll::before { content: ''; width: 4px; height: 4px; border-radius: 50%; background: var(--fg-faint); }
.sv2-roll.live::before { background: var(--fg-strong); }
/* #7016 — `.sv2-picture-note` is gone from all three rules with the span it
   styled: a desktop app never mentions picture, so there is no note to ellipsis
   and no orphaned class left behind to tempt the word back. */
.sv2-rate { color: var(--fg-faint); }
.sv2-session {
  min-width: 0;
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--fg-dim);
  font: 8.5px var(--mono);
  white-space: nowrap;
  overflow: hidden;
}
.sv2-session i { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; background: var(--fg-faint); }
.sv2-session span { overflow: hidden; text-overflow: ellipsis; }
.sv2-session.linked i { background: var(--sv2-lime-deep); }
.sv2-session.unlinked i { background: var(--st-flagged); }
.sv2-session.mismatch i { background: var(--st-danger, #B46868); }
.sv2-session.down i { background: transparent; border: 1px dashed var(--line-strong); }
.sv2-session .sv2-pt-motion { flex: 0 0 22px; overflow: visible; }
.sv2-pt-motion > i { position: absolute; inset: 7px; width: 7px; height: 7px; }

.sv2-split { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: row; overflow: hidden; }
.sv2-selection.is-stacked .sv2-split { flex-direction: column; }
.sv2-notes-basis,
.sv2-sfx-basis { min-width: 0; min-height: 0; display: flex; }
.sv2-sfx-basis {
  flex: 1 1 0;
  opacity: 1;
  transform: translateX(0);
  transition: opacity .18s ease, transform .18s ease;
}
.sv2-selection.is-wide .sv2-notes-basis { min-width: 236px; }
.sv2-selection.is-wide .sv2-sfx-basis { min-width: 248px; }
/* #6805 - 132px could not hold the notes half's own content floor
   (half-label 25 + toolbar ~42 + .ns-main min 110 + .nsd-slot min 92),
   so the bottom drawer was clipped by .sv2-half{overflow:hidden} at every
   thin width. The drawer is the bottom of this surface; a minimum that
   cannot fit it is not a minimum. SFX keeps flex:1 1 0 and its own 168px
   floor, so it yields this space rather than the drawer losing it. */
.sv2-selection.is-stacked .sv2-notes-basis { min-height: 272px; }
.sv2-selection.is-stacked .sv2-sfx-basis { min-height: 168px; }

/* #7073 — SV2 first opens as the exact single SV1 companion column. AppKit
   grows only the right edge when this drawer opens; the 360px notes column
   therefore does not jump while the new SFX pixels arrive. The old draggable
   divider is intentionally retired under the founder's explicit licence. */
/* ══ #7115 · THE DRAWER PEEK — the edge you click to grow the window ══════
   Founder 2026-09-02, walking SV3: he wanted "a drawer peek thing", not a top
   button. This is an in-flow flex child of .sv2-split, so it takes 14 real
   pixels at the edge and never floats over the SFX pane's scrollbar or its
   right-hand controls. Closed, it is the only thing to the right of the notes
   column — the visible edge of the drawer that is still shut. Open, it stays
   pinned at the far edge as the way back. The chevron points where the click
   goes: '<' pulls the drawer out, '>' pushes it back. */
.sv2-drawer-peek {
  flex: 0 0 14px;
  align-self: stretch;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 0;
  border: 0;
  border-left: 1px solid var(--line);
  background: var(--bg-sub);
  color: var(--fg-mute);
  cursor: pointer;
  transition: background .16s ease, color .16s ease, border-color .16s ease;
}
.sv2-drawer-peek:hover { background: var(--bg-sub); color: var(--fg-strong); border-left-color: var(--line-strong); }
.sv2-drawer-peek:focus-visible { outline: 2px solid var(--sv2-lime); outline-offset: -2px; }
/* the grip — three hairlines, the universal "this edge moves" tell */
.sv2-drawer-peek .pk-grip {
  width: 4px; height: 18px;
  background-image: linear-gradient(to right, currentColor 1px, transparent 1px);
  background-size: 2px 100%;
  opacity: .5;
}
.sv2-drawer-peek:hover .pk-grip { opacity: .85; }
/* the label reads bottom-to-top up the rail; full word, never clipped */
.sv2-drawer-peek .pk-label {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font: 650 8px var(--mono);
  letter-spacing: .16em;
}
.sv2-drawer-peek .pk-chev { font: normal 12px/1 var(--ui); color: var(--sv2-lime); }
/* stacked (narrow) — the split runs top-to-bottom, so the edge is the bottom
   one and the rail lies down with it. Same button, same contract. */
.sv2-selection.is-stacked .sv2-drawer-peek {
  flex: 0 0 14px;
  flex-direction: row;
  border-left: 0;
  border-top: 1px solid var(--line);
  /* MEASURED, not assumed: stacked mode reorders the halves (sfx order:1,
     notes order:3 — sfx sits ABOVE), so the drawer's edge in this orientation
     is the line between them, not the bottom of the frame. Without an explicit
     order the peek defaults to 0 and jumps to the very top, above the SFX pane
     — which the proof rig caught. order:2 puts it exactly where the drawer
     opens from, directly over the notes column. */
  order: 2;
}
.sv2-selection.is-stacked .sv2-drawer-peek:hover { border-top-color: var(--line-strong); }
.sv2-selection.is-stacked .sv2-drawer-peek .pk-grip {
  width: 18px; height: 4px;
  background-image: linear-gradient(to bottom, currentColor 1px, transparent 1px);
  background-size: 100% 2px;
}
.sv2-selection.is-stacked .sv2-drawer-peek .pk-label { writing-mode: horizontal-tb; transform: none; }
/* the notes column yields the peek's 14px rather than the drawer losing them */
.sv2-selection.drawer-closed .sv2-notes-basis {
  flex: 1 1 100% !important;
  width: 100%;
  min-width: 0 !important;
  min-height: 0 !important;
}
.sv2-selection.drawer-closed .sv2-sfx-basis {
  flex: 0 0 0 !important;
  width: 0;
  min-width: 0 !important;
  min-height: 0 !important;
  opacity: 0;
  transform: translateX(12px);
  visibility: hidden;
  pointer-events: none;
  overflow: hidden;
  transition: opacity .18s ease, transform .18s ease, visibility 0s linear .18s;
}
/* ══ #7137 · SHARE THE GAIN EQUALLY ════════════════════════════════════════
   Founder, finding 18: "if user extends window with sfx open (both sides open)
   then both sides equally share the width gain".

   This was the defect: notes sat at `flex: 0 0 360px` — a fixed basis with NO
   grow — so every pixel the window gained went to SFX and the notes column
   never moved. Equal grow factors over two remembered bases is that sentence
   expressed in flex: the browser splits each new pixel 50/50 on its own, live,
   including during the native drag of the window edge.

   The bases default to the shipped shape (360 notes / 420 sfx) so nothing about
   first paint changes until the founder actually drags the divider; after that
   his remembered numbers ride in as custom properties from the policy. */
.sv2-selection.drawer-open.is-wide .sv2-notes-basis {
  flex: 1 1 var(--sv2-notes-basis, 360px);
  width: auto;
  min-width: var(--sv2-notes-floor, 236px);
  border-right: 0;
}
.sv2-selection.drawer-open.is-wide .sv2-sfx-basis {
  flex: 1 1 var(--sv2-sfx-basis, var(--sv2-drawer-width));
  width: auto;
  min-width: var(--sv2-sfx-floor, 248px);
}

/* ══ #7137 · THE DIVIDER — the seam you can actually grab ══════════════════
   6px of real column between the halves (the border it replaces was 1px and
   ungrabbable). It is `role="separator"` with a tab stop and arrow keys, so it
   is not a mouse-only control. `is-dragging` and the body class keep the
   cursor and the no-select rule alive while the pointer is captured — without
   them a drag over the SFX pane selects its text instead of moving the seam. */
.sv2-divider {
  flex: 0 0 6px;
  align-self: stretch;
  position: relative;
  padding: 0;
  border: 0;
  border-left: 1px solid var(--line);
  border-right: 1px solid var(--line);
  background: var(--bg-sub);
  cursor: col-resize;
  display: flex;
  align-items: center;
  justify-content: center;
  touch-action: none;
  transition: background .12s ease, border-color .12s ease;
}
.sv2-divider:hover,
.sv2-divider.is-dragging { background: var(--bg-raise, var(--bg-sub)); border-left-color: var(--line-strong); border-right-color: var(--line-strong); }
.sv2-divider:focus-visible { outline: 2px solid var(--sv2-lime); outline-offset: -2px; }
.sv2-divider .dv-grip {
  width: 2px; height: 26px; border-radius: 2px;
  background: var(--fg-faint);
  opacity: .55;
  pointer-events: none;
}
.sv2-divider:hover .dv-grip,
.sv2-divider.is-dragging .dv-grip { opacity: .9; background: var(--fg-mute); }
/* while dragging, the whole window agrees about the cursor and stops selecting */
body.sv2-split-dragging,
body.sv2-split-dragging * { cursor: col-resize !important; user-select: none !important; }

/* #6805 FOUNDER — THIN/VERTICAL SV2 PUTS SFX ON TOP AND NOTES ON THE BOTTOM.
   Verbatim: "we move the SFX window to the bottom but we already have a bottom
   drawer on notes its weird lets try doing SFX on top and notes on bottom when
   thin in sv2 app."

   HIS REASON IS THE SPEC. Notes already ends in its own bottom drawer
   (.nsd-slot, drawer-bottom.css), so stacking notes first put a second, larger
   panel underneath a drawer that is meant to BE the bottom of the surface. Two
   things claiming the bottom edge is what read as weird and collided. With the
   halves swapped the notes drawer is the bottom of the window again, which is
   the shape it was designed for.

   WHY `order` AND NOT A DOM SWAP: the DOM order (notes, then SFX) is also the
   tab order and the reading order, and
   notes is the primary surface — it should keep coming first for the keyboard
   and for a screen reader even when it is painted second. `order` moves the
   paint without touching either.

   SCOPED TO .is-stacked ONLY: the wide layout is left exactly as it was, not by
   care but by construction — every selector here carries .is-stacked. */
.sv2-selection.is-stacked .sv2-sfx-basis { order: 1; }
.sv2-selection.is-stacked .sv2-notes-basis { order: 3; }

.sv2-half { position: relative; min-width: 0; min-height: 0; width: 100%; display: flex; flex-direction: column; overflow: hidden; }
.sv2-notes { background: var(--bg-app); }
.sv2-sfx { background: var(--bg-panel); }
.sv2-half-label {
  height: 25px;
  flex: 0 0 25px;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 0 9px;
  border-bottom: 1px solid var(--line-soft);
  background: var(--bg-app);
  color: var(--fg-dim);
  font: 8px var(--mono);
  letter-spacing: .18em;
  text-transform: uppercase;
}
.sv2-half-context { color: var(--fg-faint); letter-spacing: .11em; }
.sv2-notes-host { flex: 1; min-width: 0; min-height: 0; overflow: hidden; }
.sv2-notes-host > * { width: 100%; height: 100%; min-width: 0; min-height: 0; }
.sv2-selection .ns-selection-only .ns-pt { display: none !important; }

/* Notes already owns the exact production list and drawer. SV2 only adapts
   their geometry to a half-window and applies the approved state hierarchy. */
.sv2-selection .ns-mainwrap.layout-v > .ns-main { min-height: 110px; }
/* #6805 — this rule overrode only `flex`, so drawer-bottom.css:45-46
   (height / max-height: min(36vh,320px)) stayed in force on the same element
   and the two files disagreed about how tall the drawer is. It was harmless
   only while 30vh < 36vh made the flex basis win the main axis; on a short
   thin window it is the drawer refusing to give the panel its space back.
   Stating height/max-height here makes the flex basis the single answer. */
.sv2-selection .ns-mainwrap.layout-v > .nsd-slot {
  width: auto;
  flex: 0 1 min(30vh, 230px);
  height: auto;
  max-height: min(30vh, 230px);
  min-height: 92px;
  border-left: 0;
  border-top: 1px solid var(--line-strong);
}
.sv2-selection .ns-list .ci-row.full.sel,
.sv2-selection .ns-list .ci-row.full.multi,
.sv2-selection .ns-list .ns-row.sel,
.sv2-selection .ns-list .ns-row.multi {
  background-color: var(--bg-row) !important;
  background-image: linear-gradient(var(--sv2-lime-wash), var(--sv2-lime-wash)) !important;
  box-shadow: inset 3px 0 0 var(--sv2-lime) !important;
}
.sv2-selection .ns-list .ci-row.full.sel .ci-tc,
.sv2-selection .ns-list .ns-row.sel .ns-tc { color: var(--sv2-lime) !important; }
.sv2-selection .ns-list .ci-row.full.resolved,
.sv2-selection .ns-list .ns-row.resolved { background-color: #282930; }
.sv2-selection .ns-list .ci-row.full.resolved .ci-body,
.sv2-selection .ns-list .ns-row.resolved .ns-body { color: var(--fg-dim); text-decoration: none; }
.sv2-selection .ns-list .nt-pill.resolved { display: none !important; }

/* #6861 — THE SPACE CHIP GETS A RESERVED SLOT; NO SIBLING MOVES ON STATE.
   FOUNDER RULE (#6840, verbatim): "for a rule of thumb we should never
   dynamically shift around buttons positions lke that."
   ss-transport-focus.js draws the chip with DISPLAY:
     .ss-space-glyph                                        { display: none }        (:318)
     html[data-ss-space-owner="sfx"]   …[data-space-for="sfx"]      { inline-flex }  (:322)
     html[data-ss-space-owner="master"]…[data-space-for="timeline"] { inline-flex }  (:323)
     html[data-ss-space-surface="text"][data-ss-space-owner] …      { none }         (:330)
   so the chip ENTERS AND LEAVES THE FLEX FLOW every time the user clicks
   between the timeline, a note row, an SFX row and a text field. On the SFX
   head it sits in front of the "SFX Library" button, and acceptance measured
   the consequence: button at window x 580-672 with the chip, 527-620 without.
   A real CGEvent click at x=625 — dead centre in the first layout — MISSED the
   control in the second and the library window did not open.
   THE FIX: keep the box, toggle the ink. The chip is always laid out on this
   surface and only its VISIBILITY changes, so every sibling's box is identical
   in both states and the door stays where the eye last saw it. visibility also
   takes the chip out of the accessibility tree while it does not apply, which
   display:none did too — the state is not misreported to a screen reader.
   SCOPED TO .sv2-selection ON PURPOSE. This is the SV2 surface's geometry
   promise; ss-transport-focus.js is shared with SV1/SSPT/workstation and stays
   the single owner of WHICH surface owns SPACE. The !important is load-bearing,
   not lazy: ss-transport-focus.js injects its sheet at runtime, and its
   text-field rule (:330) is specificity (0,4,1) — a plain override would be a
   tie decided by injection order, which is exactly the fragility that produced
   this bug. Only `display` is forced; visibility below is ordinary cascade. */
.sv2-selection .ss-space-glyph[data-space-for] { display: inline-flex !important; visibility: hidden; }
html[data-ss-space-owner="sfx"] .sv2-selection .ss-space-glyph[data-space-for="sfx"],
html[data-ss-space-owner="master"] .sv2-selection .ss-space-glyph[data-space-for="timeline"] { visibility: visible; }
html[data-ss-space-surface="text"][data-ss-space-owner] .sv2-selection .ss-space-glyph[data-space-for] { visibility: hidden; }

.sv2-sfx-head {
  min-height: 34px;
  flex: 0 0 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 5px 9px;
  background: var(--bg-sub);
  border-bottom: 1px solid var(--line);
}
.sv2-sfx-label { color: var(--fg-dim); font: 8px var(--mono); letter-spacing: .18em; text-transform: uppercase; }
.sv2-suggestion-motion { flex: 0 0 40px; }
.sv2-library-button {
  height: 23px;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 0 9px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-1);
  background: var(--btn-grad);
  color: var(--fg);
  box-shadow: var(--inset-panel);
  font: 11.5px var(--ui);
  cursor: pointer;
}
.sv2-library-button:hover { background: var(--btn-grad-h); color: var(--fg-strong); }
.sv2-library-button.active { background: #43444E; color: var(--fg-strong); box-shadow: none; }
.sv2-library-button kbd { margin-left: 1px; color: var(--fg-faint); border: 0; background: none; font: 8px var(--mono); }
.sv2-library-icon { color: var(--fg-mute); font: 12px/1 var(--mono); }
.sv2-sfx-context { min-width: 0; flex: 1; display: flex; align-items: center; gap: 6px; overflow: hidden; white-space: nowrap; color: var(--fg-faint); font: 8px var(--mono); letter-spacing: .1em; text-transform: uppercase; }
.sv2-sfx-context b { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--fg-mute); font-weight: 400; letter-spacing: .03em; text-transform: none; }

.sv2-sfx-body { flex: 1; min-height: 0; min-width: 0; display: flex; flex-direction: column; background: var(--bg-app); }
.sv2-sfx-cue {
  min-height: 29px;
  flex: 0 0 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 10px;
  border-bottom: 1px solid var(--line-soft);
  background: var(--bg-row);
}
.sv2-sfx-cue .tc { color: var(--sv2-lime); font: 10px var(--mono); white-space: nowrap; }
.sv2-sfx-cue .copy { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--fg); font-size: 11.5px; }
.sv2-sfx-cue .ucs { color: var(--fg-dim); font: 8px var(--mono); letter-spacing: .07em; text-transform: uppercase; white-space: nowrap; }
.sv2-sfx-cue .coverage { padding: 2px 6px; border: 1px solid var(--line); border-radius: var(--r-1); color: var(--fg-dim); font: 8px var(--mono); letter-spacing: .1em; text-transform: uppercase; white-space: nowrap; }
.sv2-sfx-cue .coverage.laid { color: var(--cue-amber, #c19355); border-color: rgba(193,147,85,.4); background: rgba(193,147,85,.09); }
/* #6862 — .coverage.selected is DELETED with the middle rung it painted. The
   chip now says exactly two things: laid (amber, above) or needs sound (the
   base rule). */
.sv2-pool-host { flex: 1; min-height: 0; min-width: 0; display: flex; overflow: hidden; }
.sv2-pool-host > .sx-pool { width: 100%; height: 100%; min-height: 0; }
.sv2-pool-host .sx-pool-list { flex: 1; min-height: 0; }
.sv2-wave-host { flex: 0 0 auto; min-height: 118px; max-height: 170px; border-top: 1px solid var(--line); overflow: hidden; }
.sv2-wave-host .sx-wavepane { height: 100%; }

/* ══ THE SFX CARD STATE LADDER — #6830 / #6845, then #6862 ═══════════════
   #6830 + #6845, two founder passes on the same rows, in his words:
     "dont use lime green for those preselected sfx. (sv2 app) need to be clear."
     "not loving the yellow on the 'pulled' sfx … use like a grey or more
      nuetral color just different than normal notes, different than hovered
      state"
   #6862, FOUNDER 2026-08-29, then removed the state those two passes were
   about: "we do not do any sort of preselection/favorite at all … there is no
   middle layer. its just here are the suggested SFX for the cues, here at the
   cues you have LAID."

   SO THE LADDER IS TWO RUNGS AND A FOCUS, and the grey channel is retired:
     needs sound  nothing
     hover        the faintest neutral wash, no rail, no ring
     LAID         the amber accent rail + amber wash (--cue-amber, already the
                  Pro Tools marker colour; lime stays reserved to its six uses,
                  #6024, so the terminal state takes the accent the palette
                  actually permits here)
     SELECTOR     a full inset RING — shape, not hue, so it reads on top of the
                  rail and a card that is both shows both
   --sv2-pulled and every .pre / .issel rule are DELETED with the state. The
   neutral grey survives in ONE place only — the hover wash, which was always
   its own rung and is the faintest thing on the surface. No colour was added to
   the palette (#6024's own instruction), and one was given back. */
.sv2-selection {
  --sv2-neutral-rgb: 161, 159, 173;      /* --fg-mute, hover only */
  --sv2-laid: var(--cue-amber, #c19355);
  --sv2-laid-rgb: 193, 147, 85;
  --sv2-laid-wash: rgba(var(--sv2-laid-rgb), .11);
}

/* HOVER — the faintest rung, and now the only neutral one. */
.sv2-selection .sxb-row:hover,
.sv2-selection .sx-row:hover {
  background-color: transparent !important;
  background-image: linear-gradient(rgba(var(--sv2-neutral-rgb), .035), rgba(var(--sv2-neutral-rgb), .035)) !important;
}

/* LAID — in the Pro Tools session. The terminal state gets the accent. */
.sv2-selection .sxb-row.laid,
.sv2-selection .sxb-row.laid:hover {
  background-color: var(--bg-row) !important;
  background-image: linear-gradient(var(--sv2-laid-wash), var(--sv2-laid-wash)) !important;
  box-shadow: inset 3px 0 0 var(--sv2-laid);
}
.sv2-selection .sxb-laid {
  color: var(--sv2-laid);
  border-color: rgba(var(--sv2-laid-rgb), .42);
  background: rgba(var(--sv2-laid-rgb), .07);
}
/* a second, colour-blind-safe channel saying "this one is in the session" */
.sv2-selection .sxb-laid::before { content: '\25C6'; margin-right: 3px; font-size: 7px; line-height: 1; opacity: .85; }
.sv2-selection .sxb-grp.laid .l { color: var(--sv2-laid); }
.sv2-selection .sxb-grp.laid.empty .l { color: var(--fg-dim); opacity: .75; }

/* SELECTOR — the transient focus that drives the waveform and SPACE.
   #6845 also asked for focused != hover: hover has no ring and a wash a third
   as strong, so the two can never be read as the same row. */
.sv2-selection .sxb-row.focused,
.sv2-selection .sx-row.focused {
  background-color: var(--bg-row-hover) !important;
  background-image: none !important;
  box-shadow: inset 0 0 0 1px var(--sv2-lime);
}
/* both at once: the rail keeps saying "this is in the session", the ring keeps
   saying "this is the one in the waveform". Two channels, no clash. */
.sv2-selection .sxb-row.laid.focused {
  background-image: linear-gradient(var(--sv2-laid-wash), var(--sv2-laid-wash)) !important;
  box-shadow: inset 3px 0 0 var(--sv2-laid), inset 0 0 0 1px var(--sv2-lime);
}
/* the row verb keeps its own weight and never competes with either state.
   #6862 — Remove is the SAME BOX as Lay (#6840: a control may never move), so
   only its ink changes: the danger red the product already uses for a
   destructive verb, and the hold fill drawn inside the button. */
.sv2-selection .sxb-spot1 { border-color: rgba(var(--sv2-lime-rgb),.38); color: var(--sv2-lime); }
.sv2-selection .sxb-spot1.rm { border-color: rgba(var(--sv2-laid-rgb),.5); color: var(--sv2-laid); }
.sv2-selection .sxb-spot1.rm:hover { border-color: var(--st-danger, #b46868); color: var(--st-danger, #b46868); }
.sv2-selection .sxb-spot1.nolay { border-color: var(--line-soft); color: var(--fg-faint); }

/* #6880 — SYNC. It sits at the foot of the SFX half, immediately above the
   #6871 session band, and it is the loudest verb on the surface: it rewrites
   whole tracks. So it holds to confirm, states its scope in its own title, and
   carries the count it would apply beside it rather than behind a click. */
.sv2-sync { flex: 0 0 auto; padding: 7px 10px; border-top: 1px solid var(--line); background: var(--bg-sub); }
.sv2-sync-row { display: flex; align-items: center; gap: 9px; min-width: 0; }
.sv2-sync-btn { position: relative; overflow: hidden; flex: 0 0 auto; height: 24px; min-width: 84px; padding: 0 var(--ep-pad-btn, 10px);
  border: 1px solid var(--cue-amber, #c19355); border-radius: var(--r-1, 3px); background: var(--btn-grad);
  color: var(--cue-amber, #c19355); font-family: var(--ui); font-size: var(--ep-fs); cursor: pointer; white-space: nowrap; }
.sv2-sync-btn .lb { position: relative; z-index: 1; }
.sv2-sync-fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: currentColor; opacity: .22; z-index: 0; }
.sv2-sync-btn.dead, .sv2-sync-btn[disabled] { border-color: var(--line-soft); color: var(--fg-faint); cursor: not-allowed; }
.sv2-sync-cnt { flex: 0 0 auto; font: 9px var(--mono); letter-spacing: .04em; color: var(--fg-dim); }
.sv2-sync-why { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 10px; color: var(--fg-mute); }
.sv2-sync-prog { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.sv2-sync-prog .bar { flex: 1; height: 3px; border-radius: 2px; background: var(--line); overflow: hidden; }
.sv2-sync-prog .bar i { display: block; height: 100%; background: var(--cue-amber, #c19355); transition: width 160ms linear; }
.sv2-sync-prog .t { flex: 0 0 auto; font: 9px var(--mono); color: var(--fg-dim); }
.sv2-sync-report { margin-top: 6px; font-size: 10.5px; line-height: 1.5; color: var(--fg-mute); }
.sv2-sync-report b { color: var(--fg-strong); font-weight: 600; }
.sv2-sync-report.ok b { color: var(--cue-amber, #c19355); }
.sv2-sync-report.warn { color: var(--fg); }
.sv2-sync-report.err { color: var(--st-danger, #b46868); }

/* #6846 — the session-mismatch banner. It is the loudest thing on the half
   when it appears, and it never appears in the healthy state. */
.sv2-sesswarn { display: flex; align-items: flex-start; gap: 8px; margin: 0; padding: 9px 12px;
  border-bottom: 1px solid var(--line); background: rgba(180,104,104,.10); }
.sv2-sesswarn .d { flex: 0 0 6px; width: 6px; height: 6px; margin-top: 5px; border-radius: 50%;
  background: var(--st-danger, #b46868); }
.sv2-sesswarn .t { font-size: 11px; line-height: 1.5; color: var(--fg); }
.sv2-sesswarn .t b { color: var(--st-danger, #b46868); font-weight: 600; }
.sv2-sesswarn.no-session { background: rgba(193,147,85,.10); }
.sv2-sesswarn.no-session .d { background: var(--cue-amber, #c19355); }
.sv2-sesswarn.no-session .t b { color: var(--cue-amber, #c19355); }
.sv2-sesswarn.unreachable { background: rgba(161,159,173,.09); }
.sv2-sesswarn.unreachable .d { background: var(--fg-mute, #A19FAD); }
.sv2-sesswarn.unreachable .t b { color: var(--fg-mute, #A19FAD); }

.sv2-free-library { flex: 1; min-height: 0; display: flex; flex-direction: column; padding: 18px 20px; gap: 11px; background: var(--bg-app); }
.sv2-free-copy { max-width: 52ch; display: flex; flex-direction: column; gap: 7px; }
.sv2-free-copy b { color: var(--fg-mute); font-size: 12.5px; font-weight: 500; }
.sv2-free-copy span { color: var(--fg-dim); font-size: 11px; line-height: 1.6; }
.sv2-free-search { height: 28px; max-width: 540px; display: flex; align-items: center; gap: 8px; padding: 0 9px; border: 1px solid var(--line); border-radius: var(--r-1); background: var(--bg-deep); color: var(--fg-dim); }
.sv2-free-search:focus-within { border-color: var(--line-strong); }
.sv2-free-search input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; color: var(--fg-strong); font: 11.5px var(--ui); }
.sv2-free-results { flex: 1; min-height: 0; max-width: 700px; overflow: auto; border-top: 1px solid var(--line-soft); }
.sv2-free-row { width: 100%; height: 32px; display: flex; align-items: center; gap: 9px; padding: 0 9px; border: 0; border-bottom: 1px solid var(--line-soft); background: var(--bg-row); color: var(--fg); text-align: left; cursor: default; }
.sv2-free-row .name { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sv2-free-row .root, .sv2-free-row .duration { color: var(--fg-dim); font: 8px var(--mono); }
.sv2-free-none, .sv2-honest-empty { margin: auto; padding: 20px; color: var(--fg-dim); font-size: 11.5px; line-height: 1.55; text-align: center; }

.sv2-footer {
  height: 22px;
  flex: 0 0 22px;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 0 9px;
  overflow: hidden;
  border-top: 1px solid var(--line);
  background: var(--bg-deep);
  color: var(--fg-faint);
  font: 8px var(--mono);
  letter-spacing: .11em;
  text-transform: uppercase;
  white-space: nowrap;
}
.sv2-footer b { color: var(--fg-mute); font-weight: 400; }

@container (max-width: 640px) {
  .sv2-sfx-context, .sv2-half-context, .sv2-footer > span:nth-child(3) { display: none; }
  .sv2-sfx-cue .ucs { display: none; }
  .sv2-wave-host { min-height: 92px; max-height: 118px; }
}

@container (max-width: 480px) {
  .sv2-rate, .sv2-roll, .sv2-footer > span:nth-child(2) { display: none; }
  .sv2-project { max-width: 180px; }
  .sv2-library-button kbd { display: none; }
  .sv2-sfx-cue .coverage { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .sv2-selection *, .sv2-selection *::before, .sv2-selection *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ═══ #6871 · SV1'S SESSION BAND, ON THIS SURFACE ═══════════════════════════
   FOUNDER 2026-08-29: SV2 said "Use the session control above…" and there was
   no control above. #6846 mounted the ONE check here but passed `launcherOnly`,
   which draws no launcher while the body sits behind `open` — so it probed,
   published its verdict and rendered nothing. app.jsx's `inline` mode is that
   same component drawing SV1's band instead; this is only its clothing.

   It is FIXED to the foot of the window rather than placed in the flex column,
   because the control is mounted as a SIBLING of .sv2-selection (App renders it
   next to SV2SelectionMoment, which is height:100% and overflow:hidden — an
   in-flow band there is pushed out of the window, which is the second reason
   nothing was visible). Fixed at the foot it is present without scrolling at
   1440 and at the 420 floor, it never covers the project switcher or the rail,
   and the only thing it yields is the counts strip. */
.ss-ptband-off { display: none; }

.ss-ptband {
  --ptband-key: #E8846B;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 300;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  font-family: var(--ui);
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--fg-mute, #b9bcc6);
  background: #2A1E1E;
  border-top: 1px solid #7C3B3B;
  box-shadow: 0 -6px 18px rgba(0, 0, 0, .42);
}
.ss-ptband.sync {
  --ptband-key: #6BA8E8;
  background: #1E242A;
  border-top-color: #3B5C7C;
}

.ss-ptband .k {
  flex: 0 0 auto;
  font-family: var(--mono);
  font-size: 8.5px;
  font-weight: 650;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ptband-key);
}
.ss-ptband .m { flex: 1 1 200px; min-width: 0; }
.ss-ptband .m b { color: var(--fg, #edeef2); font-weight: 600; }

.ss-ptband .a {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 7px;
}
.ss-ptband .a button {
  font-family: var(--ui);
  font-size: 11px;
  font-weight: 550;
  white-space: nowrap;
  padding: 6px 11px;
  border-radius: var(--r-1, 4px);
  border: 1px solid #A3B520;
  background: #CCDE49;
  color: #16171B;
  cursor: pointer;
}
.ss-ptband .a button:hover:not(:disabled) { background: #D6E663; }
.ss-ptband .a button:disabled { opacity: .45; cursor: default; }
.ss-ptband .a button.x {
  background: transparent;
  border-color: var(--line, #45464e);
  color: var(--fg-mute, #b9bcc6);
}
.ss-ptband .a button.x:hover:not(:disabled) { background: rgba(255, 255, 255, .06); }

/* the 420 floor: the sentence and the choices stack, and every button stays a
   full-width target rather than a 40 px sliver. */
@media (max-width: 600px) {
  .ss-ptband { flex-wrap: wrap; row-gap: 7px; }
  .ss-ptband .m { flex: 1 1 100%; order: 2; }
  .ss-ptband .a { flex: 1 1 100%; order: 3; }
  .ss-ptband .a button { flex: 1 1 auto; }
}

@media (prefers-reduced-motion: reduce) {
  .ss-ptband, .ss-ptband * { transition-duration: .01ms !important; }
}

/* ═══ #6999 · THUMBS-DOWN → "WHY BAD?" → PER-CUE NEGATIVE WORDS ════════════
   FOUNDER 2026-08-30: every SFX suggestion gets a thumbs-down; it opens a
   small window that shows the sound's words as chips; picking one adds a
   NEGATIVE WORD to that cue's suggestor, which persists, shows as a deletable
   chip, and makes every sound carrying that word leave the suggestions.

   COLOUR, DELIBERATELY: nothing here is lime. The surface already spends its
   one lime on selection (feedback_spotsheet_primary_colour_lime — one lime per
   surface), and the LAID amber is the other spoken-for colour. A negative
   verb is neutral ink on the neutral panel; the only "on" state a chip wears
   is the same #43444E the SFX Library button already wears when it is active,
   so this card introduces no new colour to the product at all.

   SCOPING: every selector below is under .sv2-selection. .sxb-neg is rendered
   by the SHARED row component (sspt-b-core.jsx), so scoping it here is the
   second guarantee — after the opt-in onWhyBad prop — that SV1's browser pool
   is untouched by this card. */

/* the row control. Same box, same reserved-space discipline and the same
   hover-changes-emphasis-only rule as .sxb-dots beside it (sspt-b.css:109 —
   "reserve the space and keep the control in it", #6840). It sits BEFORE the
   ⋯ and never enters or leaves a mounted row: a suggested row that becomes a
   laid row is a different React key in a different group, which the pool
   already remounts. */
.sv2-selection .sxb-neg {
  width: var(--ep-control-h, 22px);
  height: var(--ep-control-h, 22px);
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid transparent;
  border-radius: var(--r-1, 4px);
  background: transparent;
  color: var(--fg-dim);
  opacity: .8;
  cursor: pointer;
  transition: opacity 90ms linear, color 90ms linear;
}
.sv2-selection .sxb-row:hover .sxb-neg,
.sv2-selection .sxb-row.focused .sxb-neg { opacity: 1; color: var(--fg); }
.sv2-selection .sxb-neg:hover,
.sv2-selection .sxb-neg.open { background: var(--bg-sub); color: var(--fg); border-color: var(--line); opacity: 1; }
.sv2-selection .sxb-neg:focus-visible { opacity: 1; outline: 1px solid var(--line-strong); outline-offset: 1px; }
.sv2-selection .sxb-neg:disabled { opacity: .4; cursor: default; }

/* the cue's negative words, directly under the "Suggestions for …" caption.
   It wraps rather than scrolls: these are a handful of words, and a word the
   editor cannot see is a filter they cannot undo. */
.sv2-negrow {
  flex: 0 0 auto;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px;
  padding: 5px 9px;
  background: var(--bg-sub);
  border-bottom: 1px solid var(--line);
}
.sv2-negrow .l {
  flex: 0 0 auto;
  color: var(--fg-faint);
  font: 8px var(--mono);
  letter-spacing: .14em;
  text-transform: uppercase;
}
.sv2-negchip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  max-width: 100%;
  min-width: 0;
  height: 18px;
  padding: 0 3px 0 7px;
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  background: var(--bg-panel);
  color: var(--fg-mute);
  font: 10.5px var(--ui);
}
.sv2-negchip b { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; color: var(--fg); }
.sv2-negchip.wide { border-style: dashed; }
.sv2-negchip button {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--fg-dim);
  font: 12px/1 var(--ui);
  cursor: pointer;
}
.sv2-negchip button:hover { background: rgba(255, 255, 255, .10); color: var(--fg-strong); }
.sv2-negchip button:disabled { opacity: .4; cursor: default; }
.sv2-negrow .err { color: var(--fg-dim); font: 10px var(--ui); }

/* the "Why bad?" window. Mounted on the SURFACE, clamped inside it, over the
   same transparent .sxb-optscrim the ⋯ panel uses — so an outside click
   cancels, and the two windows cannot drift apart geometrically. */
.sv2-whybad {
  position: absolute;
  z-index: 60;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-3, 7px);
  background: var(--bg-panel);
  box-shadow: var(--float);
}
.sv2-whybad .h {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 8px 6px 10px;
  border-bottom: 1px solid var(--line-soft);
}
.sv2-whybad .h .t { flex: 1; color: var(--fg-strong); font: 11.5px var(--ui); font-weight: 550; }
.sv2-whybad .h .x {
  width: 18px; height: 18px; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: var(--r-1, 4px);
  background: transparent; color: var(--fg-dim); font: 13px/1 var(--ui); cursor: pointer;
}
.sv2-whybad .h .x:hover { background: var(--bg-sub); color: var(--fg); }
.sv2-whybad .nm {
  padding: 6px 10px 0;
  color: var(--fg-mute);
  font: 9.5px var(--mono);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sv2-whybad .say { padding: 5px 10px 0; color: var(--fg-dim); font: 10.5px var(--ui); }
.sv2-whybad .chips {
  display: flex; flex-wrap: wrap; gap: 5px;
  padding: 8px 10px;
  max-height: 168px; overflow-y: auto;
}
.sv2-whybad .chips::-webkit-scrollbar { width: 7px; }
.sv2-whybad .chips::-webkit-scrollbar-thumb { background: var(--line-strong); }
.sv2-whybad .chips button {
  height: 21px;
  max-width: 100%;
  padding: 0 9px;
  border: 1px solid var(--line-strong);
  border-radius: 11px;
  background: var(--bg-sub);
  color: var(--fg-mute);
  font: 11px var(--ui);
  cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sv2-whybad .chips button:hover { color: var(--fg-strong); border-color: var(--line-strong); background: #3B3C45; }
.sv2-whybad .chips button[aria-pressed="true"] { background: #43444E; color: var(--fg-strong); box-shadow: none; }
.sv2-whybad .chips button:focus-visible { outline: 1px solid var(--line-strong); outline-offset: 1px; }
.sv2-whybad .chips button.already { border-style: dashed; opacity: .55; cursor: default; }
.sv2-whybad .none { padding: 8px 10px; color: var(--fg-dim); font: 10.5px var(--ui); }
.sv2-whybad .ft {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 9px;
  border-top: 1px solid var(--line-soft);
  background: var(--bg-sub);
}
.sv2-whybad .ft .hint { flex: 1; min-width: 0; color: var(--fg-faint); font: 9.5px var(--ui); }
.sv2-whybad .ft .go {
  flex: 0 0 auto;
  height: 22px;
  padding: 0 10px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-1, 4px);
  background: var(--btn-grad);
  color: var(--fg);
  box-shadow: var(--inset-panel);
  font: 11px var(--ui);
  cursor: pointer;
}
.sv2-whybad .ft .go:hover:not(:disabled) { background: var(--btn-grad-h); color: var(--fg-strong); }
.sv2-whybad .ft .go:disabled { opacity: .45; cursor: default; }


/* ══════════════════════════════════════════════════════════════════════════
   #7000 · LAYING — THE WHOLE CARD IS THE IN-FLIGHT STATE
   FOUNDER 2026-08-30, verbatim: "spotsheet sv2 needs a much better
   visualization for the laying process. it currently just disables the button
   and changes the text from 'lay' to 'laying' i want to see like a full sfx
   card loding or processing state ideally with that lime green outline on the
   card does a suble movement."

   THE LIME OUTLINE HE MEANS ALREADY EXISTS ON THIS SURFACE. It is the SELECTOR
   ring above (.sxb-row.focused -> inset 0 0 0 1px var(--sv2-lime)). So this
   state adds no second lime: the laying card TAKES that one, its stroke
   travels, and while it holds it every OTHER focused row on the surface drops
   to the neutral ring. ONE LIME PER SURFACE (#6024) is kept by handing the
   colour over rather than by minting another instance of it. In the ordinary
   case the two are the same row anyway — sspt-b-core.jsx's doLay focuses the
   card it lays on the same tick.

   THE MOTION IS ONE ANIMATED PROPERTY ON ONE ELEMENT: stroke-dashoffset on a
   single SVG rect, 2.6s linear, a 16-unit segment travelling a 100-unit
   pattern, which loops seamlessly whether or not the browser honours
   pathLength. No conic-gradient, no mask-composite, no filter, no box-shadow
   animation — nothing that forces the row's text to repaint every frame. The
   card body dims a little so the moving stroke is the brightest thing on it,
   and the phase line borrows the waveform's own 150px box so a lay costs the
   card zero reflow.

   NOTHING HERE IS A LOGO. The 3D mark stays cover + header calling card only
   (founder 2026-08-28); a lay is announced by the card it happens on.
   ══════════════════════════════════════════════════════════════════════════ */

/* the card, working */
.sv2-selection .sxb-row.laying {
  background-color: var(--bg-row) !important;
  background-image: linear-gradient(rgba(var(--sv2-lime-rgb), .055), rgba(var(--sv2-lime-rgb), .055)) !important;
  box-shadow: inset 0 0 0 1px rgba(var(--sv2-lime-rgb), .30);
}
/* dimmed body — the sound's own facts stay readable, just quieter than the
   thing that is happening to them */
.sv2-selection .sxb-row.laying .nm,
.sv2-selection .sxb-row.laying .dur,
.sv2-selection .sxb-row.laying .sxb-packb { opacity: .55; }

/* THE TRAVELLING OUTLINE. The stroke is declared here and nowhere else, so the
   same markup on a surface that does not load this sheet renders as nothing
   rather than as a stray box. */
.sv2-selection .sxb-row.laying .sxb-layring { overflow: visible; }
.sv2-selection .sxb-row.laying .sxb-layring rect {
  fill: none;
  stroke: var(--sv2-lime);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-dasharray: 16 84;
  animation: sv2LayTravel 2.6s linear infinite;
}
@keyframes sv2LayTravel { from { stroke-dashoffset: 0; } to { stroke-dashoffset: -100; } }

/* ONE LIME PER SURFACE, for exactly as long as the lay is in flight. The ring
   is shape, not hue — so a focused row that gives up the lime keeps saying
   "this is the one in the waveform" in the neutral ink, and gets it back the
   moment the card settles. If :has() is unavailable the fallback is the state
   that shipped yesterday (a lime selector ring), never a broken row. */
.sv2-selection:has(.sxb-row.laying) .sxb-row.focused:not(.laying),
.sv2-selection:has(.sxb-row.laying) .sx-row.focused:not(.laying) {
  box-shadow: inset 0 0 0 1px var(--line-strong);
}
.sv2-selection:has(.sxb-row.laying) .sxb-row.laid.focused:not(.laying) {
  box-shadow: inset 3px 0 0 var(--sv2-laid), inset 0 0 0 1px var(--line-strong);
}

/* THE PHASE LINE — observed phases only (sfxsel-bridge.jsx #7000), the landing
   beat, or the refusal. It borrows .wv's box, so it never moves anything. */
.sv2-selection .sxb-layline {
  display: inline-block;
  /* .wv is a fixed 150px that never shrinks, which on a narrow surface took the
     whole box and collapsed the FILENAME to three characters (measured at
     390x844). Mid-flight the editor needs both facts — WHICH sound, and what is
     happening to it — so neither wins outright: both shrink, and a refusal gets
     twice the share because on that one card the reason matters more than the
     name. Every one of them still carries its full text in its title. */
  flex: 1 1 150px;
  width: 150px;
  min-width: 0;
  font-family: var(--mono);
  font-size: 9.5px;
  line-height: 15px;
  letter-spacing: .02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 1;
}
.sv2-selection .sxb-layline.go  { color: var(--sv2-lime); }
.sv2-selection .sxb-layline.ok  { color: var(--sv2-laid); }
.sv2-selection .sxb-layline.bad { color: var(--st-danger, #b46868); flex-grow: 2; }

/* THE CONTROL, working. Same box, same width, same place — the spinner is a
   sibling inside it (#6840). The disabled grey that .sxb-spot1[disabled] would
   otherwise paint is overridden here, because a control that is working is not
   a control that is dead and must not look like one. */
.sv2-selection .sxb-spot1.working[disabled] {
  color: var(--sv2-lime);
  border-color: rgba(var(--sv2-lime-rgb), .45);
  cursor: progress;
}
.sv2-selection .sxb-layspin {
  display: inline-block;
  width: 8px; height: 8px;
  border: 1.5px solid rgba(var(--sv2-lime-rgb), .26);
  border-top-color: var(--sv2-lime);
  border-radius: 50%;
  animation: sv2LaySpin .9s linear infinite;
}
@keyframes sv2LaySpin { to { transform: rotate(360deg); } }

/* EVERY OTHER ACTION ON THE CARD IS INERT UNTIL IT SETTLES. The verb itself is
   really disabled in the markup; these are the ones that would otherwise open a
   panel over a card that is mid-write. */
.sv2-selection .sxb-row.laying .sxb-dots,
.sv2-selection .sxb-row.laying .sxb-neg,
.sv2-selection .sxb-row.laying .sxb-scan,
.sv2-selection .sxb-row.laying .sx-btn { pointer-events: none; opacity: .35; }

/* SETTLE, SUCCESS — one second of "it landed", then the row is simply LAID and
   wears the amber terminal state it always did. */
.sv2-selection .sxb-row.laid-just,
.sv2-selection .sxb-row.laid.laid-just {
  background-image: linear-gradient(rgba(var(--sv2-laid-rgb), .20), rgba(var(--sv2-laid-rgb), .20)) !important;
  box-shadow: inset 3px 0 0 var(--sv2-laid), inset 0 0 0 1px rgba(var(--sv2-laid-rgb), .45);
}

/* SETTLE, FAILURE — the card keeps its previous state and its verb comes back
   live; the only addition is the reason, said on the card in the same words the
   pool banner says in full (#6873's sentences, unchanged). */
.sv2-selection .sxb-row.layfail { box-shadow: inset 3px 0 0 var(--st-danger, #b46868); }

/* REDUCED MOTION — the outline stays lime and solid, the copy still updates.
   The state is carried by colour and words either way; only the travel and the
   spin are removed, which is exactly what the setting asks for. */
@media (prefers-reduced-motion: reduce) {
  .sv2-selection .sxb-row.laying .sxb-layring rect {
    animation: none;
    stroke-dasharray: none;
    stroke-width: 1.25;
  }
  .sv2-selection .sxb-layspin {
    animation: none;
    border-color: rgba(var(--sv2-lime-rgb), .30);
    border-top-color: var(--sv2-lime);
  }
}

/* #7000 — AND THE SOUND KEEPS ITS NAME. .nm is flex:1 with a 0% basis, so under
   compression it is the first thing to reach zero width: at 390x844 the laying
   card showed a phase line and a button and NO FILENAME AT ALL (measured, in
   the 390 run). While the card is working — or has just failed, or just landed —
   the name gets a floor, and the phase line yields instead. Which sound this is
   happening to is not the optional half of that sentence. */
.sv2-selection .sxb-row.laying .nm,
.sv2-selection .sxb-row.layfail .nm,
.sv2-selection .sxb-row.laid-just .nm { min-width: 84px; }
