/* =========================================================================
   Slide Studio — app chrome
   Owner: Builder C.  Consumes chrome-tokens.css only.
   Every class is prefixed `ss-`.  That is not decoration: Bootstrap 5.1 ships
   `.toast:not(.show){display:none}` at specificity (0,2,0) and the old build
   lost to it, making every toast in the app — including "Generation Failed" —
   invisible.  Namespacing removes the whole class of collision rather than
   fighting it with `.show`.
   Spec: 07-design-spec §H (components), §I (responsive), §J (motion / a11y).
   ========================================================================= */

/* ---------------------------------------------------------------- base -- */

.ss-app,
.ss-app * { box-sizing: border-box; }

.ss-app {
  font-family: var(--c-font);
  color: var(--c-text-1);
  font-size: var(--fs-md);
  line-height: var(--lh-md);
}

.ss-app p { margin: 0; }

/* No horizontal page scroll at any width >= 360px (§K.23). */
html, body { overflow-x: clip; }

.ss-visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

.ss-skip-link {
  position: fixed;
  top: var(--sp-4); left: var(--sp-4);
  z-index: 9000;
  transform: translateY(-200%);
  background: var(--c-bg-2);
  color: var(--c-text-1);
  border: 1px solid var(--c-border);
  border-radius: var(--r-sm);
  padding: var(--sp-2) var(--sp-4);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  text-decoration: none;
}
.ss-skip-link:focus { transform: translateY(0); }

/* ---------------------------------------------------------- §J.1 focus -- */

.ss-app :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--c-focus);
  outline-offset: 2px;
  border-radius: inherit;
  box-shadow: 0 0 0 4px var(--c-bg-0);
}
/* Keyboard focus inside a modal must be visible against the panel, not the page. */
.ss-modal :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  box-shadow: 0 0 0 4px var(--c-bg-1);
}

/* -------------------------------------------------- §J.3 reduced motion -- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  /* The two site aurora layers become static gradients: position and opacity
     kept, animation stopped.  Also a permanent GPU saving. */
  body::before, body::after { animation: none !important; }

  .ss-card:hover, .ss-thumb:hover { transform: none !important; }
  .ss-spinner { animation: none !important; border-top-color: currentColor !important; }
  .ss-indeterminate::after { animation: none !important; width: 40% !important; left: 0 !important; }
  /* Opacity-only crossfades at 80ms are retained — no vestibular risk. */
  .ss-view { transition: opacity 80ms linear !important; }
}

/* -------------------------------------------------------- §H.4 buttons -- */

.ss-btn {
  --btn-h: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  height: var(--btn-h);
  padding: 0 var(--sp-4);
  border-radius: var(--r-sm);
  border: 1px solid transparent;
  background: transparent;
  color: var(--c-text-1);
  font-family: inherit;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  line-height: 1;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--t-micro) var(--ease-enter),
              border-color var(--t-micro) var(--ease-enter),
              color var(--t-micro) var(--ease-enter);
}
.ss-btn i, .ss-btn svg { font-size: 18px; width: 18px; height: 18px; flex: none; }

.ss-btn--primary   { background: var(--c-primary); color: var(--c-on-primary); }
.ss-btn--primary:hover:not(:disabled) { background: var(--c-primary-hov); }

.ss-btn--secondary { border-color: var(--c-border); color: var(--c-text-1); }
.ss-btn--secondary:hover:not(:disabled) { background: var(--c-bg-2); }

.ss-btn--ghost     { --btn-h: 36px; padding: 0 var(--sp-3); color: var(--c-text-2); }
.ss-btn--ghost:hover:not(:disabled) { background: var(--c-bg-2); color: var(--c-text-1); }

.ss-btn--danger    { color: var(--c-danger); border-color: color-mix(in srgb, var(--c-danger) 50%, transparent); }
.ss-btn--danger:hover:not(:disabled) { background: var(--c-danger-fill); }

.ss-btn--large     { --btn-h: 48px; padding: 0 var(--sp-5); border-radius: var(--r-md);
                     background: var(--c-primary); color: var(--c-on-primary); }
.ss-btn--large:hover:not(:disabled) { background: var(--c-primary-hov); }

.ss-btn--block     { width: 100%; }

.ss-btn:disabled,
.ss-btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }

/* Busy: width is held, label swapped for spinner + present-tense verb. */
.ss-btn[data-busy="true"] { pointer-events: none; }

/* Icon button: 36x36 visual, 44x44 hit area via ::after (§J.5). */
.ss-iconbtn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px; height: 36px;
  flex: none;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--c-text-2);
  cursor: pointer;
  transition: background-color var(--t-micro) var(--ease-enter),
              color var(--t-micro) var(--ease-enter);
}
.ss-iconbtn::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: var(--r-sm);
}
.ss-iconbtn:hover:not(:disabled) { background: var(--c-bg-2); color: var(--c-text-1); }
.ss-iconbtn:disabled { opacity: .45; cursor: not-allowed; }
.ss-iconbtn i { font-size: 18px; pointer-events: none; }
.ss-iconbtn--danger:hover:not(:disabled) { background: var(--c-danger-fill); color: var(--c-danger); }

@media (pointer: coarse) {
  .ss-iconbtn { width: 44px; height: 44px; }
}

.ss-spinner {
  width: 16px; height: 16px;
  flex: none;
  border: 2px solid color-mix(in srgb, currentColor 30%, transparent);
  border-top-color: currentColor;
  border-radius: 50%;
  animation: ss-spin 700ms linear infinite;
}
@keyframes ss-spin { to { transform: rotate(360deg); } }

/* --------------------------------------------------------- §H.5 inputs -- */

.ss-field { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; }

.ss-label {
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
  font-weight: var(--fw-medium);
  color: var(--c-text-2);
}
.ss-label .ss-req { color: var(--c-danger); margin-left: 2px; }

.ss-help {
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
  color: var(--c-text-3);
}
.ss-error-text {
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
  color: var(--c-danger);
  display: flex; align-items: center; gap: var(--sp-1);
}

.ss-input, .ss-textarea, .ss-select {
  width: 100%;
  min-width: 0;
  height: 40px;
  padding: 0 var(--sp-3);
  background: var(--c-bg-2);
  border: 1px solid var(--c-border);
  border-radius: var(--r-sm);
  color: var(--c-text-1);
  font-family: inherit;
  font-size: var(--fs-md);
  line-height: var(--lh-md);
  transition: border-color var(--t-micro) var(--ease-enter);
}
.ss-textarea {
  height: auto;
  min-height: 96px;
  padding: var(--sp-3);
  resize: vertical;
}
.ss-select {
  appearance: none;
  padding-right: var(--sp-6);
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 18px center, right 12px center;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}
.ss-input::placeholder, .ss-textarea::placeholder { color: var(--c-text-3); }
.ss-input:hover, .ss-textarea:hover, .ss-select:hover { border-color: var(--c-text-3); }
.ss-input:focus, .ss-textarea:focus, .ss-select:focus { border-color: var(--c-primary); }
.ss-input[aria-invalid="true"], .ss-textarea[aria-invalid="true"] { border-color: var(--c-danger); }
.ss-input:disabled, .ss-textarea:disabled, .ss-select:disabled {
  background: var(--c-bg-1); color: var(--c-text-3); border-color: var(--c-border-sub); cursor: not-allowed;
}
.ss-input--lg { height: 48px; font-size: var(--fs-lg); }

.ss-counter {
  align-self: flex-end;
  font-size: var(--fs-xs);
  line-height: var(--lh-xs);
  color: var(--c-text-3);
  font-variant-numeric: tabular-nums;
}
.ss-counter[data-short="true"] { color: var(--c-warning); }

/* Segmented control — used for slide count.  Unavailable options are
   RENDERED AND DISABLED with a reason, never omitted (§H.2). */
.ss-segmented {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}
.ss-seg {
  min-width: 56px;
  height: 40px;
  padding: 0 var(--sp-3);
  border: 1px solid var(--c-border);
  border-radius: var(--r-sm);
  background: var(--c-bg-2);
  color: var(--c-text-1);
  font: inherit;
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: background-color var(--t-state) var(--ease-enter),
              border-color var(--t-state) var(--ease-enter);
}
.ss-seg:hover:not(:disabled) { background: var(--c-bg-3); }
.ss-seg[aria-checked="true"] {
  background: var(--c-primary); border-color: var(--c-primary); color: var(--c-on-primary);
}
.ss-seg:disabled { opacity: .45; cursor: not-allowed; }

.ss-details {
  border: 1px solid var(--c-border-sub);
  border-radius: var(--r-sm);
  background: var(--c-bg-1);
}
.ss-details > summary {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  cursor: pointer;
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  color: var(--c-text-1);
  list-style: none;
}
.ss-details > summary::-webkit-details-marker { display: none; }
.ss-details > summary::before {
  content: "\f105"; /* fa chevron-right */
  font-family: "Font Awesome 6 Free"; font-weight: 900;
  color: var(--c-text-3);
  width: 12px;
  transition: transform var(--t-state) var(--ease-enter);
}
.ss-details[open] > summary::before { transform: rotate(90deg); }
.ss-details__body { padding: 0 var(--sp-4) var(--sp-4) var(--sp-6); display: grid; gap: var(--sp-4); }

/* ------------------------------------------------------------ app shell -- */

.ss-shell {
  display: grid;
  grid-template-columns: 248px minmax(0, 1fr);
  min-height: calc(100dvh - var(--nav-h));
  background: var(--c-bg-0);
}

.ss-sidebar {
  background: var(--c-bg-1);
  border-right: 1px solid var(--c-border-sub);
  padding: var(--sp-5) var(--sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
}
.ss-sidebar__nav { display: flex; flex-direction: column; gap: var(--sp-1); }
.ss-navitem {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  height: 40px;
  padding: 0 var(--sp-3);
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--c-text-2);
  font: inherit;
  font-weight: var(--fw-medium);
  text-align: left;
  cursor: pointer;
  transition: background-color var(--t-micro) var(--ease-enter), color var(--t-micro) var(--ease-enter);
}
.ss-navitem i { width: 18px; text-align: center; }
.ss-navitem:hover { background: var(--c-bg-2); color: var(--c-text-1); }
.ss-navitem[aria-current="page"] { background: var(--c-bg-3); color: var(--c-text-1); }

