/* ═══════════════════════════════════════════════════════════════════════
   THE DESIGN SYSTEM                                          2026-09-11

   Built from ELEVENLABS-UI-SPEC.md, which was written from 27 screenshots
   of elevenlabs.io the operator sent. Every screen of the new Studio is
   built out of what is in this file - nothing here is page-specific.

   The two things that make it look right, and that our old shell got the
   other way round:

     1. LIGHT AND MONOCHROME. There is NO accent colour. Primary buttons
        are solid black. The active nav item is a grey fill, not a colour.
        Colour appears ONLY in avatars, flags and brand logos.
     2. SEPARATION BY HAIRLINE, NOT SHADOW. Almost nothing casts a shadow.
        Cards are white on white, told apart by a 1px border.

   Dark mode is defined at the bottom and is a straight inversion - the
   product stays monochrome in both.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  /* surfaces */
  /* The page is a step off white so a white card lifts off it. Identical
     values made every card a rectangle of hairline and nothing else. */
  --bg:        #fafbfb;
  --surface:   #ffffff;
  --well:      #f3f5f6;   /* inset cards: promos, empty states, toolbars */
  --track:     #eef1f2;   /* segmented-control track, active nav fill */
  --edge:      #e3e7e9;   /* the hairline that does all the separating */
  --edge-soft: #eef1f2;

  /* ink: near-black with a trace of cool, so it reads as ink and not as
     the absence of light */
  --ink:    #0f1417;
  --ink-2:  #5d6b72;
  --ink-3:  #93a1a8;

  /* the accent: one colour for the things you press and the things that
     are selected. Teal 600 - white on it clears 4.9:1, it is nowhere
     near the red that means destructive, and it is not the indigo that
     every dashboard has used since 2016. */
  --acc:       #0d9488;
  --acc-hover: #0f766e;
  --acc-soft:  rgba(13, 148, 136, .10);
  --acc-ink:   #ffffff;

  /* the alarms, which the accent must never be confused with */
  --danger: #e5484d;
  --ok:     #2f9e44;

  /* A second, quieter palette: only for things where the colour says
     something the label would otherwise have to. Tints, never fills. */
  --c-green:  #0f7b40;  --c-green-bg:  rgba(15, 123, 64, .10);
  --c-amber:  #a16207;  --c-amber-bg:  rgba(161, 98, 7, .12);
  --c-violet: #6d3fc4;  --c-violet-bg: rgba(109, 63, 196, .11);
  --c-blue:   #1f5fd0;  --c-blue-bg:   rgba(31, 95, 208, .10);
  --c-rose:   #c0333a;  --c-rose-bg:   rgba(192, 51, 58, .10);

  --radius-btn:   10px;
  --radius-card:  12px;
  --radius-input: 10px;

  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, monospace;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* ── type ──────────────────────────────────────────────────────────────
   Headings are noticeably heavier than body and tracked tight. That
   weight contrast is most of what makes the page read as "theirs". */
h1 { font-size: 30px; font-weight: 700; letter-spacing: -.02em; margin: 0 0 .6rem; }
h2 { font-size: 20px; font-weight: 650; letter-spacing: -.015em; margin: 0 0 .4rem; }
h3 { font-size: 16px; font-weight: 600; letter-spacing: -.01em; margin: 0 0 .3rem; }
.sub  { color: var(--ink-2); font-size: 14px; }
.mono { font-family: var(--mono); }

/* ── buttons ───────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
  min-height: 40px; padding: .5rem .95rem;
  border-radius: var(--radius-btn);
  font: inherit; font-size: 14px; font-weight: 550;
  cursor: pointer; border: 1px solid transparent;
  transition: background .12s, border-color .12s, opacity .12s;
  white-space: nowrap;
}
.btn-primary   { background: var(--acc); color: var(--acc-ink); }
.btn-primary:hover:not(:disabled) { background: var(--acc-hover); }
.btn-secondary { background: var(--surface); color: var(--ink); border-color: var(--edge); }
.btn-secondary:hover:not(:disabled) { background: var(--well); }
.btn-ghost     { background: transparent; color: var(--ink-2); }
.btn-ghost:hover:not(:disabled) { background: var(--well); color: var(--ink); }
.btn-danger    { background: var(--danger); color: #fff; }
.btn:disabled  { opacity: .45; cursor: not-allowed; }
.btn-sm { min-height: 32px; padding: .3rem .7rem; font-size: 13px; }

/* Split button — label + a caret half that opens a menu. When the action
   is unavailable the LABEL greys but the caret stays live, because the
   menu still works (that is how their Publish control behaves). */
