/* Scrolling Stories components. Classes use the `ss-` prefix and read only tokens.css.
   Spec and usage rules: docs/design-system/components.md */

/* ---- Base ---- */
.ss-root {
  background: var(--ss-paper);
  color: var(--ss-ink);
  font: var(--ss-weight-regular) var(--ss-text-md) / var(--ss-leading-ui) var(--ss-font-ui);
  -webkit-font-smoothing: antialiased;
}
.ss-root *, .ss-root *::before, .ss-root *::after { box-sizing: border-box; }
.ss-root :focus-visible { outline: 2px solid var(--ss-focus); outline-offset: 2px; }
/* A control may be smaller to look at than it is to hit. These grow the box that answers a
   press to --ss-touch without moving anything, and only up and down: controls in a row sit side
   by side, so a wider one would steal its neighbour's press. Each of them keeps room above and
   below for the overshoot; a chip row widens its own row gap to make it. */
@media (pointer: coarse) {
  .ss-root .ss-chip,
  .ss-root .ss-segmented > *,
  .ss-root button.ss-tag,
  .ss-root .ss-switch { position: relative; }
  .ss-root .ss-chip::before,
  .ss-root .ss-segmented > *::before,
  .ss-root button.ss-tag::before,
  .ss-root .ss-switch::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    height: var(--ss-touch);
    transform: translateY(-50%);
  }
  /* The switch is the one that is also too narrow; nothing sits within 4px of it. */
  .ss-root .ss-switch::before { left: -4px; right: -4px; }
}
.ss-root a { color: var(--ss-forest); text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--ss-forest) 35%, transparent); text-underline-offset: 3px; }
.ss-root a:hover { color: var(--ss-forest-hover); text-decoration-color: currentColor; }
.ss-vh { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* A component class that sets `display` outranks the user agent's rule for [hidden], so an
   `.ss-inline-error[hidden]` still takes up space. Restore what the attribute promises. */
.ss-root [hidden] { display: none !important; }
/* The reader's skip link, on every shell: off-screen until focused, then a real control. */
.ss-skip { position: absolute; left: var(--ss-space-2); top: -100px; z-index: var(--ss-z-toast); padding: var(--ss-space-2) var(--ss-space-4);
  border-radius: var(--ss-radius-md); background: var(--ss-print); color: var(--ss-ink); box-shadow: var(--ss-shadow-menu); }
.ss-skip:focus { top: var(--ss-space-2); }

/* ---- Type ---- */
.ss-title-xl, .ss-title-l, .ss-title-m, .ss-title-s, .ss-title-xs {
  font-family: var(--ss-font-display); font-weight: var(--ss-weight-medium);
  color: var(--ss-ink-heading); line-height: var(--ss-leading-tight); margin: 0;
}
.ss-title-xl { font-size: var(--ss-display-xl); letter-spacing: -0.01em; }
.ss-title-l  { font-size: var(--ss-display-l); letter-spacing: -0.01em; }
.ss-title-m  { font-size: var(--ss-display-m); }
.ss-title-s  { font-size: var(--ss-display-s); line-height: 1.2; }
.ss-title-xs { font-size: var(--ss-display-xs); line-height: 1.25; }
.ss-chapter  { font-family: var(--ss-font-display); font-style: italic; color: var(--ss-ink-heading); }
.ss-label    { font-size: var(--ss-text-xs); font-weight: var(--ss-weight-semibold); color: var(--ss-ink-2); }
.ss-hint     { font-size: var(--ss-text-xs); color: var(--ss-ink-3); }
.ss-meta     { font-size: var(--ss-text-xs); color: var(--ss-ink-3); }
.ss-eyebrow  { font-size: var(--ss-text-xs); font-weight: var(--ss-weight-semibold); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ss-forest); }
.ss-code     { font-family: var(--ss-font-mono); font-size: var(--ss-text-sm); }

