/* ── Tokens ─────────────────────────────────────────────────────────── */
:root {
  color-scheme: light dark;

  --bg:        oklch(1 0 0);
  --surface:   oklch(0.974 0.003 250);
  --surface-2: oklch(0.945 0.005 250);
  --line:      oklch(0.906 0.005 250);
  --line-soft: oklch(0.940 0.004 250);
  --ink:       oklch(0.185 0.015 250);
  --muted:     oklch(0.470 0.016 250);
  --faint:     oklch(0.555 0.012 250);   /* 4.8:1 — carries placeholder + item text */

  --primary:    oklch(0.495 0.170 250);
  --primary-fg: oklch(0.470 0.170 250);
  --primary-dim:oklch(0.495 0.170 250 / 0.12);
  --on-primary: oklch(1 0 0);

  --accent:     oklch(0.560 0.125 72);
  --accent-dim: oklch(0.560 0.125 72 / 0.14);

  --danger:     oklch(0.505 0.195 27);
  --danger-dim: oklch(0.505 0.195 27 / 0.12);

  --focus: var(--primary-fg);

  --r-sm: 8px;
  --r:    11px;
  --r-lg: 18px;

  --z-sticky: 10;
  --z-dock:   30;
  --z-drag:   40;
  --z-sheet:  50;
  --z-toast:  60;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --fast: 140ms;
  --base: 200ms;

  --shadow: 0 1px 2px oklch(0.185 0.015 250 / 0.06), 0 8px 24px oklch(0.185 0.015 250 / 0.08);
  --shadow-lift: 0 2px 6px oklch(0.185 0.015 250 / 0.10), 0 16px 32px oklch(0.185 0.015 250 / 0.16);

  /* Mode-swappable surfaces. Planuj leaves them at the neutral defaults. */
  --row:       var(--bg);
  --row-press: var(--surface);
  --ring:      var(--line);
  --band:      transparent;
  --band-ink:  var(--muted);
}

/* ── Mode themes ──────────────────────────────────────────────────────
   Two jobs, two rooms. Planuj is the workbench at home: white page, grey
   chrome, blue reserved for the one button that commits something. Kupuj is
   the aisle: blue bar over a cool-tinted page so the white rows lift off it,
   solid section bands findable at arm's length, and blue tick rings so an
   untouched item reads as work left. Nothing but these tokens changes. */
.mode-shop {
  --bg:        oklch(0.949 0.019 250);
  --row:       oklch(1 0 0);
  --row-press: oklch(0.936 0.034 250);
  --ring:      oklch(0.720 0.090 250);
  --band:      oklch(0.912 0.031 250);
  --band-ink:  oklch(0.395 0.135 250);
  --line-soft: oklch(0.900 0.006 250);
}

@media (prefers-color-scheme: dark) {
  .mode-shop {
    --bg:        oklch(0.118 0.014 250);
    --row:       oklch(0.208 0.013 250);
    --row-press: oklch(0.262 0.022 250);
    --ring:      oklch(0.500 0.080 250);
    --band:      oklch(0.168 0.020 250);
    --band-ink:  oklch(0.800 0.105 250);
    --line-soft: oklch(0.268 0.010 250);
  }
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg:        oklch(0.145 0 0);
    --surface:   oklch(0.190 0.005 250);
    --surface-2: oklch(0.238 0.007 250);
    --line:      oklch(0.300 0.009 250);
    --line-soft: oklch(0.255 0.008 250);
    --ink:       oklch(0.965 0.004 250);
    --muted:     oklch(0.700 0.014 250);
    --faint:     oklch(0.600 0.012 250);   /* 5.0:1 — carries placeholder + item text */

    --primary:    oklch(0.545 0.175 250);
    --primary-fg: oklch(0.760 0.135 250);
    --primary-dim:oklch(0.760 0.135 250 / 0.16);
    --on-primary: oklch(1 0 0);

    --accent:     oklch(0.800 0.130 78);
    --accent-dim: oklch(0.800 0.130 78 / 0.16);

    --danger:     oklch(0.620 0.190 27);
    --danger-dim: oklch(0.620 0.190 27 / 0.18);

    --shadow: 0 1px 2px oklch(0 0 0 / 0.5), 0 8px 24px oklch(0 0 0 / 0.55);
    --shadow-lift: 0 2px 6px oklch(0 0 0 / 0.6), 0 18px 36px oklch(0 0 0 / 0.7);
  }
}