.split { display: inline-flex; border-radius: var(--radius-btn); overflow: hidden; }
.split > .split-main {
  border-radius: 0; border: none;
  background: var(--ink); color: #fff;
  padding: .5rem .95rem; min-height: 40px;
  font: inherit; font-size: 14px; font-weight: 550; cursor: pointer;
}
.split > .split-main:disabled { background: #c8c8cc; color: #fff; opacity: 1; cursor: not-allowed; }
.split > .split-caret {
  border: none; background: var(--ink); color: #fff;
  padding: 0 .6rem; min-height: 40px; cursor: pointer;
  border-left: 1px solid rgba(255,255,255,.22);
}

/* ── chips ─────────────────────────────────────────────────────────────
   Two different things that look similar on purpose:
   .chip   is a CONTROL you press (filters, + Agent)
   .status is a LABEL you read  (New, Alpha, Primary, Default) */
.chip {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .32rem .7rem; border-radius: 999px;
  border: 1px solid var(--edge); background: var(--surface);
  font-size: 13px; font-weight: 500; color: var(--ink); cursor: pointer;
  white-space: nowrap;
}
.chip:hover { background: var(--well); }
.chip.on { background: var(--acc); color: var(--acc-ink); border-color: var(--acc); }

/* A badge inside a control is decoration, not a target: without this the
   tap lands on the pill and the button it labels never fires. "Memory
   Alpha" was unclickable for exactly this reason. */
.btn .status, .seg > button .status, .chip .status { pointer-events: none; }

.status {
  display: inline-flex; align-items: center;
  padding: .18rem .55rem; border-radius: 999px;
  background: var(--track); color: var(--ink-2);
  font-size: 12px; font-weight: 550; white-space: nowrap;
}
.status-dark { background: var(--ink); color: #fff; }
/* Tinted variants. Usable on .status and on a tile; the pair is always
   a soft background with its own text colour, so the thing stays
   readable and never turns into a block of colour. */
.t-green  { background: var(--c-green-bg);  color: var(--c-green); }
.t-amber  { background: var(--c-amber-bg);  color: var(--c-amber); }
.t-violet { background: var(--c-violet-bg); color: var(--c-violet); }
.t-blue   { background: var(--c-blue-bg);   color: var(--c-blue); }
.t-rose   { background: var(--c-rose-bg);   color: var(--c-rose); }
.t-green b, .t-amber b, .t-violet b, .t-blue b, .t-rose b { color: inherit; }
/* On a tile the label under the number must stay quiet, or the whole
   card becomes shouting. */
.t-green .sub, .t-amber .sub, .t-violet .sub,
.t-blue .sub, .t-rose .sub { color: inherit; opacity: .72; }
.status-line { background: transparent; border: 1px solid var(--edge); }

/* ── cards ─────────────────────────────────────────────────────────── */
.card {
  background: var(--surface); border: 1px solid var(--edge);
  border-radius: var(--radius-card); padding: 1rem;
}
.well { background: var(--well); border: none; border-radius: var(--radius-card); padding: 1rem; }

/* ── list rows: voices, languages, nav, feature lists ──────────────── */
.rows { border: 1px solid var(--edge); border-radius: var(--radius-card); overflow: hidden; }
.row {
  display: flex; align-items: center; gap: .7rem;
  padding: .8rem 1rem; background: var(--surface);
  border-bottom: 1px solid var(--edge-soft); cursor: pointer;
}
.rows .row:last-child { border-bottom: none; }
.row:hover { background: var(--well); }
.row .grow { flex: 1; min-width: 0; }
.row .chev { color: var(--ink-3); flex: none; }

/* ── segmented control ─────────────────────────────────────────────── */
.seg { display: inline-flex; background: var(--track); border-radius: 10px; padding: 3px; gap: 2px; }
.seg > button {
  border: none; background: transparent; color: var(--ink-2);
  font: inherit; font-size: 14px; font-weight: 550;
  padding: .38rem .85rem; border-radius: 8px; cursor: pointer;
}
.seg > button.on {
  background: var(--surface); color: var(--acc);
  box-shadow: 0 1px 2px rgba(0,0,0,.06);
}

/* ── toggle ────────────────────────────────────────────────────────── */
.tog { position: relative; display: inline-block; width: 42px; height: 24px; flex: none; }
.tog input { opacity: 0; width: 0; height: 0; }
.tog .slider {
  position: absolute; inset: 0; background: #d8d8dd;
  border-radius: 999px; transition: background .15s; cursor: pointer;
}
.tog .slider::before {
  content: ''; position: absolute; height: 18px; width: 18px; left: 3px; top: 3px;
  background: #fff; border-radius: 50%; transition: transform .15s;
  box-shadow: 0 1px 2px rgba(0,0,0,.2);
}
.tog input:checked + .slider { background: var(--acc); }
.tog input:checked + .slider::before { transform: translateX(18px); }

/* ── inputs ────────────────────────────────────────────────────────── */
label { display: block; font-size: 14px; font-weight: 550; margin: .9rem 0 .35rem; }
label .req { color: var(--danger); }
input[type=text], input[type=email], input[type=password], input[type=number],
select, textarea {
  width: 100%; padding: .62rem .8rem;
  border: 1px solid var(--edge); border-radius: var(--radius-input);
  background: var(--surface); color: var(--ink);
  font: inherit; font-size: 15px;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--acc); box-shadow: 0 0 0 3px var(--acc-soft);
}
/* Keyboard focus on anything clickable, which the monochrome sheet left
   to the browser default and dark mode then made almost invisible. */
a:focus-visible, button:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--acc); outline-offset: 2px; border-radius: 6px;
}
a { color: var(--acc); }
::placeholder { color: var(--ink-3); }