/* ---- Buttons ---- */
.ss-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--ss-space-2);
  height: var(--ss-control-md); padding: 0 var(--ss-space-4);
  border: 1px solid var(--ss-line-control); border-radius: var(--ss-radius-md);
  background: var(--ss-print); color: var(--ss-ink);
  font: var(--ss-weight-medium) var(--ss-text-sm) / 1 var(--ss-font-ui);
  text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: background var(--ss-duration-fast) var(--ss-ease), border-color var(--ss-duration-fast) var(--ss-ease);
}
.ss-root a.ss-btn { text-decoration: none; color: var(--ss-ink); }
.ss-btn:hover { background: var(--ss-fill); }
.ss-btn svg { width: var(--ss-icon-sm); height: var(--ss-icon-sm); flex-shrink: 0; }
.ss-btn--primary, .ss-root a.ss-btn--primary { background: var(--ss-forest); border-color: var(--ss-forest); color: var(--ss-white); font-weight: var(--ss-weight-semibold); }
.ss-btn--primary:hover { background: var(--ss-forest-hover); border-color: var(--ss-forest-hover); }
.ss-btn--primary:active { background: var(--ss-forest-active); }
.ss-btn--ghost, .ss-root a.ss-btn--ghost { background: transparent; border-color: transparent; color: var(--ss-ink-2); }
.ss-btn--ghost:hover { background: var(--ss-fill); color: var(--ss-ink); }
.ss-btn--danger, .ss-root a.ss-btn--danger { background: transparent; border-color: transparent; color: var(--ss-terracotta-text); }
.ss-btn--danger:hover { background: var(--ss-terracotta-tint); }
.ss-btn--danger-fill { background: var(--ss-terracotta-text); border-color: var(--ss-terracotta-text); color: var(--ss-white); font-weight: var(--ss-weight-semibold); }
/* Sign-in providers (#229): the fill is the provider's own colour, from tokens.css — Google's
   white button with the coloured G and a grey border, Apple's black and Facebook's blue with
   the mark inverted to white. Hover darkens the brand colour a step instead of swapping to
   --ss-fill. The label keeps 4.5:1 on each (tests/unit/test_design_tokens.py). */
.ss-btn--google, .ss-root a.ss-btn--google { background: var(--ss-brand-google); border-color: var(--ss-line-control); color: var(--ss-ink); }
.ss-btn--google:hover { background: color-mix(in srgb, var(--ss-brand-google) 94%, var(--ss-ink)); }
.ss-btn--apple, .ss-root a.ss-btn--apple { background: var(--ss-brand-apple); border-color: var(--ss-brand-apple); color: var(--ss-white); }
.ss-btn--apple:hover { background: color-mix(in srgb, var(--ss-brand-apple) 86%, var(--ss-white)); }
.ss-btn--facebook, .ss-root a.ss-btn--facebook { background: var(--ss-brand-facebook); border-color: var(--ss-brand-facebook); color: var(--ss-white); }
.ss-btn--facebook:hover { background: color-mix(in srgb, var(--ss-brand-facebook) 88%, var(--ss-ink)); }
.ss-btn--apple .ss-provider__mark, .ss-btn--facebook .ss-provider__mark { filter: brightness(0) invert(1); }
.ss-btn--sm { height: var(--ss-control-sm); padding: 0 var(--ss-space-3); }
.ss-btn--lg { height: var(--ss-control-lg); padding: 0 var(--ss-space-6); font-size: var(--ss-text-md); }
.ss-btn--icon { width: var(--ss-control-md); padding: 0; border-color: transparent; background: transparent; color: var(--ss-ink-2); }
.ss-btn--icon.ss-btn--sm { width: var(--ss-control-sm); }
.ss-btn[disabled], .ss-btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
@media (pointer: coarse) { .ss-btn, .ss-btn--icon { min-height: var(--ss-touch); min-width: var(--ss-touch); } }

