/* Playbakk — screens in the Qlaas language (research QLAAS_LANGUAGE, design/tokens.json v2). Palettes and every colour
   live in tokens.css; motifs, message styles, corners, density and per-theme type in themes.css (both load before
   this file). This file uses tokens only. Light first; one curvature (controls are pills, cards 28/32, panes
   clamp(24,3vw,40)); open space; flat: no gradients, no box-shadow, no scale; tone and hairlines separate; glass only
   on the floating tab-bar island. Motion: colour 240 ms ease-soft, sheets and panes 480 ms ease-settle in / 240 ms
   out, nothing loops. Physical left/right are logical (RTL, docs/I18N.md). */
@font-face { font-family: "Sora"; src: url(fonts/sora.woff2) format("woff2"); font-weight: 100 800; font-style: normal; font-display: swap; }
/* v1 names older modules still use, mapped onto the v2 tokens */
:root {
  --f: var(--font); --m: var(--mono); --e: var(--ease-soft); --es: var(--ease-settle); --ease-in: var(--ease-settle); --ease-out: var(--ease-soft);
  --r-btn: var(--r-pill); --r-sheet: var(--r-pane); --r-xs: 4px; --r-s: 8px; --r-m: var(--r-in); --r-l: var(--r-row); --r-xl: var(--r-card);
  --r-loop: var(--r-pill); --r-inset: var(--r-in); --r-ctl: var(--r-row); --d-2: var(--d2);
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--t1); }
body {
  font-family: var(--font); font-size: var(--fs-body); line-height: var(--lh-body); font-weight: var(--w-body); letter-spacing: var(--tr-body);
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; font-optical-sizing: auto;
}
button, input, textarea, select { font: inherit; color: inherit; letter-spacing: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }
/* focus: 2 px t1, offset 2, never brass, never a glow, :focus-visible only */
button:focus-visible, a:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible, summary:focus-visible, video:focus-visible, [tabindex="0"]:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
/* programmatic focus targets (dialogs, headings that receive focus after a change) */
[tabindex="-1"]:focus { outline: none; }
.sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
::placeholder { color: var(--t3); opacity: 1; }
input.in, .fx-pal-in, .collab-in { text-overflow: ellipsis; }
::selection { background: var(--inv-bg); color: var(--inv-t); }
[dir=rtl] .ic.flip { transform: scaleX(-1); }
a { color: inherit; }
/* type: large and light. Titles 28–32 / 300, display 40–56 / 250, headings 18 / 400, body 15 / 350 */
h1 { font-size: var(--fs-title); line-height: var(--lh-title); font-weight: var(--w-title); letter-spacing: var(--tr-title); margin: 0; }
h2 { font-size: var(--fs-heading); line-height: var(--lh-heading); font-weight: var(--w-heading); letter-spacing: var(--tr-heading); margin: 0; }
h3 { font-size: var(--fs-body); line-height: var(--lh-body); font-weight: var(--w-heading); letter-spacing: var(--tr-body); margin: 0; }
p { margin: 0; }
strong, b { font-weight: var(--w-strong); }
.display { font-size: var(--fs-display); line-height: var(--lh-display); font-weight: var(--w-display); letter-spacing: var(--tr-display); }
.mono { font-family: var(--mono); font-size: var(--fs-mono); line-height: var(--lh-mono); letter-spacing: 0; }
.small { font-size: var(--fs-body-s); line-height: var(--lh-body-s); }
.muted { color: var(--t2); }
.micro, time { font-variant-numeric: tabular-nums; }
.ic { flex: none; }
[hidden] { display: none !important; }
/* a theme, scheme, density or size change applies instantly (web/theme.ts sets data-sw for one frame) */
html[data-sw] *, html[data-sw] *::before, html[data-sw] *::after { transition: none !important; }
.tnum, .msg-time, .c-time, .k-meta, .life-ends, .mono { font-variant-numeric: tabular-nums; }

/* labels: caps 11 px, tracked, muted. A section label is preceded by a 20 px hairline in the rule colour (never
   brass: brass is the one "you are here in time" marker). Form labels and spec-sheet labels carry no rule. */
.cap, .klabel, .tag, .menu-cap, .ic-label, .steps, .flabel, .field label, .grid dt, .k-urg, .rrow .r-k {
  font-size: var(--fs-label); line-height: var(--lh-label); font-weight: var(--w-label); letter-spacing: var(--tr-label); text-transform: var(--tt-label); color: var(--t2);
}
.cap { margin: 0; }
.cap:not(label, summary, .row > .cap, .bub .cap)::before { content: ""; display: inline-block; inline-size: 20px; block-size: 1px; margin-inline-end: 12px; vertical-align: middle; background: var(--line); }
/* user data and proper names inside a caps label keep their own case and spacing */
:is(.cap, .btn, .tag, .ic-label, .grid dt) :is(bdi, .mono) { text-transform: none; letter-spacing: 0; }

/* glass: only where content scrolls beneath a floating layer (the tab-bar island). Flat: tone + blur, no shadow.
   Solid under reduced transparency and in Night and Contrast (tokens.css). */
.glass { background: var(--solid); }

/* panes: the card tone (tokens.css --card: s1 in the dark twins, the stone step in the light twins) and, inside a pane,
   every control that stands on the raised tone (--s2: secondary buttons, choices, avatars, segments, the sample
   composer) moves to --on-card so it still reads; the hairlines and the field underline are re-derived on the pane
   tone (Contrast keeps its own visible line). A selected pane is a 5 % ink tint of the pane, never the control tone. */
.kcard, .intent-card, .fr-card, .reach, .choice, .erow, .door, .safety, .auto-row, .onb [data-group=pk-offer], .hl-tile, .hl-card, .hl-pre, .fx-card, .fx-preview {
  --s2: var(--on-card); --bub-them: var(--on-card); --field-line: var(--t2); --card-on: color-mix(in srgb, var(--t1) 5%, var(--card));
}
[data-scheme="light"]:not([data-theme="contrast"]) :is(.kcard, .intent-card, .fr-card, .reach, .choice, .erow, .door, .safety, .auto-row, .onb [data-group=pk-offer], .hl-tile, .hl-card, .hl-pre, .fx-card, .fx-preview) {
  --line: color-mix(in srgb, var(--t1) 14%, var(--card));
}

/* buttons: pills, 48 px (56 for the full-width primary), no borders, a caps label. One primary per view (inverse);
   secondary on the raised tone; text buttons for quiet secondaries. Hover and press are a tint change only. */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: var(--tap); padding: 12px 24px; border-radius: var(--r-pill); background: var(--s2); color: var(--t1); border: 0; font-size: var(--fs-btn); line-height: 1rem; font-weight: var(--w-label); letter-spacing: var(--tr-btn); text-transform: var(--tt-label); text-decoration: none; text-align: center; white-space: normal; overflow-wrap: break-word; min-width: 0; transition: var(--tint); }
.btn:hover { background: color-mix(in srgb, var(--t1) 8%, var(--s2)); }
.btn:active { background: color-mix(in srgb, var(--t1) 14%, var(--s2)); }
.btn.primary { background: var(--inv-bg); color: var(--inv-t); }
.btn.primary:hover { background: color-mix(in srgb, var(--bg) 12%, var(--inv-bg)); }
.btn.primary:active { background: color-mix(in srgb, var(--bg) 20%, var(--inv-bg)); }
.btn.primary small { display: block; max-width: 100%; white-space: normal; text-align: center; font-size: var(--fs-micro); line-height: var(--lh-micro); font-weight: var(--w-body); letter-spacing: 0; text-transform: none; color: var(--inv-t2); opacity: 1; }
.btn.primary:has(small) { flex-direction: column; gap: 4px; padding: 12px 24px; min-height: var(--tap-primary); }
.btn.text, .btn.ghost { background: transparent; padding-inline: 16px; }
.btn.text:hover, .btn.ghost:hover { background: color-mix(in srgb, var(--t1) 6%, transparent); }
.btn.text:active, .btn.ghost:active { background: color-mix(in srgb, var(--t1) 12%, transparent); }
.btn.danger, .btn.text.danger, .danger { color: var(--danger); }
/* compact buttons are sentence case and keep the minimum target */
.btn.small { min-height: var(--tap-min); padding: 8px 16px; font-size: var(--fs-body-s); line-height: var(--lh-body-s); font-weight: var(--w-heading); letter-spacing: 0; text-transform: none; }
.btn.wide { width: 100%; min-height: var(--tap-primary); margin-top: 8px; }
.btn[disabled] { opacity: .45; pointer-events: none; }
.btn.primary[disabled] { opacity: 1; background: var(--s2); color: var(--t3); }
.icon-btn { width: var(--tap-min); height: var(--tap-min); flex: none; display: inline-grid; place-items: center; border-radius: var(--r-pill); color: var(--t1); transition: var(--tint); }
.icon-btn:hover { background: color-mix(in srgb, var(--t1) 6%, transparent); }
/* inline text links: sentence case, underlined */
.link { color: var(--t2); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; font: inherit; line-height: 1rem; padding: 4px; margin-block: -4px; transition: color var(--d2) var(--ease-soft); }
.link:hover { color: var(--t1); }
/* legacy hooks other modules still use: in-bubble time (groups, imports), tags, the boot mark */
.bt { position: absolute; inset-inline-end: 12px; bottom: 4px; font-size: var(--fs-micro); line-height: var(--lh-micro); color: var(--t3); opacity: 1; }
.bub.me .bt { color: var(--inv-t2); }
.tag { display: inline-flex; align-items: center; gap: 4px; margin-inline-start: 8px; white-space: nowrap; }
.tag.ghost { color: var(--t3); }
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip { display: inline-flex; align-items: center; min-height: 32px; padding: 4px 12px; border-radius: var(--r-pill); background: var(--s2); color: var(--t2); font-size: .75rem; }
.dot { width: 18px; height: 18px; border-radius: 50%; border: 3px solid var(--t1); position: relative; }
.dot::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--t1); }
.boot { min-height: 100dvh; display: grid; place-items: center; }
.brand.big { display: flex; gap: 8px; align-items: center; font-weight: var(--w-heading); }
.ic.sym { display: block; }
.klabel { margin-inline-start: 8px; white-space: nowrap; flex: none; }
.foot { color: var(--t2); font-size: var(--fs-body-s); line-height: var(--lh-body-s); display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 0; }
.err { color: var(--danger); font-size: var(--fs-body-s); }
.wrap { white-space: normal !important; }

