/**
 * SNACKBAR: the list of landing pages, and the two-pane editor (docs/20 §9).
 *
 * ── WHAT THIS FILE IS ALLOWED TO INVENT ─────────────────────────────────────
 *
 * The SPLIT (an editor beside a frame), the BLOCK LIST (a listbox that can be
 * dragged and driven from a keyboard), and the PREVIEW STAGE (a document at a
 * device's real width, scaled down). Everything else composes from what the
 * console already has: .cb-table for the list, .cb-input for every box,
 * .cb-badge for every state, .cb-dialog for the three dialogs. Nothing here
 * redefines any of them, so `check:classes` sees one owner per name.
 *
 * ── NO RAIL, ANYWHERE ───────────────────────────────────────────────────────
 *
 * A block that is hidden, a check that blocks a publish and a field that
 * overrides the base are all things this screen has to mark, and every one of
 * them is exactly the case somebody reaches for a coloured bar down a left
 * edge. docs/10 forbids it by name and gives the replacements, which are what
 * is used here: a tinted GROUND and the state written in WORDS for a hidden
 * block, the whole border for a refusal, an indent for "this belongs to the row
 * above". The word is never optional: colour alone is not a label.
 *
 * ── THE PREVIEW IS A DOCUMENT SCALED, NOT A SMALL DOCUMENT ──────────────────
 *
 * `--cbs-snack-scale` and the stage's height are both set by
 * views/snackbar-preview.ts, because a transform does not change the space an
 * element takes and the pane would otherwise keep a fourteen-hundred-pixel hole
 * under a picture six hundred tall. They are the two numbers in this file that
 * cannot be written down, which is the same argument console-bonbonniere.css
 * makes for `--cbs-scale`.
 */

/* ---------------------------------------------------------------------------
   The list: eighteen pages, and the shared base above them.
   ------------------------------------------------------------------------ */

.cb-snack-base {
  display: flex;
  align-items: center;
  gap: var(--cb-space-lg);
  flex-wrap: wrap;
  padding: var(--cb-space-2xl) var(--cb-space-3xl);
  margin-bottom: var(--cb-space-3xl);
  border: 1px solid var(--cbc-line);
  border-radius: var(--cb-radius-xl);
  background: var(--cbc-surface);
  color: var(--cbc-ink);
  text-decoration: none;
  transition: background var(--cbc-grace) var(--cbc-spring);
}

.cb-snack-base:hover {
  background: var(--cbc-hover);
}

.cb-snack-base-name {
  font-weight: var(--cb-font-weight-semibold);
}

.cb-snack-base-note {
  flex: 1 1 var(--cb-width-xxs);
  min-width: 0;
  color: var(--cbc-ink-muted);
  font-size: var(--cb-type-sm-size);
}

.cb-snack-table td {
  vertical-align: middle;
}

/* One page on the list. The class is on the row rather than on a cell so the
   screen has a name for "a page" that a test and a stylesheet can both use. */
.cb-snack-row {
  vertical-align: middle;
}

.cb-snack-open {
  color: var(--cbc-ink);
  font-weight: var(--cb-font-weight-medium);
  text-decoration: none;
}

.cb-snack-open:hover {
  color: var(--cbc-accent-text);
}

.cb-snack-slug,
.cb-snack-field-id {
  font-family: var(--cb-font-mono);
  font-size: var(--cb-type-xs-size);
  color: var(--cbc-ink-muted);
}

.cb-snack-when {
  color: var(--cbc-ink-muted);
  font-size: var(--cb-type-sm-size);
  white-space: nowrap;
}

/* One cell holding a badge and the thing it is about. */
.cb-snack-cell {
  display: inline-flex;
  align-items: center;
  gap: var(--cb-space-md);
  flex-wrap: wrap;
}

.cb-snack-version {
  font-family: var(--cb-font-mono);
  font-size: var(--cb-type-sm-size);
  color: var(--cbc-ink);
}

.cb-snack-out {
  display: inline-flex;
  color: var(--cbc-ink-faint);
  transition: color var(--cbc-grace) var(--cbc-spring);
}

.cb-snack-out:hover {
  color: var(--cbc-accent-text);
}

/* ---------------------------------------------------------------------------
   The editor: the panes, and the line that speaks a move out loud.
   ------------------------------------------------------------------------ */

.cb-snack-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--cb-space-4xl);
  align-items: start;
}