/* ── Reset ──────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html { -webkit-text-size-adjust: 100%; }

/* `clip` guards against any stray horizontal scroll without creating a scroll
   container, so `overflow-y` stays visible and the sticky bar/composer keep
   working. `hidden` here would break both. */
html { overflow-x: clip; }

body {
  /* svh, not dvh: on reload Safari shows the full-height URL bar, and a dvh
     body is taller than what is on screen — you get a scrollbar with nothing
     under it. svh is the smallest viewport, so the page always fits. */
  min-height: 100svh;
  overflow-x: clip;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--ink);
  font: 400 0.9375rem/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        "Helvetica Neue", system-ui, sans-serif;
  font-synthesis-weight: none;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior-y: none;
}

/* A class with `display` outranks the UA's [hidden] rule; make hidden win. */
[hidden] { display: none !important; }

button, input, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; touch-action: manipulation; }
svg { display: block; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: 4px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

.sprite { position: absolute; width: 0; height: 0; }

.ico {
  width: 21px; height: 21px; flex: none;
  fill: none; stroke: currentColor;
  stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round;
}
.ico--fill { fill: currentColor; stroke: none; }

/* ── App bar ────────────────────────────────────────────────────────── */
.bar {
  /* sticky is also the containing block for .meter — no `position: relative`
     may follow, it would silently un-stick the bar. */
  position: sticky; top: 0; z-index: var(--z-sticky);
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: max(8px, env(safe-area-inset-top)) 16px 8px;
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
  background: var(--bg);
  border-bottom: 1px solid var(--line-soft);
}


/* Equal-width columns keep the thumb a constant size, so only transform moves. */
.seg {
  position: relative; display: grid; grid-template-columns: 1fr 1fr;
  padding: 3px; gap: 2px;
  background: var(--surface-2); border-radius: 999px;
}
.seg-btn {
  position: relative; z-index: 1;
  padding: 6px 14px; border-radius: 999px;
  font-size: 0.875rem; font-weight: 550; color: var(--muted);
  transition: color var(--base) var(--ease);
}
.seg-btn[aria-pressed="true"] { color: var(--ink); }
.seg-thumb {
  position: absolute; z-index: 0; top: 3px; bottom: 3px; left: 3px;
  width: calc((100% - 8px) / 2);
  transform: translateX(var(--thumb-x, 0px));
  background: var(--bg); border-radius: 999px;
  box-shadow: 0 1px 2px oklch(0 0 0 / 0.12);
  transition: transform var(--base) var(--ease);
}

/* Kupuj is a mode you are *in*: the bar goes brand-colour so a glance at the
   top of the screen tells you which one, costing no extra height. */
.mode-shop .bar { background: var(--primary); border-bottom-color: transparent; }
.mode-shop .status-text { color: oklch(1 0 0 / 0.82); }
.mode-shop .status-text b { color: oklch(1 0 0); }
.mode-shop .seg { background: oklch(1 0 0 / 0.22); }
.mode-shop .seg-btn { color: oklch(1 0 0 / 0.85); }
.mode-shop .seg-btn[aria-pressed="true"] { color: var(--primary); }
.mode-shop .seg-thumb { background: oklch(1 0 0); }
.mode-shop .meter { background: oklch(1 0 0 / 0.28); }
.mode-shop .meter-fill { background: oklch(1 0 0); }
.mode-shop :focus-visible { outline-color: oklch(1 0 0); }

/* ── Status + progress (both live inside the bar; no extra row) ─────── */
.status-text {
  flex: 1 1 auto; min-width: 0;
  font-size: 0.9375rem; color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.status-text b { color: var(--ink); font-weight: 600; }

/* Rides on the bar's own bottom edge, so progress costs zero height. */
.meter {
  position: absolute; left: 0; right: 0; bottom: -1px;
  height: 2px; overflow: hidden;
}
.meter-fill {
  display: block; height: 100%; width: 100%;
  transform: scaleX(var(--progress, 0)); transform-origin: left center;
  background: var(--primary);
  transition: transform 320ms var(--ease);
}

.net {
  display: flex; align-items: center; gap: 8px;
  margin: 10px 16px 0; padding: 8px 12px;
  background: var(--accent-dim); color: var(--ink);
  border-radius: var(--r); font-size: 0.8125rem;
}
.net .ico { width: 17px; height: 17px; color: var(--accent); }

/* ── List ───────────────────────────────────────────────────────────── */
.list {
  flex: 1 1 auto;
  padding: 2px 0 4px;
  padding-left: max(0px, env(safe-area-inset-left));
  padding-right: max(0px, env(safe-area-inset-right));
}

.sec-head {
  position: sticky; top: 0; z-index: 2;
  overflow: hidden;
}
.sec-slide {
  display: flex; align-items: center; gap: 6px;
  padding: 9px 16px 2px;
  background: linear-gradient(var(--bg) 72%, transparent);
  transition: transform var(--base) var(--ease);
  touch-action: pan-y;
}
.sec-name {
  font-size: 0.8125rem; font-weight: 600; color: var(--muted);
  letter-spacing: 0.005em;
}
.sec-count {
  font-size: 0.75rem; color: var(--faint);
  font-variant-numeric: tabular-nums;
}
/* An aisle marker you can find at arm's length, not a whispered label. */
.mode-shop .sec-slide { background: var(--band); padding: 7px 16px 6px; }
.mode-shop .sec-name { color: var(--band-ink); font-size: 0.875rem; font-weight: 650; }
/* Size carries the hierarchy here; fading it would cost real contrast. */
.mode-shop .sec-count { color: var(--band-ink); }
.sec-tools { margin-left: auto; display: flex; gap: 2px; }
.sec-tools button {
  display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: var(--r-sm);
  color: var(--muted);
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.sec-tools button:hover:not(:disabled) { background: var(--surface-2); color: var(--ink); }
.sec-tools button:disabled { opacity: 0.3; cursor: default; }
.sec-tools .ico { width: 18px; height: 18px; }
.mode-shop .sec-tools { display: none; }

.sec--empty .sec-name { color: var(--faint); }
.mode-shop .sec--empty { display: none; }

/* ── Row ────────────────────────────────────────────────────────────── */
.row {
  position: relative;
  overflow: hidden;
  transition: opacity var(--base) var(--ease);
}
.row-slide {
  position: relative;
  display: flex; align-items: center; gap: 8px;
  padding: 0 16px 0 8px;
  min-height: 44px;
  background: var(--row);
  transition: transform var(--base) var(--ease), background var(--fast) var(--ease);
  touch-action: pan-y;
}
.mode-shop .row-slide { min-height: 50px; }

/* Revealed by a leftward swipe; tapping it is the confirmation. Hidden
   outright until then — a sticky header's gradient cannot hide it. */
.row-del, .sec-del {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: 96px; display: grid; place-items: center; gap: 2px;
  background: var(--danger); color: oklch(1 0 0);
  font-size: 0.8125rem; font-weight: 600;
  opacity: 0; pointer-events: none;
  transition: opacity var(--fast) var(--ease);
}
.row.swiping .row-del, .row[data-open="1"] .row-del,
.sec-head.swiping .sec-del, .sec-head[data-open="1"] .sec-del {
  opacity: 1; pointer-events: auto;
}
/* Section headers are too short for icon + label. */
.sec-del { bottom: 2px; gap: 0; }
.sec-del .ico { display: none; }
.row-del .ico { width: 19px; height: 19px; }
.row-del:active, .sec-del:active { filter: brightness(0.92); }
.row::after {
  content: ""; position: absolute; left: 60px; right: 0; bottom: 0;
  height: 1px; background: var(--line-soft);
}
.row:last-child::after { display: none; }
/* In Shop mode the whole row is the tick target, so it needs press feedback. */
.mode-shop .row-slide:active { background: var(--row-press); }

/* The circle is drawn with ::before so the button itself keeps a full 44px
   touch target while the visible ring stays small — that is what lets the
   row height come down without shrinking anything you actually hit. */
.row-check {
  flex: none; position: relative;
  display: grid; place-items: center;
  width: 44px; height: 44px;
  color: transparent;
  transition: color var(--fast) var(--ease);
}
.row-check::before {
  content: ""; position: absolute; inset: 10px;
  border-radius: 50%; border: 1.75px solid var(--ring);
  transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease),
              transform var(--fast) var(--ease);
}
.mode-shop .row-check::before { inset: 9px; }
.row-check .ico { position: relative; width: 15px; height: 15px; stroke-width: 2.5; }
.mode-shop .row-check .ico { width: 18px; height: 18px; }
.row-check:hover::before { border-color: var(--primary-fg); }
.row-check:active::before { transform: scale(0.88); }

.row--done .row-check { color: var(--on-primary); }
.row--done .row-check::before { background: var(--primary); border-color: var(--primary); }

.row-body {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; gap: 10px;
  padding: 5px 0; text-align: left;
  font-size: 1.0625rem; line-height: 1.3;
}
.mode-shop .row-body { font-size: 1.1875rem; }
.row-text { overflow-wrap: anywhere; }
.row--done .row-text { color: var(--muted); text-decoration: line-through; text-decoration-thickness: 1.5px; }
.row--done { opacity: 0.62; }

.row-thumb {
  flex: none; width: 34px; height: 34px; border-radius: var(--r-sm);
  object-fit: cover; background: var(--surface-2);
  border: 1px solid var(--line-soft);
}
.mode-shop .row-thumb { width: 40px; height: 40px; }

.row-untitled { color: var(--faint); font-style: italic; }

.row-play {
  flex: none; display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--accent-dim); color: var(--accent);
  transition: transform var(--fast) var(--ease);
}
.row-play:active { transform: scale(0.92); }
.row-play .ico { width: 15px; height: 15px; }
.row-play .ico--fill { fill: currentColor; stroke: none; }

.row-star { flex: none; color: var(--accent); }
.row-star .ico { width: 15px; height: 15px; fill: currentColor; stroke: none; }

.row-grip {
  flex: none; display: grid; place-items: center;
  width: 34px; height: 40px; margin-right: -8px;
  color: var(--faint); cursor: grab;
  touch-action: none;
}
.row-grip .ico { width: 20px; height: 20px; stroke-width: 2.75; }
.mode-shop .row-grip { display: none; }

.row--pending { opacity: 0.55; }
.row--pending .row-check::before { border-style: dashed; }

/* Drag */
.row--drag {
  overflow: visible;
  position: relative; z-index: var(--z-drag);
  box-shadow: var(--shadow-lift);
  border-radius: var(--r);
  cursor: grabbing;
}
.row--drag::after { display: none; }
.row--drag .row-slide { background: var(--surface); border-radius: var(--r); }
.row--lifted { opacity: 0.25; }
/* A slot the exact height of the lifted row, so nothing below it shifts. */
.drop-line {
  margin: 0 12px; border-radius: var(--r);
  background: var(--primary-dim);
  border: 1.5px dashed var(--primary-fg);
}

/* ── Empty state ────────────────────────────────────────────────────── */
.empty {
  padding: 44px 28px; text-align: center; max-width: 34ch; margin: 0 auto;
}
.empty h2 { font-size: 1.0625rem; font-weight: 600; margin-bottom: 8px; }
.empty p { font-size: 0.9375rem; color: var(--muted); text-wrap: pretty; }
.empty kbd {
  font: inherit; font-weight: 600; color: var(--ink);
  background: var(--surface-2); border-radius: 5px; padding: 1px 5px;
}

/* ── Staples tray ───────────────────────────────────────────────────── */
.tray {
  border-top: 1px solid var(--line-soft);
  padding: 14px 16px 4px;
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
}
.mode-shop .tray { display: none; }
.tray-title { font-size: 0.8125rem; font-weight: 600; color: var(--muted); margin-bottom: 10px; }
.tray-group { margin-bottom: 12px; }
.tray-group-name { font-size: 0.75rem; color: var(--faint); margin-bottom: 6px; }
.chips { display: flex; flex-wrap: wrap; gap: 7px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--line);
  font-size: 0.875rem; color: var(--ink);
  transition: border-color var(--fast) var(--ease), background var(--fast) var(--ease),
              transform var(--fast) var(--ease);
}
.chip:hover { border-color: var(--primary-fg); }
.chip:active { transform: scale(0.96); }
.chip .ico { width: 15px; height: 15px; color: var(--accent); }
.chip--on {
  background: var(--primary-dim); border-color: transparent; color: var(--primary-fg);
  font-weight: 550;
}