.ss-quota { display: grid; gap: var(--sp-3); }
.ss-quota__row { display: grid; gap: var(--sp-2); }
.ss-quota__label {
  display: flex; justify-content: space-between; gap: var(--sp-2);
  font-size: var(--fs-sm); line-height: var(--lh-sm); color: var(--c-text-2);
}
.ss-meter {
  height: 6px;
  border-radius: var(--r-pill);
  background: var(--c-bg-3);
  overflow: hidden;
}
.ss-meter__fill {
  height: 100%;
  border-radius: var(--r-pill);
  background: var(--c-primary);
  transition: width var(--t-state) var(--ease-enter), background-color var(--t-state) var(--ease-enter);
}
.ss-meter[data-level="warn"] .ss-meter__fill { background: var(--c-warning); }
.ss-meter[data-level="full"] .ss-meter__fill { background: var(--c-danger); }

.ss-main { min-width: 0; display: flex; flex-direction: column; }

/* View switching: opacity only — the canvas must not appear to move (§J.4). */
.ss-view { display: none; min-width: 0; min-height: 0; flex: 1; }
.ss-view[data-active="true"] { display: flex; flex-direction: column; animation: ss-fade var(--t-view) var(--ease-enter); }
@keyframes ss-fade { from { opacity: 0; } to { opacity: 1; } }

.ss-viewhead {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-4);
  flex-wrap: wrap;
  padding: var(--sp-6) var(--gutter) var(--sp-5);
}
.ss-viewhead h1 {
  margin: 0;
  font-size: var(--fs-2xl); line-height: var(--lh-2xl);
  font-weight: var(--fw-bold); color: var(--c-text-1);
}
.ss-viewhead p { margin: var(--sp-1) 0 0; font-size: var(--fs-md); color: var(--c-text-2); }
.ss-viewhead__actions { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }

/* ----------------------------------------------------- §H.1 deck cards -- */

.ss-library { padding: 0 var(--gutter) var(--sp-8); }

.ss-toolbar-row {
  display: flex; align-items: center; gap: var(--sp-3);
  flex-wrap: wrap;
  margin-bottom: var(--sp-5);
}
.ss-search { position: relative; flex: 1 1 260px; max-width: 420px; }
.ss-search .ss-input { padding-left: 38px; }
.ss-search > i {
  position: absolute; left: var(--sp-3); top: 50%; transform: translateY(-50%);
  color: var(--c-text-3); pointer-events: none;
}

.ss-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(288px, 1fr));
  gap: var(--sp-5);
  align-items: stretch;
}

.ss-card {
  position: relative;
  /* A <button> shrink-wraps its content. Without an explicit width each card
     sized to the length of its own title, so the three "columns" in a row were
     232/262/234px wide and their thumbnails — and therefore their titles —
     landed on three different baselines. */
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  text-align: left;
  padding: 0;
  background: var(--c-bg-1);
  border: 1px solid var(--c-border-sub);
  border-radius: var(--r-md);
  box-shadow: var(--el-1);
  color: inherit;
  font: inherit;
  cursor: pointer;
  overflow: hidden;
  transition: background-color var(--t-micro) var(--ease-enter),
              border-color var(--t-micro) var(--ease-enter),
              box-shadow var(--t-micro) var(--ease-enter),
              transform var(--t-micro) var(--ease-enter);
}
.ss-card:hover {
  background: var(--c-bg-2);
  border-color: var(--c-border);
  box-shadow: var(--el-2);
  transform: translateY(-2px);
}
.ss-card[aria-current="true"] { border: 2px solid var(--c-primary); background: var(--c-bg-3); }

.ss-card__thumb {
  display: block;
  /* The engine's slide is 16:9; without pinning BOTH the ratio and the meta
     block the three cards in a row ended up ~130/145/133px tall and their
     titles sat on three different baselines. A grid whose rows do not read as
     rows is the clearest possible sign nobody swept the layout. */
  aspect-ratio: 16 / 9;
  flex: 0 0 auto;
  width: 100%;
  background: var(--c-bg-2);
  border-bottom: 1px solid var(--c-border-sub);
  border-radius: var(--r-md) var(--r-md) 0 0;
  overflow: hidden;
  position: relative;
  container-type: inline-size;
}
.ss-card__thumb > * { position: absolute; inset: 0; width: 100%; height: 100%; }
.ss-card__thumb .sl-slide { transform-origin: top left; }

.ss-card__meta {
  padding: var(--sp-4);
  display: grid;
  grid-template-rows: auto auto;
  gap: var(--sp-2);
  /* FIXED height so rows align — the point of §H.1's rule. 108px, not the
     spec's 92px: two lines of --fs-lg title (52) + a meta row (20) + the gap
     and padding do not fit in 92, and clipping the status pill to honour the
     number would defeat the rule it exists to serve. */
  height: 108px;
  align-content: start;
  justify-items: stretch;
  overflow: hidden;
}
.ss-card__metarow {
  display: flex; align-items: center; gap: var(--sp-2);
  min-width: 0;
}
.ss-card__metarow .ss-card__sub {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ss-card__title {
  width: 100%;
  height: calc(var(--lh-lg) * 2);   /* always two lines of box, clamped */
  font-size: var(--fs-lg); line-height: var(--lh-lg);
  font-weight: var(--fw-semibold); color: var(--c-text-1);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ss-card__sub { font-size: var(--fs-sm); line-height: var(--lh-sm); color: var(--c-text-3); }

.ss-pill {
  display: inline-flex;
  justify-self: start; align-items: center; gap: var(--sp-1);
  font-size: var(--fs-xs); line-height: var(--lh-xs); font-weight: var(--fw-semibold);
  border-radius: var(--r-pill); padding: 3px 8px;
  background: var(--c-bg-3); color: var(--c-text-3);
}
.ss-pill--ready      { background: var(--c-success-fill); color: var(--c-success); }
.ss-pill--generating { background: var(--c-primary-fill); color: var(--c-primary-txt); }
.ss-pill--warn       { background: var(--c-warning-fill); color: var(--c-warning); }

.ss-card__actions {
  position: absolute; top: var(--sp-2); right: var(--sp-2);
  display: flex; gap: var(--sp-1);
  opacity: 0;
  transition: opacity var(--t-micro) var(--ease-enter);
}
.ss-card:hover .ss-card__actions,
.ss-card:focus-within .ss-card__actions,
.ss-card__actions:focus-within { opacity: 1; }
.ss-card__actions .ss-iconbtn {
  width: 32px; height: 32px;
  background: var(--c-bg-1);
  border: 1px solid var(--c-border);
}
@media (pointer: coarse) {
  .ss-card__actions { opacity: 1; }
  .ss-card__actions .ss-iconbtn { width: 44px; height: 44px; }
}

/* The card is a <button>; its per-card action buttons live in a sibling
   layer so we never nest interactive elements. */
.ss-card-wrap { position: relative; display: block; min-width: 0; height: 100%; }

/* -------------------------------------------------- §H.8 empty states --- */

.ss-empty {
  max-width: 440px;
  margin: 0 auto;
  padding: var(--sp-8) var(--sp-4);
  text-align: center;
  display: grid;
  justify-items: center;
}
.ss-empty__glyph { font-size: 48px; color: var(--c-text-3); margin-bottom: var(--sp-4); }
.ss-empty__glyph--danger { color: var(--c-danger); }
.ss-empty h2 {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-xl); line-height: var(--lh-xl);
  font-weight: var(--fw-semibold); color: var(--c-text-1);
}
.ss-empty p { font-size: var(--fs-md); line-height: var(--lh-md); color: var(--c-text-2); margin: 0 0 var(--sp-5); }
.ss-empty__actions { display: flex; gap: var(--sp-3); flex-wrap: wrap; justify-content: center; }

.ss-example-card { margin-top: var(--sp-7); width: 100%; max-width: 360px; }
.ss-example-card .ss-card { cursor: default; }
.ss-example-card .ss-card:hover { transform: none; }

/* ---------------------------------------------------------- §H.2 wizard -- */

.ss-wizard { max-width: 720px; margin: 0 auto; padding: var(--sp-6) var(--gutter) var(--sp-8); width: 100%; }
/* D13 — the view heading belongs in the same 720px column as the fields it
   introduces. It used to sit on the library's gridline, ~270px to the left of
   every control below it, with an empty column between them. */
.ss-viewhead--inline { padding: 0 0 var(--sp-5); }
.ss-progress > .ss-viewhead--inline { padding: 0 0 var(--sp-4); }
.ss-wizard__stack { display: grid; gap: var(--sp-5); }

.ss-templates {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--sp-3);
}
.ss-template {
  display: grid; gap: var(--sp-1); align-content: start;
  padding: var(--sp-3) var(--sp-4);
  min-height: 84px;
  text-align: left;
  background: var(--c-bg-1);
  border: 1px solid var(--c-border-sub);
  border-radius: var(--r-sm);
  color: inherit; font: inherit; cursor: pointer;
  transition: background-color var(--t-state) var(--ease-enter), border-color var(--t-state) var(--ease-enter);
}
.ss-template:hover { background: var(--c-bg-2); border-color: var(--c-border); }
.ss-template[aria-pressed="true"] { border: 1px solid var(--c-primary); background: var(--c-bg-3); }
.ss-template__name { font-size: var(--fs-md); font-weight: var(--fw-semibold); color: var(--c-text-1); }
.ss-template__desc { font-size: var(--fs-sm); line-height: var(--lh-sm); color: var(--c-text-3); }

.ss-cost {
  display: flex; align-items: flex-start; gap: var(--sp-2);
  font-size: var(--fs-sm); line-height: var(--lh-sm);
  color: var(--c-text-2);
  padding: var(--sp-3) var(--sp-4);
  background: var(--c-bg-1);
  border: 1px solid var(--c-border-sub);
  border-radius: var(--r-sm);
}
.ss-cost i { color: var(--c-text-3); margin-top: 2px; }
.ss-cost b { color: var(--c-text-1); font-weight: var(--fw-semibold); }
.ss-cost .ss-over { color: var(--c-warning); font-weight: var(--fw-semibold); }