/* Mirrors --cb-width-2xl (1024px): below it the two panes stop being two
   columns and become one, because a 500px editor beside a 500px preview is
   two things neither of which can be read. */
@media (max-width: 1023px) {
  .cb-snack-split {
    grid-template-columns: minmax(0, 1fr);
  }
}

.cb-snack-edit {
  display: flex;
  flex-direction: column;
  gap: var(--cb-space-3xl);
  min-width: 0;
}

/**
 * What a keyboard move just did, said out loud.
 *
 * Visible as well as announced: a person watching the list sees the row move
 * and a person reading the sentence gets the position, and the two together are
 * what a drag gives you for free.
 */
.cb-snack-said {
  margin: 0 0 var(--cb-space-lg);
  min-height: var(--cb-space-2xl);
  color: var(--cbc-ink-muted);
  font-size: var(--cb-type-sm-size);
}

.cb-snack-group {
  border: 1px solid var(--cbc-line);
  border-radius: var(--cb-radius-2xl);
  background: var(--cbc-surface);
  overflow: hidden;
}

.cb-snack-group-head {
  padding: var(--cb-space-2xl) var(--cb-space-3xl);
  border-bottom: 1px solid var(--cbc-line);
  background: var(--cbc-sunken);
}

.cb-snack-group-head h2 {
  margin: 0;
  font-size: var(--cb-type-md-size);
  font-weight: var(--cb-font-weight-semibold);
  color: var(--cbc-ink);
}

.cb-snack-group-head p {
  margin: var(--cb-space-xxs) 0 0;
  font-size: var(--cb-type-sm-size);
  color: var(--cbc-ink-muted);
}

.cb-snack-group-body {
  display: flex;
  flex-direction: column;
  gap: var(--cb-space-2xl);
  padding: var(--cb-space-3xl);
}

/* ---------------------------------------------------------------------------
   One editable string, and where it came from.
   ------------------------------------------------------------------------ */

.cb-snack-field-row {
  display: flex;
  flex-direction: column;
  gap: var(--cb-space-md);
}

.cb-snack-field-row-head {
  display: flex;
  align-items: center;
  gap: var(--cb-space-md);
  flex-wrap: wrap;
}

.cb-snack-label {
  font-size: var(--cb-type-sm-size);
  font-weight: var(--cb-font-weight-medium);
  color: var(--cbc-ink);
}

/**
 * "Changed from the shared base", as a word rather than as a colour.
 *
 * The whole point of the mark is that somebody can tell an inherited string
 * from one this page decided, and a tint alone would say that only to people
 * who can see it.
 */
.cb-snack-from {
  font-size: var(--cb-type-xs-size);
  color: var(--cbc-accent-text);
}

.cb-snack-move {
  display: inline-flex;
  gap: var(--cb-space-xs);
  margin-left: auto;
  flex: 0 0 auto;
}

.cb-snack-list {
  display: flex;
  flex-direction: column;
  gap: var(--cb-space-lg);
}

.cb-snack-listrow {
  display: flex;
  align-items: flex-end;
  gap: var(--cb-space-lg);
}

.cb-snack-listrow > .cb-snack-field-row {
  flex: 1 1 auto;
  min-width: 0;
}

/* ---------------------------------------------------------------------------
   A question, and a progress step: a head, then its parts, indented under it.
   ------------------------------------------------------------------------ */

.cb-snack-field,
.cb-snack-step {
  display: flex;
  flex-direction: column;
  gap: var(--cb-space-md);
  padding: var(--cb-space-xl);
  border: 1px solid var(--cbc-line);
  border-radius: var(--cb-radius-xl);
  background: var(--cbc-sunken);
}

/**
 * ONE LINE, AND THE CONTROLS ALWAYS IN THE SAME PLACE.
 *
 * `flex-wrap: wrap` put the switch on a second line for the two stages whose
 * id happened to be a few characters longer, so the same control sat somewhere
 * different depending on the row and a column of controls stopped being a
 * column. That is rule 15's complaint about REMOVING a control, in the milder
 * costume of moving one: the name takes whatever is left and truncates, the
 * controls keep their place.
 */
.cb-snack-field-head,
.cb-snack-step-head {
  display: flex;
  align-items: center;
  gap: var(--cb-space-md);
  flex-wrap: nowrap;
}

