/* ===========================================================================
   NOW PLAYING - the look
   ---------------------------------------------------------------------------
   Built the way an iOS app is built, so it feels familiar on the phone it
   lives on:

   - System type (SF on Apple devices), sized on Apple's text styles, with
     tracking that tightens as text grows.
   - Inset grouped lists, like Settings. Things that belong together share a
     rounded group; a header names it, a footnote explains it.
   - One tint colour for anything you can press, and nothing else coloured.
     The user's photo is the most colourful thing on screen.
   - Translucent chrome. The navigation bar is a material that content
     scrolls underneath, and it only appears once something is under it.
   - Follows the system light and dark appearance.
   =========================================================================== */

/* The slide itself still draws its words in these faces, so they stay loaded
   even though the interface no longer uses them. */
@font-face {
  font-family: 'Instrument Serif';
  src: url('../assets/fonts/instrument-serif-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Instrument Serif';
  src: url('../assets/fonts/instrument-serif-400-italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: 'DM Sans';
  src: url('../assets/fonts/dm-sans-var.woff2') format('woff2');
  font-weight: 100 1000;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Cormorant Garamond';
  src: url('../assets/fonts/cormorant-garamond-var.woff2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Montserrat';
  src: url('../assets/fonts/montserrat-var.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Figtree';
  src: url('../assets/fonts/figtree-var.woff2') format('woff2');
  font-weight: 300 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('../assets/fonts/jetbrains-mono-var.woff2') format('woff2');
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

/* --- Tokens --------------------------------------------------------------
   Apple's system colours, light then dark. */

:root {
  --bg: #F2F2F7;
  --bg-2: #FFFFFF;
  --bg-3: #F2F2F7;
  --fill: rgba(118, 118, 128, 0.12);
  --fill-strong: rgba(118, 118, 128, 0.2);
  --label: #000000;
  --label-2: rgba(60, 60, 67, 0.6);
  --label-3: rgba(60, 60, 67, 0.3);
  --sep: rgba(60, 60, 67, 0.29);
  --tint: #FF2D55;
  --tint-soft: rgba(255, 45, 85, 0.12);
  --on-tint: #FFFFFF;
  --thumb: #FFFFFF;
  --material: rgba(249, 249, 249, 0.78);
  --material-edge: rgba(0, 0, 0, 0.12);
  --shadow: 0 8px 28px rgba(0, 0, 0, 0.12), 0 1px 3px rgba(0, 0, 0, 0.08);
  --stage: #E5E5EA;

  --font: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  --r-group: 12px;
  --r-button: 14px;
  --r-control: 10px;

  /* Critically damped: settles without overshoot. Close to a spring with
     damping 1.0 and a response of about 0.35s. */
  --ease: cubic-bezier(0.25, 1, 0.5, 1);
  --t-press: 100ms;
  --t-ui: 280ms;
  --t-screen: 380ms;

  --tap: 44px;
  --gutter: 16px;
  --nav: 52px;

  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #000000;
    --bg-2: #1C1C1E;
    --bg-3: #2C2C2E;
    --fill: rgba(118, 118, 128, 0.24);
    --fill-strong: rgba(118, 118, 128, 0.36);
    --label: #FFFFFF;
    --label-2: rgba(235, 235, 245, 0.6);
    --label-3: rgba(235, 235, 245, 0.3);
    --sep: rgba(84, 84, 88, 0.6);
    --tint: #FF375F;
    --tint-soft: rgba(255, 55, 95, 0.18);
    --thumb: #FFFFFF;
    --material: rgba(30, 30, 30, 0.72);
    --material-edge: rgba(255, 255, 255, 0.1);
    --shadow: 0 8px 28px rgba(0, 0, 0, 0.5), 0 1px 3px rgba(0, 0, 0, 0.4);
    --stage: #0A0A0A;
  }
}

@media (prefers-contrast: more) {
  :root { --sep: var(--label-2); --material: var(--bg-2); }
}

/* --- Reset -------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }

body {
  background: var(--bg);
  color: var(--label);
  font: 400 17px/1.29 var(--font);
  letter-spacing: -0.022em;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none;
}

img { max-width: 100%; display: block; }
[hidden] { display: none !important; }
button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
button { -webkit-user-select: none; user-select: none; }

:focus-visible { outline: 2px solid var(--tint); outline-offset: 2px; }

/* --- Type ----------------------------------------------------------------
   Apple's text styles. Tracking tightens as size grows. */

.large-title {
  margin: 0;
  font-size: 34px;
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: -0.026em;
}
.subtitle { margin: 4px 0 0; color: var(--label-2); font-size: 17px; }

.footnote {
  margin: 0;
  padding: 7px var(--gutter) 0;
  color: var(--label-2);
  font-size: 13px;
  line-height: 1.38;
  letter-spacing: -0.006em;
}

.num { font-variant-numeric: tabular-nums; }

/* --- App frame ----------------------------------------------------------- */

#app {
  position: relative;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* The bar is a material floating over the screen. It is see-through at the
   top of a page and becomes a material once content slides under it, so it
   only separates when there is something to separate. */
.topbar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 30;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  height: calc(var(--nav) + env(safe-area-inset-top, 0px));
  padding: env(safe-area-inset-top, 0px) 8px 0;
  border-bottom: 0.5px solid transparent;
  transition: background-color var(--t-ui) var(--ease), border-color var(--t-ui) var(--ease);
}
.topbar.is-scrolled {
  background: var(--material);
  border-bottom-color: var(--sep);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
}
.topbar__left { justify-self: start; display: flex; align-items: center; min-width: 0; }
.topbar__right { justify-self: end; display: flex; align-items: center; }
.topbar__title {
  font-size: 17px;
  font-weight: 600;
  white-space: nowrap;
  opacity: 0;
  transition: opacity var(--t-ui) var(--ease);
}
/* The page's own large title has scrolled away, so the bar names it. */
.topbar.is-scrolled .topbar__title { opacity: 1; }

.screen {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: calc(var(--nav) + env(safe-area-inset-top, 0px)) var(--gutter)
           calc(32px + env(safe-area-inset-bottom, 0px));
}

/* Screens move like a navigation stack: forward slides in from the right,
   back slides in from the left, so leaving goes the way arriving came. */
.screen.is-push { animation: push-in var(--t-screen) var(--ease) both; }
.screen.is-pop { animation: pop-in var(--t-screen) var(--ease) both; }
@keyframes push-in { from { transform: translateX(28%); opacity: 0; } }
@keyframes pop-in { from { transform: translateX(-28%); opacity: 0; } }

.page { display: flex; flex-direction: column; gap: 28px; width: 100%; }
.page__head { padding: 4px 4px 0; }

.section { display: flex; flex-direction: column; }
.section__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin: 0;
  padding: 0 var(--gutter) 7px;
  color: var(--label-2);
  font-size: 13px;
  letter-spacing: -0.006em;
  text-transform: uppercase;
}
.section__value { font-variant-numeric: tabular-nums; text-transform: none; }

/* --- Groups and rows: the inset grouped list ----------------------------- */

.group {
  display: flex;
  flex-direction: column;
  background: var(--bg-2);
  border-radius: var(--r-group);
  overflow: hidden;
}
.group--pad { padding: 12px var(--gutter); gap: 12px; }

.row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: var(--tap);
  padding: 10px var(--gutter);
  border: none;
  background: transparent;
  color: var(--label);
  text-align: left;
  font-size: 17px;
  transition: background-color var(--t-press) linear;
}
button.row { cursor: pointer; }
/* Highlight the moment a finger lands, not when it lifts. */
button.row:active { background: var(--fill-strong); transition: none; }

/* A hairline between rows, starting where the text starts. */
.group > * + * { position: relative; }
.group > * + *::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  left: var(--inset, var(--gutter));
  height: 0.5px;
  background: var(--sep);
  pointer-events: none;
}
.group--art { --inset: 76px; }