.ss-wizard__submit { display: flex; justify-content: flex-end; gap: var(--sp-3); }
@media (max-width: 767px) {
  .ss-wizard__submit { flex-direction: column-reverse; }
  .ss-wizard__submit .ss-btn { width: 100%; }
}

/* ----------------------------------------------------- §H.3 editor shell -- */

.ss-editor {
  display: grid;
  grid-template-columns: var(--rail-now) minmax(0, 1fr) var(--inspector-now);
  /* `notices` is a RESERVED ROW, not an overlay. It is `auto`, so it is zero
     high until a notice exists and then takes exactly the height it needs,
     shrinking the `minmax(0, 1fr)` canvas row by that much. That is what
     makes it impossible for a notice to cover a control: the canvas never
     occupies the space the notice is in. A floating stack could not achieve
     this — it was measured covering the slide canvas at every scroll
     position, and the site footer's links at the bottom of the page. */
  grid-template-rows: var(--toolbar-h) auto auto minmax(0, 1fr);
  grid-template-areas:
    "toolbar toolbar toolbar"
    "banner  banner  banner"
    "notices notices notices"
    "rail    canvas  canvas";
  height: calc(100dvh - var(--nav-h));
  min-height: 520px;
  background: var(--c-bg-0);
}

.ss-etoolbar {
  grid-area: toolbar;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  height: var(--toolbar-h);
  padding: 0 var(--sp-4);
  background: var(--c-bg-1);
  border-bottom: 1px solid var(--c-border-sub);
  position: relative;
  z-index: 20;            /* below every overlay — see .ss-modal z-index */
  min-width: 0;
}
.ss-etoolbar__title {
  flex: 1 1 200px;
  min-width: 120px;
  height: 36px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  color: var(--c-text-1);
  font: inherit;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  padding: 0 var(--sp-2);
}
.ss-etoolbar__title:hover { border-color: var(--c-border-sub); }
.ss-etoolbar__title:focus { background: var(--c-bg-2); border-color: var(--c-primary); }

.ss-etoolbar__group { display: flex; align-items: center; gap: var(--sp-1); flex: none; }
.ss-etoolbar__sep { width: 1px; height: 24px; background: var(--c-border-sub); flex: none; margin: 0 var(--sp-2); }
.ss-etoolbar__spacer { flex: 1 1 auto; min-width: var(--sp-2); }

.ss-savestate {
  font-size: var(--fs-sm); line-height: var(--lh-sm);
  color: var(--c-text-3);
  white-space: nowrap;
  flex: none;
  display: inline-flex; align-items: center; gap: var(--sp-2);
}
.ss-savestate[data-state="error"] { color: var(--c-danger); }

/* --- slide rail -------------------------------------------------------- */

.ss-rail {
  grid-area: rail;
  background: var(--c-bg-1);
  border-right: 1px solid var(--c-border-sub);
  padding: var(--sp-3);
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-gutter: stable;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  min-width: 0;
}
.ss-rail__list { display: flex; flex-direction: column; gap: var(--sp-2); list-style: none; margin: 0; padding: 0; }

.ss-thumb {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  background: var(--c-bg-2);
  border: 1px solid var(--c-border-sub);
  border-radius: var(--r-sm);
  cursor: pointer;
  overflow: hidden;
  font: inherit; color: inherit; text-align: left;
  transition: border-color var(--t-micro) var(--ease-enter),
              box-shadow var(--t-micro) var(--ease-enter),
              transform var(--t-micro) var(--ease-enter);
}
.ss-thumb__surface { display: block; aspect-ratio: 16 / 9; width: 100%; position: relative; container-type: inline-size; }
.ss-thumb__surface > * { position: absolute; inset: 0; }
.ss-thumb[aria-selected="true"] { border: 2px solid var(--c-primary); box-shadow: var(--el-2); }
.ss-thumb:hover { border-color: var(--c-border); }
.ss-thumb__idx {
  flex: none;
  min-width: 15px;
  font-size: var(--fs-xs); line-height: var(--lh-xs);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--c-text-3);
}
.ss-thumb[aria-selected="true"] .ss-thumb__idx { color: var(--c-primary-txt); }
.ss-thumb__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ss-thumb__label {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  padding: var(--sp-2);
  font-size: var(--fs-sm); line-height: var(--lh-sm);
  color: var(--c-text-2);
  min-width: 0;
}
.ss-thumb__tools {
  position: absolute; top: 4px; right: 4px; z-index: 3;
  display: flex; gap: 2px;
  opacity: 0;
  transition: opacity var(--t-micro) var(--ease-enter);
}
.ss-railitem:hover .ss-thumb__tools,
.ss-railitem:focus-within .ss-thumb__tools { opacity: 1; }
.ss-thumb__tools .ss-iconbtn {
  width: 28px; height: 28px;
  background: var(--c-bg-1);
  border: 1px solid var(--c-border);
}
.ss-thumb__tools .ss-iconbtn i { font-size: 13px; }
@media (pointer: coarse) { .ss-thumb__tools { opacity: 1; } }

.ss-railitem { position: relative; min-width: 0; }
.ss-railitem[data-dragging="true"] { opacity: .4; }
.ss-railitem[data-dropbefore="true"]::before,
.ss-railitem[data-dropafter="true"]::after {
  content: "";
  position: absolute; left: 0; right: 0; height: 3px;
  background: var(--c-primary);
  border-radius: var(--r-pill);
  z-index: 5;
}
.ss-railitem[data-dropbefore="true"]::before { top: -6px; }
.ss-railitem[data-dropafter="true"]::after { bottom: -6px; }

.ss-rail__add { margin-top: var(--sp-2); }

/* --- canvas ------------------------------------------------------------ */

.ss-canvasregion {
  grid-area: canvas;
  background: var(--c-bg-0);
  display: grid;
  place-items: center;
  padding: var(--sp-6);
  overflow: auto;
  min-width: 0; min-height: 0;
}
.ss-canvas {
  /* A 1px rim, not a drop shadow. --el-3 is a black shadow, and on the
     near-black --c-bg-0 it rendered nothing at all: the slide read as a flat
     pasted rectangle rather than an object on a surface. In light mode the
     white slide on a near-white field lost its edge entirely. */
  outline: 1px solid rgba(255, 255, 255, .10);
  outline-offset: 0;
  width: 100%;
  /* `--notices-h` is published by ui/toast.js from the real height of the
     editor's notice band. Without it a notice makes the slide taller than
     the row it now has, and the region scrolls the slide out of view. */
  max-width: calc((100dvh - var(--nav-h) - var(--toolbar-h) - var(--notices-h, 0px) - (2 * var(--sp-6))) * 16 / 9);
  aspect-ratio: 16 / 9;
  background: var(--c-bg-2);
  border-radius: var(--r-sm);
  box-shadow: var(--el-3);
  overflow: hidden;
  position: relative;
  container-type: inline-size;
  flex: none;
}
.ss-canvas > * { position: absolute; inset: 0; }

/* The load-bearing rule: never narrower than 960 CSS px at >=1024 (§I). */
@media (min-width: 1024px) {
  .ss-canvas { min-width: var(--canvas-min); }
}

.ss-canvas__fallback {
  display: grid; place-content: center; gap: var(--sp-3);
  text-align: center; padding: var(--sp-6);
  color: var(--c-text-2);
}
.ss-canvas__fallback i { font-size: 32px; color: var(--c-text-3); }

/* --- inspector --------------------------------------------------------- */

.ss-inspector {
  position: fixed;
  top: var(--nav-h);
  right: 0;
  bottom: 0;
  width: min(340px, 100vw);
  z-index: 8100;
  background: var(--c-bg-1);
  border-left: 1px solid var(--c-border);
  box-shadow: var(--el-4);
  overflow-y: auto;
  overflow-x: hidden;
  min-width: 0;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  visibility: hidden;
  transition: transform var(--t-surface) var(--ease-exit), visibility 0s linear var(--t-surface);
}
.ss-inspector[data-open="true"] {
  transform: none;
  visibility: visible;
  transition: transform var(--t-surface) var(--ease-enter), visibility 0s;
}
.ss-inspector__head { display: flex; }
.ss-inspector-scrim {
  /* A click-catcher, NOT a scrim. This is a non-modal drawer: dimming the
     canvas behind it greys out the exact slide whose settings are being
     changed, so the user cannot see the effect of the control they are
     using. It stays fully transparent and only closes the drawer on click. */
  position: fixed; inset: 0; z-index: 8050;
  background: transparent;
}
.ss-inspector-scrim[hidden] { display: none; }
.ss-inspector__head {
  align-items: center; justify-content: space-between;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--c-border-sub);
}
.ss-inspector__head h2 { margin: 0; font-size: var(--fs-lg); font-weight: var(--fw-semibold); }

.ss-section { border-bottom: 1px solid var(--c-border-sub); }
.ss-section > summary {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  cursor: pointer; list-style: none;
  font-size: var(--fs-sm); line-height: var(--lh-sm);
  font-weight: var(--fw-semibold);
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--c-text-3);
}
.ss-section > summary::-webkit-details-marker { display: none; }
.ss-section > summary::after {
  content: "\f107"; font-family: "Font Awesome 6 Free"; font-weight: 900;
  margin-left: auto; transition: transform var(--t-state) var(--ease-enter);
}
.ss-section[open] > summary::after { transform: rotate(180deg); }
.ss-section__body { padding: 0 var(--sp-4) var(--sp-4); display: grid; gap: var(--sp-4); }

.ss-quickactions { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.ss-chip {
  height: 32px; padding: 0 var(--sp-3);
  border: 1px solid var(--c-border);
  border-radius: var(--r-pill);
  background: var(--c-bg-2);
  color: var(--c-text-1);
  font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-medium);
  cursor: pointer;
  transition: background-color var(--t-state) var(--ease-enter), border-color var(--t-state) var(--ease-enter);
}
.ss-chip:hover:not(:disabled) { background: var(--c-bg-3); }
.ss-chip[aria-pressed="true"] { background: var(--c-primary); border-color: var(--c-primary); color: var(--c-on-primary); }
.ss-chip:disabled { opacity: .45; cursor: not-allowed; }