.cb-snack-field-name {
  margin: 0;
  min-width: 0;
  font-size: var(--cb-type-sm-size);
  font-weight: var(--cb-font-weight-semibold);
  color: var(--cbc-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The raw id is the thing to lose first when a row is tight: the name above it
   says the same thing in words. */
.cb-snack-field-head .cb-snack-field-id,
.cb-snack-step-head .cb-snack-field-id {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.cb-snack-part {
  display: grid;
  grid-template-columns: var(--cb-space-9xl) minmax(0, 1fr);
  align-items: center;
  gap: var(--cb-space-lg);
}

.cb-snack-part-label {
  font-size: var(--cb-type-xs-size);
  color: var(--cbc-ink-muted);
}

/**
 * A part that cannot be filled in yet reads as unavailable rather than as
 * broken, and its own tooltip says which field to fill in first (rule 15).
 *
 * A LITERAL, LIKE EVERY OTHER DIM IN THIS CONSOLE, and this one is worth a
 * note. It was `opacity: var(--cbc-dim)`, which looks like the right token by
 * its name and is a `cubic-bezier` by its value: substituting it made the
 * declaration invalid at computed-value time, so opacity took its INITIAL
 * value and every turned-off row was drawn at full strength (rule 19, "a
 * token's name is not its type"). check:tokens cannot see that, because it IS
 * a token. Opacity has no scale in the token set; `.cb-set[data-depends="off"]`
 * in console-panels.css writes 0.5 for exactly this and so does this.
 */
.cb-snack-part[aria-disabled="true"],
.cb-snack-detail-row[aria-disabled="true"] {
  opacity: 0.5;
}

/* ---------------------------------------------------------------------------
   The report's blocks: a listbox that drags.
   ------------------------------------------------------------------------ */

.cb-snack-blocks {
  display: flex;
  flex-direction: column;
  gap: var(--cb-space-xs);
  padding: var(--cb-space-xs);
  border: 1px solid var(--cbc-line);
  border-radius: var(--cb-radius-xl);
  background: var(--cbc-sunken);
}

.cb-snack-blocks:focus-visible {
  outline: 2px solid var(--cbc-focus);
  outline-offset: var(--cbc-focus-gap);
}

.cb-snack-block {
  display: flex;
  align-items: center;
  gap: var(--cb-space-md);
  padding: var(--cb-space-md) var(--cb-space-lg);
  border-radius: var(--cb-radius-lg);
  background: var(--cbc-surface);
  cursor: grab;
  transition: background var(--cbc-grace) var(--cbc-spring);
}

.cb-snack-block:hover {
  background: var(--cbc-hover);
}

/* The active option in the listbox. A filled row, which is what docs/10 says
   to use instead of a bar down the edge. */
.cb-snack-block[aria-selected="true"] {
  background: var(--cbc-accent-wash);
}

/* The row being dragged, faded so the gap it leaves reads as the gap. A
   literal for the reason the note further down gives: --cbc-dim is a curve. */
.cb-snack-block[data-dragging] {
  opacity: 0.4;
  cursor: grabbing;
}

/**
 * The grip: furniture, revealed on approach rather than always on.
 *
 * One handle at a time, not seven, which is the rule the dashboard's cards
 * already follow. It is hidden from assistive technology because dragging is
 * the only thing it does; the keyboard's path is the listbox around it.
 */
.cb-snack-grip {
  color: var(--cbc-ink-faint);
  opacity: 0;
  transition: opacity var(--cbc-grace) var(--cbc-spring);
}

.cb-snack-block:hover .cb-snack-grip,
.cb-snack-block[aria-selected="true"] .cb-snack-grip {
  opacity: 1;
}

.cb-snack-block-order {
  min-width: var(--cb-space-2xl);
  font-family: var(--cb-font-mono);
  font-size: var(--cb-type-xs-size);
  color: var(--cbc-ink-faint);
  text-align: right;
}

.cb-snack-block-words {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
}

.cb-snack-block-name {
  font-size: var(--cb-type-sm-size);
  font-weight: var(--cb-font-weight-medium);
  color: var(--cbc-ink);
}

.cb-snack-block-says {
  font-size: var(--cb-type-xs-size);
  color: var(--cbc-ink-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cb-snack-marks {
  display: inline-flex;
  align-items: center;
  gap: var(--cb-space-md);
}

.cb-snack-mark {
  display: inline-flex;
  align-items: center;
  gap: var(--cb-space-xs);
  color: var(--cbc-ink-muted);
  font-size: var(--cb-type-xs-size);
}

.cb-snack-mark-word {
  white-space: nowrap;
}

/* A hidden block reads as hidden: a quieter ground, and the word "Hidden" on
   it. Never a colour on its own. */
.cb-snack-block[data-kind] .cb-snack-mark {
  color: var(--cbc-ink-muted);
}

.cb-snack-add {
  display: flex;
  justify-content: flex-start;
}

/* ---------------------------------------------------------------------------
   The chosen block's own fields, under the list rather than inside it.
   ------------------------------------------------------------------------ */

.cb-snack-detail {
  display: flex;
  flex-direction: column;
  gap: var(--cb-space-lg);
  padding: var(--cb-space-xl);
  border: 1px solid var(--cbc-line);
  border-radius: var(--cb-radius-xl);
  background: var(--cbc-sunken);
}

.cb-snack-detail-head {
  margin: 0;
  font-size: var(--cb-type-sm-size);
  font-weight: var(--cb-font-weight-semibold);
  color: var(--cbc-ink);
}

.cb-snack-detail-row {
  display: grid;
  grid-template-columns: var(--cb-space-9xl) minmax(0, 1fr);
  align-items: center;
  gap: var(--cb-space-lg);
}

.cb-snack-detail-wide {
  align-items: start;
}

/* ---------------------------------------------------------------------------
   The preview: the real widget, at a real width, scaled down.
   ------------------------------------------------------------------------ */

.cb-snack-preview {
  position: sticky;
  top: var(--cb-space-3xl);
  display: flex;
  flex-direction: column;
  gap: var(--cb-space-lg);
  min-width: 0;
}

.cb-snack-preview-bar {
  display: flex;
  align-items: center;
  gap: var(--cb-space-lg);
  flex-wrap: wrap;
}

.cb-snack-sizes {
  display: inline-flex;
  gap: var(--cb-space-xxs);
  padding: var(--cb-space-xxs);
  border: 1px solid var(--cbc-line);
  border-radius: var(--cb-radius-full);
  background: var(--cbc-sunken);
}

.cb-snack-size {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--cb-space-sm) var(--cb-space-lg);
  border: 0;
  border-radius: var(--cb-radius-full);
  background: transparent;
  color: var(--cbc-ink-muted);
  cursor: pointer;
  transition:
    background var(--cbc-grace) var(--cbc-spring),
    color var(--cbc-grace) var(--cbc-spring);
}

.cb-snack-size:hover {
  color: var(--cbc-ink);
}

/* The chosen width, shown as the filled control rather than as a bar beside
   it: two options with the current one marked, which is what removes the
   decision (docs/10). */
.cb-snack-size[aria-pressed="true"] {
  background: var(--cbc-accent);
  color: var(--cbc-on-accent);
}

.cb-snack-stage {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--cbc-line);
  border-radius: var(--cb-radius-xl);
  background: var(--cbc-sunken);
}

.cb-snack-frame {
  display: block;
  border: 0;
  transform: scale(var(--cbs-snack-scale, 1));
  transform-origin: top left;
}

/**
 * WHAT IS DRAWN WHEN THE WIDGET'S HARNESS IS NOT RUNNING.
 *
 * Opaque, and over the whole stage, because the alternative is the browser's
 * own connection-refused page showing through underneath and reading as this
 * console being broken. It says what to start and where, and it never draws a
 * report: a plausible one nobody's draft produced is the single worst thing
 * this pane could do.
 */
.cb-snack-absent {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--cb-space-lg);
  padding: var(--cb-space-4xl);
  background: var(--cbc-sunken);
  color: var(--cbc-ink-muted);
  font-size: var(--cb-type-sm-size);
}

.cb-snack-absent-head {
  margin: 0;
  font-size: var(--cb-type-md-size);
  font-weight: var(--cb-font-weight-semibold);
  color: var(--cbc-ink);
}

.cb-snack-absent p {
  margin: 0;
}

.cb-snack-absent-where {
  font-family: var(--cb-font-mono);
  font-size: var(--cb-type-xs-size);
  color: var(--cbc-ink-faint);
  overflow-wrap: anywhere;
}

/* ---------------------------------------------------------------------------
   Publishing: the checks, the versions, the block, and the restamp.
   ------------------------------------------------------------------------ */

.cb-snack-dialog {
  width: min(var(--cb-width-xl), 92vw);
}

.cb-snack-checks {
  display: flex;
  flex-direction: column;
  gap: var(--cb-space-lg);
  margin-bottom: var(--cb-space-2xl);
}

.cb-snack-problems {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--cb-space-md);
  max-height: var(--cb-space-11xl);
  overflow-y: auto;
}

.cb-snack-problem {
  display: flex;
  align-items: baseline;
  gap: var(--cb-space-md);
  flex-wrap: wrap;
  padding: var(--cb-space-md) var(--cb-space-lg);
  border-radius: var(--cb-radius-lg);
  background: var(--cbc-sunken);
}

/* A refusal takes the whole border in its colour, never a bar down one edge
   (docs/10). The word "Blocks" is on the badge beside it, so the colour is
   never carrying the meaning by itself. */
.cb-snack-problem[data-blocks="yes"] {
  border: 1px solid var(--cbc-poor);
}

.cb-snack-problem-said {
  flex: 1 1 var(--cb-width-xxs);
  min-width: 0;
  color: var(--cbc-ink);
  font-size: var(--cb-type-sm-size);
}

/* The same refusal, on the box it is about. */
.cb-snack-problem-line {
  margin: var(--cb-space-xs) 0 0;
}

.cb-snack-versions {
  border: 1px solid var(--cbc-line);
  border-radius: var(--cb-radius-2xl);
  background: var(--cbc-surface);
  padding: var(--cb-space-3xl);
}

.cb-snack-versions h3 {
  margin: 0 0 var(--cb-space-lg);
  font-size: var(--cb-type-md-size);
  font-weight: var(--cb-font-weight-semibold);
  color: var(--cbc-ink);
}

.cb-snack-version-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--cb-space-md);
}