/* ---- Fields ---- */
.ss-field { display: flex; flex-direction: column; gap: var(--ss-space-1); }
.ss-input, .ss-select, .ss-textarea {
  width: 100%; min-height: var(--ss-control-md); padding: 0 var(--ss-space-3);
  border: 1px solid var(--ss-line-control); border-radius: var(--ss-radius-md);
  background: var(--ss-print); color: var(--ss-ink);
  font: var(--ss-text-field) / var(--ss-leading-ui) var(--ss-font-ui);
}
.ss-textarea { padding: var(--ss-space-2) var(--ss-space-3); min-height: 5rem; resize: vertical; }
.ss-input::placeholder, .ss-textarea::placeholder { color: var(--ss-ink-3); }
.ss-select { appearance: none; padding-right: var(--ss-space-8);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235a5448' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center; }
.ss-field--error .ss-input, .ss-field--error .ss-textarea { border-color: var(--ss-terracotta-text); }
.ss-field__error { font-size: var(--ss-text-xs); color: var(--ss-terracotta-text); }
/* Catches a field a surface styles itself, or one a script writes before it is given
   `.ss-input`. Checkboxes and the rest are left alone: nothing is typed into them. */
@media (pointer: coarse) {
  .ss-root input:not([type="checkbox"], [type="radio"], [type="range"], [type="file"], [type="color"]),
  .ss-root select,
  .ss-root textarea { font-size: var(--ss-text-field); }
  /* A 34px box has to be hit before it can be typed in, and a slider's 16px track more so —
     hence no `[type="range"]` here, unlike the font size above. */
  .ss-input, .ss-select,
  .ss-root input:not([type="checkbox"], [type="radio"], [type="file"], [type="color"]),
  .ss-root select { min-height: var(--ss-touch); }
}

/* Switch: every on/off setting. Markup: <button role="switch" aria-checked="true" class="ss-switch"> */
.ss-switch { position: relative; width: 38px; height: 22px; border-radius: var(--ss-radius-round); border: 1px solid var(--ss-line-control); background: var(--ss-fill); cursor: pointer; padding: 0; flex-shrink: 0; }
.ss-switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--ss-white); box-shadow: var(--ss-shadow-raised); transition: transform var(--ss-duration-fast) var(--ss-ease); }
.ss-switch[aria-checked="true"] { background: var(--ss-forest); border-color: var(--ss-forest); }
.ss-switch[aria-checked="true"]::after { transform: translateX(16px); }

/* ---- Choice ---- */
/* Chips: pick one named preset from a set (motion, text style). role="radiogroup" + role="radio". */
.ss-chips { display: flex; flex-wrap: wrap; gap: var(--ss-space-2); }
/* 7px of hit area above and below each chip, so two rows of them need 14px between. */
@media (pointer: coarse) { .ss-chips { row-gap: 14px; align-items: center; min-height: var(--ss-touch); } }
.ss-chip { display: inline-flex; align-items: center; gap: var(--ss-space-1); height: 30px; padding: 0 var(--ss-space-3);
  border: 1px solid var(--ss-line-control); border-radius: var(--ss-radius-md); background: var(--ss-print);
  font-size: var(--ss-text-sm); color: var(--ss-ink); cursor: pointer; }
/* A chip is on whichever way it says so: one of a set (`aria-checked`) or a toggle on its own. */
.ss-chip[aria-checked="true"], .ss-chip[aria-pressed="true"] {
  background: var(--ss-ink); border-color: var(--ss-ink); color: var(--ss-white); }
.ss-chip__default { color: var(--ss-ink-3); }
.ss-chip[aria-checked="true"] .ss-chip__default { color: color-mix(in srgb, var(--ss-white) 70%, transparent); }
/* Segmented: switch between 2–4 views or modes. role="tablist" or radiogroup. */
.ss-segmented { display: inline-flex; gap: 2px; padding: 3px; border-radius: 9px; background: var(--ss-fill); }
.ss-segmented > * { padding: 5px var(--ss-space-4); border-radius: 7px; border: 0; background: transparent; font: var(--ss-weight-medium) var(--ss-text-sm) / 1.4 var(--ss-font-ui); color: var(--ss-ink-2); cursor: pointer; }
.ss-segmented > [aria-selected="true"], .ss-segmented > [aria-checked="true"] { background: var(--ss-print); color: var(--ss-ink); box-shadow: var(--ss-shadow-raised); }