/* Theme swatches — role=radiogroup / radio (§J.5). */
.ss-swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: var(--sp-2); }
.ss-swatch {
  display: grid; gap: var(--sp-1);
  padding: var(--sp-2);
  border: 1px solid var(--c-border-sub);
  border-radius: var(--r-sm);
  background: var(--c-bg-2);
  cursor: pointer;
  font: inherit; color: inherit; text-align: left;
}
.ss-swatch:hover { border-color: var(--c-border); }
.ss-swatch[aria-checked="true"] { border: 2px solid var(--c-primary); padding: calc(var(--sp-2) - 1px); }
.ss-swatch__strip { height: 26px; border-radius: var(--r-xs); display: flex; overflow: hidden; }
.ss-swatch__strip span { flex: 1; }
.ss-swatch__strip span:last-child { flex: 0 0 26%; }
.ss-swatch__name { font-size: var(--fs-xs); line-height: var(--lh-xs); color: var(--c-text-2); text-transform: capitalize; }

.ss-health { display: grid; gap: var(--sp-2); }
.ss-health__row {
  display: flex; align-items: flex-start; gap: var(--sp-2);
  font-size: var(--fs-sm); line-height: var(--lh-sm);
  color: var(--c-text-2);
}
.ss-health__row i { margin-top: 3px; }
.ss-health__row--ok i { color: var(--c-success); }
.ss-health__row--warn i { color: var(--c-warning); }

.ss-notice {
  display: flex; gap: var(--sp-2);
  padding: var(--sp-3);
  border-radius: var(--r-sm);
  font-size: var(--fs-sm); line-height: var(--lh-sm);
  background: var(--c-bg-2);
  color: var(--c-text-2);
  border: 1px solid var(--c-border-sub);
}
.ss-notice i { margin-top: 2px; flex: none; }
.ss-notice--warn { background: var(--c-warning-fill); border-color: color-mix(in srgb, var(--c-warning) 40%, transparent); }
.ss-notice--warn i { color: var(--c-warning); }
.ss-notice--info i { color: var(--c-primary-txt); }

.ss-editbanner {
  grid-area: banner;
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--gutter);
  background: var(--c-bg-2);
  border-bottom: 1px solid var(--c-border-sub);
  font-size: var(--fs-sm); color: var(--c-text-2);
}
.ss-editbanner[hidden] { display: none; }

/* ---------------------------------------------------------- §H.6 modals -- */

.ss-modal {
  position: fixed;
  inset: 0;
  z-index: 10000;   /* above the site-wide chat widget, which was clipping the
                       "Generate them" button in the cost dialog at 390px */             /* above the editor toolbar (z-index 20) — the
                                old build's toolbar painted over the variant
                                modal's header and close button */
  display: grid;
  place-items: center;
  padding: var(--sp-4);
  background: var(--c-scrim);
  backdrop-filter: blur(4px);
  animation: ss-fade var(--t-surface) var(--ease-enter);
}
.ss-modal[hidden] { display: none; }

.ss-modal__panel {
  width: min(560px, calc(100vw - 32px));
  max-height: min(720px, calc(100dvh - 64px));
  display: flex;
  flex-direction: column;
  background: var(--c-bg-1);
  border: 1px solid var(--c-border-sub);
  border-radius: var(--r-lg);
  box-shadow: var(--el-4);
  overflow: hidden;
  animation: ss-rise var(--t-surface) var(--ease-enter);
}
.ss-modal__panel--wide { width: min(880px, calc(100vw - 32px)); }
@keyframes ss-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

.ss-modal__head {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: var(--sp-5);
  border-bottom: 1px solid var(--c-border-sub);
  flex: none;
}
.ss-modal__head h2 {
  margin: 0; flex: 1;
  font-size: var(--fs-xl); line-height: var(--lh-xl);
  font-weight: var(--fw-semibold); color: var(--c-text-1);
}
.ss-modal__body {
  padding: var(--sp-5);
  overflow-y: auto;
  font-size: var(--fs-md); line-height: var(--lh-md);
  color: var(--c-text-2);
  display: grid; gap: var(--sp-4);
  min-height: 0;
}
.ss-modal__foot {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  border-top: 1px solid var(--c-border-sub);
  flex: none;
  flex-wrap: wrap;
}
.ss-modal__foot > .ss-spacer { flex: 1 1 auto; }

.ss-compare { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
.ss-compare__col { display: grid; gap: var(--sp-2); min-width: 0; }
.ss-compare__cap {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
  font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--c-text-2);
}
.ss-compare__stage {
  display: block;
  aspect-ratio: 16 / 9;
  background: var(--c-bg-2);
  border: 1px solid var(--c-border-sub);
  border-radius: var(--r-sm);
  overflow: hidden;
  position: relative;
  container-type: inline-size;
}
.ss-compare__stage > * { position: absolute; inset: 0; }
@media (max-width: 719px) { .ss-compare { grid-template-columns: 1fr; } }

/* Preview overlay */
.ss-preview__stage {
  width: min(1280px, calc(100vw - 64px));
  aspect-ratio: 16 / 9;
  background: var(--c-bg-2);
  border-radius: var(--r-sm);
  box-shadow: var(--el-4);
  overflow: hidden; position: relative;
  container-type: inline-size;
}
.ss-preview__stage > * { position: absolute; inset: 0; }
.ss-preview__bar {
  display: flex; align-items: center; justify-content: center; gap: var(--sp-4);
  margin-top: var(--sp-4);
  color: var(--c-text-2);
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
}
.ss-preview__notes {
  margin-top: var(--sp-3);
  max-width: min(1280px, calc(100vw - 64px));
  font-size: var(--fs-sm); line-height: var(--lh-sm); color: var(--c-text-2);
  max-height: 96px; overflow-y: auto;
}

/* ----------------------------------------------------------- §H.7 toast -- */

/* NOT `.toast` — see the file header. */
#ssToasts {
  position: fixed;
  top: calc(var(--nav-h) + var(--sp-4));
  right: var(--sp-4);
  /* In the EDITOR the top-right is free and the bottom-right belongs to the
     image-batch panel. Everywhere else the top-right is where the wizard's
     own controls live — a toast there covered the Sources tab strip — so
     notices move to the bottom-right, clear of the chat widget. */
  z-index: 9500;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  width: min(360px, calc(100vw - 32px));
  pointer-events: none;
}
.ss-toast {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--c-bg-2);
  border: 1px solid var(--c-border);
  border-left: 3px solid var(--c-text-3);
  border-radius: var(--r-sm);
  box-shadow: var(--el-3);
  pointer-events: auto;
  animation: ss-toast-in var(--t-state) var(--ease-enter);
}
.ss-toast[data-leaving="true"] { animation: ss-toast-out var(--t-micro) var(--ease-exit) forwards; }
@keyframes ss-toast-in  { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes ss-toast-out { to { opacity: 0; transform: translateY(8px); } }

.ss-toast--success { border-left-color: var(--c-success); }
.ss-toast--error   { border-left-color: var(--c-danger); }
.ss-toast--warning { border-left-color: var(--c-warning); }
.ss-toast--info    { border-left-color: var(--c-primary); }
.ss-toast__icon { margin-top: 2px; flex: none; font-size: 16px; }
.ss-toast--success .ss-toast__icon { color: var(--c-success); }
.ss-toast--error   .ss-toast__icon { color: var(--c-danger); }
.ss-toast--warning .ss-toast__icon { color: var(--c-warning); }
.ss-toast--info    .ss-toast__icon { color: var(--c-primary-txt); }
.ss-toast__body { flex: 1; min-width: 0; }
.ss-toast__title { font-size: var(--fs-md); font-weight: var(--fw-semibold); color: var(--c-text-1); }
.ss-toast__msg { font-size: var(--fs-sm); line-height: var(--lh-sm); color: var(--c-text-2); margin-top: 2px; overflow-wrap: anywhere; }
.ss-toast__action {
  margin-top: var(--sp-2);
  background: transparent; border: 1px solid var(--c-border); border-radius: var(--r-sm);
  color: var(--c-text-1); font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-semibold);
  height: 30px; padding: 0 var(--sp-3); cursor: pointer;
}
.ss-toast__action:hover { background: var(--c-bg-3); }

/* In-flow notices (§H.7b).
   Outside the editor a notice is part of the layout rather than a thing on
   top of it, so it cannot cover a control. `:empty` matters: the host sits
   in a `display:grid` body, and an empty div would otherwise leave a gap
   where no notice is. */
.ss-notices { display: grid; gap: var(--sp-2); }
.ss-notices:empty { display: none; }
/* The editor's band sits in its own reserved grid row under the toolbar. */
.ss-notices--editor {
  grid-area: notices;
  padding: var(--sp-2) var(--gutter);
  background: var(--c-bg-1);
  border-bottom: 1px solid var(--c-border-sub);
  /* Several failures can arrive together (an image batch reports per slide).
     The band scrolls rather than eating the canvas without limit. */
  max-height: 40vh;
  overflow-y: auto;
}
/* The band is as wide as the editor, but a sentence is not. Left unbounded,
   a notice set one line across 1376px is a measurably worse read than the
   same words in a column. */
.ss-notices--editor .ss-toast { max-width: 880px; }
/* Flatter than the floating version — it is sitting ON the surface now, not
   hovering above it, so it should not cast a shadow onto its own panel. */
.ss-toast--inflow { box-shadow: none; background: var(--c-bg-3); }

/* ------------------------------------------------- §H.7 progress panel --- */