/* ── Finish ─────────────────────────────────────────────────────────── */
.finish-wrap { padding-top: 10px; }
.btn-finish { width: 100%; }

/* ── Buttons ────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; padding: 0 18px; border-radius: var(--r);
  font-size: 0.9375rem; font-weight: 570; letter-spacing: -0.005em;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease),
              opacity var(--fast) var(--ease), transform var(--fast) var(--ease);
}
.btn:active:not(:disabled) { transform: scale(0.975); }
.btn:disabled { opacity: 0.4; cursor: default; }
.btn-block { width: 100%; }

.btn-primary { background: var(--primary); color: var(--on-primary); }
.btn-primary:hover:not(:disabled) { background: oklch(from var(--primary) calc(l - 0.04) c h); }

.btn-ghost { background: var(--surface-2); color: var(--ink); }
.btn-ghost:hover { background: var(--line); }
.btn-ghost[aria-pressed="true"] { background: var(--accent-dim); color: var(--accent); }

.btn-danger { background: var(--danger-dim); color: var(--danger); }
.btn-danger:hover { background: var(--danger); color: var(--on-primary); }

.icon-btn {
  display: grid; place-items: center; flex: none;
  width: 44px; height: 44px; border-radius: var(--r);
  color: var(--muted);
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease),
              transform var(--fast) var(--ease);
}
.icon-btn:hover { background: var(--surface-2); color: var(--ink); }
.icon-btn:active { transform: scale(0.94); }
.icon-btn--live { color: var(--accent); background: var(--accent-dim); }

/* ── Composer ───────────────────────────────────────────────────────── */
.composer {
  position: sticky; bottom: 0; z-index: var(--z-dock);
  background: var(--bg);
  border-top: 1px solid var(--line);
  padding: 10px 16px max(10px, env(safe-area-inset-bottom));
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
}
.compose-row { display: flex; align-items: flex-end; gap: 8px; }