.row__main { flex: 1; min-width: 0; display: block; }
.row__title, .row__sub {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.row__sub { margin-top: 1px; color: var(--label-2); font-size: 15px; letter-spacing: -0.016em; }
.row__value {
  flex: none;
  color: var(--label-2);
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}
.row__value--stack { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.row .icon--chevron { color: var(--label-3); width: 14px; height: 14px; }

.row.is-selected,
.row-wrap:has(> .row.is-selected) { background: var(--tint-soft); }
.row-wrap > .row.is-selected { background: none; }
.row.is-selected .row__title { color: var(--tint); font-weight: 600; }

/* A row with buttons at its end: the row itself and its trailing actions. */
.row-wrap { display: flex; align-items: center; padding-right: 6px; }
.row-wrap > .row { flex: 1; min-width: 0; }
.row-wrap .btn--icon { color: var(--label-2); }

.art {
  width: 48px;
  height: 48px;
  flex: none;
  object-fit: cover;
  border-radius: 6px;
  background: var(--fill);
  outline: 0.5px solid var(--sep);
  outline-offset: -0.5px;
}

.tag {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 5px;
  background: var(--fill);
  color: var(--label-2);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.empty {
  margin: 0;
  padding: 22px var(--gutter);
  background: var(--bg-2);
  border-radius: var(--r-group);
  color: var(--label-2);
  font-size: 15px;
  text-align: center;
}

/* --- Buttons --------------------------------------------------------------
   Every button shrinks a touch the instant it is pressed. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--tap);
  padding: 11px 18px;
  border: none;
  border-radius: var(--r-button);
  background: var(--tint-soft);
  color: var(--tint);
  font-size: 17px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: transform var(--t-ui) var(--ease), opacity var(--t-ui) var(--ease);
}
.btn:active { transform: scale(0.97); opacity: 0.8; transition-duration: var(--t-press); }
.btn:disabled { opacity: 0.4; cursor: default; transform: none; }

.btn--primary { min-height: 50px; background: var(--tint); color: var(--on-tint); }
.btn--plain { background: transparent; padding-left: 8px; padding-right: 8px; font-weight: 400; }
.btn--small { min-height: 32px; padding: 6px 14px; border-radius: 999px; font-size: 15px; }
.btn--block { width: 100%; }

.btn--icon {
  width: var(--tap);
  min-width: var(--tap);
  height: var(--tap);
  padding: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--tint);
}
/* Undo and redo in the editor's bar: a little narrower than a full button,
   so they fit beside the back button on the smallest phone. */
.btn--history { width: 36px; min-width: 36px; }
.btn--history .icon { width: 20px; height: 20px; }
.btn--history:disabled { color: var(--label-3); opacity: 1; }
.btn--back { padding: 0 8px 0 0; font-weight: 400; background: transparent; gap: 2px; }
.btn--back .icon { width: 24px; height: 24px; }

.icon { width: 22px; height: 22px; flex: none; fill: currentColor; }
.icon--sm { width: 18px; height: 18px; }

/* Capsule chips, for adding things. */
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 6px 14px 6px 10px;
  border: none;
  border-radius: 999px;
  background: var(--bg-2);
  color: var(--label);
  font-size: 15px;
  cursor: pointer;
  transition: transform var(--t-ui) var(--ease);
}
.chip .icon { color: var(--tint); }
.chip:active { transform: scale(0.95); transition-duration: var(--t-press); }

/* --- Segmented control ----------------------------------------------------
   A track with a raised thumb that slides to the chosen segment. The thumb
   moves with a transition, which a browser retargets from wherever it is, so
   a second tap mid-slide just turns it round. */

/* Corner shapes: six little panes, the chosen one outlined in the tint. */
.shapes { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; }
.shapes__option {
  display: grid;
  place-items: center;
  height: 52px;
  border: 0;
  border-radius: 12px;
  background: var(--fill);
  cursor: pointer;
  transition: transform 100ms ease-out;
}
.shapes__option:active { transform: scale(0.95); }
.shapes__option[aria-checked="true"] { box-shadow: inset 0 0 0 2px var(--tint); }
.shapes__swatch {
  width: 22px;
  height: 32px;
  background: var(--label-2);
  opacity: 0.85;
}
.shapes__option[aria-checked="true"] .shapes__swatch { background: var(--tint); opacity: 1; }

/* A pop-up menu in a capsule, its chevron drawn in. */
.menu-pill {
  appearance: none;
  -webkit-appearance: none;
  font: 600 15px/1 -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  color: var(--label);
  background: var(--fill)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238E8E93' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
    no-repeat right 12px center;
  border: 0;
  border-radius: 999px;
  min-height: 32px;
  padding: 0 30px 0 14px;
  cursor: pointer;
}
.menu-pill:focus-visible { outline: 2px solid var(--tint, #0A84FF); outline-offset: 2px; }

.seg {
  --n: 2;
  --i: 0;
  position: relative;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  padding: 2px;
  border-radius: 9px;
  background: var(--fill);
}
.seg__thumb {
  position: absolute;
  top: 2px;
  bottom: 2px;
  left: 2px;
  width: calc((100% - 4px) / var(--n));
  border-radius: 7px;
  background: var(--bg-2);
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.12), 0 3px 1px rgba(0, 0, 0, 0.04);
  transform: translateX(calc(var(--i) * 100%));
  transition: transform var(--t-ui) var(--ease);
}
@media (prefers-color-scheme: dark) { .seg__thumb { background: #636366; } }
.seg button {
  position: relative;
  min-height: 32px;
  padding: 4px 6px;
  border: none;
  background: transparent;
  color: var(--label);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: -0.006em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  transition: opacity var(--t-press) linear;
}
.seg button[aria-pressed='true'] { font-weight: 600; }
.seg button:active { opacity: 0.55; }

/* --- Switch ------------------------------------------------------------- */

.switch {
  position: relative;
  flex: none;
  width: 51px;
  height: 31px;
  margin: 0;
  border-radius: 999px;
  background: var(--fill-strong);
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
  transition: background-color var(--t-ui) var(--ease);
}
.switch::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 27px;
  height: 27px;
  border-radius: 999px;
  background: var(--thumb);
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15), 0 3px 1px rgba(0, 0, 0, 0.06);
  transition: transform var(--t-ui) var(--ease);
}
.switch:checked { background: #34C759; }
.switch:checked::after { transform: translateX(20px); }

/* --- Inputs -------------------------------------------------------------- */

.field { display: flex; flex-direction: column; gap: 6px; }
.field > label { color: var(--label-2); font-size: 13px; }

.input {
  width: 100%;
  min-height: var(--tap);
  padding: 10px 12px;
  border: none;
  border-radius: var(--r-control);
  background: var(--fill);
  color: var(--label);
  /* 17px: under 16px, iOS zooms the whole page when the field is focused. */
  font-size: 17px;
  -webkit-appearance: none;
}
.input::placeholder { color: var(--label-2); }
.input:focus { outline: 2px solid var(--tint); outline-offset: 0; }
.input--inline { width: 96px; text-align: right; background: transparent; padding: 6px 0; }
.input--inline:focus { outline: none; }

.search { position: relative; display: flex; align-items: center; }
.search .icon { position: absolute; left: 9px; color: var(--label-2); pointer-events: none; }
.search .input { min-height: 40px; padding-left: 34px; }
.search .input::-webkit-search-cancel-button { -webkit-appearance: none; }

/* --- Sliders ------------------------------------------------------------- */

.slider {
  --fill: 50%;
  width: 100%;
  height: 32px;
  margin: 0;
  background: transparent;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
  touch-action: pan-y;
}
.slider::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(to right, var(--tint) 0 var(--fill), var(--fill-strong) var(--fill) 100%);
}
.slider::-moz-range-track {
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(to right, var(--tint) 0 var(--fill), var(--fill-strong) var(--fill) 100%);
}
.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 27px;
  height: 27px;
  margin-top: -11.5px;
  border: none;
  border-radius: 999px;
  background: var(--thumb);
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.18), 0 0 0 0.5px rgba(0, 0, 0, 0.06);
  transition: transform var(--t-ui) var(--ease);
}
.slider:active::-webkit-slider-thumb { transform: scale(1.1); transition-duration: var(--t-press); }
.slider::-moz-range-thumb {
  width: 27px;
  height: 27px;
  border: none;
  border-radius: 999px;
  background: var(--thumb);
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.18);
}