.ss-progress {
  display: grid;
  gap: var(--sp-5);
  max-width: 720px;
  margin: 0 auto;
  padding: var(--sp-7) var(--gutter);
  width: 100%;
}
.ss-progress__head { display: flex; align-items: center; gap: var(--sp-5); flex-wrap: wrap; }
.ss-ring { width: 88px; height: 88px; flex: none; transform: rotate(-90deg); }
.ss-ring__track { fill: none; stroke: var(--c-border-sub); stroke-width: 6; }
.ss-ring__fill {
  fill: none; stroke: var(--c-primary); stroke-width: 6; stroke-linecap: round;
  transition: stroke-dashoffset var(--t-surface) var(--ease-enter);
}
.ss-progress__headings { min-width: 0; flex: 1 1 260px; }
.ss-progress__title { font-size: var(--fs-xl); line-height: var(--lh-xl); font-weight: var(--fw-semibold); color: var(--c-text-1); }
/* ONE status line. Not two. */
.ss-progress__status { font-size: var(--fs-md); line-height: var(--lh-md); color: var(--c-text-2); margin-top: var(--sp-1); }
.ss-progress__timing {
  display: flex; gap: var(--sp-4); flex-wrap: wrap;
  margin-top: var(--sp-2);
  font-size: var(--fs-sm); line-height: var(--lh-sm);
  font-variant-numeric: tabular-nums;
}
.ss-progress__elapsed { color: var(--c-text-3); }
.ss-progress__eta { color: var(--c-text-2); }

.ss-stages { display: grid; gap: var(--sp-2); list-style: none; margin: 0; padding: 0; }
.ss-stage {
  display: flex; align-items: center; gap: var(--sp-3);
  font-size: var(--fs-sm); line-height: var(--lh-sm);
  color: var(--c-text-3);
}
.ss-stage__icon { width: 16px; text-align: center; flex: none; }
.ss-stage[data-state="done"]   { color: var(--c-success); }
.ss-stage[data-state="active"] { color: var(--c-text-1); font-weight: var(--fw-medium); }

.ss-samplewrap { display: grid; gap: var(--sp-2); }
.ss-samplewrap__cap { font-size: var(--fs-sm); color: var(--c-text-3); }
.ss-sample {
  display: block;
  aspect-ratio: 16 / 9;
  background: var(--c-bg-2);
  border: 1px solid var(--c-border-sub);
  border-radius: var(--r-sm);
  overflow: hidden; position: relative;
  container-type: inline-size;
}
.ss-sample > * { position: absolute; inset: 0; }
.ss-sample[data-empty="false"] .ss-skeleton { display: none; }
.ss-indeterminate {
  position: relative; height: 4px; border-radius: var(--r-pill);
  background: var(--c-bg-3); overflow: hidden;
}
.ss-indeterminate::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 34%;
  background: var(--c-primary); border-radius: var(--r-pill);
  animation: ss-slide-x 1400ms var(--ease-enter) infinite;
}
@keyframes ss-slide-x { from { left: -34%; } to { left: 100%; } }

/* --------------------------------------------------- background status --- */

.ss-bgstatus {
  position: fixed;
  right: var(--sp-4);
  /* Clears the site-wide "Ask Keeper" widget, which is fixed bottom-right on
     every page and was sitting on this panel's Dismiss button. */
  bottom: calc(var(--sp-4) + 68px);
  z-index: 7000;
  width: 340px;
  max-width: calc(100vw - 32px);
  padding: var(--sp-4);
  background: var(--c-bg-2);
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  box-shadow: var(--el-3);
  display: grid;
  gap: var(--sp-2);
}
.ss-bgstatus:empty { display: none; border: 0; padding: 0; box-shadow: none; background: none; }
.ss-bgstatus__title { font-size: var(--fs-md); font-weight: var(--fw-semibold); color: var(--c-text-1); }
.ss-bgstatus__sub { font-size: var(--fs-sm); line-height: var(--lh-sm); color: var(--c-text-2); }

/* -------------------------------------------------------- §I responsive -- */

/*
 * THE INSPECTOR IS ALWAYS A DRAWER.
 *
 * It used to dock above 1600px, and that produced the defect a critic found
 * and I had reported as a win: canvas 1144px at 1280, 1156px at 1440 but
 * 1096px at 1760 — buying a bigger monitor made your slide smaller, because
 * above 1600 a fixed 340px pane appeared and the canvas absorbed the loss.
 * Any docking threshold has that step in it somewhere. Keeping the inspector
 * as an overlay at every width makes the canvas monotonic in the viewport:
 * Measured at a 900px viewport height, where the canvas is height-bound
 * above 1440: 1024 -> 960 | 1280 -> 1048 | 1440 -> 1176 | 1600..1920 -> 1188.
 * On a taller window it keeps growing: 1920x1200 -> 1596x898. The property
 * that matters is that it NEVER shrinks as the viewport grows, and the shoot
 * asserts that rather than trusting this comment.
 */
:root { --inspector-now: 0px; }

@media (max-width: 1759px) { :root { --rail-now: 230px; } }
@media (max-width: 1599px) { :root { --rail-now: 200px; } }

@media (min-width: 1024px) {
  .ss-editor { grid-template-areas: "toolbar toolbar toolbar" "banner banner banner" "notices notices notices" "rail canvas canvas"; }
}
/* 1280–1439: a NARROWER rail, not an icon rail.
   §I called for an "icon rail" at this range and what shipped was the full
   slide artwork scaled to ~60px — four coloured smudges with number badges and
   no titles, at the commonest laptop width there is. It keeps a readable
   thumbnail AND its title; the canvas pays 168px for navigation that works. */
@media (max-width: 1439px) {
  :root { --rail-now: 168px; }
  .ss-thumb__label { font-size: var(--fs-xs); line-height: var(--lh-xs); padding: var(--sp-1) var(--sp-2); }
  .ss-rail { padding: var(--sp-2); }
}

/* 1024–1279 and below: stacked.  Rail becomes a horizontal strip below the
   canvas, inspector becomes a bottom sheet.  This is the 1024 layout the
   audit found strictly better than the old 1280 three-pane one. */
@media (max-width: 1279px) {
  :root { --rail-now: 0px; --gutter: 24px; }
  .ss-editor {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: var(--toolbar-h) auto auto minmax(0, 1fr) auto;
    grid-template-areas: "toolbar" "banner" "notices" "canvas" "rail";
    height: calc(100dvh - var(--nav-h));
  }
  .ss-rail {
    flex-direction: row;
    align-items: center;
    height: 96px;
    border-right: 0;
    border-top: 1px solid var(--c-border-sub);
    overflow-x: auto; overflow-y: hidden;
    scroll-snap-type: x proximity;
    padding: var(--sp-2);
  }
  .ss-rail__list { flex-direction: row; }
  .ss-railitem { scroll-snap-align: center; }
  .ss-thumb__label {
    position: absolute; top: 4px; left: 4px; z-index: 2;
    display: inline-flex; padding: 1px 5px;
    background: var(--c-scrim); border-radius: var(--r-xs);
  }
  .ss-thumb__idx { color: var(--c-text-1); }
  .ss-thumb__name { display: none; }
  .ss-thumb { width: 124px; }
  .ss-thumb__label { display: none; }
  .ss-rail__add { margin: 0 0 0 var(--sp-2); }
  .ss-rail__add .ss-btn { height: 64px; width: 64px; padding: 0; }
  .ss-rail__add .ss-btn span { display: none; }
  .ss-canvas { max-width: none; }
  .ss-canvasregion { padding: var(--sp-6) var(--sp-6) var(--sp-4); }

  .ss-inspector {
    top: auto;
    left: 0; right: 0; bottom: 0;
    width: 100%;
    height: 60dvh;
    border-left: 0;
    border-top: 1px solid var(--c-border);
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    transform: translateY(100%);
  }
  .ss-shell { grid-template-columns: minmax(0, 1fr); }
  .ss-sidebar {
    border-right: 0;
    border-bottom: 1px solid var(--c-border-sub);
    flex-direction: row; flex-wrap: wrap; align-items: center;
    gap: var(--sp-4);
    padding: var(--sp-3) var(--gutter);
  }
  .ss-sidebar__nav { flex-direction: row; }
  .ss-quota { grid-auto-flow: column; gap: var(--sp-5); align-items: center; }
  .ss-quota__row { min-width: 140px; }
}

@media (max-width: 1023px) {
  .ss-canvas { min-width: 0; }
  /* Export is the primary action and must never be the thing that falls off
     the edge. Below 1024 the per-slide icons move into the overflow menu —
     where every one of them already exists — so Preview and Export keep
     their place. Adding a fourth icon here is what pushed Export off-screen
     at 768 and reintroduced the exact defect the audit named. */
  .ss-etoolbar__group--slide { display: none; }
  .ss-savestate { display: none; }
  .ss-rail { height: 80px; }
  .ss-thumb { width: 104px; }
  .ss-canvasregion { padding: var(--sp-4); }
  .ss-inspector { height: 72dvh; }
}

@media (max-width: 767px) {
  :root { --gutter: 16px; }
  .ss-etoolbar { gap: var(--sp-1); padding: 0 var(--sp-2); }
  /* Everything that does not fit moves into the overflow menu rather than
     being clipped off-screen — the old build clipped "Export PPTX" at 768px. */
  .ss-etoolbar__group--wide { display: none; }
  .ss-etoolbar__title { flex: 1 1 80px; min-width: 60px; }
  .ss-savestate { display: none; }
  .ss-rail { height: 72px; }
  .ss-thumb { width: 92px; }
  /* A 44x44 touch target cannot share a 92px thumbnail with its own artwork,
     and shrinking it below 44px fails J.5. The actions move to the overflow
     menu, where they act on the selected slide. */
  .ss-thumb__tools { display: none; }
  .ss-inspector { height: 100dvh; top: 0; border-radius: 0; }
  .ss-modal { padding: var(--sp-2); align-items: end; }
  .ss-modal__panel { width: 100%; max-height: calc(100dvh - 24px); }
  .ss-quota { grid-auto-flow: row; }
  .ss-sidebar { gap: var(--sp-3); }
  .ss-viewhead { padding: var(--sp-5) var(--gutter) var(--sp-4); }
  .ss-grid { grid-template-columns: 1fr; }
  #ssToasts { top: auto; bottom: var(--sp-4); left: var(--sp-4); right: var(--sp-4); width: auto; }
}