/* ---- Status tags ---- */
.ss-tag { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 9px; border-radius: var(--ss-radius-sm);
  font-size: var(--ss-text-xs); font-weight: var(--ss-weight-medium); white-space: nowrap; background: var(--ss-fill); color: var(--ss-ink-2); }
.ss-tag--dot::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.ss-tag--published { background: var(--ss-moss-tint); color: var(--ss-moss); }
.ss-tag--scheduled, .ss-tag--attention { background: var(--ss-ochre-tint); color: var(--ss-ochre-text); }
.ss-tag--private, .ss-tag--members { background: var(--ss-heather-tint); color: var(--ss-heather); }
.ss-tag--featured { background: var(--ss-forest-tint); color: var(--ss-forest); }
.ss-tag--error { background: var(--ss-terracotta-tint); color: var(--ss-terracotta-text); }

/* A small unread count beside a navigation item (PCB-23). The number is text, not a dot:
   the bell has to say how many without a screen reader having to read a label that repeats it. */
.ss-count { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px;
  padding: 0 6px; border-radius: 10px; background: var(--ss-forest); color: var(--ss-print);
  font-size: var(--ss-text-xs); font-weight: var(--ss-weight-medium); line-height: 1; }

/* ---- Surfaces ---- */
.ss-card { background: var(--ss-print); border: 1px solid var(--ss-line); border-radius: var(--ss-radius-lg); }
.ss-card--pad { padding: var(--ss-space-6); }
.ss-divider { height: 1px; background: var(--ss-line); border: 0; margin: 0; }
/* A photo shown on a light surface. Never on the stage or in the reader. */
.ss-print { display: inline-block; background: var(--ss-white); padding: 3px; box-shadow: var(--ss-shadow-print); }
.ss-print > img { display: block; object-fit: cover; }
.ss-placeholder { display: flex; align-items: center; justify-content: center; gap: var(--ss-space-2); background: var(--ss-fill); color: var(--ss-ink-2); font-size: var(--ss-text-xs); }

/* ---- Menus, dialogs, sheets ---- */
.ss-menu { background: var(--ss-print); border: 1px solid var(--ss-line); border-radius: var(--ss-radius-lg); box-shadow: var(--ss-shadow-menu); padding: var(--ss-space-1); min-width: 200px; z-index: var(--ss-z-menu); }
.ss-menu__item { display: flex; align-items: center; gap: var(--ss-space-3); width: 100%; min-height: 36px; padding: 0 var(--ss-space-3); border: 0; border-radius: 6px; background: transparent; font: var(--ss-text-md) var(--ss-font-ui); color: var(--ss-ink); text-align: left; cursor: pointer; }
.ss-menu__item:hover, .ss-menu__item:focus-visible { background: var(--ss-fill); }
@media (pointer: coarse) { .ss-menu__item { min-height: var(--ss-touch); } }
.ss-root a.ss-menu__item { color: var(--ss-ink); text-decoration: none; }
.ss-menu__item--danger { color: var(--ss-terracotta-text); }
.ss-menu__desc { display: block; font-size: var(--ss-text-xs); color: var(--ss-ink-3); }
.ss-scrim { position: fixed; inset: 0; background: var(--ss-scrim); z-index: var(--ss-z-dialog); display: flex; align-items: center; justify-content: center; padding: var(--ss-space-4); }
.ss-dialog { width: min(440px, 100%); background: var(--ss-print); border-radius: var(--ss-radius-lg); box-shadow: var(--ss-shadow-dialog); padding: var(--ss-space-6); }
.ss-dialog__title { font: var(--ss-weight-semibold) var(--ss-text-lg) / 1.3 var(--ss-font-ui); margin: 0 0 var(--ss-space-2); }
.ss-dialog__body { color: var(--ss-ink-2); margin: 0 0 var(--ss-space-6); }
.ss-dialog__actions { display: flex; justify-content: flex-end; gap: var(--ss-space-2); }
.ss-sheet { position: fixed; left: 0; right: 0; bottom: 0; max-height: 85dvh; overflow: auto; background: var(--ss-print); border-radius: var(--ss-radius-xl) var(--ss-radius-xl) 0 0; box-shadow: var(--ss-shadow-dialog); z-index: var(--ss-z-sheet); }
.ss-sheet__grip { width: 36px; height: 4px; border-radius: 2px; background: var(--ss-line-control); margin: var(--ss-space-2) auto; }