/* Prompt card — the textarea and a footer bar INSIDE the same border,
   carrying hints and inline controls. This is the signature component of
   their agent editor. */
.prompt { border: 1px solid var(--edge); border-radius: var(--radius-card); overflow: hidden; }
.prompt textarea {
  border: none; border-radius: 0; resize: vertical; min-height: 92px; font-size: 15px;
}
.prompt textarea:focus { box-shadow: none; }
.prompt-foot {
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  padding: .5rem .8rem; background: var(--well);
  border-top: 1px solid var(--edge-soft); font-size: 13px; color: var(--ink-2);
}
.prompt-foot code {
  background: var(--track); border-radius: 5px; padding: .1rem .3rem; font-family: var(--mono);
}

/* ── search ────────────────────────────────────────────────────────── */
.search { position: relative; }
.search input { padding-left: 2.3rem; }
.search svg { position: absolute; left: .75rem; top: 50%; transform: translateY(-50%); color: var(--ink-3); }

/* ── table ─────────────────────────────────────────────────────────── */
/* width:100% inside an overflow-x:auto wrapper does not scroll - it
   shrinks to the wrapper and wraps every cell. min-width lets the table
   exceed its box, which is what makes the wrapper scroll. */
table.data { width: 100%; min-width: 460px; border-collapse: collapse; font-size: 14px; }
/* A timestamp is one thing; broken across four lines it stops being
   readable as a date at all. */
table.data td.when, table.data th.when { white-space: nowrap; }
table.data th {
  text-align: left; font-weight: 550; color: var(--ink-2);
  padding: .6rem .5rem; border-bottom: 1px solid var(--edge); white-space: nowrap;
}
table.data td { padding: .75rem .5rem; border-bottom: 1px solid var(--edge-soft); }
table.data tr:hover td { background: var(--well); }

/* ── accordion ─────────────────────────────────────────────────────── */
.acc { border: 1px solid var(--edge); border-radius: var(--radius-card); overflow: hidden; }
.acc summary {
  display: flex; align-items: center; gap: .7rem;
  padding: .85rem 1rem; cursor: pointer; list-style: none; background: var(--surface);
}
.acc summary::-webkit-details-marker { display: none; }
.acc[open] summary { border-bottom: 1px solid var(--edge-soft); }
.acc .acc-body { padding: 1rem; }

/* ── grouped menu ──────────────────────────────────────────────────────
   Unavailable items stay VISIBLE and greyed. Hiding them makes the menu
   move around between visits; greying teaches what exists. */