/* Overflow menu (used at <=767px and for secondary editor actions). */
.ss-menu { position: relative; }
.ss-menu__panel {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 8200;
  min-width: 220px;
  padding: var(--sp-2);
  background: var(--c-bg-2);
  border: 1px solid var(--c-border);
  border-radius: var(--r-sm);
  box-shadow: var(--el-3);
  display: grid; gap: 2px;
}
.ss-menu__panel[hidden] { display: none; }
.ss-menu__item {
  display: flex; align-items: center; gap: var(--sp-3);
  width: 100%; height: 40px; padding: 0 var(--sp-3);
  border: 0; border-radius: var(--r-xs);
  background: transparent; color: var(--c-text-1);
  font: inherit; text-align: left; cursor: pointer;
}
.ss-menu__item i { width: 18px; text-align: center; color: var(--c-text-3); }
.ss-menu__item:hover:not(:disabled) { background: var(--c-bg-3); }
.ss-menu__item:disabled { opacity: .45; cursor: not-allowed; }

/* ---------------------------------------------- landing: example output -- */

.ss-proof { display: grid; gap: var(--sp-4); }
.ss-proof__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--sp-4); }
.ss-proof__slide {
  aspect-ratio: 16 / 9;
  border-radius: var(--r-sm);
  box-shadow: var(--el-2);
  padding: 8%;
  /* D25 — the three examples ran at three internal scales and three different
     content top-edges, so the row read as one finished slide flanked by two
     drafts. One scale, one top alignment, container-relative so all three
     stay identical whatever the column width. */
  container-type: inline-size;
  display: flex; flex-direction: column; justify-content: flex-start; gap: .5em;
  overflow: hidden;
  font-family: var(--c-font);
}
.ss-proof__slide h3 { margin: 0; font-size: 7.4cqw; line-height: 1.16; font-weight: 700; letter-spacing: -0.01em; }
.ss-proof__slide p  { margin: 0; font-size: 3.6cqw; line-height: 1.4; opacity: .92; }
.ss-proof__stat { font-size: 13cqw; line-height: 1; font-weight: 700; margin-bottom: .1em; }
.ss-proof__rule { flex: none; }
.ss-proof__rule { width: 2.4em; height: 3px; border-radius: 2px; }
.ss-proof__cap { font-size: var(--fs-sm); color: var(--c-text-3); }

/* The editor owns the whole width: the app sidebar is a library/wizard
   concern and would eat 248px of canvas.  §I's breakpoint table is solved
   for a canvas with no app sidebar beside it. */
.ss-app[data-view="editor"] .ss-sidebar { display: none; }
.ss-app[data-view="editor"] .ss-shell { grid-template-columns: minmax(0, 1fr); }
.ss-app[data-view="editor"] .ss-main { overflow: hidden; }

.ss-ringwrap { position: relative; width: 88px; height: 88px; flex: none; display: grid; place-items: center; }
.ss-ringwrap .ss-ring { position: absolute; inset: 0; width: 100%; height: 100%; }
.ss-ringwrap__pct {
  position: relative;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--c-text-1);
  font-variant-numeric: tabular-nums;
}

/* Theme picker: Auto first, then 5 dark and 4 light (spec §C.3/C.5). */
.ss-swatches__head {
  grid-column: 1 / -1;
  margin: var(--sp-2) 0 0;
  font-size: var(--fs-xs); line-height: var(--lh-xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--c-text-3);
}
.ss-swatch__strip--auto {
  display: grid; place-items: center;
  background: linear-gradient(135deg, var(--c-primary), color-mix(in srgb, var(--c-primary) 40%, var(--c-bg-3)));
  color: var(--c-on-primary);
}
.ss-swatch__strip--auto i { font-size: 13px; }
.ss-swatch__cap { font-size: var(--fs-xs); line-height: var(--lh-xs); color: var(--c-text-3); }
.ss-swatch[aria-checked="true"] .ss-swatch__cap { color: var(--c-text-2); }

/* ------------------------------------------- image batch status panel --- */

.ss-bgstatus__row { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; }
.ss-bgstatus__row > div { min-width: 0; }
.ss-ringwrap--sm { width: 56px; height: 56px; }
.ss-ringwrap--sm .ss-ringwrap__pct { font-size: var(--fs-sm); }
.ss-bgstatus__actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.ss-bgstatus__actions .ss-btn { flex: 1 1 auto; }

/* Every failure named, with the server's own reason (§H.9). */
.ss-faillist { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-3); }
.ss-faillist li {
  display: grid;
  /* A fixed action column: `auto` sized to each row's own text, so the two
     "Go to slide" buttons sat 27px out of line with each other. */
  grid-template-columns: minmax(0, 1fr) 118px;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3);
  background: var(--c-bg-2);
  border: 1px solid var(--c-border-sub);
  border-radius: var(--r-sm);
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
  color: var(--c-text-2);
}
.ss-faillist b { color: var(--c-text-1); }
.ss-faillist .ss-btn { width: 100%; }

/* ------------------------------------------------- source ingestion --- */

.ss-tabs {
  display: flex;
  gap: var(--sp-1);
  padding: var(--sp-1);
  background: var(--c-bg-2);
  border-radius: var(--r-sm);
  overflow-x: auto;
  scrollbar-width: none;
}
.ss-tabs::-webkit-scrollbar { display: none; }
.ss-tab {
  flex: 1 1 auto;
  min-height: 34px;
  padding: 0 var(--sp-3);
  border: 0;
  border-radius: var(--r-xs);
  background: transparent;
  color: var(--c-text-2);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--t-state) var(--ease-enter), color var(--t-state) var(--ease-enter);
}
.ss-tab:hover { color: var(--c-text-1); }
.ss-tab[aria-selected="true"] {
  background: var(--c-bg-3);
  color: var(--c-text-1);
  font-weight: var(--fw-semibold);
  box-shadow: inset 0 -2px 0 var(--c-primary);
}
.ss-tab:not([aria-selected="true"]) { color: var(--c-text-3); }
.ss-tabpane { display: grid; gap: var(--sp-3); margin-top: var(--sp-3); }
.ss-tabpane[hidden] { display: none; }

/* File inputs: the native control is unstyleable across browsers, so it gets
   the same box as every other input and nothing more clever than that. */
.ss-input[type="file"] { height: auto; padding: var(--sp-2) var(--sp-3); line-height: 1.6; }
.ss-input[type="file"]::file-selector-button {
  margin-right: var(--sp-3);
  height: 28px;
  padding: 0 var(--sp-3);
  border: 1px solid var(--c-border);
  border-radius: var(--r-xs);
  background: var(--c-bg-1);
  color: var(--c-text-1);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  cursor: pointer;
}

/* fetch() cannot report upload progress; a 10 MB PDF with no feedback reads
   as a hang, so uploads go through XHR and fill this. */
.ss-progressbar {
  height: 4px;
  border-radius: var(--r-pill);
  background: var(--c-bg-3);
  overflow: hidden;
}
.ss-progressbar > div {
  height: 100%;
  width: 0%;
  border-radius: var(--r-pill);
  background: var(--c-primary);
  transition: width var(--t-state) linear;
}

.ss-sourcelist { list-style: none; margin: var(--sp-3) 0 0; padding: 0; display: grid; gap: var(--sp-2); }
.ss-sourcelist:empty { display: none; }
.ss-source {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  background: var(--c-bg-2);
  border: 1px solid var(--c-border-sub);
  border-radius: var(--r-sm);
}
.ss-source > i { color: var(--c-text-3); }
.ss-source__body { display: grid; gap: 2px; min-width: 0; }
.ss-source__title {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--c-text-1);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* --------------------------------------- light mode over the dark nav --- */

/*
 * index1.css is dark-only and is not ours to re-cut, so in light mode the
 * shared navigation stays dark. Rather than let that read as a bug, it is
 * treated as a deliberate fixed dark band: the app draws a matching dark
 * strip behind the nav's full width and a crisp edge under it, which is a
 * common and legitimate pattern (dark chrome, light workspace).
 */
:root[data-ui-theme="light"] .nav-container,
:root[data-ui-theme="light"] body > .promo-banner,
:root[data-ui-theme="light"] .ss-navband { --ss-navband: #0D0C1D; }

@media (prefers-color-scheme: light) {
  :root:not([data-ui-theme="dark"]) .ss-app { --ss-navband: #0D0C1D; }
  :root:not([data-ui-theme="dark"]) .ss-shell {
    border-top: 1px solid rgba(13, 12, 29, .18);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .6);
  }
  /* The app's own top edge picks up the nav's dark, so the seam is a chosen
     line rather than an accident of two stylesheets meeting. */
  :root:not([data-ui-theme="dark"]) .ss-sidebar { border-right-color: rgba(13, 12, 29, .12); }
  :root:not([data-ui-theme="dark"]) .ss-etoolbar { border-bottom-color: rgba(13, 12, 29, .14); }
}
:root[data-ui-theme="light"] .ss-shell {
  border-top: 1px solid rgba(13, 12, 29, .18);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .6);
}

/* In light mode the page surface and a white slide are within a few percent
   of each other, so the slide's edge survives only on its shadow. The canvas
   REGION drops to the raised-surface tone so a light slide reads as a sheet
   on a desk — the same relationship dark mode already had for free. */
@media (prefers-color-scheme: light) {
  :root:not([data-ui-theme="dark"]) .ss-canvasregion { background: var(--c-bg-2); }
}
:root[data-ui-theme="light"] .ss-canvasregion { background: var(--c-bg-2); }

.ss-health__row--err i { color: var(--c-danger); }
/* Health copy must never be truncated mid-sentence: it wraps instead. */
.ss-health__row span { min-width: 0; overflow-wrap: anywhere; }

@media (prefers-color-scheme: light) {
  :root:not([data-ui-theme="dark"]) .ss-canvas { outline-color: rgba(13, 12, 29, .14); }
}
:root[data-ui-theme="light"] .ss-canvas { outline-color: rgba(13, 12, 29, .14); }

/* D17 — the shared "Ask Keeper" launcher is fixed bottom-right on every page
   at z-index 2147483000, so it cannot be out-stacked; it has to be hidden.
   It was covering the canvas corner, the thumbnail strip, and — worst — the
   "Generate them" button in the spend-confirmation modal at 390px, which is
   the control that spends the user's image allowance.
   PRODUCT DECISION FOR THE LEAD: this suppresses a site-wide widget on one
   tool's editor and under any modal. It stays visible on the deck library,
   the wizard and the guest landing page. */