#entry {
  flex: 1 1 auto; min-width: 0;
  min-height: 44px; max-height: 40vh;
  padding: 11px 14px; resize: none;
  /* 16px exactly: iOS zooms the page into any field below it on focus, and the
     zoomed page then pans sideways under your thumb. */
  font-size: 1rem;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r);
  line-height: 1.45; overflow-y: auto;
  transition: border-color var(--fast) var(--ease), background var(--fast) var(--ease);
}
#entry::placeholder { color: var(--faint); }
#entry:focus { outline: none; border-color: var(--primary-fg); background: var(--bg); }
#entry:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }

.hint {
  margin-top: 8px; font-size: 0.8125rem; color: var(--muted);
  text-wrap: pretty;
}
.hint b { color: var(--ink); font-weight: 600; }
.mode-shop .hint { display: none; }

/* Kupuj wants the aisle, not the keyboard: the composer folds away to a strip
   and comes back on the plus. Its padding goes with it, so a folded composer
   with nothing to show is a hairline over the home-indicator gap. */
.composer--folded .compose-row { display: none; }
.composer--folded { padding-top: 0; padding-bottom: max(6px, env(safe-area-inset-bottom)); }

.fab { display: none; }
.mode-shop .fab {
  display: grid; place-items: center;
  position: fixed; z-index: var(--z-dock);
  right: max(16px, env(safe-area-inset-right));
  bottom: calc(var(--composer-h, 24px) + 12px);
  width: 56px; height: 56px; border-radius: 50%;
  background: var(--primary); color: oklch(1 0 0);
  box-shadow: var(--shadow-lift);
  transition: transform var(--fast) var(--ease);
}
.fab .ico { width: 26px; height: 26px; transition: transform var(--base) var(--ease); }
.fab[aria-expanded="true"] .ico { transform: rotate(45deg); }
.fab:active { transform: scale(0.94); }