.cb-snack-version-row {
  display: flex;
  align-items: center;
  gap: var(--cb-space-lg);
  flex-wrap: wrap;
  padding: var(--cb-space-md) var(--cb-space-lg);
  border-radius: var(--cb-radius-lg);
  background: var(--cbc-sunken);
}

.cb-snack-version-note {
  flex: 1 1 var(--cb-width-xxs);
  min-width: 0;
  font-size: var(--cb-type-sm-size);
  color: var(--cbc-ink);
}

.cb-snack-version-who {
  font-size: var(--cb-type-xs-size);
  color: var(--cbc-ink-muted);
  white-space: nowrap;
}

.cb-snack-block-text {
  font-family: var(--cb-font-mono);
  font-size: var(--cb-type-xs-size);
}

.cb-snack-restamp-range {
  display: flex;
  gap: var(--cb-space-lg);
  flex-wrap: wrap;
  margin-bottom: var(--cb-space-lg);
}

.cb-snack-datebox {
  display: flex;
  flex-direction: column;
  gap: var(--cb-space-xs);
}

.cb-snack-tick {
  display: flex;
  align-items: flex-start;
  gap: var(--cb-space-lg);
  padding: var(--cb-space-md) 0;
  cursor: pointer;
}

.cb-snack-tick-words {
  display: flex;
  flex-direction: column;
  gap: var(--cb-space-xxs);
  font-size: var(--cb-type-sm-size);
  color: var(--cbc-ink);
}