/*
 * The 84px lane that used to be here did not work, and could not have: the
 * widget is `position: fixed`, so it collides with whatever sits at the
 * viewport's bottom-right at ANY scroll position. Padding below the grid is
 * simply scrolled past. Measured with the last card scrolled into view:
 * `cardsCovered=["Website Rebuild Proposal"]`.
 *
 * So the widget is suppressed across the whole app shell, not just the
 * editor. It remains on the guest landing page, and support is reachable
 * from every other page on the site.
 *
 * FLAGGED FOR THE LEAD: this widens an earlier approval (editor + modals) to
 * the deck library and the wizard. It is one line to revert.
 */
.ss-app ~ .pk-root,
body:has(.ss-app) .pk-root,
body:has(.ss-modal) .pk-root { display: none !important; }

/* ------------------------------------------------ D18: theme as a slide --- */

.ss-swatches { grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: var(--sp-3); }
.ss-swatch {
  display: grid;
  gap: 0;
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--c-border-sub);
}
.ss-swatch[aria-checked="true"] {
  border: 1px solid var(--c-primary);
  padding: 0;
  box-shadow: 0 0 0 1px var(--c-primary);
}
.ss-swatch__slide {
  display: block;
  position: relative;
  aspect-ratio: 16 / 9;
  padding: 11% 10%;
  container-type: inline-size;
  overflow: hidden;
}
.ss-swatch__accent {
  display: block; width: 22%; height: 4px; border-radius: 2px; margin-bottom: 7%;
}
.ss-swatch__head {
  display: block;
  font-size: clamp(9px, 11cqw, 15px);
  line-height: 1.12;
  font-weight: var(--fw-bold);
  letter-spacing: -0.01em;
}
.ss-swatch__sub {
  display: block; margin-top: 4%;
  font-size: clamp(6px, 5.4cqw, 9px); line-height: 1.2;
}
.ss-swatch__chip {
  position: absolute; right: 8%; bottom: 10%;
  width: 26%; height: 22%; border-radius: 3px;
}
.ss-swatch__slide--auto {
  display: grid; place-items: center; gap: 6px; text-align: center;
  background: linear-gradient(135deg, var(--c-primary), color-mix(in srgb, var(--c-primary) 45%, var(--c-bg-3)));
  color: var(--c-on-primary);
}
.ss-swatch__slide--auto i { font-size: clamp(12px, 12cqw, 20px); }
.ss-swatch__autotext { font-size: clamp(8px, 6.4cqw, 11px); line-height: 1.25; font-weight: var(--fw-medium); }
.ss-swatch__foot {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  background: var(--c-bg-2);
  border-top: 1px solid var(--c-border-sub);
}
.ss-swatch__name {
  font-size: var(--fs-sm); line-height: var(--lh-sm);
  font-weight: var(--fw-medium); color: var(--c-text-1);
  text-transform: capitalize;
}
.ss-swatch__tag {
  font-size: var(--fs-xs); line-height: var(--lh-xs); font-weight: var(--fw-semibold);
  color: var(--c-primary-txt); white-space: nowrap;
}
.ss-swatch__tag--quiet { color: var(--c-text-3); font-weight: var(--fw-regular); }

/* --------------------------------------------- D8: a real upload control --- */

.ss-drop {
  display: grid;
  justify-items: center;
  gap: var(--sp-1);
  padding: var(--sp-5) var(--sp-4);
  border: 1px dashed var(--c-border);
  border-radius: var(--r-sm);
  background: var(--c-bg-2);
  cursor: pointer;
  text-align: center;
  transition: background-color var(--t-state) var(--ease-enter), border-color var(--t-state) var(--ease-enter);
}
.ss-drop:hover, .ss-drop[data-over="true"] { background: var(--c-bg-3); border-color: var(--c-primary); }
.ss-drop[hidden] { display: none; }
.ss-drop > i { font-size: 20px; color: var(--c-text-3); }
.ss-drop__main { font-size: var(--fs-md); color: var(--c-text-1); }
.ss-drop__link { color: var(--c-primary-txt); text-decoration: underline; }
.ss-drop__types { font-size: var(--fs-xs); line-height: var(--lh-xs); color: var(--c-text-3); }
.ss-drop:focus-within { outline: 2px solid var(--c-focus); outline-offset: 2px; }

.ss-filechip {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  background: var(--c-bg-2);
  border: 1px solid var(--c-border-sub);
  border-radius: var(--r-sm);
}
.ss-filechip[hidden] { display: none; }
.ss-filechip > i { color: var(--c-text-3); }
.ss-filechip__name {
  flex: 1; min-width: 0;
  font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--c-text-1);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ------------------------------------------- canvas block editing (§8) --- */

.ss-blocklayer { position: absolute; inset: 0; pointer-events: none; z-index: 5; }

/* The grid is SHOWN while dragging. Everything snaps to the 12x9 cells —
   that is the price of preview and .pptx never disagreeing — so the snapping
   has to read as intentional rather than as laggy imprecision. */
.ss-blockgrid { position: absolute; inset: 0; opacity: 0; transition: opacity var(--t-state) var(--ease-enter); }
.ss-canvas.is-dragging .ss-blockgrid {
  opacity: 1;
  background-image:
    repeating-linear-gradient(to right,  rgba(127,127,170,.30) 0 1px, transparent 1px calc(100% / 12)),
    repeating-linear-gradient(to bottom, rgba(127,127,170,.30) 0 1px, transparent 1px calc(100% / 9));
}

.ss-blockhover {
  position: absolute;
  border: 1px dashed var(--c-primary);
  border-radius: 2px;
  background: color-mix(in srgb, var(--c-primary) 8%, transparent);
  pointer-events: none;
}
.ss-blockbox {
  position: absolute;
  border: 2px solid var(--c-primary);
  border-radius: 2px;
  pointer-events: none;
}
.ss-blockbox[data-overridden="true"] { border-style: solid; box-shadow: 0 0 0 1px var(--c-bg-0); }
.ss-blockhandle {
  position: absolute;
  width: 10px; height: 10px;
  margin: -5px 0 0 -5px;
  background: var(--c-bg-0);
  border: 2px solid var(--c-primary);
  border-radius: 2px;
  pointer-events: none;
}
.ss-blockhandle--nw { top: 0;    left: 0; }
.ss-blockhandle--n  { top: 0;    left: 50%; }
.ss-blockhandle--ne { top: 0;    left: 100%; }
.ss-blockhandle--e  { top: 50%;  left: 100%; }
.ss-blockhandle--se { top: 100%; left: 100%; }
.ss-blockhandle--s  { top: 100%; left: 50%; }
.ss-blockhandle--sw { top: 100%; left: 0; }
.ss-blockhandle--w  { top: 50%;  left: 0; }

/* touch-action is only suppressed where dragging exists (>=1024px). Below
   that the canvas must keep scrolling the page. */
@media (min-width: 1024px) {
  .ss-canvas.is-dragging { touch-action: none; user-select: none; }
}

/* --------------------------------------------- D11: the wait has a shape --- */

/* A 360px empty grey rectangle occupied more than half the viewport for most
   of the minute. A skeleton in the slide's own proportions says "a slide is
   being made for you" instead of "nothing is here". */
.ss-skeleton {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; justify-content: center;
  gap: 2.6%;
  padding: 8% 8%;
}
.ss-skeleton span { display: block; border-radius: 4px; background: var(--c-bg-3); position: relative; overflow: hidden; }
.ss-skeleton__kicker { width: 18%; height: 3.4%; background: color-mix(in srgb, var(--c-primary) 45%, var(--c-bg-3)) !important; }
.ss-skeleton__head   { width: 78%; height: 11%; }
.ss-skeleton__head--short { width: 52%; }
.ss-skeleton__sub    { width: 40%; height: 4.6%; margin-top: 2%; }
.ss-skeleton__chip   { width: 26%; height: 16%; margin-top: auto; align-self: flex-end; }
.ss-skeleton span::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--c-text-3) 22%, transparent), transparent);
  transform: translateX(-100%);
  animation: ss-shimmer 1800ms var(--ease-enter) infinite;
}
.ss-skeleton__head::after  { animation-delay: 120ms; }
.ss-skeleton__sub::after   { animation-delay: 240ms; }
.ss-skeleton__chip::after  { animation-delay: 360ms; }
@keyframes ss-shimmer { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
  .ss-skeleton span::after { animation: none !important; opacity: .35; transform: none !important; }
}

.ss-progress__foot { display: flex; justify-content: center; }

/* The current stage needs to read as an indicator, not a text-cursor artefact. */
.ss-stage[data-state="active"] { color: var(--c-text-1); }
.ss-stage[data-state="active"] .ss-stage__icon { color: var(--c-primary-txt); }

/* D12 — say what changed, above the panes. */
.ss-comparesum {
  font-size: var(--fs-md); line-height: var(--lh-md);
  color: var(--c-text-1);
  padding: var(--sp-3) var(--sp-4);
  background: var(--c-bg-2);
  border: 1px solid var(--c-border-sub);
  border-radius: var(--r-sm);
}
.ss-compare__cap { align-items: baseline; }

/* ================================================= storyboard view ===== */

/* The deck as a sequence. Every other action in the editor is single-slide;
   fixing an AI deck is mostly a sequencing job, and a 168px rail is not a
   tool for it. */
.ss-editor[data-storyboard="true"] .ss-rail,
.ss-editor[data-storyboard="true"] .ss-canvasregion { display: none; }
.ss-editor[data-storyboard="true"] {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "toolbar" "banner" "notices" "canvas";
}

.ss-storyboard {
  grid-area: canvas;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--c-bg-0);
  overflow: hidden;
}
.ss-storyboard[hidden] { display: none; }
.ss-storyboard__bar {
  display: flex; align-items: center; gap: var(--sp-3);
  flex-wrap: wrap;
  padding: var(--sp-4) var(--gutter) var(--sp-2);
}
.ss-storyboard__count {
  font-size: var(--fs-lg); line-height: var(--lh-lg);
  font-weight: var(--fw-semibold); color: var(--c-text-1);
}
.ss-storyboard__actions { display: flex; gap: var(--sp-2); margin-left: auto; flex-wrap: wrap; }
.ss-storyboard__hint { padding: 0 var(--gutter) var(--sp-4); }