/* ── Sheets ─────────────────────────────────────────────────────────── */
.sheet {
  width: min(440px, 100%);
  margin: auto auto 0; padding: 0; border: 0;
  background: var(--bg); color: var(--ink);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  box-shadow: var(--shadow-lift);
}
@media (min-width: 560px) {
  .sheet { margin: auto; border-radius: var(--r-lg); }
}
.sheet::backdrop { background: oklch(0 0 0 / 0.42); backdrop-filter: blur(2px); }

.sheet[open] { animation: sheet-in var(--base) var(--ease); }
.sheet[open]::backdrop { animation: fade-in var(--base) var(--ease); }
@keyframes sheet-in { from { transform: translateY(14px); opacity: 0; } }
@keyframes fade-in { from { opacity: 0; } }

.sheet-inner {
  display: flex; flex-direction: column; gap: 16px;
  padding: 10px 20px max(20px, env(safe-area-inset-bottom));
}
.sheet-grip {
  width: 36px; height: 4px; border-radius: 999px;
  background: var(--line); margin: 0 auto 4px;
}
.sheet-text {
  width: 100%; min-height: 46px; padding: 11px 14px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); font-size: 1.0625rem;
}
.sheet-text:focus { outline: none; border-color: var(--primary-fg); background: var(--bg); }
.sheet-label { font-size: 0.8125rem; font-weight: 600; color: var(--muted); margin-bottom: 9px; }
.sheet-actions { display: flex; gap: 8px; }
.sheet-actions .btn { flex: 1; }