/* ---- Panel (a dialog a page fills itself) and popover menus ---- */
/* A dialog whose body scrolls, so a long list is never cut off at the bottom of the window
   with nothing on screen to say more follows. */
.ss-panel {
  display: flex;
  flex-direction: column;
  width: min(760px, 100%);
  max-height: min(86dvh, 900px);
  background: var(--ss-print);
  border-radius: var(--ss-radius-lg);
  box-shadow: var(--ss-shadow-dialog);
}
.ss-panel__head {
  display: flex;
  align-items: center;
  gap: var(--ss-space-3);
  padding: var(--ss-space-4) var(--ss-space-5);
  border-bottom: 1px solid var(--ss-line);
}
.ss-panel__body {
  flex: 1 1 auto;
  overflow: auto;
  padding: var(--ss-space-5);
  display: flex;
  flex-direction: column;
  gap: var(--ss-space-6);
}
.ss-panel__foot {
  display: flex;
  align-items: center;
  gap: var(--ss-space-3);
  padding: var(--ss-space-4) var(--ss-space-5);
  border-top: 1px solid var(--ss-line);
}
.ss-panel > .ss-inline-error { padding: 0 var(--ss-space-5) var(--ss-space-4); }

/* A "More" menu. `ssMenu` puts it on the body and sets left/top, so it is never clipped by a
   card that hides its own overflow. It is opened from a control, so it has to outrank whatever
   that control is on: at --ss-z-menu it was drawn behind the beats editor's panel, which is a
   sheet, and the beat's ⋯ menu could not be seen or pressed on a phone at all. */
.ss-menu--pop { position: absolute; z-index: var(--ss-z-dialog); }
/* On a phone a panel is a bottom sheet, as the inspector and the library are
   (components.md § Menus, dialogs, and sheets). `:has` keeps this off the confirm dialogs,
   which share the scrim but stay centred. */
@media (max-width: 599px) {
  .ss-scrim:has(.ss-panel) { align-items: flex-end; padding: 0; }
  .ss-panel {
    width: 100%;
    max-height: 92dvh;
    border-radius: var(--ss-radius-xl) var(--ss-radius-xl) 0 0;
    padding-bottom: env(safe-area-inset-bottom);
  }
}