/* --- shell: rail 88 | list 360 (320 under 1024, 400 from 1280) | main; one pane under 760 with the floating tab-bar island ----- */
#app { height: 100%; }
.shell { --rail-w: max(88px, 5.5rem); display: grid; grid-template-columns: var(--rail-w) 360px minmax(0, 1fr); height: 100dvh; background: var(--bg); }
.rail { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 24px 0 16px; background: var(--bg); border-inline-end: 1px solid var(--line); z-index: 5; min-height: 0; overflow-y: auto; scrollbar-width: none; }
.rail .brand { display: grid; place-items: center; height: 48px; margin-bottom: 12px; color: var(--t1); flex: none; }
.nav-btn { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; width: max(72px, 4.5rem); min-height: 56px; padding: 8px 4px; border-radius: var(--r-pill); color: var(--t2); flex: none; transition: var(--tint); }
.nav-btn:hover { color: var(--t1); background: color-mix(in srgb, var(--t1) 6%, transparent); }
.nav-btn.on { background: var(--inv-bg); color: var(--inv-t); }
.nav-ic { position: relative; display: grid; place-items: center; }
.nav-label { font-size: var(--fs-micro); line-height: var(--lh-micro); font-weight: var(--w-heading); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.badge { min-width: 18px; height: 18px; padding: 0 4px; border-radius: var(--r-pill); background: var(--t1); color: var(--bg); font-size: var(--fs-micro); font-weight: 600; line-height: 18px; text-align: center; font-variant-numeric: tabular-nums; }
.nav-ic .badge { position: absolute; top: -6px; inset-inline-start: 13px; }
.ndot { position: absolute; top: -1px; inset-inline-start: 18px; width: 6px; height: 6px; border-radius: 50%; background: var(--t1); }
.nav-btn.on .badge { background: var(--inv-t); color: var(--inv-bg); }
.nav-btn.on .ndot { background: var(--inv-t); }
.net { margin-top: auto; width: 6px; height: 6px; border-radius: 50%; border: 1.5px solid var(--t2); flex: none; }
.net.on { background: var(--t3); border-color: var(--t3); }
/* cards in the list column keep the 24 px padding at every width (the column is at most 400 px, a phone's width); 16 in compact */
[data-density="compact"] .list-pane { --card-pad: 16px; }
.list-pane { --card-pad: 24px; overflow-y: auto; min-width: 0; border-inline-end: 1px solid var(--line); background: var(--bg); overscroll-behavior: contain; }
.main-pane { min-width: 0; overflow: hidden; position: relative; background: var(--bg); }
.pane { min-height: 100%; padding-bottom: 48px; }
.pane-head { position: sticky; top: 0; z-index: 3; display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 88px; padding: 24px var(--gutter) 16px; background: var(--bg); }
.pane-head h1 { font-size: var(--fs-title); line-height: var(--lh-title); font-weight: var(--w-title); letter-spacing: var(--tr-title); margin: 0; overflow-wrap: anywhere; }
.pane-head h2 { font-size: var(--fs-heading); line-height: var(--lh-heading); font-weight: var(--w-heading); letter-spacing: var(--tr-heading); margin: 0; }
.ph-t { min-width: 0; }
.pane-head .sub { color: var(--t2); font-size: var(--fs-body-s); line-height: var(--lh-body-s); margin-top: 4px; }
.head-acts { display: flex; gap: 4px; margin-inline-end: -12px; flex: none; }
.empty-main { height: 100%; display: grid; place-content: center; justify-items: center; text-align: center; gap: 16px; padding: 48px; max-width: 640px; margin: 0 auto; color: var(--t2); }
.empty-main .mark { color: var(--t1); margin-bottom: 16px; }
.empty-main h2 { font-size: clamp(1.75rem, .75rem + 2.6vw, 3.5rem); line-height: var(--lh-display); font-weight: var(--w-display); letter-spacing: var(--tr-display); color: var(--t1); margin: 0; text-wrap: balance; }
.empty-main p { margin: 0; font-size: var(--fs-lead); line-height: var(--lh-lead); max-width: 40ch; }
.empty { text-align: center; padding: 64px 24px; color: var(--t2); display: grid; gap: 12px; justify-items: center; }
.empty h3 { color: var(--t1); font-size: var(--fs-title); line-height: var(--lh-title); font-weight: var(--w-title); letter-spacing: var(--tr-title); margin: 0; text-wrap: balance; }
.empty p { margin: 0; max-width: 36ch; }
.acts-text { display: flex; gap: 4px; flex-wrap: wrap; align-items: center; }
.empty .acts-text { justify-content: center; margin-top: 8px; }

/* filters, quiet rows */
.filters { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 var(--gutter) 24px; }
.fchip { flex: none; min-height: var(--tap-min); padding: 0 16px; border-radius: var(--r-pill); background: var(--s2); color: var(--t2); font-size: var(--fs-body-s); font-weight: var(--w-heading); transition: var(--tint); }
.fchip:hover { color: var(--t1); }
.fchip.on { background: var(--inv-bg); color: var(--inv-t); }
.auto-row { display: flex; align-items: center; gap: 12px; width: calc(100% - 2 * var(--gutter)); margin: 0 var(--gutter) 16px; min-height: var(--tap); padding: 12px 24px; border-radius: var(--r-pill); background: var(--card); color: var(--t2); font-size: var(--fs-body-s); line-height: var(--lh-body-s); text-align: start; transition: var(--tint); }
.auto-row > span { flex: 1; min-width: 0; }
.auto-row:hover { color: var(--t1); }
.auto-row .chev { margin-inline-start: auto; }

/* avatars (DOM contract .av/.av-h/.av-a): kind by shape, never colour. People are circles; agents a squircle. */
.av { width: var(--s, 40px); height: var(--s, 40px); flex: none; display: inline-grid; place-items: center; background: var(--s2); color: var(--t1); font-weight: var(--w-heading); font-size: calc(var(--s, 40px) * .36); letter-spacing: .02em; }
.av-h { border-radius: 50%; }
.av-a { border-radius: 32%; }
.av-g { border-radius: 32%; }
.avatar { display: inline-grid; place-items: center; width: 40px; height: 40px; flex: none; border-radius: 50%; background: var(--s2); }

/* --- knock cards: a solid raised card, 28/32, padded 24/32; who → principal → purpose → scope → actions → meta ---- */
.cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; padding: 0 var(--gutter) 24px; }
/* the list column is narrower than a phone up to 1023 (320 px beside the rail): panes keep the phone's 12 px inset there */
@media (max-width: 1023px) { .cards { padding-inline: 12px; } }
.kcard { position: relative; background: var(--card); border-radius: var(--r-card); padding: var(--card-pad); display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--k-gap, 16px); min-width: 0; color: var(--t1); }
.kcard > * { min-width: 0; margin: 0; }
.kcard.on { background: var(--card-on); }
.kcard.leaving { height: 0 !important; padding-block: 0; opacity: 0; overflow: hidden; margin-bottom: -16px; transition: height var(--d2) var(--ease-soft), padding var(--d2) var(--ease-soft), opacity var(--d2) var(--ease-soft), margin var(--d2) var(--ease-soft); }
@media (min-width: 760px) { .kcard[data-knock] { cursor: default; } }
.k-head { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 16px; align-items: center; }
.k-head > .more { position: absolute; top: 12px; inset-inline-end: 12px; }
.kcard .k-id > .name { padding-inline-end: 32px; }
.k-id { min-width: 0; display: grid; gap: 4px; }
.name { display: flex; align-items: center; min-width: 0; font-weight: var(--w-heading); }
.name > bdi { min-width: 0; overflow-wrap: anywhere; }
.kcard .name { font-size: var(--fs-heading); line-height: var(--lh-heading); letter-spacing: var(--tr-heading); flex-wrap: wrap; column-gap: 8px; }
.kcard .name > .klabel, .kcard .name > .k-urg { margin-inline-start: 0; }
.pl { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; color: var(--t2); font-size: var(--fs-body-s); line-height: var(--lh-body-s); min-width: 0; }
.pl .mono { overflow-wrap: anywhere; }
.k-urg { color: var(--t1); flex: none; }
.purpose { font-size: var(--fs-lead); line-height: var(--lh-lead); overflow-wrap: anywhere; text-wrap: pretty; }
.purpose.full { display: block; }
.purpose2, .k-scope { color: var(--t2); font-size: var(--fs-body-s); line-height: var(--lh-body-s); }
.k-novel { font-size: var(--fs-body-s); line-height: var(--lh-body-s); font-weight: var(--w-strong); color: var(--t1); margin: 0; }
/* a returning knock whose name matches someone this device blocked (web/blocks.ts sameNameHint): neutral, never accusing */
.same-name { color: var(--t2); font-size: var(--fs-body-s); line-height: var(--lh-body-s); margin: 0; border-inline-start: 2px solid var(--ctl); padding-inline-start: 12px; }
/* "Let in for": message / voice / video pressed as the person asked (upstream 0e48b66) */
.k-pick { display: grid; gap: 8px; }
.k-meta { color: var(--t3); font-size: var(--fs-micro); line-height: var(--lh-micro); }
.acts { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.kcard .acts .btn.primary { flex: 1 1 100%; min-width: 0; }
@media (min-width: 760px) { .kcard .acts .btn.primary { flex: 0 1 auto; } }
.acts-2 { display: flex; gap: 4px; align-items: center; flex-wrap: wrap; min-width: 0; }
.acts-2 > .btn { padding-inline: 16px; }
.safety-acts, .safety-bar { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.safety-bar { padding: 8px 16px; background: var(--bg); border-bottom: 1px solid var(--line); }

/* overflow menus (details/summary) and the composer's + popover: solid, flat, a hairline edge */
.more { position: relative; }
.more > summary { list-style: none; display: grid; place-items: center; width: var(--tap-min); height: var(--tap-min); border-radius: var(--r-pill); color: var(--t2); cursor: pointer; transition: var(--tint); }
.more > summary::-webkit-details-marker { display: none; }
.more > summary:hover, .more[open] > summary { background: color-mix(in srgb, var(--t1) 8%, transparent); color: var(--t1); }
.menu { position: absolute; inset-inline-end: 0; top: calc(100% + 8px); z-index: 30; min-width: 240px; max-width: min(320px, calc(100vw - 24px)); padding: 8px; border-radius: var(--r-row); background: var(--solid); border: 1px solid var(--line); display: grid; color: var(--t1); }
.menu.up { top: auto; bottom: calc(100% + 8px); inset-inline-end: auto; inset-inline-start: 0; }
.menu > button, .menu > a, .menu .tr-ctl { display: flex; gap: 12px; align-items: center; width: 100%; min-height: var(--tap-min); padding: 8px 16px; border-radius: var(--r-in); text-align: start; color: var(--t1); font-size: var(--fs-body); line-height: 1.25rem; white-space: normal; margin: 0; transition: var(--tint); }
.menu > button:hover, .menu > a:hover, .menu .tr-ctl:hover { background: var(--s2); }
.menu > .danger { color: var(--danger); }
.menu .tr-ctl .ic { display: none; }
.menu-cap { padding: 12px 16px 4px; }
.menu .ic { color: var(--t2); }

/* --- rows: chats (72 / 56 compact), passes, calls, Line; 24 px from the pane edge ------------------------------- */
.rows { list-style: none; margin: 0; padding: 0 8px 8px; display: grid; gap: 4px; }
.crow { width: 100%; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-rows: auto auto; column-gap: 16px; row-gap: 2px; align-items: center; min-height: var(--row-h, 72px); padding: 12px 16px; border-radius: var(--r-row); text-align: start; color: var(--t1); transition: var(--tint); }
.crow > .av { grid-column: 1; grid-row: 1 / span 2; --s: var(--av-row, 48px) !important; }
.crow > .c-name { grid-column: 2; grid-row: 1; }
.crow > .c-time { grid-column: 3; grid-row: 1; }
.crow > .prev { grid-column: 2; grid-row: 2; }
.crow > .c-state { grid-column: 3; grid-row: 2; }
.crow:hover { background: var(--s1); }
.crow.on { background: var(--s2); }
.c-name { display: flex; align-items: center; min-width: 0; font-weight: var(--w-heading); font-size: var(--fs-body); line-height: var(--lh-body); }
.c-name > bdi { min-width: 0; overflow-wrap: anywhere; }
.c-time { justify-self: end; align-self: start; padding-top: 4px; color: var(--t3); font-size: var(--fs-micro); line-height: var(--lh-micro); white-space: nowrap; flex: none; }
.crow .prev { grid-column: 2; }
.c-state { grid-column: 3; justify-self: end; display: flex; align-items: center; min-height: 14px; }
.udot { width: 8px; height: 8px; border-radius: 50%; background: var(--t1); }
.c-end { color: var(--t2); font-size: var(--fs-micro); line-height: var(--lh-micro); white-space: nowrap; }
.needs { color: var(--t1); font-weight: var(--w-heading); }
.cmid { flex: 1; min-width: 0; }
.prev { color: var(--t2); font-size: var(--fs-body-s); line-height: var(--lh-body-s); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.lrow { display: flex; gap: 16px; align-items: center; width: 100%; min-height: var(--row-h, 72px); padding: 12px 16px; border-radius: var(--r-row); text-align: start; color: var(--t1); transition: var(--tint); }
button.lrow:hover, .prow:hover, .call-row:hover { background: var(--s1); }
.lrow.on { background: var(--s2); }
.lrow .name { font-size: var(--fs-body); line-height: var(--lh-body); }
.lrow:not(.fx-saved-row) .prev { white-space: normal; overflow-wrap: anywhere; }
.lrow > .ic { color: var(--t2); }
.group { padding: 8px var(--gutter) 32px; display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; min-width: 0; }
.group .btn.wide { margin-top: 4px; }
.group > .rows { padding: 0; margin-inline: -16px; }
.group > summary { cursor: pointer; padding: 8px 0; list-style-position: inside; }
.group.head-row { padding-bottom: 4px; }
.proof { color: var(--t3); font-size: var(--fs-micro); }
.dot-s { width: 8px; height: 8px; border-radius: 50%; border: 1.5px solid var(--t3); flex: none; }
.dot-s.on { background: var(--t1); border-color: var(--t1); }
.erow { display: grid; gap: 4px; padding: 16px 24px; border-radius: var(--r-row); background: var(--card); }
.erow + .erow { margin-top: 8px; }
.erow > button { text-align: start; font-size: .875rem; line-height: 1.25rem; color: var(--t2); padding: 2px 0; }
.erow > button:hover strong { text-decoration: underline; text-underline-offset: 3px; }
.erow strong { color: var(--t1); font-weight: var(--w-heading); }
.erow .acts-text { margin-inline-start: -16px; }
.suggest { max-width: 32ch; color: var(--t1); }
.rrow .name { white-space: normal; }

/* --- conversation (DOM contract: .conv > .conv-head, .thread::before motif, .thread-col, .msg rows) ------------- */
.conv { display: flex; flex-direction: column; height: 100dvh; min-width: 0; position: relative; background: var(--bg); container: conv / inline-size; }
.conv > * { min-width: 0; }
/* banners, pinned strip, safety bar, dock: the thread stays the one flexible region */
.conv > :not(.thread) { flex: none; }
.conv-head { position: relative; display: flex; align-items: center; gap: 12px; min-height: 72px; padding: 12px 16px 12px 24px; background: var(--bg); border-bottom: 1px solid var(--line); z-index: 4; flex: none; }
.conv-head .back { display: none; }
.conv-head .who { flex: 1; min-width: 0; }
.conv-head .name { font-size: var(--fs-heading); line-height: var(--lh-heading); letter-spacing: var(--tr-heading); flex-wrap: wrap; }
.conv-head .pl { display: block; overflow-wrap: anywhere; }
.conv-head > .icon-btn, .conv-head > .av, .conv-head > .more { flex: 0 0 auto; }
.conv-head > .pchip { flex: 0 0 auto; min-width: 0; }
.pchip { display: inline-flex; align-items: center; gap: 4px; min-height: var(--tap-min); padding-block: 0; padding-inline: 16px 8px; border-radius: var(--r-pill); background: var(--s2); color: var(--t1); font-size: var(--fs-body-s); line-height: var(--lh-body-s); white-space: nowrap; transition: var(--tint); }
.pchip:hover { background: color-mix(in srgb, var(--t1) 8%, var(--s2)); }
.pchip-t { min-width: 0; }
.pchip .ic { color: var(--t2); flex: none; }
/* The conversation contract elements (.thread, .thread-col, .msg, .msg-author, .bubble, .msg-time, .day-sep,
   .new-anchor, .marker, .sys-line, .thread-start, the .intent-card chassis) are styled by the theme lane
   (web/themes.css: motifs, message styles, corners, density). What follows is a zero-specificity :where() base with
   the same grid model, so it renders on its own and every theme rule wins whatever the load order. */
.thread { flex: 1; min-height: 0; }
:where(.thread) { position: relative; overflow-y: auto; overscroll-behavior: contain; }
.thread:not(:has(.thread-col)) { display: flex; flex-direction: column; padding: 16px 24px 24px; gap: 8px; }
:where(.thread-col) { --bub-max: min(88%, 560px); --time-w: 2.75rem; position: relative; z-index: 1; display: flex; flex-direction: column; width: 100%; max-width: 760px; margin: 0 auto; padding: 12px 16px 24px; }
@media (min-width: 760px) { :where(.thread-col) { --bub-max: min(72%, 560px); padding-inline: 24px; } }
:where(.thread-start) { display: grid; justify-items: center; gap: 4px; max-width: 400px; margin: 0 auto 16px; padding-top: 48px; text-align: center; }
.thread-start .av { margin-bottom: 12px; }
:where(.ts-name) { font-size: var(--fs-title); line-height: var(--lh-title); font-weight: var(--w-title); letter-spacing: var(--tr-title); }
.thread-start .pl { justify-content: center; }
:where(.ts-meta) { color: var(--t2); font-size: var(--fs-body-s); line-height: var(--lh-body-s); margin: 4px 0 0; }
:where(.ts-proof) { color: var(--t3); font-size: var(--fs-micro); line-height: var(--lh-micro); margin: 4px 0 0; }
.ts-proof .link { color: var(--t2); }
:where(.day-sep, .new-anchor) { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 24px 0 12px; font-size: var(--fs-label); line-height: var(--lh-label); font-weight: var(--w-label); letter-spacing: var(--tr-label); text-transform: var(--tt-label); color: var(--t2); font-variant-numeric: tabular-nums; }
:where(.new-anchor) { color: var(--t1); }
/* brass = "you are here in time": one per screen, always with its text */
:where(.marker) { display: inline-block; flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--marker); }
body:has(.sheet-wrap.in) .new-anchor .marker { visibility: hidden; }
:where(.msg) { display: grid; grid-template-columns: fit-content(var(--bub-max)) auto; grid-template-areas: "a a" "b t"; justify-content: start; align-items: end; column-gap: 8px; margin-top: var(--gap-between, 12px); min-width: 0; }
:where(.msg[data-pos="mid"], .msg[data-pos="last"]) { margin-top: var(--gap-group, 2px); }
:where(.msg[data-me="1"]) { grid-template-columns: auto fit-content(var(--bub-max)); grid-template-areas: "a a" "t b"; justify-content: end; }
/* the author is always in the DOM (screen readers, the transcript and letter styles); visually hidden elsewhere */
.msg-author { grid-area: a; }
html:not([data-msg="transcript"]):not([data-msg="letter"]) .msg-author { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
:where(.bubble) { grid-area: b; min-width: 0; max-width: 64ch; padding: var(--bub-py, 8px) var(--bub-px, 16px); border-radius: var(--r-bub, 22px); background: var(--bub-them); color: var(--t1); font-size: var(--msg-fs, .9375rem); line-height: var(--msg-lh, 1.375rem); white-space: pre-wrap; overflow-wrap: anywhere; }
:where(.msg[data-me="1"] .bubble) { background: var(--bub-me); color: var(--bub-me-t); }
:where(.msg[data-me="0"][data-pos="first"] .bubble) { border-end-start-radius: var(--r-join, 8px); }
:where(.msg[data-me="0"][data-pos="mid"] .bubble) { border-start-start-radius: var(--r-join, 8px); border-end-start-radius: var(--r-join, 8px); }
:where(.msg[data-me="0"][data-pos="last"] .bubble) { border-start-start-radius: var(--r-join, 8px); }
:where(.msg[data-me="1"][data-pos="first"] .bubble) { border-end-end-radius: var(--r-join, 8px); }
:where(.msg[data-me="1"][data-pos="mid"] .bubble) { border-start-end-radius: var(--r-join, 8px); border-end-end-radius: var(--r-join, 8px); }
:where(.msg[data-me="1"][data-pos="last"] .bubble) { border-start-end-radius: var(--r-join, 8px); }
/* time: on the last bubble of a group it sits inside the bubble at the end of the last line (a spacer reserves its
   room); elsewhere it waits beside the bubble and shows on hover/focus (opacity only: nothing reflows) */
:where(.msg-time) { grid-area: t; align-self: end; padding-bottom: 2px; opacity: 0; white-space: nowrap; font-size: var(--fs-micro); line-height: var(--lh-micro); color: var(--t3); font-variant-numeric: tabular-nums; }
:where(.msg:hover .msg-time, .msg:focus-within .msg-time) { opacity: 1; }
:where(.msg[data-pos="last"] .msg-time, .msg[data-pos="single"] .msg-time) { grid-area: b; justify-self: end; opacity: 1; padding: 0; margin: 0 var(--bub-px, 16px) calc(var(--bub-py, 8px) + 1px); pointer-events: none; }
:where(.msg[data-pos="last"] .bubble, .msg[data-pos="single"] .bubble)::after { content: ""; display: inline-block; width: var(--time-w, 2.75rem); height: 1px; }
:where(.msg[data-me="1"][data-pos="last"] .msg-time, .msg[data-me="1"][data-pos="single"] .msg-time) { color: var(--inv-t2); }
:where(.msg[data-kind="intent"]) { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "a t" "b b"; justify-content: stretch; width: 100%; max-width: 640px; }
:where(.msg[data-kind="intent"][data-me="1"]) { margin-inline-start: auto; }
:where(.msg[data-kind="intent"] .bubble, .msg[data-kind="system"] .bubble) { background: none; padding: 0; border-radius: 0; max-width: none; color: var(--t1); white-space: normal; }
:where(.msg[data-kind="intent"] .bubble)::after { content: none; }
:where(.msg[data-kind="intent"] .msg-time) { grid-area: t; opacity: 1; justify-self: end; margin: 0 0 4px; padding: 0; }
:where(.msg[data-kind="system"]) { grid-template-columns: minmax(0, 1fr); grid-template-areas: "b"; justify-content: center; }
:where(.sys-line) { grid-area: b; margin: 8px auto; max-width: 48ch; text-align: center; color: var(--t3); font-size: var(--fs-body-s); line-height: var(--lh-body-s); }
.bub:focus { outline: none; }
.bub.me .muted, .bub.me .foot { color: var(--inv-t2); }
/* legacy bubbles outside the contract (group chats, imported chats, the first-run sample) */
.bub:not(.bubble) { max-width: min(72%, 560px); padding: 8px 16px; border-radius: var(--r-bub, 22px); position: relative; white-space: pre-wrap; overflow-wrap: anywhere; font-size: var(--fs-body); line-height: var(--lh-body); }
.bub.them:not(.bubble) { align-self: flex-start; background: var(--bub-them); color: var(--t1); }
.bub.me:not(.bubble) { align-self: flex-end; background: var(--bub-me); color: var(--bub-me-t); }
.msg-status { align-self: flex-end; margin-top: 4px; color: var(--t3); font-size: var(--fs-micro); line-height: var(--lh-micro); }
.sys { align-self: center; max-width: min(80%, 480px); margin: 0; text-align: center; color: var(--t3); font-size: var(--fs-body-s); line-height: var(--lh-body-s); }
.e2e { align-self: center; display: inline-flex; gap: 8px; align-items: center; min-height: var(--tap-min); font-size: .75rem; color: var(--t3); padding: 8px 12px; border-radius: var(--r-pill); margin-bottom: 8px; }
/* new arrivals only (never history, never a list on render): a fade, nothing moves */
@keyframes pb-in { from { opacity: 0; } }
.fresh { animation: pb-in var(--d2) var(--ease-soft) both; }

/* intent cards: always a solid card, never restyled by message style or by the sender. Its details are a spec
   sheet (caps label column, value column, hairline rows). */
:where(.intent-card) { background: var(--card); color: var(--t1); border-radius: var(--r-card, 28px); padding: var(--card-pad, 24px); display: grid; gap: 16px; min-width: 0; text-align: start; }
.intent-card { gap: 16px; }
.intent-card > * { margin: 0; min-width: 0; }
.ic-label { display: flex; flex-wrap: wrap; gap: 0 8px; }
.ic-label > span:not(:last-child)::after { content: "·"; margin-inline-start: 8px; }
.ic-title { font-size: 1.375rem; line-height: 1.75rem; font-weight: var(--w-title); letter-spacing: var(--tr-title); overflow-wrap: anywhere; }
.ic-reason { color: var(--t2); font-size: var(--fs-body); line-height: var(--lh-body); }
/* the spec sheet: label column + value column, a hairline between rows */
.grid { display: grid; grid-template-columns: minmax(88px, 32%) minmax(0, 1fr); gap: 0 16px; margin: 0; border-block-end: 1px solid var(--line); }
.grid dt, .grid dd { margin: 0; padding-block: 12px; border-block-start: 1px solid var(--line); }
.grid dt { line-height: var(--lh-body); overflow-wrap: anywhere; hyphens: auto; }
.grid dd { font-size: var(--fs-body); line-height: var(--lh-body); overflow-wrap: anywhere; }
.ic-acts { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.ic-choose { display: grid; gap: 16px; }
.ic-choices { display: grid; gap: 8px; }
.ic-choice { display: flex; gap: 12px; align-items: center; min-height: var(--tap); padding: 12px 24px; border-radius: var(--r-pill); background: var(--s2); cursor: pointer; font-size: var(--fs-body); line-height: var(--lh-body); transition: var(--tint); }
.ic-choice input { flex: none; width: 18px; height: 18px; margin: 0; accent-color: var(--t1); }
@media (max-width: 359px) { .ic-choice { padding-inline: 16px; } }
.ic-choice:has(input:checked) { background: var(--inv-bg); color: var(--inv-t); }
.ic-choice:has(input:checked) input { accent-color: var(--inv-t); }
.ic-choice:has(input:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
.ic-foot { color: var(--t3); font-size: var(--fs-micro); line-height: var(--lh-micro); }
.intent-card.done { padding: 0; }
.ic-row { display: flex; gap: 8px; align-items: center; width: 100%; min-height: var(--tap-primary); padding: 12px 24px; border-radius: var(--r-card); text-align: start; font-size: var(--fs-body-s); line-height: var(--lh-body-s); color: var(--t1); transition: var(--tint); }
.ic-row:hover { background: var(--card-on); }
.ic-dec { font-weight: var(--w-strong); flex: none; }
.ic-what { flex: 1; min-width: 0; color: var(--t2); overflow-wrap: anywhere; }
.ic-when { flex: none; color: var(--t3); font-size: var(--fs-micro); }
.ic-row .ic { color: var(--t3); flex: none; }
.resolved { color: var(--t2); font-size: .75rem; }
.opts { display: flex; flex-wrap: wrap; gap: 8px; }

/* composer: a pill on the raised tone (a soft card when it grows), one trailing button (mic ⇄ send), the + popover */
.dock-in { flex: none; position: relative; z-index: 5; width: 100%; max-width: 760px; margin: 0 auto; padding: 0 24px 24px; }
@media (max-width: 759px) { .dock-in { padding: 0 12px max(12px, env(safe-area-inset-bottom)); } }
.composer-note { margin: 0 0 8px; text-align: center; color: var(--t3); font-size: var(--fs-micro); line-height: var(--lh-micro); }
.composer { display: flex; gap: 4px; align-items: flex-end; min-height: var(--tap-primary); padding: 4px; border-radius: var(--r-field); background: var(--s2); border: 0; transition: var(--tint); }
/* typing keeps focus here for a whole conversation: a quiet ring at the control contrast (≥ 3:1), not the 2 px ink one */
.composer:focus-within { outline: 2px solid var(--ctl); outline-offset: 0; }
.composer-in { flex: 1; min-width: 0; resize: none; border: 0; outline: none; background: transparent; color: var(--t1); padding: 12px 8px; max-height: 160px; font-size: var(--fs-body); line-height: 1.5rem; }
.composer-in:focus-visible { outline: none; }
.composer .icon-btn { width: 48px; height: 48px; border-radius: 50%; }
.composer .send { background: var(--inv-bg); color: var(--inv-t); }
.composer .send:hover { background: color-mix(in srgb, var(--bg) 12%, var(--inv-bg)); }
.composer .att-btn, .composer .more > summary { color: var(--t2); }
.composer .more > summary { width: 48px; height: 48px; border-radius: 50%; }
.composer.dead { justify-content: space-between; align-items: center; gap: 8px; padding-block: 4px; padding-inline: 24px 4px; font-size: var(--fs-body-s); color: var(--t2); flex-wrap: wrap; }
.group-conv > div:last-child { padding: 0 12px 12px; }
/* the group header: identity, then its actions; the actions wrap under the name before anything is cut */
.group-conv .conv-head { flex-wrap: wrap; }
.ch-id { display: flex; align-items: center; gap: 12px; flex: 1 1 120px; min-width: 0; }
.ch-acts { display: flex; align-items: center; gap: 4px; flex: none; margin-inline-start: auto; }

/* --- sheets, toasts, forms: a sheet enters in 480 ms ease-settle (opacity + 12 px) and leaves in 240 ms; the scrim
       fades with it; flat (no shadow) ------------------------------------------------------------------------------ */
.sheet-wrap { position: fixed; inset: 0; z-index: 50; display: grid; grid-template-columns: minmax(0, 1fr); place-items: end center; background: transparent; transition: background-color var(--d2) var(--ease-soft); }
.sheet-wrap.in { background: var(--scrim); transition: background-color var(--d3) var(--ease-settle); }
.sheet-wrap.closing { pointer-events: none; } /* fading out: taps reach what is under it; Escape twice closes two sheets */
.sheet { width: min(600px, 100%); max-height: 88dvh; overflow: auto; background: var(--solid); color: var(--t1); border-radius: var(--r-pane) var(--r-pane) 0 0; padding: 8px 24px max(24px, env(safe-area-inset-bottom)); transform: translateY(12px); opacity: 0; transition: transform var(--d2) var(--ease-soft), opacity var(--d2) var(--ease-soft); }
.sheet-wrap.in .sheet { transform: none; opacity: 1; transition: transform var(--d3) var(--ease-settle), opacity var(--d3) var(--ease-settle); }
@media (min-width: 720px) {
  .sheet-wrap { place-items: center; }
  .sheet { border-radius: var(--r-pane); padding: 16px 32px 32px; }
  .sheet.wide { width: min(760px, calc(100% - 48px)); }
}
/* the high-stakes review is full screen at phone widths; Accept sits at the bottom, after the terms */
.sheet:has(.review) { max-height: 100dvh; display: flex; flex-direction: column; }
.sheet > .review { flex: 1 0 auto; display: flex; flex-direction: column; }
.review-acts { margin-top: auto; padding-top: 16px; }
@media (max-width: 719px) { .sheet:has(.review) { height: 100dvh; width: 100%; border-radius: 0; } }
.sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 0; position: sticky; top: -8px; background: var(--solid); z-index: 1; }
@media (min-width: 720px) { .sheet-head { top: -16px; } }
.sheet-head h2 { font-size: 1.375rem; line-height: 1.75rem; font-weight: var(--w-title); letter-spacing: var(--tr-title); margin: 0; min-width: 0; overflow-wrap: anywhere; text-wrap: balance; }
.sheet-head .icon-btn { margin-inline-end: -12px; }
/* forms and receipts are spec sheets: a caps label column and a value column, a hairline between rows */
.pass-form { display: grid; gap: 16px; min-width: 0; }
.pass-form > * { min-width: 0; margin: 0; }
.pass-form .row { display: grid; grid-template-columns: minmax(88px, 32%) minmax(0, 1fr); align-items: baseline; gap: 16px; padding: 12px 0; border-block-start: 1px solid var(--line); }
.pass-form .row + .row { margin-block-start: -16px; }
.pass-form .row:not(:has(+ .row)) { border-block-end: 1px solid var(--line); }
.pass-form .row > .cap { overflow-wrap: anywhere; hyphens: auto; }
.pass-form .row > span:last-child { overflow-wrap: anywhere; }
.pass-form .row > .seg, .pass-form .row > .checks { justify-self: start; }
.pass-form .row .segb { padding-inline: 12px; }
@media (max-width: 519px) { .pass-form .row:has(> .in, > textarea, > .field) { grid-template-columns: minmax(0, 1fr); gap: 0; } }
.pass-form .row:has(> .in) + .row { border-block-start: 0; }
.pass-form .row:has(> .in):not(:has(+ .row)) { border-block-end: 0; }
.review .grid { margin-block: 0; }
.review-acts { display: grid; gap: 4px; justify-items: center; margin-top: 8px; }
.checks { display: flex; flex-wrap: wrap; gap: 4px 16px; }
.sentence { font-size: 1.375rem; line-height: 1.875rem; font-weight: var(--w-title); letter-spacing: var(--tr-title); text-wrap: pretty; }
.seg { display: inline-flex; flex-wrap: wrap; gap: 4px; padding: 4px; border-radius: var(--r-field); background: var(--s2); border: 0; max-width: 100%; }
.seg.big { display: flex; margin: 0 var(--gutter) 24px; }
.seg.big .segb { flex: 1 1 auto; white-space: nowrap; }
.seg[role=tablist] .segb { flex: 1 1 auto; }
@media (max-width: 430px) { .seg.big .segb, .seg[role=tablist] .segb { padding-inline: 12px; } }
.segb { min-height: var(--tap-min); min-width: var(--tap-min); padding: 8px 16px; border-radius: var(--r-pill); font-size: var(--fs-body-s); line-height: var(--lh-body-s); font-weight: var(--w-heading); color: var(--t1); transition: var(--tint); }
.segb:hover { background: color-mix(in srgb, var(--t1) 8%, transparent); }
.segb.on { background: var(--inv-bg); color: var(--inv-t); }
.check { display: inline-flex; align-items: center; gap: 8px; min-height: var(--tap-min); font-size: .875rem; }
.check input { width: 18px; height: 18px; margin: 0; accent-color: var(--t1); flex: none; }
/* fields: underline only (transparent, a bottom line at the control contrast), large type, the caps label above */
:where(input, textarea, select).in, .sel { width: 100%; min-height: var(--tap-primary); padding: 12px 0; border: 0; border-bottom: 1px solid var(--field-line); border-radius: 0; background: transparent; color: var(--t1); outline: none; font-size: 1.125rem; line-height: 1.75rem; font-weight: var(--w-title); transition: border-color var(--d2) var(--ease-soft); }
:where(input, textarea, select).in:hover, .sel:hover { border-bottom-color: var(--t2); }
:where(input, textarea, select).in:focus-visible, .sel:focus-visible { outline: none; border-bottom: 2px solid var(--t1); padding-bottom: calc(12px - 1px); }
textarea.in { resize: vertical; }
.sel { width: auto; display: inline; min-height: var(--tap-min); padding: 4px 0; font-size: inherit; line-height: inherit; font-weight: var(--w-heading); max-width: 100%; }
.sel:focus-visible { padding-bottom: 3px; }
.flabel { display: block; }
.pass-form > .flabel, .onb-body > .flabel { margin-bottom: -8px; }
.safety { font-size: 1.375rem; letter-spacing: .06em; line-height: 2.125rem; padding: 24px; border-radius: var(--r-card); background: var(--card); text-align: center; }
.warn-line { color: var(--t1); font-size: var(--fs-body-s); line-height: var(--lh-body-s); padding: 12px 24px; border-radius: var(--r-row); background: var(--s2); }
.rule-builder .sel { margin-block: 2px; }
/* toasts: pills. `transform` places; only opacity changes (nothing moves) */
.toast { position: fixed; z-index: 60; left: 50%; right: auto; bottom: 24px; transform: translateX(-50%); opacity: 0; transition: opacity var(--d2) var(--ease-soft); display: flex; gap: 12px; align-items: center; padding-block: 4px; padding-inline: 24px 4px; min-height: var(--tap-primary); border-radius: var(--r-field); background: var(--solid); color: var(--t1); border: 1px solid var(--line); width: max-content; max-width: min(560px, calc(100vw - 32px)); font-size: .875rem; line-height: 1.25rem; }
.toast.show { opacity: 1; }
.toast-t { min-width: 0; padding-block: 8px; padding-inline-end: 16px; }
.toast-act { flex: none; min-height: var(--tap); padding: 8px 24px; border-radius: var(--r-pill); background: var(--s2); color: var(--t1); font-size: var(--fs-btn); font-weight: var(--w-label); letter-spacing: var(--tr-btn); text-transform: var(--tt-label); transition: var(--tint); }
.toast-act:hover { background: color-mix(in srgb, var(--t1) 8%, var(--s2)); }
/* desktop: bottom inline-start, over the end of the list pane (never over a conversation or a detail's actions);
   phone: above the tab-bar island (never over a card's primary action), above the composer in a chat */
@media (min-width: 760px) {
  body:has(.shell) .toast { left: 112px; transform: none; max-width: min(312px, calc(100vw - 128px)); }
  [dir=rtl] body:has(.shell) .toast { left: auto; right: 112px; }
}
@media (min-width: 760px) and (max-width: 1023px) { body:has(.shell) .toast { max-width: 272px; } }
/* desktop: the list pane keeps room under its last card while a toast sits over its end */
@media (min-width: 760px) { body:has(.toast.show) .list-pane > .pane { padding-bottom: 96px; } }
@media (max-width: 759px) {
  .toast { bottom: calc(88px + env(safe-area-inset-bottom)); }
  body:has(.shell.has-open):not(:has(.call, .sheet-wrap.in)) .toast { bottom: calc(88px + env(safe-area-inset-bottom)); }
}
/* with a sheet or a call on screen: at the top, centred */
body:has(.sheet-wrap.in) .toast, body:has(.call) .toast, [dir=rtl] body:has(.sheet-wrap.in) .toast { top: 16px; bottom: auto; left: 50%; right: auto; transform: translateX(-50%); }
body:has(.call) .toast { top: 80px; }
[data-scheme="light"] body:has(.call) .toast { background: var(--inv-bg); color: var(--inv-t); border-color: transparent; }
[data-scheme="light"] body:has(.call) .toast-act { background: color-mix(in srgb, var(--inv-t) 14%, var(--inv-bg)); color: var(--inv-t); }
/* while a toast shows at phone widths the list and the thread can scroll their last item above it */
@media (max-width: 759px) { body:has(.toast.show) :is(.list-pane, .shell.has-sec .detail) { padding-bottom: calc(160px + env(safe-area-inset-bottom)); } body:has(.toast.show) .thread-col { padding-bottom: 96px; } }

/* the pass lifespan: t2 for elapsed, the brass dot at now, labels under it */
.life { display: grid; gap: 12px; padding: 8px 0 12px; }
.life-bar { position: relative; height: 4px; border-radius: 2px; background: color-mix(in srgb, var(--t1) 14%, transparent); margin: 4px 0; }
.life-fill { position: absolute; inset-block: 0; inset-inline-start: 0; border-radius: 2px; background: var(--t2); }
.life-bar .marker { position: absolute; top: -3px; width: 10px; height: 10px; margin-inline-start: -5px; }
.life-ends { display: flex; justify-content: space-between; gap: 8px; color: var(--t2); font-size: var(--fs-micro); line-height: var(--lh-micro); }
.life-ends > span:nth-child(2) { color: var(--t1); }

/* --- detail panes (main at ≥760: a knock, a call, a Line section): one reading column, generous margins --------- */
.detail { height: 100dvh; overflow-y: auto; background: var(--bg); }
.detail-col { width: 100%; max-width: 720px; margin: 0 auto; padding: 48px 48px 64px; display: grid; gap: 24px; align-content: start; min-width: 0; }
.detail-col > * { margin: 0; min-width: 0; }
.detail-col .group { padding: 0; }
.detail-col .group > .rows { margin-inline: -16px; }
.detail .k-head .name { font-size: var(--fs-title); line-height: var(--lh-title); font-weight: var(--w-title); letter-spacing: var(--tr-title); }
.line-sec .detail-col { padding-top: 16px; }
.sec-head { justify-content: flex-start; min-height: 64px; }
.line-sec > .sec-head { max-width: 720px; margin-inline: auto; padding: 48px 48px 0; }
@media (max-width: 759px) { .line-sec > .sec-head { padding: 16px 24px 0; } }
.sec-head .back { display: none; margin-inline-start: -12px; }

/* --- Line: identity, who can reach you (a spec sheet; the list pane is narrow, so its label sits above the value), the index ------------------------------------------------- */
.line-hero { padding: 0 var(--gutter) 24px; display: grid; grid-template-columns: minmax(0, 1fr); gap: 4px; }
.handle { font-size: var(--fs-display); line-height: var(--lh-display); font-weight: var(--w-display); letter-spacing: var(--tr-display); overflow-wrap: anywhere; }
.line-hero .btn.primary { justify-self: start; margin-top: 12px; }
.door { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; margin-top: 12px; padding: 16px 8px 8px; border-radius: var(--r-card); background: var(--card); min-width: 0; }
.door .mono { flex: 1 1 100%; min-width: 0; padding: 0 16px 8px; overflow-wrap: anywhere; color: var(--t2); }
.reach { margin: 0 var(--gutter) 24px; padding: var(--card-pad) var(--card-pad) 8px; border-radius: var(--r-card); background: var(--card); display: grid; }
@media (max-width: 1023px) { .reach { margin-inline: 12px; } .line-hero .door { margin-inline: -12px; } .rows:has(> .erow) { padding-inline: 12px; } }
.reach > .cap { padding: 0 0 16px; }
.rrow { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 16px; row-gap: 4px; align-items: baseline; width: 100%; min-height: var(--tap); padding: 12px 0; border-block-start: 1px solid var(--line); text-align: start; color: var(--t1); transition: var(--tint); }
.rrow .r-k { grid-column: 1; line-height: var(--lh-body-s); overflow-wrap: anywhere; hyphens: auto; }
.rrow .r-v { grid-column: 1; color: var(--t1); font-size: var(--fs-body); line-height: var(--lh-body); }
.rrow > .ic { grid-column: 2; grid-row: 1 / span 2; align-self: center; color: var(--t3); }
button.rrow:hover .r-v { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.index { display: grid; padding: 0 8px 32px; }
.irow { display: flex; align-items: center; gap: 16px; width: 100%; min-height: var(--tap-primary); padding: 12px 16px; border-radius: var(--r-row); text-align: start; color: var(--t1); font-size: var(--fs-body); transition: var(--tint); }
.irow > .ic:first-child { color: var(--t2); }
.irow > .ic:last-child { color: var(--t3); }
.i-label { flex: 1; min-width: 0; }
.i-val { color: var(--t2); font-size: var(--fs-body-s); line-height: var(--lh-body-s); text-align: end; overflow-wrap: anywhere; max-width: 50%; }
button.irow:hover { background: var(--s1); }
.irow.on { background: var(--s2); }
.irow.danger, .irow.danger > .ic:first-child { color: var(--danger); }
.irow.mode { width: auto; margin: 0 8px 4px; flex-wrap: wrap; row-gap: 8px; }
.irow.mode .i-label { flex: 1 0 auto; }
.irow.mode .seg { margin-inline-start: auto; }
.irow.mode .segb { padding-inline: 12px; }
@media (max-width: 400px) { .irow.mode .seg { margin-inline-start: 32px; } }

/* --- onboarding and the door: light, calm, one column, a display heading, underline fields, one pill to continue;
       the brass dot is the current step ---------------------------------------------------------------------------- */
.onb { min-height: 100dvh; background: var(--bg); color: var(--t1); padding: clamp(32px, 9vh, 96px) 24px 64px; }
.onb-col { width: min(480px, 100%); margin: 0 auto; display: grid; gap: 32px; }
.onb-brand { display: flex; align-items: center; gap: 12px; color: var(--t1); font-weight: var(--w-heading); font-size: var(--fs-heading); letter-spacing: -.02em; }
.steps { display: flex; align-items: center; gap: 12px; margin-bottom: -16px; }
.steps .dots { display: flex; gap: 8px; }
.steps .dots > span { width: 6px; height: 6px; border-radius: 50%; background: var(--s2); }
.steps .dots > span.done { background: var(--t2); }
.steps .dots > span.marker { background: var(--marker); }
.onb-body { display: grid; gap: 16px; min-width: 0; }
.onb-body > * { margin: 0; min-width: 0; }
.onb h1 { font-size: var(--fs-display); line-height: var(--lh-display); font-weight: var(--w-display); letter-spacing: var(--tr-display); margin: 0 0 8px; overflow-wrap: anywhere; text-wrap: balance; }
.onb h2:not(.cap) { font-size: var(--fs-heading); line-height: var(--lh-heading); font-weight: var(--w-heading); }
.onb-body > .cap, .onb-body .pass-form > .cap { margin-top: 16px; }
.onb-body > label.cap, .pass-form > label.cap { margin-bottom: -16px; }
.onb-body .muted { font-size: var(--fs-lead); line-height: var(--lh-lead); }
.onb-body .seg { justify-self: start; }
.onb-body > .btn.wide { margin-top: 16px; }
.onb-links { display: grid; justify-items: start; margin-top: 8px; margin-inline-start: -16px; }
.onb-links .pk-signin { display: contents; }
/* these are inline text links, not actions: sentence case */
.onb-links .btn { justify-content: flex-start; text-align: start; font-size: var(--fs-body-s); line-height: var(--lh-body-s); font-weight: var(--w-heading); letter-spacing: 0; text-transform: none; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.onb-body.center { text-align: start; }
.done-line { color: var(--t2); font-size: var(--fs-body-s); line-height: var(--lh-body-s); }
.choices { display: grid; gap: 8px; }
.choice { display: grid; gap: 4px; text-align: start; padding: 16px 24px; border-radius: var(--r-card); background: var(--card); color: var(--t1); transition: var(--tint); }
.choice strong { font-weight: var(--w-heading); }
.choice span { color: var(--t2); font-size: var(--fs-body-s); line-height: var(--lh-body-s); }
.choice:hover { background: var(--card-on); }
.choice.on { background: var(--inv-bg); color: var(--inv-t); }
.choice.on span { color: var(--inv-t2); }
.handle-in { display: flex; align-items: baseline; border-bottom: 1px solid var(--field-line); transition: border-color var(--d2) var(--ease-soft); }
.handle-in:focus-within { border-bottom: 2px solid var(--t1); margin-bottom: -1px; }
.handle-in > span { color: var(--t2); font-size: 1.125rem; font-weight: var(--w-title); }
.handle-in .in, .handle-in .in:focus-visible { border: 0; padding: 12px 0 12px 4px; }
.onb .who, .door-page .who { display: flex; gap: 16px; align-items: center; }
.onb .handle { font-size: var(--fs-heading); line-height: var(--lh-heading); font-weight: var(--w-heading); letter-spacing: var(--tr-heading); }
.onb .door { margin-top: 0; }
.onb [data-group=pk-offer] { padding: var(--card-pad); border-radius: var(--r-card); background: var(--card); gap: 12px; }
.onb [data-group=pk-offer] p { color: var(--t2); font-size: var(--fs-body-s); line-height: var(--lh-body-s); }
.onb [data-group=pk-offer] .btn.wide { margin-top: 0; min-height: var(--tap); }
.agent-foot { color: var(--t3); padding-top: 16px; overflow-wrap: anywhere; }
.door-chat { height: 100dvh; max-width: 760px; margin: 0 auto; }
.door-chat .conv-head .back { display: none; }
.band { display: grid; gap: 8px; margin-top: 16px; }
.band-row { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: 16px; }
.band select.in, .band-row select.in { appearance: auto; }
/* waiting: a still ring (nothing loops); the line beside it says what is happening */
.spinner { width: 24px; height: 24px; border-radius: 50%; border: 2px solid var(--s2); border-top-color: var(--t1); }

/* --- calls: flat ground, labelled controls, a static recording dot. The call surface is dark: web/tokens.css maps
       [data-call] and .call-surface (1:1, the recording request, live, group call, call notes) to the current
       theme's dark twin, colour-scheme included. Nothing here names a colour. -------------------------------------- */
.call { position: fixed; inset: 0; z-index: 40; display: grid; place-items: center; background: var(--bg); color: var(--t1); }
.call.incoming { align-content: center; justify-items: center; gap: 0; text-align: center; padding: 24px; }
.call.incoming h2, .voice-face h2 { font-size: var(--fs-display); line-height: var(--lh-display); font-weight: var(--w-display); letter-spacing: var(--tr-display); margin: 16px 0 0; overflow-wrap: anywhere; }
.call.incoming .av { margin-bottom: 8px; }
.call-pass { color: var(--t2); font-size: var(--fs-body-s); line-height: var(--lh-body-s); margin: 8px 0 0; }
.call .remote { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; background: var(--bg); }
.call.voice .remote { opacity: 0; }
.call .local { position: absolute; inset-inline-end: 16px; top: 80px; width: 120px; aspect-ratio: 9/16; object-fit: cover; border-radius: var(--r-row); transform: scaleX(-1); z-index: 2; }
.voice-face { display: grid; justify-items: center; gap: 4px; z-index: 1; text-align: center; padding: 0 16px; }
.call-top { position: absolute; top: max(16px, env(safe-area-inset-top)); left: 50%; transform: translateX(-50%); display: flex; gap: 12px; align-items: center; min-height: var(--tap-min); padding: 8px 24px; border-radius: var(--r-pill); background: var(--s1); color: var(--t1); z-index: 3; font-size: var(--fs-body-s); white-space: nowrap; max-width: calc(100vw - 24px); }
.call-top > * { white-space: nowrap; }
@media (max-width: 359px) { .call-top { flex-wrap: wrap; justify-content: center; row-gap: 0; white-space: normal; } }
.lockline { display: inline-flex; gap: 8px; align-items: center; min-height: var(--tap-min); margin-block: -8px; color: var(--t1); }
.warn { color: var(--t1); font-weight: var(--w-strong); }
.route { font-size: .75rem; color: var(--t2); }
.recline { display: inline-flex; gap: 8px; align-items: center; }
.recdot { width: 8px; height: 8px; border-radius: 50%; background: var(--danger); flex: none; }
.dock { position: absolute; bottom: max(24px, env(safe-area-inset-bottom)); left: 50%; transform: translateX(-50%); display: flex; gap: 4px; padding: 12px 16px 8px; border-radius: 48px; background: var(--s1); z-index: 3; }
.ctl { display: grid; justify-items: center; gap: 4px; width: 64px; }
.ctl .lbl { font-size: var(--fs-micro); line-height: var(--lh-micro); color: var(--t2); white-space: nowrap; }
.call.incoming .dock { position: static; transform: none; background: none; gap: 64px; margin-top: 48px; padding: 0; }
.call.incoming .round { width: 64px; height: 64px; }
.round { width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center; background: var(--s2); color: var(--t1); transition: var(--tint); }
.round:hover { background: color-mix(in srgb, var(--t1) 8%, var(--s2)); }
.round.on, .round.fill { background: var(--inv-bg); color: var(--inv-t); }
.round.end { background: var(--danger); color: var(--inv-t); }
.round.justme.rec { color: var(--danger); }
.cap-note { position: absolute; left: 50%; transform: translateX(-50%); bottom: calc(max(24px, env(safe-area-inset-bottom)) + 96px); z-index: 3; margin: 0; max-width: calc(100vw - 32px); text-align: center; color: var(--t2); font-size: var(--fs-body-s); line-height: var(--lh-body-s); }
.captions { position: absolute; left: 50%; bottom: calc(max(24px, env(safe-area-inset-bottom)) + 120px); transform: translateX(-50%); z-index: 3; max-width: min(640px, calc(100vw - 32px)); padding: 12px 24px; border-radius: var(--r-card); background: var(--s1); font-size: 1.0625rem; line-height: 1.5rem; color: var(--t1); text-align: center; }
.consent { position: fixed; z-index: 45; left: 50%; bottom: 140px; transform: translateX(-50%); width: min(440px, calc(100% - 32px)); padding: var(--card-pad); border-radius: var(--r-card); background: var(--solid); color: var(--t1); border: 1px solid var(--line); display: grid; gap: 16px; }
.consent h3 { font-size: var(--fs-heading); line-height: var(--lh-heading); font-weight: var(--w-heading); margin: 0; }
.consent p { margin: 0; color: var(--t2); }
.clip { width: 100%; max-height: 60dvh; aspect-ratio: 9/16; background: var(--bg); border-radius: var(--r-row); object-fit: contain; }

/* --- adapted to the screen ----------------------------------------------------------------------------------- */
@media (max-width: 1023px) { .shell { grid-template-columns: var(--rail-w) 320px minmax(0, 1fr); } .detail-col, .line-sec > .sec-head { padding-inline: 32px; } .empty-main { padding: 24px; } }
@media (min-width: 1280px) { .shell { grid-template-columns: var(--rail-w) 400px minmax(0, 1fr); } }
@media (max-width: 759px) {
  .shell { grid-template-columns: minmax(0, 1fr); }
  /* the tab bar: a floating pill island, 12 px from the edges plus the safe area; flat translucent raised tone,
     blurred and desaturated, no shadow, no border; the current tab is the inverse pill */
  .rail { position: fixed; inset-inline: 12px; bottom: calc(12px + env(safe-area-inset-bottom)); top: auto; flex-direction: row; justify-content: space-between; align-items: stretch; gap: 0; height: 64px; padding: 4px; overflow: visible; border: 0; border-radius: var(--r-pill); background: var(--island); -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur); z-index: 20; }
  .rail .brand, .rail .net { display: none; }
  .nav-btn { flex: 1 1 0; width: auto; min-width: 0; min-height: 0; padding: 4px 0; gap: 2px; }
  .nav-btn:hover { background: none; }
  .nav-btn.on, .nav-btn.on:hover { background: var(--inv-bg); color: var(--inv-t); }
  .nav-label { font-size: .625rem; line-height: .75rem; overflow: visible; }
  /* six or more tabs do not fit their labels in 366 px: the current tab carries its label beside the icon, the others
     are their icon (the label stays in the accessibility tree) */
  .rail:has(.nav-btn:nth-of-type(6)) .nav-btn { flex: 1 1 0; }
  .rail:has(.nav-btn:nth-of-type(6)) .nav-btn:not(.on) .nav-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .rail:has(.nav-btn:nth-of-type(6)) .nav-btn.on { flex: none; flex-direction: row; gap: 8px; padding: 0 12px; max-width: 40%; }
  .rail:has(.nav-btn:nth-of-type(6)) .nav-btn.on .nav-label { overflow: hidden; text-overflow: ellipsis; }
  .rail:has(.nav-btn:nth-of-type(6)) .nav-btn.on .nav-label { font-size: var(--fs-body-s); line-height: var(--lh-body-s); font-weight: var(--w-heading); }
  .list-pane { border: 0; height: 100dvh; padding-bottom: calc(88px + env(safe-area-inset-bottom)); }
  .main-pane { display: none; }
  .shell.has-open .list-pane, .shell.has-open .rail { display: none; }
  .shell.has-open .main-pane { display: block; }
  .shell.has-sec .list-pane { display: none; }
  .shell.has-sec .main-pane { display: block; }
  .shell.has-sec .detail { height: 100dvh; padding-bottom: calc(88px + env(safe-area-inset-bottom)); }
  .conv-head .back, .sec-head .back { display: inline-grid; }
  .conv-head { gap: 8px; padding: 8px 8px; min-height: 64px; }
  /* the island's tabs touch: a ring outside a tab would cross its neighbour (invisible against the inverse pill),
     so the ring sits 4 px inside the tab, in the inverse text colour on the active pill */
  .rail .nav-btn:focus-visible { outline-offset: -4px; }
  .rail .nav-btn.on:focus-visible { outline-color: var(--inv-t); }

  .call-top { font-size: .75rem; gap: 8px; padding: 8px 16px; }
  .call-top .lbl-long { display: none; }
  .dock .ctl { width: 56px; }
  .round { width: 48px; height: 48px; }
  .consent { bottom: calc(max(24px, env(safe-area-inset-bottom)) + 208px); }
  .detail-col { padding: 16px 24px 48px; }
  .empty-main { padding: 32px 24px; }
}
/* a narrow conversation (a phone, or the main pane beside the list on a tablet) keeps the name whole: the avatar
   already stands at the top of the thread */
@container conv (max-width: 520px) {
  .conv-head > .av, .ch-id > .av { display: none; }
  .conv-head .name { font-size: 1rem; line-height: 1.375rem; }
  .pchip { padding-inline: 12px; }
  .pchip .ic { display: none; }
  /* two rows (UX_SPEC): back, name and principal take the first with the whole width; the pass chip starts the
     second and the call buttons (people) or the pass ring (agents) and the menu end it. Every single conversation
     takes the two rows: with one row an agent's "Verified · handle" line broke mid-handle into a 130 px column
     (four lines at 390, six at 137.5 % text). */
  .conv:not(.group-conv) .conv-head { flex-wrap: wrap; row-gap: 4px; }
  .conv:not(.group-conv) .conv-head .who { flex: 1 1 calc(100% - 52px); }
  .conv:not(.group-conv) .conv-head > .pchip { margin-inline-end: auto; }
}
/* a pane opened on a phone enters like a sheet: opacity + 12 px, 480 ms ease-settle — only on the draw that opens it */
@keyframes pb-push { from { opacity: 0; transform: translateX(12px); } }
@keyframes pb-push-rtl { from { opacity: 0; transform: translateX(-12px); } }
@media (max-width: 759px) { .main-pane.push { animation: pb-push var(--d3) var(--ease-settle) both; } [dir=rtl] .main-pane.push { animation-name: pb-push-rtl; } }
/* 320 px: six or more tabs are their icons; the current tab is the inverse pill (its label stays in the accessibility tree) */
@media (max-width: 359px) {
  .rail:has(.nav-btn:nth-of-type(6)) .nav-btn.on { flex: 1 1 0; flex-direction: column; gap: 2px; padding: 4px 0; max-width: none; }
  .rail:has(.nav-btn:nth-of-type(6)) .nav-btn.on .nav-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
}
@media (prefers-reduced-transparency: reduce) { .rail { -webkit-backdrop-filter: none; backdrop-filter: none; } }
:is([data-theme="night"], [data-theme="contrast"]) .rail { -webkit-backdrop-filter: none; backdrop-filter: none; }
/* Contrast: every control and container carries a visible boundary */
[data-theme="contrast"] :is(.btn:not(.text, .ghost), .composer, .seg, .fchip, .chip, .pchip, .rail, .choice, .reach, .erow, .toast, .menu, .fr-card, .door, .ic-choice, .auto-row) { border: 1px solid var(--line); }
/* reduced motion: nothing moves; opacity only, 120 ms or less; no smooth scrolling */
@media (prefers-reduced-motion: reduce) {
  .fresh, .main-pane.push { animation: none; }
  .sheet, .sheet-wrap.in .sheet { transform: none !important; transition: opacity 120ms linear !important; }
  .toast, .toast.show { transition: opacity 120ms linear !important; }
  .kcard.leaving { transition: none; }
  html { scroll-behavior: auto !important; }
}
.conv.teen .safety-bar { flex: none; }
ul.plain { margin: 0; padding-inline-start: 16px; display: grid; gap: 8px; color: var(--t2); font-size: .875rem; }
a.btn.wide { text-align: center; text-decoration: none; }
[data-group=safety], [data-safety], [data-group=agents], [data-group=invites] { grid-template-columns: minmax(0, 1fr); }
[data-group=safety] .btn, [data-safety] .btn { white-space: normal; height: auto; }
.seg.wrap { flex-wrap: wrap; }

/* attachments (web/attach.ts) */
.composer .plus > .menu { min-width: 240px; }
.bub.att { padding: 8px; white-space: normal; min-width: 180px; }
.att-imgbtn { display: block; position: relative; width: min(280px, 60vw); max-height: 360px; overflow: hidden; border-radius: calc(var(--r-bub, 22px) - 8px); background: var(--s2); border: 0; padding: 0; cursor: zoom-in; }
.att-imgbtn.ph { cursor: default; display: grid; place-items: center; min-height: 120px; }
.att-imgbtn.ph .btn { position: relative; z-index: 1; }
.att-img { display: block; width: 100%; height: 100%; object-fit: cover; }
.att-img.blur { position: absolute; inset: -12px; width: calc(100% + 24px); height: calc(100% + 24px); filter: blur(8px); }
.att-voice audio { width: min(260px, 60vw); height: 40px; display: block; }
.att-file { display: flex; align-items: center; gap: 12px; padding: 8px 8px 0; }
.att-meta { flex: 1; min-width: 0; }
.att-name { font-weight: var(--w-heading); overflow-wrap: anywhere; max-width: 220px; }
.att-prog { height: 4px; margin: 8px 4px 2px; border-radius: 2px; background: var(--s2); overflow: hidden; }
.att-prog > span { display: block; height: 100%; background: currentColor; transition: width var(--d2) linear; }
.att-err { display: flex; gap: 8px; align-items: center; font-size: .75rem; padding: 8px 4px 0; }
.bub.att .opts { display: flex; gap: 8px; padding: 8px 4px 0; }
.att-full { display: grid; gap: 12px; }
.att-full-img { max-width: 100%; max-height: 70vh; margin: 0 auto; border-radius: var(--r-row); }
.rec-overlay { position: fixed; left: 50%; bottom: 96px; transform: translateX(-50%); z-index: 60; display: flex; align-items: center; gap: 12px; padding-block: 4px; padding-inline: 24px 4px; border-radius: var(--r-pill); background: var(--solid); border: 1px solid var(--line); color: var(--t1); font-size: .875rem; }
.rec-overlay .mono { font-size: var(--fs-body-s); }

/* groups (docs/GROUPS.md) */
.groups-sec { padding: 16px var(--gutter) 24px; display: grid; gap: 8px; }
.groups-sec > .rows { padding: 0; margin-inline: -16px; }
.gs-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; padding: 4px 0; }
.ginv { margin: 0; }
.gname { display: block; font-size: .75rem; font-weight: var(--w-heading); color: var(--t2); margin-bottom: 2px; }
.gatt { display: grid; gap: 4px; max-width: min(72%, 560px); }
.gatt.them { align-self: flex-start; }
.gatt.me { align-self: flex-end; }
.gm-rep { margin-inline-start: 8px; font-size: var(--fs-micro); color: var(--t3); text-decoration: underline; opacity: 0; }
.bub:hover .gm-rep, .gatt:hover .gm-rep, .gm-rep:focus-visible { opacity: 1; }
@media (hover: none) { .gm-rep { opacity: 1; } }
.thread:not(:has(.thread-col)) > .bub { padding-bottom: 24px; }

/* interop (web/interop.ts): QR codes stay dark on white (a functional exception: phone cameras need it) */
.qr-wrap { display: grid; justify-items: center; gap: 8px; padding: 8px 0 16px; }
.qr { width: min(220px, 70vw); height: auto; border-radius: var(--r-in); background: #fff; }
.group[data-group=share] .in, .group[data-group=connections] .in, .group[data-group=discovery] .in { min-width: 0; flex: 1 1 240px; }
/* the date field's calendar glyph: muted and clickable, never hidden; the popup follows color-scheme (tokens.css) */
input[type=datetime-local].in::-webkit-calendar-picker-indicator { opacity: .6; cursor: pointer; }
input[type=datetime-local].in:hover::-webkit-calendar-picker-indicator { opacity: 1; }
[data-invite-sheet] { grid-template-columns: minmax(0, 1fr); }
.group[data-group=share], .group[data-group=connections] { min-width: 0; }
.group[data-group=connections] .lrow, .group[data-group=connect-agent] .lrow { flex-wrap: wrap; }
.group[data-group=connections] .cmid { flex: 1 1 200px; }
.group[data-group=connections] .check { display: flex; gap: 8px; align-items: center; white-space: normal; }
.group[data-group=connections] .prev, .group[data-group=share] .prev, .group[data-group=connect-agent] .prev:not(.mono) { white-space: normal; overflow-wrap: anywhere; }
/* wellbeing (web/health.ts, docs/HEALTH.md) */
.hl .seg.big, .hl > .seg { margin: 8px var(--gutter); }
.hl .hl-note { padding: 0 var(--gutter); }
.hl-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 8px; padding: 8px var(--gutter); }
.hl-tile { border-radius: var(--r-row); padding: 16px; background: var(--card); }
.hl-v { font-size: 1.375rem; line-height: 1.75rem; font-weight: var(--w-title); font-variant-numeric: tabular-nums; }
.hl-card { margin: 8px var(--gutter); border-radius: var(--r-card); background: var(--card); }
.hl-card.crisis { outline: 1px solid var(--danger); }
.hl-card p { margin: 0; }
.hl-res { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.hl-res a { text-decoration: underline; text-underline-offset: 3px; }
.hl-ins summary { cursor: pointer; padding: 8px 0; }
.hl .opts { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.hl input, .hl select, .hl textarea, [data-consent-sheet] select { background: transparent; color: var(--t1); border: 0; border-bottom: 1px solid var(--field-line); border-radius: 0; padding: 8px 0; min-height: var(--tap-min); }
.hl textarea { width: 100%; resize: vertical; }
.hl-chart { display: block; width: calc(100% - 2 * var(--gutter)); height: 120px; margin: 8px var(--gutter); }
.hl-chart rect { fill: var(--t2); }
.hl-table { width: calc(100% - 2 * var(--gutter)); margin: 0 var(--gutter) 12px; border-collapse: collapse; font-variant-numeric: tabular-nums; font-size: var(--fs-body-s); }
.hl-table caption { text-align: start; color: var(--t2); padding: 4px 0; }
.hl-table th, .hl-table td { text-align: start; padding: 8px 0; border-bottom: 1px solid var(--line); font-weight: var(--w-body); }
.hl-pre { white-space: pre-wrap; font: inherit; margin: 0; padding: 16px; border-radius: var(--r-row); background: var(--card); }
[data-consent-sheet] fieldset { border: 1px solid var(--ctl); border-radius: var(--r-row); margin: 8px 0; display: grid; gap: 8px; }
.hl-pad, .hl > .btn, .hl > .lrow { margin: 8px var(--gutter); }
.hl > .lrow { width: auto; }

/* --- first run, discovery, imported chats (docs/DISCOVERY.md, docs/IMPORT.md) --- */
/* the first run is one quiet row at the top of Knocks (the "Welcome tour" pill with its ×); the tour itself opens in
   a sheet, where the card is only the sheet's body: no tone, no padding, no border, no shadow (decision 3, 6 Oct 2026) */
.fr-row { display: flex; align-items: center; gap: 4px; margin: 0 var(--gutter) 16px; }
@media (max-width: 1023px) { .fr-row { margin-inline: 12px; } }
.fr-row > .auto-row { flex: 1; width: auto; margin: 0; }
.fr-card { position: relative; margin: 0 var(--gutter) 24px; padding: var(--card-pad); border-radius: var(--r-card); background: var(--card); display: grid; gap: 12px; }
@media (max-width: 1023px) { .fr-card { margin-inline: 12px; } }
.sheet .fr-card { margin: 0; padding: 0; background: transparent; --s2: inherit; --bub-them: inherit; --field-line: inherit; --card-on: inherit; }
.fr-card h2 { font-size: var(--fs-heading); line-height: var(--lh-heading); font-weight: var(--w-heading); margin: 0; text-wrap: balance; }
.fr-card p { margin: 0; }
/* a quiet action under the card's text aligns its label with the text column */
.fr-card .btn.text, .fr-card .acts > .btn:is(.text, .ghost):first-child { justify-self: start; margin-inline-start: -16px; }
.fr-dots { display: flex; gap: 8px; }
.fr-dots span { width: 6px; height: 6px; border-radius: 50%; background: var(--s2); }
.fr-dots span.on { background: var(--t1); }
.fr-who { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.fr-thread { max-height: 260px; padding: 4px 0; gap: 8px; }
.fr-card .composer { position: static; }
.fr-card .door { background: var(--s2); }
.fr-card .qr { width: min(160px, 50vw); }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.import-thread { max-height: 70dvh; padding: 8px 0; }
.import-thread img, .import-thread video { max-width: 100%; max-height: 320px; border-radius: var(--r-s); display: block; margin-bottom: 4px; }
.import-thread .bub { padding-bottom: 8px; }
.import-thread .bub .bt { position: static; display: block; text-align: end; margin-top: 4px; }
[data-group=imports] .crow { display: flex; }

/* encrypted backup (web/backup.ts, docs/BACKUP.md) */
.field { display: grid; gap: 8px; }
.words { columns: 2; column-gap: 24px; padding-inline-start: 32px; margin: 0; font-size: var(--fs-body); line-height: 1.625rem; }

/* one curvature: a soft squircle wherever a radius below the pill is used (progressive enhancement) */
@supports (corner-shape: superellipse(1.25)) {
  .kcard, .intent-card, .ic-row, .sheet, .menu, .menu > button, .menu > a, .menu .tr-ctl, .crow, .lrow, .irow, .erow, .choice, .reach, .fr-card, .consent,
  .captions, .safety, .warn-line, .composer, .seg, .toast, .door, .bubble, .bub, .av-a, .av-g, .hl-tile, .hl-card, .hl-pre, .clip, .call .local, .att-imgbtn,
  .att-full-img, .qr, .onb [data-group=pk-offer], [data-consent-sheet] fieldset { corner-shape: var(--q-shape); }
}

/* --- upstream launch-convergence surfaces on the v2 tokens (merged 6 Oct 2026) --- */
/* the outbox (web/outbox.ts): queued and failed texts, and the connection status while the socket is down */
.bub.pending:not(.att) { opacity: .78; }
.bub.pending.failed { opacity: 1; outline: 1.5px dashed currentColor; outline-offset: -4px; }
.bub .out-st { display: block; margin-top: 4px; font-size: var(--fs-mono); line-height: var(--lh-mono); opacity: .8; white-space: normal; }
.bub.pending .opts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; white-space: normal; }
.netbar { position: fixed; top: max(12px, env(safe-area-inset-top)); left: 50%; transform: translateX(-50%); z-index: 55; display: flex; align-items: center; gap: 8px; max-width: calc(100vw - 32px); min-height: 36px; padding: 8px 16px; border-radius: var(--r-pill); background: var(--solid); border: 1px solid var(--line); color: var(--t1); font-size: var(--fs-body-s); line-height: var(--lh-body-s); pointer-events: none; }
.netbar-dot { width: 8px; height: 8px; flex: none; border-radius: 50%; corner-shape: round; background: var(--t3); }
/* key/value lists on agent sheets (approval, AI assistants: docs/MANDATES.md §5b): spec-sheet rows */
dl.kv { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 8px 16px; margin: 4px 0; }
dl.kv dt { color: var(--t2); font-size: var(--fs-label); line-height: var(--lh-label); font-weight: var(--w-label); letter-spacing: var(--tr-label); text-transform: var(--tt-label); padding-top: 3px; }
dl.kv dd { margin: 0; font-size: var(--fs-body-s); line-height: var(--lh-body-s); min-width: 0; overflow-wrap: anywhere; }
dl.kv dd ul.plain { margin: 0; padding: 0; list-style: none; }
.assistant-scope { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
/* the members sheet: what a removal (or leaving) is doing, or why it failed (web/groups.ts) */
[data-members-status]:empty { margin: 0; }
[data-members-status=error] { font-weight: var(--w-strong); }
.btn[aria-busy=true] { cursor: progress; }
/* paid passes (web/pay.ts, docs/PAID_PASSES.md §10b): test mode is a plain tag; boxes are cards */
.tag.test-pay { color: var(--t2); white-space: normal; }
.pay-box { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; padding: 16px; border-radius: var(--r-row); background: var(--card); color: var(--t1); margin: 8px 0; }
.pay-box .foot, .pay-box .muted { color: var(--t2); }
/* a button on a row of its own (in a settings group or a box) takes the row and wraps its label when the text is large
   or the screen narrow, instead of running off the side (QA personas, older user at 24 px on 320 px, 6 Oct 2026:
   "Set up payouts with Stripe" was cut off; test/text-size.test.ts) */
.group > .btn, .pay-box > .btn { white-space: normal; text-align: center; overflow-wrap: anywhere; padding-block: 8px; }
.pay-amt { font-size: var(--fs-body); line-height: var(--lh-body); display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.pay-cards { border: 0; margin: 0; padding: 0; display: grid; gap: 8px; min-width: 0; }
.pay-chip { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: var(--fs-body-s); line-height: var(--lh-body-s); color: var(--t2); }
.money-in { display: flex; align-items: center; gap: 8px; }
.money-in .in { flex: 1; min-width: 0; }
.pay-field { display: grid; gap: 8px; }
/* skip link (conversation header → message box): out of sight until focused (WCAG 2.4.1) */
.skip:not(:focus):not(:focus-visible) { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.skip:focus, .skip:focus-visible { position: absolute; inset-inline-start: 56px; top: 100%; z-index: 5; min-height: var(--tap-min); display: inline-flex; align-items: center; padding: 8px 16px; border-radius: var(--r-pill); background: var(--inv-bg); color: var(--inv-t); font-size: var(--fs-body-s); text-decoration: none; }
.pane-head .skip:focus, .pane-head .skip:focus-visible { inset-inline-start: var(--gutter); top: calc(100% - 8px); }
/* hidden inside the header actions it takes no room: cancels the flex gap so the icons keep their places */
.head-acts > .skip:not(:focus):not(:focus-visible) { margin-inline-end: -5px; }
/* unreviewed safety text in a safety-draft locale (web/i18n.ts bilingual, docs/I18N.md "Safety drafts"): the
   translation, then its en-GB source on a line of its own, a step smaller, in the same colour (contrast unchanged) */
.bi-en { display: block; font-size: .875em; font-weight: var(--w-body); letter-spacing: normal; text-transform: none; }
/* in a compact control the source is out of sight so the control keeps its size; it stays in the accessible name,
   and web/ui.ts puts it in the button's tooltip. Full-width buttons and wrapping choice rows (report reasons) show it */
button:not(.wide) .bi-en { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.seg.wrap .segb .bi-en { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip-path: none; white-space: normal; }
/* a handle or domain is one word: it wraps before the value, never at its hyphen ("northwind-/air.example") */
.pass-form :is(.row, .foot) .mono { white-space: nowrap; }