.slider-row { display: flex; flex-direction: column; gap: 2px; }
.slider-row__head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.slider-row__head span:first-child { font-size: 15px; }
.slider-row__head span:last-child { color: var(--label-2); font-size: 15px; font-variant-numeric: tabular-nums; }

/* --- Swatches ------------------------------------------------------------ */

.swatches { display: flex; gap: 10px; overflow-x: auto; scrollbar-width: none; padding: 4px 2px; }
.swatches::-webkit-scrollbar { display: none; }
.swatches button {
  flex: 0 0 34px;
  height: 34px;
  border: none;
  border-radius: 999px;
  box-shadow: inset 0 0 0 0.5px rgba(127, 127, 127, 0.4);
  cursor: pointer;
  transition: transform var(--t-ui) var(--ease), box-shadow var(--t-ui) var(--ease);
}
.swatches button:active { transform: scale(0.9); transition-duration: var(--t-press); }
.swatches button[aria-pressed='true'] {
  box-shadow: 0 0 0 2px var(--bg-2), 0 0 0 4px var(--tint);
}

/* --- Working -------------------------------------------------------------- */

.spinner {
  width: 22px;
  height: 22px;
  margin: 14px auto;
  border-radius: 999px;
  border: 2.5px solid var(--fill-strong);
  border-top-color: var(--label-2);
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.progress { height: 4px; border-radius: 999px; background: var(--fill-strong); overflow: hidden; }
.progress__fill {
  display: block;
  height: 100%;
  width: 100%;
  border-radius: inherit;
  background: var(--tint);
  transform-origin: left;
  transform: scaleX(0);
  transition: transform 200ms linear;
}

/* --- Home ----------------------------------------------------------------- */

.hero {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 20px var(--gutter) var(--gutter);
  background: var(--bg-2);
  border-radius: 18px;
}
.hero__art {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 14px;
  background: var(--tint);
  color: var(--on-tint);
}
.hero__art .icon { width: 30px; height: 30px; }
.hero__title { margin: 4px 0 0; font-size: 22px; font-weight: 700; letter-spacing: -0.02em; }
.hero__text { margin: 0 0 6px; color: var(--label-2); font-size: 15px; }

/* --- Song ----------------------------------------------------------------- */

/* The chosen track, shown the way a player shows what is playing. */
.now {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 8px 0 4px;
  text-align: center;
}
.now__art {
  width: min(62vw, 240px);
  aspect-ratio: 1;
  object-fit: cover;
  margin-bottom: 14px;
  border-radius: 10px;
  background: var(--fill);
  box-shadow: var(--shadow);
}
.now__title { margin: 0; font-size: 22px; font-weight: 700; letter-spacing: -0.02em; }
.now__sub { margin: 0; color: var(--label-2); font-size: 17px; }

/* --- Editor --------------------------------------------------------------- */

.screen--editor {
  overflow: hidden;
  padding: calc(var(--nav) + env(safe-area-inset-top, 0px)) 0 0;
  background: var(--bg);
}
.editor-stage {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px var(--gutter) 0;
}
.stagewrap {
  position: relative;
  background: var(--stage);
  border-radius: 6px;
  overflow: hidden;
  box-shadow: var(--shadow);
  touch-action: none;
}
/* Zoomed in, the slide outgrows its room and the room scrolls. Auto
   margins keep it centred while it fits and let it start at the edge once
   it does not, so no part is ever out of reach. */
.editor-stage.is-zoomed { overflow: auto; align-items: flex-start; justify-content: flex-start; }
.stagewrap { flex: none; margin: auto; }
.stagewrap canvas { display: block; width: 100%; height: 100%; }

/* Zoom: minus, the amount, plus, in one small capsule. */
.zoom {
  display: flex;
  align-items: center;
  flex: none;
  border-radius: 999px;
  background: var(--fill);
}
.zoom__btn {
  width: 30px;
  height: 30px;
  border: 0;
  background: none;
  color: var(--label);
  font: 500 18px/1 -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  cursor: pointer;
}
.zoom__btn:active { opacity: 0.5; }
.zoom__read {
  min-width: 38px;
  text-align: center;
  color: var(--label-2);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.stagewrap__overlay { position: absolute; inset: 0; }

/* Transport: play, and where in the loop we are, like a player's scrubber. */
.transport {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px var(--gutter) 10px 6px;
}
.transport .btn--icon { color: var(--label); }
.transport__size { color: var(--label-2); font-size: 13px; font-variant-numeric: tabular-nums; }
/* On a phone the timeline needs the room more; Export still says the size. */
@media (max-width: 430px) { .transport__size { display: none; } }

.timer { flex: 1; display: flex; align-items: center; gap: 10px; min-width: 0; }
.timer__track {
  flex: 1;
  height: 4px;
  border-radius: 999px;
  background: var(--fill-strong);
  overflow: hidden;
}
.timer__fill {
  display: block;
  height: 100%;
  width: 100%;
  border-radius: inherit;
  background: var(--label-2);
  transform-origin: left;
  transform: scaleX(0);
}
.timer__time { color: var(--label-2); font-size: 13px; font-variant-numeric: tabular-nums; min-width: 2.6em; }
.timer__time:last-child { text-align: right; }

.sheet {
  flex: none;
  display: flex;
  flex-direction: column;
  background: var(--bg-2);
  border-radius: 14px 14px 0 0;
  box-shadow: 0 -0.5px 0 var(--sep);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.sheet__tabs { padding: 12px var(--gutter) 4px; }
.sheet__body {
  display: flex;
  flex-direction: column;
  gap: 22px;
  padding: 12px var(--gutter) 22px;
  /* A fixed height: the slide is sized from what is left, so the sheet must
     not change height when you switch tabs. */
  height: clamp(170px, 30dvh, 280px);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  /* Rows fade as they pass under the tabs instead of being cut off. */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 14px);
  mask-image: linear-gradient(to bottom, transparent 0, #000 14px);
}
/* The sheet scrolls; nothing in it may be squeezed to fit instead. A group
   clips its corners with overflow: hidden, which lets a flex column shrink
   it, and the Effects tab was cutting its sliders off. */
.sheet__body > * { flex-shrink: 0; }
/* Inside the sheet the groups sit on the sheet's colour, so they step down. */
.sheet .group, .sheet .empty, .sheet .chip { background: var(--bg-3); }
.sheet .section__head, .sheet .footnote { padding-left: 4px; padding-right: 4px; }
.sheet .row, .sheet .group--pad { padding-left: 12px; padding-right: 12px; }
.sheet .group { --inset: 12px; }

/* A row that opens something: tinted words and a chevron, like Settings. */
.row--link { color: var(--tint); font-size: 15px; }
.row--link .icon { color: var(--label-3); }

/* Layer tab: the way back to the list, and what is being edited. */
.layer-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 32px; }
.layer-head__back {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 4px 6px 4px 0;
  border: 0;
  background: none;
  color: var(--tint);
  font-size: 15px;
  cursor: pointer;
}
.layer-head__back:active { opacity: 0.5; }
.layer-head__name {
  color: var(--label);
  font-weight: 600;
  font-size: 15px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.effect__head { display: flex; align-items: center; gap: 0; padding-left: 12px; min-height: var(--tap); }
.effect__name { flex: 1; font-weight: 600; font-size: 15px; }
.effect__head .btn--icon { color: var(--label-2); }

/* The loop bar under the slide is a scrubber: drag it to move through time. */
.timer { cursor: pointer; touch-action: none; padding: 10px 0; }
.timer.is-scrubbing .timer__track { height: 8px; }
.timer__track { transition: height var(--t-ui) var(--ease); }

/* --- Keyframes ---------------------------------------------------------- */

.key { color: var(--label-3); }
.key[aria-pressed='true'] { color: var(--tint); }
.key .icon { width: 16px; height: 16px; }
.slider-row__head .key {
  width: 32px;
  min-width: 32px;
  height: 32px;
  margin: -6px -6px -6px 0;
}

/* A keyframe row with no slider: its name, its ◆, and the strip under it. */
.key-row { flex-direction: column; align-items: stretch; gap: 0; padding-top: 4px; padding-bottom: 4px; }
.key-row__head { display: flex; align-items: center; min-height: 36px; }
.key-row__head .key { margin-right: -10px; }
.key-row .keys { margin-left: 13px; margin-right: 13px; }
.slider-row__head span:first-child { flex: 1; }

/* The strip under a keyed slider: the loop from start to end, a diamond for
   each keyframe, and a line where the playhead is. */
.keys {
  position: relative;
  height: 24px;
  margin: 2px 13px 0;
}
.keys::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1px;
  background: var(--sep);
}
.keys__mark {
  position: absolute;
  /* The sheet scrolls; without this a sideways drag can be taken for a scroll
     and cancelled halfway. */
  touch-action: none;
  top: 50%;
  width: 24px;
  height: 24px;
  margin: -12px 0 0 -12px;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
}
.keys__mark::after {
  content: '';
  position: absolute;
  inset: 7px;
  border-radius: 2px;
  background: var(--tint);
  transform: rotate(45deg);
  transition: transform var(--t-ui) var(--ease);
}
/* The picked keyframe: larger, with a ring, so Delete is clearly aimed. */
.keys__mark.is-picked::after {
  inset: 5px;
  box-shadow: 0 0 0 2px var(--bg-2), 0 0 0 3.5px var(--tint);
}
.keys { cursor: copy; }
.keys__mark { cursor: grab; }
.keys__mark:active::after { transform: rotate(45deg) scale(0.8); transition-duration: var(--t-press); }
.keys__head {
  position: absolute;
  top: 2px;
  bottom: 2px;
  width: 2px;
  margin-left: -1px;
  border-radius: 1px;
  background: var(--label);
  pointer-events: none;
}

/* --- Export --------------------------------------------------------------- */

.slides { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: start; }
.slide-card { margin: 0; display: flex; flex-direction: column; gap: 8px; }
.slide-card img,
.slide-card canvas,
.slide-card video {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 10px;
  background: var(--stage);
  box-shadow: var(--shadow);
}
.slide-card figcaption { color: var(--label-2); font-size: 13px; text-align: center; }

.facts { margin: 0; }
.facts .row dt { flex: 1; }
.facts .row dd { margin: 0; color: var(--label-2); font-variant-numeric: tabular-nums; }

.step {
  flex: none;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  background: var(--tint);
  color: var(--on-tint);
  font-size: 14px;
  font-weight: 600;
}
.steps .row { align-items: center; font-size: 15px; }
.steps { --inset: 54px; }
.steps strong { font-weight: 600; }

.status { margin: 0; color: var(--label-2); font-size: 15px; text-align: center; }

/* --- Toast ----------------------------------------------------------------
   A small material capsule that arrives from the top and leaves the same
   way. Blur and scale come in together, so it materialises rather than just
   fading. */

.toast {
  position: fixed;
  left: 50%;
  top: calc(env(safe-area-inset-top, 0px) + 10px);
  z-index: 40;
  max-width: min(90vw, 420px);
  padding: 12px 20px;
  border-radius: 999px;
  background: var(--material);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
  box-shadow: var(--shadow), inset 0 0 0 0.5px var(--material-edge);
  font-size: 15px;
  font-weight: 500;
  text-align: center;
  transform: translateX(-50%);
  animation: toast-in var(--t-screen) var(--ease) both;
}
.toast.is-leaving { animation: toast-out var(--t-ui) var(--ease) both; }
@keyframes toast-in {
  from { opacity: 0; transform: translate(-50%, -14px) scale(0.9); filter: blur(6px); }
}
@keyframes toast-out {
  to { opacity: 0; transform: translate(-50%, -14px) scale(0.9); filter: blur(6px); }
}

/* --- Reduced motion and transparency -------------------------------------
   Movement becomes a short cross-fade. Feedback stays, travel goes. */

@media (prefers-reduced-motion: reduce) {
  .screen.is-push, .screen.is-pop { animation: fade-in 200ms linear both; }
  .toast, .toast.is-leaving { animation-name: fade-in; }
  .toast.is-leaving { animation-direction: reverse; }
  .seg__thumb, .switch::after, .btn, .chip { transition-duration: 1ms; }
  .btn:active, .chip:active { transform: none; }
  .spinner { animation-duration: 2.4s; }
}
@keyframes fade-in { from { opacity: 0; } }

@media (prefers-reduced-transparency: reduce) {
  .topbar.is-scrolled, .toast {
    background: var(--bg-2);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* --- Wider screens --------------------------------------------------------

     from 640px   an upright tablet or a small window: the column stops at a
                  readable width and the slide gets more room.

     from 1024px  a sideways tablet or a desktop: the sheet becomes a sidebar
                  beside the slide, like an inspector. */

@media (min-width: 640px) {
  .page { max-width: 620px; margin: 0 auto; }
  .screen--editor .editor-stage,
  .screen--editor .transport,
  .screen--editor .sheet { max-width: 620px; width: 100%; margin: 0 auto; }
  .screen--editor .editor-stage { padding-top: 16px; }
  .sheet__body { height: clamp(200px, 32dvh, 340px); }
}

@media (min-width: 1024px) {
  .page { max-width: 680px; }
  .large-title { font-size: 40px; }

  .screen--editor.is-active {
    display: grid;
    grid-template-columns: minmax(0, 1fr) clamp(340px, 28vw, 420px);
    grid-template-rows: minmax(0, 1fr) auto;
    grid-template-areas:
      'stage sheet'
      'loop  sheet';
  }
  .screen--editor .editor-stage {
    grid-area: stage;
    max-width: none;
    margin: 0;
    padding: 28px 32px 8px;
  }
  .screen--editor .transport {
    grid-area: loop;
    width: min(100%, 620px);
    margin: 0 auto;
    padding: 8px 32px calc(18px + env(safe-area-inset-bottom, 0px)) 24px;
  }
  .screen--editor .sheet {
    grid-area: sheet;
    max-width: none;
    margin: 0;
    min-height: 0;
    border-radius: 0;
    box-shadow: -0.5px 0 0 var(--sep);
  }
  .screen--editor .sheet__body { height: auto; flex: 1; min-height: 0; }
}

@media (hover: hover) and (pointer: fine) {
  button.row:hover { background: var(--fill); }
  .btn:hover { opacity: 0.88; }
}