/* ---- Feedback ---- */
.ss-toast-region { position: fixed; left: 50%; bottom: calc(var(--ss-space-6) + env(safe-area-inset-bottom)); transform: translateX(-50%); z-index: var(--ss-z-toast); display: flex; flex-direction: column; gap: var(--ss-space-2); width: min(520px, calc(100vw - 2rem)); }
@media (max-width: 959px) { .ss-toast-region { bottom: calc(var(--ss-tabbar-h) + var(--ss-space-3) + env(safe-area-inset-bottom)); } }
.ss-toast { display: flex; align-items: center; gap: var(--ss-space-3); padding: var(--ss-space-3) var(--ss-space-4); border-radius: var(--ss-radius-md); background: var(--ss-ink); color: var(--ss-ink-on-dark); box-shadow: var(--ss-shadow-menu); font-size: var(--ss-text-sm); }
.ss-toast__action { margin-left: auto; background: none; border: 0; color: var(--ss-focus-on-dark); font: var(--ss-weight-semibold) var(--ss-text-sm) var(--ss-font-ui); cursor: pointer; }
/* Undo is often the only way back, so it is a full target; the card tightens to pay for it. */
@media (pointer: coarse) {
  .ss-toast { padding-block: var(--ss-space-1); }
  .ss-toast__action { min-height: var(--ss-touch); min-width: var(--ss-touch); padding: 0 var(--ss-space-2); }
}
.ss-banner { display: flex; align-items: center; gap: var(--ss-space-3); padding: var(--ss-space-3) var(--ss-space-4); font-size: var(--ss-text-sm); border-bottom: 1px solid var(--ss-line); }
.ss-banner--info { background: var(--ss-forest-tint); }
.ss-banner--attention { background: var(--ss-ochre-tint); }
.ss-banner--blocked { background: var(--ss-terracotta-tint); }
.ss-banner__actions { margin-left: auto; display: flex; gap: var(--ss-space-2); }
.ss-inline-error { display: flex; gap: var(--ss-space-2); align-items: flex-start; font-size: var(--ss-text-sm); color: var(--ss-terracotta-text); }
.ss-empty { text-align: center; padding: var(--ss-space-12) var(--ss-space-6); }
.ss-empty__title { font-family: var(--ss-font-display); font-size: var(--ss-display-s); color: var(--ss-ink-heading); margin: 0 0 var(--ss-space-2); }
.ss-empty__body { color: var(--ss-ink-2); margin: 0 auto var(--ss-space-4); max-width: 36ch; }
/* Two buttons in a centred empty state: laid out by whitespace they touch once they wrap. */
.ss-empty__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--ss-space-2); }
.ss-skeleton { background: linear-gradient(90deg, var(--ss-fill), var(--ss-fill-highlight), var(--ss-fill)); background-size: 200% 100%; animation: ss-shimmer 1.4s linear infinite; border-radius: var(--ss-radius-sm); }
@keyframes ss-shimmer { to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .ss-skeleton { animation: none; } }

/* ---- Notice ---- */
/* A message inside a card or a panel. Not `.ss-banner`, which is a state of the whole page
   under the top bar, and not `.ss-inline-error`, which sits against one control. */
.ss-notice {
  padding: var(--ss-space-3) var(--ss-space-4);
  border-radius: var(--ss-radius-md);
  background: var(--ss-fill);
  color: var(--ss-ink);
  font-size: var(--ss-text-md);
}
.ss-notice--error { background: var(--ss-terracotta-tint); color: var(--ss-terracotta-text); }
.ss-notice--warning { background: var(--ss-ochre-tint); color: var(--ss-ochre-text); }
.ss-notice--success { background: var(--ss-moss-tint); color: var(--ss-moss); }
.ss-notice--info { background: var(--ss-forest-tint); color: var(--ss-forest); }

/* ---- Checklist (publish) ---- */
/* The button is `white-space: nowrap` and shrinkable, so on a narrow card it used to shrink
   under its own label and print it across the heading beside it. It asks for its own width and
   drops to a line of its own instead. */
.ss-check { display: flex; flex-wrap: wrap; gap: var(--ss-space-3); padding: var(--ss-space-3) 0; border-top: 1px solid var(--ss-line); }
.ss-check > .ss-btn { flex: 0 0 auto; margin-left: auto; }
.ss-check__mark { width: 22px; height: 22px; border-radius: 50%; display: flex; align-items: center; justify-content: center; flex-shrink: 0; background: var(--ss-moss-tint); color: var(--ss-moss); }
.ss-check--todo .ss-check__mark { background: var(--ss-ochre-tint); color: var(--ss-ochre-text); }
.ss-check--blocked .ss-check__mark { background: var(--ss-terracotta-tint); color: var(--ss-terracotta-text); }

/* ---- Timeline ---- */
.ss-tl { position: relative; background: var(--ss-print); }
.ss-tl__row { display: flex; align-items: center; margin-bottom: var(--ss-space-2); }
.ss-tl__label { width: 100px; flex-shrink: 0; font-size: var(--ss-text-xs); font-weight: var(--ss-weight-medium); color: var(--ss-ink-3); }
.ss-tl__track { position: relative; flex: 1; }
.ss-tl__beat { position: absolute; top: 0; height: 44px; display: flex; align-items: center; gap: 7px; padding: 0 6px; overflow: hidden;
  border-radius: var(--ss-radius-sm); border-left: 3px solid var(--ss-lane-photo); background: var(--ss-lane-photo-tint); font-size: var(--ss-text-xs); font-weight: var(--ss-weight-medium); }