.ss-sbgrid {
  list-style: none; margin: 0;
  padding: 0 var(--gutter) var(--sp-8);
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--sp-5);
  overflow-y: auto;
  min-height: 0;
}
.ss-sbitem { position: relative; min-width: 0; }
.ss-sbitem[data-dragging="true"] { opacity: .4; }
.ss-sbitem[data-dropbefore="true"]::before,
.ss-sbitem[data-dropafter="true"]::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 3px;
  background: var(--c-primary); border-radius: var(--r-pill);
}
.ss-sbitem[data-dropbefore="true"]::before { left: calc(var(--sp-5) / -2 - 1px); }
.ss-sbitem[data-dropafter="true"]::after { right: calc(var(--sp-5) / -2 - 1px); }

.ss-sbcard {
  display: flex; flex-direction: column;
  height: 100%;
  background: var(--c-bg-1);
  border: 1px solid var(--c-border-sub);
  border-radius: var(--r-md);
  overflow: hidden;
  cursor: pointer;
  position: relative;
  transition: border-color var(--t-micro) var(--ease-enter),
              background-color var(--t-micro) var(--ease-enter),
              box-shadow var(--t-micro) var(--ease-enter);
}
.ss-sbcard:hover { border-color: var(--c-border); box-shadow: var(--el-2); }
.ss-sbcard[aria-selected="true"] {
  border-color: var(--c-primary);
  background: var(--c-bg-3);
  box-shadow: 0 0 0 1px var(--c-primary);
}
.ss-sbcard__surface {
  display: block; width: 100%; aspect-ratio: 16 / 9;
  position: relative; overflow: hidden;
  background: var(--c-bg-2);
  border-bottom: 1px solid var(--c-border-sub);
  container-type: inline-size;
}
.ss-sbcard__surface > * { position: absolute; inset: 0; width: 100%; height: 100%; }
.ss-sbcard__check {
  position: absolute; top: var(--sp-2); left: var(--sp-2); z-index: 3;
  width: 22px; height: 22px;
  display: grid; place-items: center;
  border-radius: var(--r-xs);
  border: 1px solid var(--c-border);
  background: var(--c-bg-0);
  color: transparent;
  font-size: 11px;
  /* Hidden until it is useful. Painted permanently over the artwork it sat on
     top of the slide's own first characters — the same defect as the rail's
     index badge. */
  opacity: 0;
  transition: opacity var(--t-micro) var(--ease-enter);
}
.ss-sbcard:hover .ss-sbcard__check,
.ss-sbcard:focus-visible .ss-sbcard__check,
.ss-sbcard[aria-selected="true"] .ss-sbcard__check { opacity: 1; }
@media (pointer: coarse) { .ss-sbcard__check { opacity: 1; } }
.ss-sbcard[aria-selected="true"] .ss-sbcard__check {
  background: var(--c-primary); border-color: var(--c-primary); color: var(--c-on-primary);
}
.ss-sbcard__meta { display: flex; align-items: baseline; gap: var(--sp-2); padding: var(--sp-3) var(--sp-3) var(--sp-1); min-width: 0; }
.ss-sbcard__idx {
  flex: none; font-size: var(--fs-xs); font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums; color: var(--c-text-3);
}
.ss-sbcard__title {
  min-width: 0; font-size: var(--fs-md); font-weight: var(--fw-medium); color: var(--c-text-1);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ss-sbcard__tags { display: flex; flex-wrap: wrap; gap: var(--sp-1); padding: 0 var(--sp-3) var(--sp-3); margin-top: auto; }

@media (max-width: 767px) {
  .ss-sbgrid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--sp-3); }
}

/* -------------------------------------------------- D23: 390px toolbar --- */

/* Export is the product's payoff and never leaves the toolbar; below 768 it
   keeps its icon and drops its label rather than disappearing into an
   unlabelled overflow menu. */
@media (max-width: 767px) {
  .ss-export__label { display: none; }
  .ss-export { padding: 0 var(--sp-3); }
  /* Preview matters MORE on a phone than on a desktop — it is the only way
     to see a slide at a usable size there. It keeps its place as an icon
     rather than being the control that gets dropped. */
  .ss-etoolbar__group--wide { display: flex; }
  .ss-etoolbar__group--wide #ssPreview { padding: 0; width: 36px; }
  .ss-etoolbar__group--wide #ssPreview span,
  .ss-etoolbar__group--wide #ssPreview { font-size: 0; }
  .ss-etoolbar__group--wide #ssPreview i { font-size: 18px; }
  .ss-inspector-toggle { display: none; }
  /* Reclaim the dead space around a 358x201 canvas. */
  .ss-canvasregion { padding: var(--sp-2); }
  /* A truncated title must look truncated, not like a data error. */
  .ss-etoolbar__title { text-overflow: ellipsis; }
}
.ss-etoolbar__title { text-overflow: ellipsis; overflow: hidden; white-space: nowrap; }

/* ------------------------------------------- D24: a crafted empty state --- */

/* Every empty state was a hairline outline glyph at ~60px, in a product for
   making beautiful things. This is a stack of three slides drawn in the app's
   own accent — the thing the user is about to make, not a folder icon. */
.ss-emptyart {
  position: relative;
  width: 168px; height: 108px;
  margin-bottom: var(--sp-5);
}
.ss-emptyart span {
  position: absolute;
  border-radius: var(--r-sm);
  border: 1px solid var(--c-border);
  background: var(--c-bg-2);
  box-shadow: var(--el-2);
}
.ss-emptyart span:nth-child(1) { inset: 18px 30px 22px 0;  transform: rotate(-7deg); opacity: .5; }
.ss-emptyart span:nth-child(2) { inset: 12px 12px 14px 18px; transform: rotate(4deg); opacity: .75; }
.ss-emptyart span:nth-child(3) {
  inset: 0 6px 24px 26px;
  background: var(--c-bg-1);
  border-color: var(--c-primary);
  display: grid; align-content: center; gap: 7px; padding: 0 14px;
}
.ss-emptyart span:nth-child(3)::before,
.ss-emptyart span:nth-child(3)::after {
  content: ""; display: block; height: 7px; border-radius: 3px;
}
.ss-emptyart span:nth-child(3)::before { width: 30%; background: var(--c-primary); height: 5px; }
.ss-emptyart span:nth-child(3)::after  { width: 78%; background: var(--c-text-3); opacity: .55; }

/* The one piece of proof-of-value on the page had been pushed below the fold
   by a vertically centred block. It sits beside the call to action now. */
.ss-empty--proof {
  max-width: 900px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 320px);
  align-items: center;
  gap: var(--sp-7);
  text-align: left;
  justify-items: start;
  padding-top: var(--sp-7);
}
.ss-empty--proof .ss-empty__actions { justify-content: flex-start; }
.ss-empty--proof .ss-example-card { margin-top: 0; max-width: none; }
@media (max-width: 899px) {
  .ss-empty--proof { grid-template-columns: minmax(0, 1fr); text-align: center; justify-items: center; }
  .ss-empty--proof .ss-empty__actions { justify-content: center; }
}
.ss-emptyart--search span:nth-child(3) { border-color: var(--c-border); }
.ss-emptyart--search span:nth-child(3)::before { background: var(--c-text-3); opacity: .45; }


/* --------------------------------- light mode: cards need a ground ----- */

/* Library cards measured rgb(255,255,255) on an rgb(255,255,255) page — no
   edge, no elevation, nothing separating a card from the surface it is on. */
@media (prefers-color-scheme: light) {
  :root:not([data-ui-theme="dark"]) {
    --c-bg-0: #F4F6FB;          /* the PAGE steps back so panels can sit on it */
    --c-bg-1: #FFFFFF;          /* cards and panels are the light surface */
    --c-bg-2: #F1F3F9;
    --c-bg-3: #E4E8F2;
  }
  :root:not([data-ui-theme="dark"]) .ss-card,
  :root:not([data-ui-theme="dark"]) .ss-sbcard {
    border-color: rgba(16, 20, 40, .12);
  }
}
:root[data-ui-theme="light"] {
  --c-bg-0: #F4F6FB;
  --c-bg-1: #FFFFFF;
  --c-bg-2: #F1F3F9;
  --c-bg-3: #E4E8F2;
}
:root[data-ui-theme="light"] .ss-card,
:root[data-ui-theme="light"] .ss-sbcard { border-color: rgba(16, 20, 40, .12); }

/* ------------------------------ storyboard: checkbox out of the artwork -- */

/* The selection box was painted over the thumbnail and sat on the slide's own
   first characters ("e quarter in four numbers"). This is the THIRD time this
   exact defect has appeared — rail badge, storyboard checkbox, and again on
   selection — so the rule is now explicit: nothing in the app's chrome is
   ever painted over a slide's artwork. It lives in the meta row. */
.ss-sbcard__check {
  position: static;
  opacity: 1;
  width: 16px; height: 16px;
  flex: none;
  font-size: 9px;
  align-self: center;
}
.ss-sbcard__meta { align-items: center; }

/* A ring showing 100% in success purple beside "2 failed" tells the user the
   run went fine. When anything failed it is warn-coloured and shows the
   ratio, not a percentage. */
.ss-ringwrap[data-tone="warn"] .ss-ring__fill { stroke: var(--c-warning); }
.ss-ringwrap[data-tone="warn"] .ss-ringwrap__pct { color: var(--c-warning); font-size: var(--fs-sm); }

/* Shift-click for a range was also dragging a text selection across the
   thumbnails, so a multi-select left blue highlight all over the slides. */
.ss-sbcard, .ss-thumb { user-select: none; -webkit-user-select: none; }


body:not([data-ss-view="editor"]) #ssToasts {
  top: auto;
  bottom: calc(var(--sp-4) + 76px);
}
@media (max-width: 767px) {
  body:not([data-ss-view="editor"]) #ssToasts { bottom: calc(var(--sp-4) + 76px); }
}
.ss-faillist__text { display: grid; gap: 2px; min-width: 0; }