/* Voice */
.voice-inner { align-items: center; text-align: center; }
.level {
  --lvl: 0;
  width: 84px; height: 84px; border-radius: 50%;
  background: var(--danger); margin: 8px 0 4px;
  display: grid; place-items: center;
  transform: scale(calc(0.82 + var(--lvl) * 0.32));
  transition: transform 90ms linear;
  box-shadow: 0 0 0 8px var(--danger-dim);
}
.voice-time {
  font-size: 1.5rem; font-weight: 600; font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.voice-live {
  min-height: 3em; font-size: 0.9375rem; color: var(--muted);
  text-wrap: pretty; max-width: 32ch;
}
.voice-live b { color: var(--ink); font-weight: 500; }

/* Viewer */
.viewer {
  width: 100%; height: 100%; max-width: 100%; max-height: 100%;
  padding: 0; border: 0; background: oklch(0 0 0 / 0.94);
  display: none; place-items: center;
}
.viewer[open] { display: grid; }
.viewer::backdrop { background: oklch(0 0 0 / 0.94); }
.viewer-frame { display: grid; place-items: center; width: 100%; height: 100%; }
.viewer-frame img { max-width: 100%; max-height: 100dvh; object-fit: contain; }
.viewer-close {
  position: fixed; top: max(12px, env(safe-area-inset-top)); right: 12px;
  color: oklch(1 0 0); background: oklch(1 0 0 / 0.14);
}
.viewer-close:hover { background: oklch(1 0 0 / 0.26); color: oklch(1 0 0); }

/* ── Toasts ─────────────────────────────────────────────────────────── */
.toasts {
  position: fixed; z-index: var(--z-toast);
  left: 50%; transform: translateX(-50%);
  bottom: calc(var(--composer-h, 88px) + 12px);
  display: flex; flex-direction: column-reverse; gap: 8px;
  width: min(420px, calc(100% - 32px)); pointer-events: none;
}
.toast {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 12px 11px 16px; border-radius: var(--r);
  background: var(--ink); color: var(--bg);
  font-size: 0.875rem; box-shadow: var(--shadow);
  pointer-events: auto;
  animation: toast-in var(--base) var(--ease);
}
.toast--err { background: var(--danger); color: oklch(1 0 0); }
.toast button {
  margin-left: auto; padding: 5px 11px; border-radius: var(--r-sm);
  font-weight: 600; color: inherit; background: oklch(1 0 0 / 0.16);
  white-space: nowrap;
}
.toast button:hover { background: oklch(1 0 0 / 0.28); }
@keyframes toast-in { from { transform: translateY(10px); opacity: 0; } }
.toast--out { animation: toast-out var(--fast) var(--ease) forwards; }
@keyframes toast-out { to { transform: translateY(6px); opacity: 0; } }

/* ── Wide screens ───────────────────────────────────────────────────── */
@media (min-width: 720px) {
  .net, .list, .tray, .composer > * {
    max-width: 640px; margin-inline: auto; width: 100%;
  }
  .bar { padding-inline: max(16px, calc((100% - 640px) / 2)); }
  .composer { padding-inline: 16px; }
  .row { border-radius: var(--r); }
}

/* ── Reduced motion ─────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
  .level { transform: none; }
}