.menu { background: var(--surface); border: 1px solid var(--edge); border-radius: var(--radius-card);
        padding: .35rem; min-width: 240px; box-shadow: 0 8px 28px rgba(0,0,0,.12); }
.menu-label { font-size: 12px; color: var(--ink-3); padding: .5rem .7rem .25rem; font-weight: 550; }
.menu-item {
  display: flex; align-items: center; gap: .6rem;
  padding: .55rem .7rem; border-radius: 8px; cursor: pointer; font-size: 14.5px;
}
.menu-item:hover { background: var(--well); }
.menu-item.disabled { color: var(--ink-3); cursor: default; }
.menu-item.disabled:hover { background: transparent; }
.menu-sep { height: 1px; background: var(--edge-soft); margin: .35rem 0; }

/* ── empty states ──────────────────────────────────────────────────── */
.empty { text-align: center; padding: 2.5rem 1rem; }
.empty .icon {
  width: 46px; height: 46px; margin: 0 auto .8rem;
  display: grid; place-items: center;
  background: var(--surface); border: 1px solid var(--edge); border-radius: 12px;
}
.empty b { display: block; font-size: 16px; margin-bottom: .25rem; }
.empty-dashed { border: 1px dashed var(--edge); border-radius: var(--radius-card); color: var(--ink-3); }

/* ── checklist with progress ───────────────────────────────────────── */
.bar { height: 6px; background: var(--track); border-radius: 999px; overflow: hidden; }
/* A solid black bar is the heaviest thing on a light page and the reason
   these cards read as a 1990s installer. */
.bar > i { display: block; height: 100%; background: var(--acc); border-radius: 999px; }
.check { display: flex; align-items: center; gap: .65rem; padding: .5rem 0; font-size: 14.5px; }
.check .dot {
  width: 16px; height: 16px; border-radius: 50%; flex: none;
  border: 1.5px dashed var(--ink-3);
}
.check.done .dot { border: none; background: var(--ok); }

/* ── nav ───────────────────────────────────────────────────────────── */
.nav-sec { font-size: 12.5px; color: var(--ink-3); font-weight: 550; padding: 1rem .75rem .3rem; }
.nav-item {
  display: flex; align-items: center; gap: .65rem;
  padding: .55rem .75rem; border-radius: 8px;
  color: var(--ink); font-size: 14.5px; cursor: pointer; text-decoration: none;
}
.nav-item:hover { background: var(--well); }
.nav-item.on { background: var(--track); font-weight: 550; }
.nav-item .tail { margin-left: auto; }