.ss-tl__beat--text { border-left-color: var(--ss-lane-text); background: var(--ss-lane-text-tint); }
.ss-tl__beat img { width: 32px; height: 24px; object-fit: cover; border-radius: var(--ss-radius-xs); flex-shrink: 0; }
.ss-tl__text { position: absolute; top: 0; height: 26px; border-radius: 4px; border: 1px solid var(--ss-lane-text); background: var(--ss-white); font: italic var(--ss-text-xs) / 24px var(--ss-font-display); padding: 0 var(--ss-space-2); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.ss-tl__keyframe { position: absolute; top: 9px; width: 8px; height: 8px; background: var(--ss-lane-text); border: 1.5px solid var(--ss-white); transform: rotate(45deg); }
.ss-tl__layer { position: absolute; top: 0; height: 24px; display: flex; align-items: center; gap: 5px; padding: 0 6px; border-radius: 4px; color: var(--ss-white); font-size: var(--ss-text-xs); overflow: hidden; white-space: nowrap; }
.ss-tl__layer--map { background: var(--ss-lane-map); }
.ss-tl__layer--overlay { background: var(--ss-lane-overlay); }
.ss-tl__layer--backdrop { background: var(--ss-lane-backdrop); }
.ss-tl__layer--advanced { background: var(--ss-lane-advanced); }
.ss-tl__chapter { position: absolute; top: 0; height: 20px; display: flex; align-items: center; gap: 5px; padding-left: 5px; border-left: 2px solid var(--ss-ochre); font: italic var(--ss-text-sm) var(--ss-font-display); color: var(--ss-ink-heading); white-space: nowrap; }
.ss-tl__playhead { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--ss-terracotta); pointer-events: none; }
/* A timeline block is a button, and `aria-selected` is not valid on one: the selected beat
   marks itself with `aria-current`. */
.ss-tl [aria-current="true"] { outline: 2px solid var(--ss-forest); outline-offset: 1px; }

/* ---- Reader chrome (renderer) ---- */
.ss-chrome { background: var(--ss-chrome-bg); -webkit-backdrop-filter: blur(var(--ss-chrome-blur)); backdrop-filter: blur(var(--ss-chrome-blur)); color: var(--ss-ink-on-dark); border-radius: var(--ss-radius-xl); }
.ss-chrome--pill { border-radius: var(--ss-radius-round); height: 36px; display: inline-flex; align-items: center; gap: 6px; padding: 0 14px; font-size: var(--ss-text-sm); font-weight: var(--ss-weight-semibold); }
.ss-chrome :focus-visible, .ss-chrome [aria-current="true"] { outline-color: var(--ss-focus-on-dark); color: var(--ss-focus-on-dark); }
@media (prefers-reduced-transparency: reduce) { .ss-chrome { background: var(--ss-chrome-bg-strong); backdrop-filter: none; } }

/* ---- Icons ---- */
/* One symbol from static/icons/icons.svg, drawn by {% icon %}. The size comes from the
   tag's width/height; the colour is inherited, so an icon inside a primary button is white
   and one inside a danger menu item is terracotta with no extra rule. */
.ss-icon { display: inline-block; vertical-align: -0.15em; flex-shrink: 0; }

/* ---- Layout helpers ---- */
/* Two shells every v2 page is built inside. The rest of a page's layout belongs to its own
   surface stylesheet; these are only the things every surface agreed on. */
.ss-page { max-width: var(--ss-content-max); margin: 0 auto; padding: var(--ss-space-10) var(--ss-space-12); }
.ss-stack { display: flex; flex-direction: column; gap: var(--ss-space-4); }
.ss-row { display: flex; align-items: center; gap: var(--ss-space-2); }
.ss-spacer { flex: 1 1 auto; }
@media (max-width: 599px) { .ss-page { padding: var(--ss-space-6) var(--ss-space-4); } }