/* ---------------------------------------------------------------------------
   Reduced motion gets the working page.
   ------------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  .cb-snack-grip {
    transition: none;
    opacity: 1;
  }

  .cb-snack-base,
  .cb-snack-block,
  .cb-snack-out,
  .cb-snack-size {
    transition: none;
  }
}

/* ---- The four groups, which open where they sit ----
   `details`/`summary` is the house pattern (docs/09): it opens with a keyboard,
   it is found by in-page search while shut, and it holds no state of its own.
   The marker is dropped and a chevron drawn from the console's own asset, so
   the disclosure looks like every other one here rather than like a browser's. */
.cb-snack-group > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: var(--cb-space-lg);
}
.cb-snack-group > summary::-webkit-details-marker {
  display: none;
}
.cb-snack-group > summary::after {
  content: "";
  margin-inline-start: auto;
  inline-size: var(--cb-space-2xl);
  block-size: var(--cb-space-2xl);
  background: var(--cbc-ink-muted);
  -webkit-mask: var(--cbc-chevron) center / contain no-repeat;
  mask: var(--cbc-chevron) center / contain no-repeat;
  transition: transform var(--cb-motion-fast) var(--cbc-spring);
}
.cb-snack-group[open] > summary::after {
  transform: rotate(180deg);
}
.cb-snack-group > summary:hover {
  background: var(--cbc-hover);
}
.cb-snack-group > summary:focus-visible {
  outline: 2px solid var(--cbc-focus);
  outline-offset: var(--cbc-focus-gap);
}