/* ── avatar: the one place colour is allowed ───────────────────────── */
.avatar { width: 26px; height: 26px; border-radius: 50%; flex: none;
          background: conic-gradient(from 210deg, #5eead4, #0d9488, #99f6e4, #0f766e, #5eead4); }
.avatar-lg { width: 150px; height: 150px; }

.hr { height: 1px; background: var(--edge); border: 0; margin: 1.6rem 0; }

/* ── dark mode: still monochrome, just inverted ────────────────────── */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
  /* Lighter siblings: a 600-weight hue that reads on #fafbfb has
     about the luminance of the background itself on #0b0f10. */
  --c-green:  #4ade80;  --c-green-bg:  rgba(74, 222, 128, .14);
  --c-amber:  #fbbf24;  --c-amber-bg:  rgba(251, 191, 36, .14);
  --c-violet: #c4b5fd;  --c-violet-bg: rgba(196, 181, 253, .14);
  --c-blue:   #7dd3fc;  --c-blue-bg:   rgba(125, 211, 252, .14);
  --c-rose:   #fda4af;  --c-rose-bg:   rgba(253, 164, 175, .14);
    --bg: #0b0f10; --surface: #121819; --well: #18201f; --track: #1f2829;
    --edge: #242f31; --edge-soft: #1c2425;
    --ink: #eef2f2; --ink-2: #95a5a8; --ink-3: #66787c;
    --acc: #2dd4bf; --acc-hover: #5eead4;
    --acc-soft: rgba(45, 212, 191, .16); --acc-ink: #06211d;
  }
  :root:not([data-theme="light"]) .btn-primary { background: var(--acc); color: var(--acc-ink); }
  :root:not([data-theme="light"]) .btn-primary:hover:not(:disabled) { background: var(--acc-hover); }
  :root:not([data-theme="light"]) .split > .split-main,
  :root:not([data-theme="light"]) .split > .split-caret { background: var(--acc); color: var(--acc-ink); }
  :root:not([data-theme="light"]) .tog input:checked + .slider { background: var(--acc); }
  :root:not([data-theme="light"]) .tog input:checked + .slider::before { background: #ffffff; }
  :root:not([data-theme="light"]) .chip.on { background: var(--acc); color: var(--acc-ink); border-color: var(--acc); }
}
:root[data-theme="dark"] {
  /* Lighter siblings: a 600-weight hue that reads on #fafbfb has
     about the luminance of the background itself on #0b0f10. */
  --c-green:  #4ade80;  --c-green-bg:  rgba(74, 222, 128, .14);
  --c-amber:  #fbbf24;  --c-amber-bg:  rgba(251, 191, 36, .14);
  --c-violet: #c4b5fd;  --c-violet-bg: rgba(196, 181, 253, .14);
  --c-blue:   #7dd3fc;  --c-blue-bg:   rgba(125, 211, 252, .14);
  --c-rose:   #fda4af;  --c-rose-bg:   rgba(253, 164, 175, .14);
  --bg: #0b0f10; --surface: #121819; --well: #18201f; --track: #1f2829;
  /* Teal 600 sits too close to the dark surface in luminance to read; the
     theme already flips .btn-primary to near-white for this reason. */
  --acc: #2dd4bf; --acc-hover: #5eead4;
  --acc-soft: rgba(45, 212, 191, .16); --acc-ink: #06211d;
  --edge: #242f31; --edge-soft: #1c2425;
  --ink: #eef2f2; --ink-2: #95a5a8; --ink-3: #66787c;
}
:root[data-theme="dark"] .btn-primary { background: var(--acc); color: var(--acc-ink); }
:root[data-theme="dark"] .split > .split-main,
:root[data-theme="dark"] .split > .split-caret { background: var(--acc); color: var(--acc-ink); }
:root[data-theme="dark"] .tog input:checked + .slider { background: var(--acc); }
:root[data-theme="dark"] .tog input:checked + .slider::before { background: #ffffff; }
:root[data-theme="dark"] .chip.on { background: var(--acc); color: var(--acc-ink); border-color: var(--acc); }


/* ── live channel capacity ─────────────────────────────────────────────────
   Rendered by vs-core.js, which was written against the old shell.css. Its
   class names and colour variables did not exist here, so on /app the whole
   strip rendered as unstyled stacked text (measured: .chan-grid was
   display:block, .chan-cell had 0px padding, .chan-bar was 0px tall).
   Restated in el.css's own tokens. Monochrome per ELEVENLABS-UI-SPEC.md:35
   -- the only colour is the status dot. */
.chan{border:1px solid var(--edge);border-radius:var(--radius-card);background:var(--surface);
  padding:.9rem 1rem;margin-bottom:.9rem}
.chan-top{display:flex;flex-wrap:wrap;align-items:baseline;gap:.5rem 1.1rem}
.chan-big{font-size:2rem;font-weight:700;line-height:1;font-variant-numeric:tabular-nums;color:var(--ink)}
.chan-of{color:var(--ink-2);font-size:.82rem}
.chan-age{margin-left:auto;font-family:var(--mono);font-size:.66rem;letter-spacing:.06em;
  text-transform:uppercase;display:flex;align-items:center;gap:.35rem;color:var(--ink-3)}
.chan-age .d{width:8px;height:8px;border-radius:50%;background:var(--ok);flex:0 0 auto}
.chan-age.warn .d{background:var(--ink-3)}
.chan-age.bad .d{background:var(--danger)} .chan-age.bad{color:var(--danger)}

/* The usage bar. Two segments have to be told apart without an accent, so
   human is full ink and AI is muted ink. */
.chan-bar{height:10px;border-radius:6px;background:var(--track);overflow:hidden;
  margin:.7rem 0 .55rem;display:flex}
.chan-bar i{display:block;height:100%}
.chan-bar .hu{background:var(--ink)}
.chan-bar .aiseg{background:var(--ink-3)}
.chan-bar .oth{background:var(--edge)}
/* Legend swatches mirror the bar exactly, so the key actually keys. */
.chan-sw.sw-hu{background:var(--ink)}
.chan-sw.sw-ai{background:var(--ink-3)}
.chan-sw.sw-oth{background:var(--edge)}
.chan-cell .v .sub{font-size:.7rem;color:var(--ink-3);font-weight:400}

.chan-legend{display:flex;flex-wrap:wrap;gap:.35rem .9rem;font-size:.7rem;color:var(--ink-2)}
.chan-legend b{color:var(--ink);font-weight:600}
.chan-sw{display:inline-block;width:9px;height:9px;border-radius:2px;margin-right:.3rem;
  vertical-align:baseline}
.chan-dot{display:inline-flex;align-items:center}
.chan-dot .chan-sw{background:var(--ok)}
.chan-dot.warn .chan-sw{background:var(--ink-3)} .chan-dot.warn{color:var(--ink-2)}
.chan-dot.bad .chan-sw{background:var(--danger)} .chan-dot.bad{color:var(--danger)}

.chan-grid{display:grid;gap:.5rem;grid-template-columns:repeat(auto-fit,minmax(118px,1fr));
  margin-top:.7rem}
.chan-cell{background:var(--well);border:1px solid var(--edge);border-radius:9px;
  padding:.5rem .6rem;min-width:0}
.chan-cell .v{font-size:1.05rem;font-weight:600;font-variant-numeric:tabular-nums;color:var(--ink)}
.chan-cell .k{font-size:.63rem;color:var(--ink-3);text-transform:uppercase;letter-spacing:.05em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.chan-paused{margin-top:.55rem;padding:.4rem .55rem;border-radius:8px;font-size:.72rem;
  background:var(--well);border:1px solid var(--edge);color:var(--danger)}

/* The reserve boxes wrapped mid-label on a phone and ran off the edge.
   Each label+input+button is one non-wrapping group; the groups wrap. */
.chan-res{display:flex;flex-wrap:wrap;align-items:center;gap:.45rem .6rem;margin-top:.7rem;
  font-size:.72rem;color:var(--ink-2)}
.chan-res input{width:4.5rem;min-height:32px;margin:0;padding:.25rem .4rem;font-size:.78rem;
  font-family:var(--mono);text-align:center;background:var(--bg);color:var(--ink);
  border:1px solid var(--edge);border-radius:var(--radius-input)}
.chan-res button{min-height:32px;padding:.2rem .6rem;font-size:.7rem}
.chan-res .msg{flex:1 1 100%;color:var(--ink-3)}

/* A phone is 375px wide: the big number shrinks and the freshness stamp drops
   to its own line instead of being squeezed against it. */
@media (max-width: 840px){
  /* ── tap targets ────────────────────────────────────────────────────────
     Measured on the live Studio at 375x812: 168 real controls, and 168 of
     them under the 44x44 minimum — "Test call" at 76x32, the "···" menu at
     33x22, and "Resume"/"Start" on Campaigns at 32 high. Those last two begin
     outbound calling, so an undersized control there is a mis-tap risk on an
     action that dials customers.

     Heights only, and padding-block rather than padding, so nothing becomes
     WIDER: extra width is what would push a dense row into wrapping or
     sideways overflow. Desktop keeps the replica's compact sizing — this
     block only applies where the pointer is a finger. */
  .btn, .btn-sm { min-height: 44px; }
  .btn-sm { padding-block: .55rem; }
  .chip { min-height: 44px; padding-block: .55rem; }
  .dots { min-height: 44px; min-width: 44px; }
  input[type="checkbox"], input[type="radio"] { min-width: 22px; min-height: 22px; }
  /* EXCEPT a toggle switch: `.tog input` is deliberately collapsed to 0x0
     and the visible control is the .slider. Giving it a 22px minimum put a
     22px item inside a fixed 42px switch and shoved the label out. */
  .tog input { min-width: 0; min-height: 0; }
  /* Not .btn or .chip: bare buttons inside a .seg segmented control, and
     bare selects. Both sat at 33px with min-height:auto. */
  .seg button, select { min-height: 44px; }
  /* The flow canvas toolbar — undo, zoom, fit, full screen, ADD STEP —
     was 27x23. Add step being a coin toss is part of "cant create". */
  .fc-tb { min-width: 44px; min-height: 44px; font-size: 16px; }

  .chan{padding:.8rem .85rem}
  .chan-big{font-size:1.7rem}
  .chan-age{margin-left:0;width:100%}
  .chan-grid{grid-template-columns:repeat(auto-fit,minmax(104px,1fr))}
}

/* ── flow canvas: the step inspector ───────────────────────────────────────
   Was an inline `position:absolute;right:10px;width:268px` INSIDE #fc-wrap.
   On a phone that is a 268px overlay on a 346px canvas — 68px of flow left —
   and being inline, no media query could reach it. The positioning lives here
   now, and .fc-shell is the positioned ancestor so the desktop overlay is
   unchanged while the phone can stack it. */
.fc-shell { position: relative; }
.fc-insp {
  position: absolute; right: 10px; top: 10px; width: 268px; z-index: 5;
  background: var(--surface); border: 1px solid var(--edge);
  border-radius: 12px; padding: .7rem; box-shadow: 0 2px 10px rgba(0,0,0,.10);
}
@media (max-width: 840px){
  /* Stacked under the canvas, not over it: on a phone there is no room to be
     beside anything. Static also means it can no longer collide with the zoom
     toolbar, which sits at the bottom of the canvas at the same z-index. */
  .fc-insp {
    position: static; width: auto; margin-top: .6rem; box-shadow: none;
  }
}

/* ── flow canvas: full screen ──────────────────────────────────────────────
   A fixed inset overlay rather than the Fullscreen API: iOS Safari will not
   put an arbitrary element into real fullscreen, so the API would work on a
   desktop and silently do nothing on a phone. dvh for the same reason as the
   nav drawer — vh counts the strip behind the browser toolbar. */
.fc-shell.is-full {
  position: fixed; inset: 0; z-index: 200;
  background: var(--bg); padding: .6rem;
  display: flex; flex-direction: column;
}
.fc-shell.is-full #fc-wrap { height: 100dvh; flex: 1 1 auto; }
/* In full screen the inspector goes back to being an overlay even on a phone:
   there is room for it there, and stacking would halve the canvas again. */
.fc-shell.is-full .fc-insp {
  position: absolute; right: 12px; top: 12px; width: min(268px, 72vw);
  margin-top: 0; max-height: 70dvh; overflow-y: auto;
}
/* The page behind must not scroll while the canvas owns the screen. */
body.fc-full-open { overflow: hidden; }

/* While a wire or a node is being dragged the canvas owns the gesture outright.
   The rest of the time it stays pan-y so the page still scrolls over it. */
#fc-wrap.fc-dragging { touch-action: none; cursor: grabbing; }

/* ── the live voice test panel ──────────────────────────────────────────
   These rules existed only inside studio.html, so the panel rendered in the
   new app with NO styling at all: the mic was a small square button, the
   three stats stacked vertically instead of sitting in a row, and the
   transcript had no shape. It looked broken, and it was - just not in the
   way it appeared.

   Ported with the tokens mapped to this stylesheet: the classic page has an
   accent colour and a second panel shade, and this design is deliberately
   monochrome, so --acc becomes --ink and --panel2 becomes --well rather than
   inventing colours that exist nowhere else here. */
.agv-stage{border:1px solid var(--edge);border-radius:12px;background:var(--well);
  padding:1rem .9rem;display:flex;flex-direction:column;align-items:center;gap:.7rem;margin-bottom:.8rem}
.agv-ring{position:relative;display:flex;align-items:center;justify-content:center;width:108px;height:108px}
.agv-ring::before{content:"";position:absolute;width:100px;height:100px;border-radius:50%;
  border:2px solid var(--ink);opacity:0;pointer-events:none}
.agv-ring.pulse::before{animation:agvPulse 1.7s ease-out infinite}
@keyframes agvPulse{0%{opacity:.5;transform:scale(1)}100%{opacity:0;transform:scale(1.42)}}
.agv-mic{width:100px;height:100px;min-height:100px;border-radius:50%;padding:0;
  flex-direction:column;justify-content:center;gap:.15rem;font-size:.68rem;letter-spacing:.02em}
.agv-mic svg{width:28px;height:28px;stroke:currentColor;fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}
.agv-state{display:flex;align-items:center;gap:.45rem;font-family:var(--mono);font-size:.68rem;
  letter-spacing:.09em;text-transform:uppercase;color:var(--ink-2);min-height:1.1rem;text-align:center}
.agv-dot{width:9px;height:9px;border-radius:50%;background:var(--ink-3);flex:0 0 9px}
.agv-dot.live{animation:agvBlink 1.1s ease-in-out infinite}
@keyframes agvBlink{0%,100%{opacity:1}50%{opacity:.25}}
.agv-meter{display:flex;align-items:center;gap:2px;height:32px;width:100%;max-width:23rem}
.agv-meter i{flex:1 1 0;min-width:2px;height:10%;border-radius:2px;background:var(--edge-soft);
  transition:height .07s linear,background .12s linear}
.agv-meter i.on{background:var(--ink-3)}
.agv-meter i.hot{background:var(--ink)}
.agv-mhint{font-family:var(--mono);font-size:.62rem;color:var(--ink-3);letter-spacing:.06em;text-transform:uppercase}
.agv-mhint.bad{color:var(--danger)}
.agv-log{border:1px solid var(--edge);border-radius:10px;background:var(--well);padding:.7rem;
  min-height:11rem;max-height:42vh;overflow-y:auto;display:flex;flex-direction:column;gap:.5rem}
.agv-b{max-width:82%;padding:.5rem .7rem;border-radius:12px;font-size:.85rem;
  white-space:pre-wrap;word-break:break-word}
.agv-b.a{align-self:flex-start;background:var(--surface);border:1px solid var(--edge-soft);border-bottom-left-radius:4px}
.agv-b.u{align-self:flex-end;background:var(--well);border:1px solid rgba(232,163,61,.28);border-bottom-right-radius:4px}
.agv-b.e{align-self:flex-start;background:var(--well);border:1px solid rgba(240,113,106,.3);color:var(--danger)}
.agv-b.interim{opacity:.6;border-style:dashed}
.agv-b .who{font-family:var(--mono);font-size:.6rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--ink-3);display:block;margin-bottom:.15rem}
.agv-b .lat{font-family:var(--mono);font-size:.6rem;color:var(--ink-3);display:block;margin-top:.28rem}

/* Classes the shared voice panel uses that only the classic page defined.
   Without them the three stats stacked down the page instead of sitting in a
   row, and the tuning drawer and hint text had no shape at all. Same token
   mapping as the .agv- block above: this palette is monochrome, so the
   classic accent and second panel shade become --ink and --well. */
.grid{display:grid;gap:.7rem}
.grid.g3{grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:640px){ .grid.g3{grid-template-columns:1fr} }
.stat{background:var(--surface);border:1px solid var(--edge);border-radius:12px;padding:.8rem .9rem;min-width:0}
.stat .v{font-family:var(--mono);font-size:1.25rem;font-weight:600;letter-spacing:-.02em}
.stat .k{color:var(--ink-3);font-size:.7rem;margin-top:.1rem}
.hint{color:var(--ink-3);font-size:.78rem;margin-bottom:.7rem}
.hint.sm{margin:.25rem 0 0;font-size:.72rem}
.ghost{background:var(--well);color:var(--ink);border:1px solid var(--edge-soft);
  border-radius:var(--radius-btn);padding:.4rem .7rem;cursor:pointer;font:inherit;font-size:.85rem}
.ghost:hover{border-color:var(--ink-3)}
.togrow{display:flex;align-items:center;gap:.8rem;padding:.55rem 0}
.togrow .t{display:flex;flex-direction:column;gap:.15rem;min-width:0}
.togrow .t b{font-size:.9rem}
.togrow .t span{color:var(--ink-3);font-size:.78rem}
.fix{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;min-width:0}
.fix > *{min-width:0;max-width:100%}
.agvt{border:1px solid var(--edge);border-radius:12px;padding:.6rem .75rem;margin-bottom:.7rem}
.agvt-hd{display:flex;align-items:center;justify-content:space-between;gap:.5rem;cursor:pointer}
.agvt-body{margin-top:.6rem}
.agvt-row{display:flex;align-items:center;gap:.6rem;margin-bottom:.45rem;flex-wrap:wrap}
.agvt-foot{display:flex;align-items:center;gap:.5rem;margin-top:.5rem;flex-wrap:wrap}
.agvt-live{color:var(--ok);font-size:.72rem}
