/* GroupChatRobot app components. Colours come from themes.css tokens only; the two photo tokens below
   are for chrome drawn over user photos, where the pack colour cannot be trusted. 390px first. */
:root { --photo-scrim: rgb(0 0 0 / 0.55); --photo-text: #FFFFFF; --photo-bg: #000000; }
/* A QR code stays dark on white in every pack, because phone cameras read it that way. */
:root { --qr-light: #FFFFFF; }

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; height: 100%; overflow: hidden; overscroll-behavior: none; }
html { font-size: 100%; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
@supports (font: -apple-system-body) { html { font: -apple-system-body; } }
body {
  font-family: var(--font-ui); font-size: var(--fs-body); line-height: var(--lh-body);
  background: var(--page-bg); color: var(--text); -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent;
}
button, input, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; }
img, svg { display: block; }
a { color: var(--link); }
h1, h2, h3, p { margin: 0; }
ul, ol { margin: 0; padding: 0; }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.sr-only { position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
[hidden] { display: none !important; }
.icon { flex: none; }
.mark { flex: none; color: currentColor; }
.mark__fold { fill: var(--robot-fold); }
[data-theme$="-dark"] .mark__fold { fill: var(--robot-name); }
@media (prefers-color-scheme: dark) { :root:not([data-theme]) .mark__fold { fill: var(--robot-name); } }
.code { font-family: var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; font-weight: 600; }
.code--lg { font-size: var(--fs-title3); }

/* ---------- App shell ---------- */
.app { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); height: var(--app-h, 100dvh); width: 100%; overflow: hidden; }
.app__main { position: relative; min-width: 0; height: 100%; overflow: hidden; background: var(--page-bg); }
.app__rail { display: none; min-width: 0; }
.app--rail-open .app__rail { display: block; position: absolute; inset: 0; z-index: 30; }
@media (min-width: 900px) {
  .app { grid-template-columns: 260px minmax(0, 1fr); }
  .app__rail, .app--rail-open .app__rail { display: block; position: relative; inset: auto; z-index: auto; border-right: 1px solid var(--hairline); }
}
@media (min-width: 1100px) { .app { grid-template-columns: var(--rail-w) minmax(0, 1fr); } }

/* ---------- Route changes (app.js show, railIn, railOut) ----------
   The view being left stays where it is as a ghost under (push) or over (pop) the new one until the move ends. On a
   phone the room list slides under the room: the room is lifted above it while it moves. */
.view-ghost { position: absolute !important; inset: 0; z-index: 0; pointer-events: none; }
.view-ghost--pop { z-index: 2; }
.app__main > :not(.view-ghost) { position: relative; z-index: 1; }
.app--route-over .app__main { z-index: 31; box-shadow: -8px 0 24px hsl(var(--shadow-color) / 0.16); }
.app--rail-hold .app__rail { display: block; position: absolute; inset: 0; z-index: 30; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); height: 48px; padding: 0 20px;
  border: 0; border-radius: var(--radius-md); font-size: var(--fs-body); font-weight: var(--fw-semibold); line-height: 1;
  text-decoration: none; white-space: nowrap; transition: transform var(--dur-1) var(--ease-out), background-color var(--dur-1);
}
.btn:active:not([disabled]) { transform: scale(0.96); }
.btn[disabled], .btn[aria-disabled="true"] { opacity: 0.55; cursor: default; }
.btn--primary { background: var(--accent); color: var(--accent-text); }
.btn--secondary { background: var(--accent-soft); color: var(--link); }
.btn--ghost { background: transparent; color: var(--link); }
.btn--danger { background: var(--danger); color: var(--danger-text); }
.btn--danger-text { color: var(--danger); }
.btn--block { width: 100%; }
.btn--sm { height: 36px; padding: 0 14px; font-size: var(--fs-subhead); }
@media (pointer: coarse) { .btn--sm { height: 44px; } }
@media (min-width: 900px) and (pointer: fine) { .btn { height: 40px; } .btn--sm { height: 34px; } }
@media (hover: hover) {
  .btn--primary:hover:not([disabled]) { filter: brightness(1.08); }
  .btn--secondary:hover:not([disabled]), .btn--ghost:hover:not([disabled]) { background: var(--accent-soft); }
}
.icon-btn {
  display: inline-grid; place-items: center; width: var(--hit); height: var(--hit); flex: none; padding: 0; border: 0;
  border-radius: var(--radius-md); background: transparent; color: var(--link); text-decoration: none;
}
@media (hover: hover) { .icon-btn:hover { background: var(--hairline); } }
.spinner { display: inline-block; width: 18px; height: 18px; flex: none; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: spin 0.8s linear infinite; vertical-align: -3px; }
.spinner--sm { width: 14px; height: 14px; }
@keyframes spin { to { transform: rotate(360deg); } }
.badge { display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--radius-pill); background: var(--accent); color: var(--accent-text); font-size: var(--fs-caption); font-weight: var(--fw-bold); line-height: 1; }
.tag { display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border-radius: var(--radius-pill); border: 1px solid var(--border); color: var(--text-muted); font-size: var(--fs-caption); font-weight: var(--fw-medium); }
.dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; flex: none; }
.dot--here { background: var(--success); }

/* ---------- Fields ---------- */
.field { display: flex; flex-direction: column; gap: 6px; margin: 0 0 var(--space-5); min-width: 0; }
.field--group { border: 0; padding: 0; min-width: 0; }
.field__label { font-size: var(--fs-subhead); font-weight: var(--fw-semibold); color: var(--text); padding: 0; }
legend.field__label { margin-bottom: 8px; }
.field__input {
  width: 100%; min-height: 48px; padding: 0 14px; border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--field-bg); color: var(--field-text); font-size: max(16px, 1rem); line-height: var(--lh-body);
}
textarea.field__input { padding: 12px 14px; resize: vertical; min-height: 88px; }
.field__input::placeholder { color: var(--field-placeholder); opacity: 1; }
.field__input:focus-visible, .field__input:focus { outline: 2px solid var(--focus-ring); outline-offset: 0; border-color: var(--focus-ring); }
.field__input--code { font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.08em; }
.field__hint { font-size: var(--fs-footnote); color: var(--text-muted); }
.field__error { font-size: var(--fs-footnote); color: var(--danger); font-weight: var(--fw-medium); }
.field--error .field__input { border-color: var(--danger); }

.segmented { display: flex; gap: 3px; padding: 3px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--page-bg); }
.segmented__opt { flex: 1; min-width: 0; display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: var(--hit); padding: 4px 6px; text-align: center; line-height: var(--lh-tight); border: 0; border-radius: 9px; background: transparent; color: var(--text-muted); font-size: var(--fs-subhead); font-weight: var(--fw-semibold); }
.segmented__opt--on { background: var(--sheet-bg); color: var(--text); box-shadow: var(--elev-1); }

.search { position: relative; margin: 0 0 var(--space-4); }
.search__glyph { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--text-muted); pointer-events: none; }
.search__input { width: 100%; height: 44px; padding: 0 12px 0 40px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--field-bg); color: var(--field-text); font-size: max(16px, 1rem); -webkit-appearance: none; appearance: none; }
.search__input::placeholder { color: var(--field-placeholder); opacity: 1; }
.search__input:focus { outline: 2px solid var(--focus-ring); outline-offset: 0; border-color: var(--focus-ring); }
.search--compact { margin: 0; }
.search--compact .search__input { height: 40px; }

/* ---------- Toggle ---------- */
.toggle { position: relative; width: 51px; height: 31px; flex: none; padding: 0; border: 0; border-radius: var(--radius-pill); background: var(--border); transition: background-color var(--dur-2); }
.toggle::after { content: ""; position: absolute; top: 2px; left: 2px; width: 27px; height: 27px; border-radius: 50%; background: var(--sheet-bg); box-shadow: var(--elev-1); transition: transform var(--dur-2) var(--ease-out); }
.toggle[aria-checked="true"] { background: var(--accent); }
.toggle[aria-checked="true"]::after { transform: translateX(20px); background: var(--accent-text); }
.toggle[disabled] { opacity: 0.55; }
.toggle::before { content: ""; position: absolute; inset: -7px -2px; }

/* ---------- Skeletons ---------- */
.skeleton { position: relative; overflow: hidden; background: var(--skeleton-base); border-radius: 6px; }
.skeleton::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%); background: linear-gradient(90deg, transparent, var(--skeleton-shine), transparent); animation: shine 1.4s linear infinite; }
@keyframes shine { to { transform: translateX(100%); } }
.skeleton--line { height: 12px; margin: 8px 0; }
.skeleton--bubble { height: 44px; width: 60%; border-radius: var(--bubble-radius); }
.skeleton--out { align-self: flex-end; width: 45%; }
.skeleton--card { height: 104px; border-radius: var(--radius-md); margin-bottom: var(--space-3); list-style: none; }
.skeleton--circle { width: 56px; height: 56px; border-radius: 50%; margin-bottom: 16px; }
.skeleton--field { height: 48px; border-radius: var(--radius-md); margin-top: 24px; }

/* ---------- Room ---------- */
.room { position: relative; height: 100%; overflow: hidden; }
.room-header {
  position: absolute; top: 0; left: 0; right: 0; z-index: var(--z-header);
  display: flex; align-items: center; gap: var(--space-1);
  min-height: calc(var(--header-h) + env(safe-area-inset-top));
  padding: env(safe-area-inset-top) max(var(--space-1), env(safe-area-inset-right)) 0 max(var(--space-1), env(safe-area-inset-left));
  background: var(--header-bg, var(--surface)); color: var(--header-text, var(--text)); -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur); border-bottom: 1px solid transparent;
}
.room-header--scrolled { border-bottom-color: var(--hairline); }
/* Without backdrop blur (older Android WebViews, some headless renders) the glass header would show messages through the title. */
@supports not (backdrop-filter: blur(1px)) {
  @supports not (-webkit-backdrop-filter: blur(1px)) {
    .composer, .join__home { background: var(--surface-solid); }
    .room-header { background: var(--header-bg, var(--surface-solid)); }
  }
}
.room-header__back, .page-header__back {
  position: relative; display: inline-flex; align-items: center; height: var(--hit); min-width: var(--hit); padding: 0 6px 0 0;
  border: 0; border-radius: var(--radius-md); background: transparent; color: var(--header-link, var(--link)); font-size: var(--fs-body); flex: none;
}
.room-header__chev { display: grid; place-items: center; width: 28px; }
.room-header--long .room-header__backlabel { display: none; }
.room-header__badge { margin-left: 4px; }
.room-header__info {
  flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 1px;
  height: 48px; padding: 0 var(--space-2); border: 0; border-radius: var(--radius-md); background: transparent; color: var(--header-text, var(--text)); text-align: left;
}
.room-header__title { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-body); font-weight: var(--fw-semibold); line-height: var(--lh-tight); }
.room-header__sub { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-footnote); color: var(--header-muted, var(--text-muted)); line-height: var(--lh-tight); }
.room-header--typing .room-header__sub { color: var(--header-link, var(--link)); }
.room-header__subrow { display: flex; align-items: center; gap: 4px; max-width: 100%; min-width: 0; }
.room-header__about { display: grid; flex: none; color: var(--header-muted, var(--text-muted)); }
.room-header__about[hidden] { display: none; }
.room-header__actions { display: flex; flex: none; }
.room-header__actions .icon-btn { color: var(--header-link, var(--link)); }
/* The room code, always in the header (live test 2, #14). The pill is 32px; the button around it is the 44px hit area. */
.room-header__code { position: relative; flex: none; display: inline-flex; align-items: center; height: var(--hit); padding: 0 2px; border: 0; background: transparent; color: var(--text); }
.room-header__code { gap: 7px; height: 34px; margin: auto 0; padding: 0 12px 0 4px; border: 1px solid var(--border); border-radius: var(--radius-pill); background: var(--field-bg); font-size: var(--fs-subhead); font-weight: var(--fw-semibold); }
.room-header__miniqr { display: inline-grid; width: 26px; height: 26px; overflow: hidden; border-radius: 5px; background: #FFFFFF; }
.room-header__miniqr svg { width: 100%; height: 100%; }
@media (hover: hover) { .room-header__code:hover { border-color: var(--focus-ring); } }
.share-sheet .sheet__body { display: flex; flex-direction: column; align-items: center; text-align: center; }
.share-sheet__qr { width: min(240px, 70vw); aspect-ratio: 1; overflow: hidden; border: 1px solid var(--hairline); border-radius: var(--radius-lg); background: #FFFFFF; }
.share-sheet__qr svg { width: 100%; height: 100%; }
.share-sheet__hint { margin-top: var(--space-3); font-size: var(--fs-subhead); color: var(--text-muted); }
.share-sheet__link { font-family: var(--font-mono); font-weight: var(--fw-semibold); overflow-wrap: anywhere; }
.share-sheet__code { margin-top: var(--space-2); color: var(--text-muted); font-size: var(--fs-subhead); }
.share-sheet__code .code { color: var(--text); font-size: var(--fs-body); letter-spacing: 0.06em; }
.share-sheet__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-2); margin-top: var(--space-4); }

/* Use on another device (views/devices.js): the code sheet on the device with the rooms, the /link page on the other. */
.devices-sheet .sheet__body { display: flex; flex-direction: column; }
.devices-sheet__lead { font-size: var(--fs-body); }
.devices-sheet__steps { display: grid; gap: var(--space-1); margin: var(--space-3) 0 var(--space-2); padding-left: 1.4em; font-size: var(--fs-subhead); color: var(--text-muted); }
.devices-sheet__have { margin-top: var(--space-3); font-size: var(--fs-subhead); text-align: center; }
.devices-sheet__have button { padding: 6px 0; border: 0; background: transparent; color: var(--link); font-weight: var(--fw-semibold); text-align: center; }
.devices-sheet__qr { align-self: center; }
.devices-sheet__qr--spent { opacity: 0.2; }
.devices-sheet .share-sheet__hint { text-align: center; }
.devices-sheet__code { font-size: clamp(1.75rem, 9vw, 2.25rem); line-height: 1.2; text-align: center; }
.devices-sheet__time { font-size: var(--fs-subhead); color: var(--text-muted); text-align: center; font-variant-numeric: tabular-nums; }
.devices-sheet__warn { display: flex; align-items: flex-start; gap: var(--space-2); margin-top: var(--space-4); padding: var(--space-3); border-radius: var(--radius-md); background: var(--accent-soft); font-size: var(--fs-subhead); line-height: 1.4; text-align: left; }
.devices-sheet__warn-glyph { display: grid; flex: none; color: var(--link); }
.devices-match { margin: var(--space-2) 0; font-family: var(--font-mono); font-size: clamp(3.5rem, 18vw, 5rem); font-weight: var(--fw-bold); line-height: 1; letter-spacing: 0.04em; text-align: center; font-variant-numeric: tabular-nums; }
.devices-sheet__ask { font-size: var(--fs-title3); font-weight: var(--fw-semibold); text-align: center; }
.devices-sheet__center { text-align: center; }
.devices-sheet__result { margin-bottom: var(--space-2); font-size: var(--fs-body); font-weight: var(--fw-semibold); }
.devices-sheet__answer { display: grid; gap: var(--space-2); }
.link-page__wait { display: flex; align-items: center; justify-content: center; gap: var(--space-2); color: var(--text-muted); font-size: var(--fs-subhead); }
.link-page__notes { display: grid; gap: var(--space-2); max-width: 60ch; margin: 0; padding-left: 1.2em; color: var(--text-muted); font-size: var(--fs-subhead); }
.link-page__input { font-size: var(--fs-title3); }
.link-page__form { margin-top: 0; padding-top: 0; border-top: 0; }
.link-page__rooms { margin: var(--space-2) 0 var(--space-4); padding: 0; list-style: none; border-top: 1px solid var(--hairline); }
.link-page__rooms li { padding: var(--space-3) 0; border-bottom: 1px solid var(--hairline); font-weight: var(--fw-semibold); overflow-wrap: anywhere; }
.link-page__rooms .link-page__more { font-weight: var(--fw-regular); color: var(--text-muted); }
.link-page__actions { display: grid; gap: var(--space-2); max-width: 360px; margin-top: var(--space-5); }
@media (min-width: 900px) { .link-page__rail-btn { display: none; } }
/* The same flow in a sheet (views/devices.js openLinkCodeSheet): the state's heading sits under the sheet title. */
.link-sheet__head { margin: var(--space-2) 0 var(--space-3); font-size: var(--fs-body); font-weight: var(--fw-semibold); line-height: var(--lh-tight); }
.link-sheet .link-page__actions { margin-top: var(--space-4); }
.explore__device-link { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--hit); margin-top: var(--space-3); padding: 0; border: 0; background: transparent; color: var(--link); font-size: var(--fs-subhead); font-weight: var(--fw-semibold); text-decoration: none; }
@media (hover: hover) { .room-header__info:hover, .room-header__back:hover, .page-header__back:hover { background: var(--hairline); } }
@media (min-width: 900px) {
  .room-header { padding-left: var(--space-3); padding-right: var(--space-3); }
  .room-header__back { display: none; }
}

.conn-banner {
  display: flex; align-items: center; justify-content: center; gap: var(--space-2); padding: 6px var(--space-4);
  background: var(--surface-solid); border-bottom: 1px solid var(--hairline); color: var(--text-muted); font-size: var(--fs-footnote); font-weight: var(--fw-medium); text-align: center;
}
.conn-banner--offline { color: var(--text); }
.conn-banner__icon { color: var(--danger); display: grid; }

.msg-list {
  position: absolute; inset: 0; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; overflow-anchor: none;
  background: var(--wallpaper);
  padding: calc(var(--header-real-h, 56px) + var(--space-2)) 0 calc(var(--composer-h, 64px) + var(--space-3));
}
/* A banner or the connection line shrinks the list instead of lying over it: the list's top edge moves below the band,
   so no message ever scrolls under a banner (R00-15). Without a band the list runs under the glass header. */
.room--band .msg-list { top: calc(var(--header-real-h, 56px) + var(--banners-h, 0px)); padding-top: var(--space-2); }
.msg-list__col { display: flex; flex-direction: column; justify-content: flex-end; min-height: 100%; max-width: var(--chat-max); margin: 0 auto; padding: 0 var(--space-3); }
.msg-list__inner { display: flex; flex-direction: column; }
@media (min-width: 1024px) { .msg-list { --bubble-max: min(60%, 440px); } }
.msg-list__loader { display: flex; flex-direction: column; gap: 8px; padding: 8px 0 16px; }

.msg-row { display: flex; flex-direction: column; align-items: flex-start; margin-top: var(--run-gap, var(--space-0)); min-width: 0; }
.msg-row--first { margin-top: var(--group-gap, var(--space-2)); }
.msg-row--out { align-items: flex-end; }
.msg-row--system { align-items: center; margin: var(--space-3) 0; }
.msg-row--highlight { animation: flash 1.2s var(--ease-in-out); border-radius: var(--radius-md); }
@keyframes flash { 0%, 55% { background: var(--selection-bg); } 100% { background: transparent; } }

/* Sticky offsets count from the list's content box, which the padding or the band already puts below the header. */
.day-divider { position: sticky; top: 0; z-index: 2; display: flex; justify-content: center; margin: var(--space-3) 0; pointer-events: none; }
.day-divider--under { visibility: hidden; }
/* A pinned pill is opaque so no bubble text reads through it, and it shows only while the person scrolls. */
.day-divider--pinned { opacity: 0; }
.msg-list--scrolling .day-divider--pinned { opacity: 1; }
.day-divider span, .system-line {
  display: inline-flex; align-items: center; gap: 6px; max-width: 92%; padding: 4px 12px; border-radius: var(--radius-pill);
  background: var(--system-bg); color: var(--system-text); font-size: var(--fs-footnote); font-weight: var(--fw-medium); line-height: var(--lh-body); text-align: center;
  box-shadow: 0 1px 1px hsl(var(--shadow-color) / 0.06);
}
/* Pinned: the same pill colour laid over the theme's solid wallpaper colour, so it looks unchanged but is opaque. */
.day-divider--pinned span { background: linear-gradient(var(--system-bg), var(--system-bg)), var(--wallpaper-base, var(--surface-solid)); box-shadow: var(--elev-1); }
.system-line__icon { display: grid; color: var(--system-text); }
.unread-divider { position: relative; display: flex; justify-content: center; margin: var(--space-3) calc(-1 * var(--space-3)); }
.unread-divider::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; border-top: 1px solid var(--hairline); }
.unread-divider span { position: relative; padding: 4px 12px; border-radius: var(--radius-pill); background: var(--unread-bg); color: var(--unread-text); font-size: var(--fs-footnote); font-weight: var(--fw-semibold); }

/* ---------- Bubbles ---------- */
.bubble {
  position: relative; max-width: var(--bubble-max); min-width: 0; padding: var(--bubble-pad, 6px 10px 5px);
  border-radius: var(--bubble-radius); font-size: var(--fs-body); line-height: var(--lh-body);
  overflow-wrap: anywhere; word-break: break-word; box-shadow: var(--bubble-shadow, var(--elev-1));
  -webkit-user-select: text; user-select: text; -webkit-touch-callout: none;
}
/* On touch the 450 ms press opens the action sheet (Copy lives there); selectable text would also raise the iOS
   loupe and edit bar over it. Mouse and trackpad keep selection. */
@media (pointer: coarse) { .bubble { -webkit-user-select: none; user-select: none; } }
.bubble--in { background: var(--bubble-in-bg); color: var(--bubble-in-text); }
.bubble--out { background: var(--bubble-out-bg); color: var(--bubble-out-text); }
.bubble--in.bubble--tail { border-bottom-left-radius: var(--bubble-radius-tail); }
.bubble--out.bubble--tail { border-bottom-right-radius: var(--bubble-radius-tail); }
/* A curved tail on the last bubble of a run, where the look asks for one (--tail: block). One pseudo-element in the
   bubble's colour, 13px of it under the bubble's corner, 7px outside: the bubble's edge runs down to 10px above the
   baseline, then a scooped horn (an arc of radius 10) runs out to a point at the baseline, and the underside comes
   back as an arc of radius 15 that replaces the bubble's own corner. */
.bubble--in.bubble--tail::before, .bubble--out.bubble--tail::before {
  content: ""; position: absolute; bottom: 0; width: 20px; height: 20px; display: var(--tail, none); pointer-events: none;
}
.bubble--in.bubble--tail::before { left: -7px; background: var(--bubble-in-bg); clip-path: path('M20 0 H7 V10 A10 10 0 0 1 0 19.5 V20 H5 A15 15 0 0 0 20 5 Z'); }
.bubble--out.bubble--tail::before { right: -7px; background: var(--bubble-out-bg); clip-path: path('M0 0 H13 V10 A10 10 0 0 0 20 19.5 V20 H15 A15 15 0 0 1 0 5 Z'); }
.bubble--robot.bubble--tail::before, .bubble--emoji-only.bubble--tail::before { display: none; }
.bubble--selected { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.bubble__name { font-size: var(--fs-footnote); font-weight: var(--fw-semibold); line-height: var(--lh-tight); margin: 1px 0 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 1023px) { .msg-row:not(.msg-row--first) .bubble__name { display: none; } }
.bubble__body { min-width: 0; }
.bubble__body::after { content: ""; display: block; clear: both; }
.bubble__body a { color: var(--bubble-in-link); text-decoration: underline; text-underline-offset: 2px; }
.bubble--out .bubble__body a { color: var(--bubble-out-link); }
.bubble__body code { font-family: var(--font-mono); font-size: 0.9em; padding: 1px 4px; border-radius: var(--radius-xs); background: var(--quote-in-bg); }
.bubble--out .bubble__body code { background: var(--quote-out-bg); }
.mention { font-weight: var(--fw-semibold); }
.bubble__meta {
  float: right; position: relative; top: 5px; display: inline-flex; align-items: center; gap: 3px; margin: 0 -2px 0 12px;
  font-size: var(--fs-caption); line-height: 1.6; color: var(--bubble-in-meta); white-space: nowrap; -webkit-user-select: none; user-select: none;
}
.bubble--out .bubble__meta { color: var(--bubble-out-meta); }
.bubble__edited { margin-right: 2px; }
.bubble--deleted { box-shadow: none; }
.ticks { display: inline-grid; color: var(--tick); }
.ticks svg { width: 16px; height: 16px; }
.ticks--read { color: var(--tick-read); }
.ticks--failed { color: var(--danger); }
.bubble--emoji-only { background: transparent; box-shadow: none; padding: 0 2px; }
.bubble--emoji-only .bubble__body { font-size: 2.5rem; line-height: 1.15; }
.bubble--emoji-only .bubble__meta { float: none; display: flex; justify-content: flex-end; top: 0; margin: 0; padding: 2px 8px; border-radius: var(--radius-pill); background: var(--system-bg); color: var(--system-text); font-size: var(--fs-caption); line-height: 1.4; width: max-content; margin-left: auto; }
.bubble--emoji-only .ticks { color: var(--system-text); }
.bubble--emoji-only .bubble__name { font-size: var(--fs-footnote); }
.bubble__body--metaonly { min-height: 0; }
.bubble__body--metaonly .bubble__meta { top: 0; margin-top: 2px; }

/* Message formatting (markdown.js). Blocks stack with half a line between them; every colour comes from the bubble's
   own text colour or its quote tokens, so the same rules read in the in, out and robot bubbles in every pack. */
:where(.bubble__body, .read-note__body, .doc-view__text) > :is(p, .md-list, .md-quote, .md-code, .md-table, .md-rule) { margin: 0; }
:where(.bubble__body, .read-note__body, .doc-view__text) > :is(p, .md-list, .md-quote, .md-code, .md-table, .md-rule) + :is(p, .md-list, .md-quote, .md-code, .md-table, .md-rule) { margin-top: 0.45em; }
:where(.bubble__body, .read-note__body, .doc-view__text) > * + .md-h { margin-top: 0.75em; }
.md-h { font-weight: var(--fw-bold); line-height: var(--lh-tight); text-wrap: balance; }
.md-h1 { font-size: 1.25em; }
.md-h2 { font-size: 1.125em; }
.md-h3 { font-size: 1em; }
.md-list { margin: 0; padding-left: 1.35em; }
.md-list li + li, .md-list .md-list { margin-top: 2px; }
.md-list li::marker { color: color-mix(in srgb, currentColor 70%, transparent); }
.md-list:has(> .md-check) { padding-left: 0.1em; list-style: none; }
.md-check { position: relative; padding-left: 1.45em; }
.md-box { position: absolute; left: 0; top: 0.17em; width: 1em; height: 1em; border: 1.5px solid currentColor; border-radius: 4px; opacity: 0.75; }
.md-check--done .md-box { opacity: 1; }
.md-check--done .md-box::after { content: ""; position: absolute; left: 0.27em; top: 0.06em; width: 0.28em; height: 0.52em; border: solid currentColor; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.md-quote { margin: 0; padding: 1px 0 1px 10px; border-left: 3px solid var(--quote-bar); }
.bubble--out .md-quote { border-left-color: var(--quote-out-bar); }
.bubble--robot .md-quote { border-left-color: var(--robot-fold); }
.md-quote > * { margin: 0; }
.md-quote > * + * { margin-top: 0.35em; }
.md-rule { height: 0; border: 0; border-top: 1px solid color-mix(in srgb, currentColor 22%, transparent); }
/* Code and tables scroll sideways inside the bubble, never the page; their text never breaks mid-word. */
.md-code, .md-table { max-width: 100%; border-radius: var(--radius-sm); overflow-wrap: normal; word-break: normal; }
.md-code { background: var(--quote-in-bg); }
.bubble--out .md-code { background: var(--quote-out-bg); }
.bubble--robot .md-code { background: color-mix(in srgb, var(--robot-border) 55%, transparent); }
.md-code__bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); padding: 2px 2px 0 10px; font-size: var(--fs-caption); }
.md-code__lang { color: color-mix(in srgb, currentColor 65%, transparent); font-family: var(--font-mono); }
.md-code__copy { position: relative; min-height: 30px; padding: 0 10px; border: 0; border-radius: var(--radius-xs); background: transparent; color: inherit; font: inherit; font-weight: var(--fw-semibold); }
.md-code__copy::after { content: ""; position: absolute; inset: -7px -2px; }
@media (hover: hover) { .md-code__copy:hover { background: color-mix(in srgb, currentColor 10%, transparent); } }
.md-code__pre { margin: 0; padding: 4px 10px 9px; overflow-x: auto; font-family: var(--font-mono); font-size: 0.85em; line-height: 1.45; white-space: pre; tab-size: 2; -webkit-overflow-scrolling: touch; }
.bubble__body .md-code__pre code { padding: 0; border-radius: 0; background: none; font-size: inherit; }
.md-table { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.md-table table { border-collapse: collapse; font-size: var(--fs-subhead); line-height: var(--lh-tight); }
.md-table th, .md-table td { min-width: 4ch; max-width: 26ch; padding: 5px 9px; border: 1px solid color-mix(in srgb, currentColor 20%, transparent); text-align: left; vertical-align: top; }
.md-table th { background: var(--quote-in-bg); font-weight: var(--fw-semibold); }
.bubble--out .md-table th { background: var(--quote-out-bg); }
.bubble--robot .md-table th { background: color-mix(in srgb, var(--robot-border) 55%, transparent); }
.md-table .md-center { text-align: center; }
.md-table .md-right { text-align: right; font-variant-numeric: tabular-nums; }
.md-code__pre:focus-visible, .md-table:focus-visible, .spoiler:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.spoiler { border-radius: 4px; background: color-mix(in srgb, currentColor 72%, transparent); cursor: pointer; }
.spoiler:not(.spoiler--shown) .spoiler__text { visibility: hidden; }
.spoiler--shown { background: color-mix(in srgb, currentColor 10%, transparent); cursor: auto; }
.mention--person { padding: 0 4px; border-radius: 5px; background: color-mix(in srgb, currentColor 13%, transparent); white-space: nowrap; }

/* Robot: a quiet card, the same in every look. Light cream (warm charcoal on a dark side) with a thin gold outline,
   told from a person's white bubble at a glance but no colour block and no folded corner: the robot is known by the
   mark before its name, the name, and gold bullets in its lists. A touch more room inside than a person's bubble and
   a wider column, so a long answer wraps like prose. */
.msg-list .msg-row--robot { --bubble-max: min(88%, 480px); }
@media (min-width: 1024px) { .msg-list .msg-row--robot { --bubble-max: min(72%, 560px); } }
.bubble--robot { padding: 8px 12px 7px; background: var(--robot-bg); color: var(--robot-text); border: 1px solid var(--robot-border); box-shadow: none; }
.bubble--robot.bubble--tail { border-bottom-left-radius: var(--bubble-radius-tail); }
.bubble--robot:focus-visible { outline-offset: -3px; }
.bubble--robot .bubble__meta { color: var(--robot-meta); }
.bubble--robot .bubble__body a { color: var(--robot-link); text-decoration-thickness: 1px; text-underline-offset: 3px; }
.bubble--robot .bubble__body code { background: color-mix(in srgb, var(--robot-border) 55%, transparent); }
/* An answer with more than two blocks is read, not glanced at: looser leading and a breath between list items. */
.bubble--robot .bubble__body:has(> :nth-child(3)) { line-height: 1.45; }
.bubble--robot .bubble__body:has(> :nth-child(3)) .md-list li + li { margin-top: 4px; }
.bubble--robot .md-list li::marker { color: var(--robot-name); }
.bubble--robot-failed .bubble__body { font-style: italic; color: var(--robot-meta); }
/* The name line: the mark and "Robot" at caption size, so the answer outranks it. When the robot joined in unasked
   the reason sits on the same line ("Robot · Joined in") instead of trailing the answer as a footnote. */
.robot-tag { display: flex; align-items: center; gap: 5px; margin: 0 20px 4px 0; font-size: var(--fs-caption); font-weight: var(--fw-semibold); line-height: var(--lh-tight); letter-spacing: 0.01em; color: var(--robot-name); }
.robot-tag .mark { color: var(--robot-name); }
.robot-tag .mark__fold { fill: var(--robot-fold); }
.robot-tag__why { font-weight: var(--fw-medium); color: var(--robot-meta); }
.robot-tag__why::before { content: "\00b7"; margin: 0 5px 0 1px; }
@media (max-width: 1023px) { .msg-row--robot:not(.msg-row--first) .robot-tag:not(.robot-tag--why) { display: none; } }
.caret { display: inline-block; width: 0.5em; height: 1.05em; margin-left: 2px; vertical-align: -0.15em; background: currentColor; opacity: 0.55; animation: blink 1s steps(2, start) infinite; }
@keyframes blink { to { visibility: hidden; } }
/* The card's foot: the files the answer used on the left, the time on the right, so the time is always last. */
.robot-foot { clear: both; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 2px 10px; margin: 5px 0 -1px; }
.robot-foot .bubble__meta { float: none; top: 0; margin: 0 -2px 0 auto; }
.source-chips { display: flex; flex-wrap: wrap; gap: 4px 6px; min-width: 0; }
/* The button shows as a 26px hairline pill; its hit area reaches 44px around it. */
.source-chip { position: relative; display: inline-flex; align-items: center; max-width: 100%; min-height: 28px; padding: 0; border: 0; background: transparent; color: var(--robot-link); font-size: var(--fs-caption); font-weight: var(--fw-semibold); }
.source-chip::after { content: ""; position: absolute; inset: -8px 0; }
.source-chip__pill { display: inline-flex; align-items: center; gap: 4px; min-width: 0; max-width: 100%; min-height: 26px; padding: 2px 9px 2px 6px; border: 1px solid var(--robot-border); border-radius: var(--radius-pill); }
.source-chip__pill svg { width: 16px; height: 16px; }
.source-chip__name { display: flex; min-width: 0; }
@media (hover: hover) { .source-chip:hover .source-chip__pill { background: color-mix(in srgb, var(--robot-border) 45%, transparent); } }
/* A robot answer on its way: the dots, what it is doing ("Searching the web for ..."), and after 5 s the seconds. */
.robot-working { display: flex; flex-wrap: wrap; align-items: center; column-gap: 8px; row-gap: 2px; min-height: 24px; }
.robot-progress { min-width: 0; font-size: var(--fs-subhead); line-height: var(--lh-tight); color: var(--robot-text); overflow-wrap: anywhere; }
.robot-elapsed { font-size: var(--fs-caption); color: var(--robot-meta); font-variant-numeric: tabular-nums; }
/* An answer made without the brain's tools carries a small info glyph beside its time; a tap shows the line. */
.robot-flag { position: relative; display: inline-grid; place-items: center; width: 18px; height: 18px; margin: 0 1px 0 0; padding: 0; border: 0; background: transparent; color: var(--robot-meta); }
.robot-flag::after { content: ""; position: absolute; inset: -10px -8px; }
.robot-flag svg { width: 15px; height: 15px; }
.robot-flag[aria-expanded="true"] { color: var(--robot-name); }
.robot-flag:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.robot-note { clear: both; margin: 3px 0 1px; font-size: var(--fs-caption); line-height: var(--lh-tight); color: var(--robot-meta); }
.robot-note[hidden] { display: none; }
/* The one tap that stops the robot joining in: a quiet caption under the card, on the card's text edge. */
.chime-off { display: inline-flex; align-items: center; min-height: 36px; margin: -4px 0 -2px 12px; padding: 0; border: 0; background: transparent; color: var(--robot-link); font-size: var(--fs-caption); font-weight: var(--fw-semibold); }
.chime-off:disabled { opacity: 0.5; }
/* Choices under a robot answer. Each button is a 44px hit area; the pill inside it is what shows. */
.choices { max-width: var(--bubble-max); margin: 2px 0 2px; }
/* On the wallpaper, not the card: full text colour, because 12px muted text misses 4.5:1 on Sky's wallpaper. */
.choices__question { margin: 0 0 1px 12px; font-size: var(--fs-caption); font-weight: var(--fw-medium); color: var(--text); }
.choices__list { display: flex; flex-wrap: wrap; gap: 0 8px; }
.choice-chip { position: relative; display: inline-flex; align-items: center; max-width: 100%; min-height: var(--hit); padding: 0 14px; border: 0; background: transparent; color: var(--robot-link); font-size: var(--fs-subhead); font-weight: var(--fw-semibold); z-index: 0; }
.choice-chip::before { content: ""; position: absolute; inset: 6px 0; z-index: -1; border: 1px solid var(--robot-border); border-radius: var(--radius-pill); background: var(--robot-bg); }
@media (hover: hover) { .choice-chip:hover::before { background: color-mix(in srgb, var(--robot-border) 45%, var(--robot-bg)); } }
.choice-chip:focus-visible { outline: none; }
.choice-chip:focus-visible::before { outline: 2px solid var(--focus-ring); outline-offset: 1px; }

/* Under a photo or file: "Robot read it", and on a tap the summary the robot keeps in memory. */
.read-note { clear: both; margin: 4px 0 0; font-size: var(--fs-caption); color: inherit; }
.bubble--media .read-note { padding: 0 8px 2px; }
.att-image .bubble__body--metaonly { right: 6px; bottom: 6px; }
.read-note, .read-note__toggle { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.read-note__toggle { width: 100%; min-height: 32px; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; }
.read-note__mark { display: grid; opacity: 0.8; }
.read-note--reading { opacity: 0.75; }
.read-note__action { margin-left: auto; font-weight: var(--fw-semibold); text-decoration: underline; text-underline-offset: 2px; }
.read-note__body { width: 100%; margin: 2px 0 4px; font-size: var(--fs-subhead); line-height: var(--lh-read); overflow-wrap: anywhere; }

/* Reply quote */
.reply-quote { display: flex; flex-direction: column; align-items: stretch; width: 100%; min-width: 0; margin: 2px 0 5px; padding: 4px 8px 5px; border: 0; border-left: 3px solid var(--quote-bar); border-radius: 6px; background: var(--quote-in-bg); color: inherit; text-align: left; }
.bubble--out .reply-quote { border-left-color: var(--quote-out-bar); background: var(--quote-out-bg); }
.bubble--robot .reply-quote { background: color-mix(in srgb, var(--robot-border) 40%, transparent); border-left-color: var(--robot-fold); }
.reply-quote__name { font-size: var(--fs-footnote); font-weight: var(--fw-semibold); color: var(--quote-bar); line-height: var(--lh-tight); }
.bubble--out .reply-quote__name { color: inherit; }
.bubble--robot .reply-quote__name { color: var(--robot-name); }
.reply-quote__text { font-size: var(--fs-subhead); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.reply-quote--deleted .reply-quote__text { font-style: italic; opacity: 0.8; }

/* Reactions */
.reactions { position: relative; z-index: 1; display: flex; flex-wrap: wrap; gap: 4px; margin: -4px 0 2px; padding: 0 8px; max-width: var(--bubble-max); }
.msg-row--out .reactions { justify-content: flex-end; }
.reaction { position: relative; display: inline-flex; align-items: center; gap: 4px; height: 26px; padding: 0 8px; border: 1px solid var(--hairline); border-radius: var(--radius-pill); background: var(--reaction-bg); color: var(--reaction-text); box-shadow: var(--elev-1); font-size: var(--fs-caption); font-weight: var(--fw-semibold); line-height: 1; }
.reaction::before { content: ""; position: absolute; inset: -9px -2px; }
.reaction--mine { background: var(--reaction-mine-bg); border-color: var(--reaction-mine-border); }
.reaction__emoji { font-size: 0.9375rem; }

/* Typing */
.typing { min-width: 56px; padding: 10px 14px; }
.typing__dots { display: inline-flex; align-items: center; gap: 4px; height: 16px; color: var(--bubble-in-meta); }
.bubble--robot .typing__dots { color: var(--robot-meta); }
.typing__dots i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: 0.3; animation: dot 1.2s infinite var(--ease-in-out); }
.typing__dots i:nth-child(2) { animation-delay: 160ms; }
.typing__dots i:nth-child(3) { animation-delay: 320ms; }
/* A wave: each dot lifts 3px as it brightens, the way the iMessage and Telegram dots breathe. */
@keyframes dot { 0%, 60%, 100% { opacity: 0.3; transform: none; } 30% { opacity: 1; transform: translateY(-3px); } }

/* Attachments */
.bubble--media { padding: 4px; }
.bubble--media .bubble__name, .bubble--media .robot-tag { padding: 2px 6px 0; }
.bubble--media .reply-quote { width: auto; margin: 0 0 4px; }
.bubble--media .bubble__body { padding: 4px 6px 1px; }
.bubble--media .bubble__body--metaonly { position: absolute; right: 10px; bottom: 10px; padding: 0 8px; border-radius: var(--radius-pill); background: var(--photo-scrim); }
.bubble--media .bubble__body--metaonly .bubble__meta, .bubble--media .bubble__body--metaonly .ticks { color: var(--photo-text); margin: 0; top: 0; }
/* A video with a read note or a watch line under it: the time goes on its own line under them, not over the note's
   Summary or the player's controls. */
.bubble--media .att-video ~ .bubble__body--metaonly { position: static; display: flex; justify-content: flex-end; padding: 0 6px 1px; background: none; }
.bubble--media .att-video ~ .bubble__body--metaonly .bubble__meta { color: var(--bubble-in-meta); }
.bubble--out.bubble--media .att-video ~ .bubble__body--metaonly .bubble__meta { color: var(--bubble-out-meta); }
.bubble--media .att-video ~ .bubble__body--metaonly .ticks { color: var(--tick); }
.bubble--media .att-video ~ .bubble__body--metaonly .ticks--read { color: var(--tick-read); }
.att-image { position: relative; display: block; width: fit-content; min-width: 120px; max-width: 260px; min-height: 120px; overflow: hidden; border-radius: calc(var(--bubble-radius) - 3px); background: var(--skeleton-base); cursor: zoom-in; }
.bubble--media.bubble--in.bubble--tail .att-image { border-bottom-left-radius: max(0px, calc(var(--bubble-radius-tail) - 2px)); }
.bubble--media.bubble--out.bubble--tail .att-image { border-bottom-right-radius: max(0px, calc(var(--bubble-radius-tail) - 2px)); }
/* The box is min(natural width, cap, bubble) wide: a small image shows at its own pixels, a wide one fits the cap.
   The cap stays a plain length so the bubble around it sizes to it too. Once the
   image has loaded its own height rules, so a short wide photo leaves no skeleton band under it. */
.att-image img { display: block; max-width: 100%; height: auto; max-height: 360px; margin: 0 auto; object-fit: cover; }
.att-image--loaded { min-width: 0; min-height: 0; }
@media (min-width: 1024px) { .att-image { max-width: 320px; } .att-image img { max-height: 420px; } }
/* The robot's charts and drawings are tall and must show whole: they may stand up to 1:2 (brain/tools/charts.mjs MAX_H).
   Its pictures fill the wider card on a phone and stop at 380px on desktop. */
.bubble--robot .att-image { max-width: 100%; }
.bubble--robot .att-image img { max-height: 520px; object-fit: contain; }
@media (min-width: 1024px) { .bubble--robot .att-image { max-width: 380px; } .bubble--robot .att-image img { max-height: 640px; } }
.att-image--uploading img { opacity: 0.6; }
.att-image__progress { position: absolute; inset: 0; display: grid; place-items: center; }
.att-image__progress svg { position: absolute; }
.att-image__progress .ring-bg { fill: var(--photo-scrim); stroke: none; }
.att-image__progress .ring { fill: none; stroke: var(--photo-text); stroke-width: 2.5; transform: rotate(-90deg); transform-origin: 18px 18px; }
.att-image__cancel { position: relative; width: var(--hit); height: var(--hit); display: grid; place-items: center; border: 0; background: transparent; color: var(--photo-text); }
.file-card { position: relative; display: flex; align-items: center; gap: 10px; min-width: min(220px, 60vw); max-width: 100%; margin: 2px 0 4px; padding: 4px 2px; color: inherit; text-decoration: none; border-radius: var(--radius-sm); }
.file-card__icon { display: grid; place-items: center; width: 36px; height: 40px; flex: none; border-radius: 6px; background: var(--quote-in-bg); font-size: var(--fs-caption); font-weight: var(--fw-bold); letter-spacing: 0.02em; }
.file-card--out .file-card__icon { background: var(--quote-out-bg); }
.file-card__text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.file-card__name { display: flex; min-width: 0; font-size: var(--fs-subhead); font-weight: var(--fw-semibold); }
.file-card__head { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-card__tail { flex: none; white-space: nowrap; }
.file-card__meta { font-size: var(--fs-caption); color: var(--bubble-in-meta); }
.file-card--out .file-card__meta { color: var(--bubble-out-meta); }
.file-card__action { display: inline-flex; align-items: center; gap: 4px; margin-top: 2px; font-size: var(--fs-caption); font-weight: var(--fw-semibold); color: var(--bubble-in-link); }
.file-card--robot .file-card__action { color: var(--robot-link); }
.file-card--out .file-card__action { color: var(--bubble-out-link); }
.file-card__action svg { display: block; }
.file-card__progress { position: absolute; left: 48px; right: 2px; bottom: 0; height: 2px; border-radius: 1px; background: var(--hairline); overflow: hidden; }
.file-card__progress span { display: block; height: 100%; background: currentColor; }
.file-card__cancel { display: grid; place-items: center; flex: none; width: 36px; height: 36px; padding: 0; border: 0; background: none; color: inherit; }
@media (pointer: coarse) { .file-card__cancel { width: var(--hit); height: var(--hit); } }

/* Voice notes and audio play in the bubble (views/media.js); video plays in a media bubble like a photo. */
/* Fixed widths, not percentages: the bubble sizes to its content, so a percentage would collapse the player. */
.voice { --voice-btn-bg: var(--accent); --voice-btn-fg: var(--accent-text); --voice-meta: var(--bubble-in-meta);
  display: flex; align-items: center; gap: 10px; width: 240px; max-width: 100%; margin: 2px 0 0; }
.bubble--out .voice { --voice-btn-bg: var(--bubble-out-text); --voice-btn-fg: var(--bubble-out-bg); --voice-meta: var(--bubble-out-meta); }
.bubble--robot .voice { --voice-btn-bg: var(--robot-name); --voice-btn-fg: var(--robot-bg); --voice-meta: var(--robot-meta); }
.voice__play { position: relative; display: grid; place-items: center; flex: none; width: var(--hit); height: var(--hit); padding: 0; border: 0; background: transparent; color: var(--voice-btn-fg); }
.voice__play::before { content: ""; position: absolute; inset: 2px; border-radius: 50%; background: var(--voice-btn-bg); }
.voice__play .icon { position: relative; }
.voice__main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
/* The track is a 28px hit area; the 4px rail and the knob sit in its middle. */
.voice__track { position: relative; height: 28px; cursor: pointer; touch-action: none; }
.voice__rail { position: absolute; left: 0; right: 0; top: 12px; height: 4px; border-radius: 2px; background: color-mix(in srgb, currentColor 22%, transparent); overflow: hidden; }
.voice__fill { position: absolute; inset: 0; background: currentColor; transform: scaleX(0); transform-origin: left; }
.voice__knob { position: absolute; top: 8px; left: 0; width: 12px; height: 12px; margin-left: -6px; border-radius: 50%; background: currentColor; }
.voice__track:focus-visible { outline-offset: 0; border-radius: 4px; }
.voice__row { display: flex; gap: 8px; min-width: 0; margin-top: -4px; font-size: var(--fs-caption); color: var(--voice-meta); font-variant-numeric: tabular-nums; }
.voice__time { flex: none; min-height: 1.2em; }
.voice__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.voice--error .voice__time::after { content: "Could not play"; }
@media (pointer: coarse) { .voice__track { height: 36px; } .voice__rail { top: 16px; } .voice__knob { top: 12px; } }
/* What the brain heard: two lines until tapped. */
.transcript { display: block; width: 240px; max-width: 100%; margin: 4px 0 0; padding: 0; border: 0; background: none; color: inherit; font-size: var(--fs-subhead); line-height: var(--lh-body); text-align: left; }
.transcript__text { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.transcript--open .transcript__text { display: block; -webkit-line-clamp: unset; line-clamp: none; }
.transcript__more { display: none; margin-top: 1px; font-size: var(--fs-footnote); font-weight: var(--fw-semibold); text-decoration: underline; text-underline-offset: 2px; }
.transcript--clamped .transcript__more { display: block; }
.transcript--status { font-size: var(--fs-footnote); font-style: italic; color: var(--bubble-in-meta); }
.bubble--out .transcript--status { color: var(--bubble-out-meta); }
.bubble--robot .transcript--status { color: var(--robot-meta); }
.transcript--pending { animation: soft-pulse 1.6s ease-in-out infinite; }
@keyframes soft-pulse { 50% { opacity: 0.55; } }
@media (prefers-reduced-motion: reduce) { .transcript--pending { animation: none; } }
.att-video + .transcript { width: auto; padding: 0 6px; }
/* A voice note on its way up: a thin bar, the percentage and a way to stop it. */
.upload-line { display: flex; align-items: center; gap: 8px; width: 240px; max-width: 100%; margin-top: 2px; font-size: var(--fs-caption); color: var(--bubble-out-meta); }
.upload-line__bar { position: relative; flex: 1; height: 3px; border-radius: 2px; background: color-mix(in srgb, currentColor 30%, transparent); overflow: hidden; }
.upload-line__bar span { position: absolute; inset: 0; background: currentColor; transform-origin: left; }
.upload-line__text { flex: none; font-variant-numeric: tabular-nums; }
.upload-line__cancel { display: grid; place-items: center; flex: none; width: 32px; height: 32px; margin: -6px -6px -6px 0; padding: 0; border: 0; background: none; color: inherit; }
@media (pointer: coarse) { .upload-line__cancel { width: var(--hit); height: var(--hit); margin: -10px -10px -10px 0; } }
/* Link previews: our own copy of the page's image, its site, title and two lines, opening in a new tab. */
.link-card { display: block; width: 100%; min-width: min(240px, 100%); max-width: 100%; margin: 2px 0 6px; overflow: hidden; border-radius: 10px; border-left: 3px solid var(--quote-bar); background: var(--quote-in-bg); color: inherit; text-decoration: none; }
.bubble--out .link-card { border-left-color: var(--quote-out-bar); background: var(--quote-out-bg); }
.link-card__img { display: block; aspect-ratio: 1.91 / 1; background: var(--skeleton-base); }
.link-card__img img { width: 100%; height: 100%; object-fit: cover; }
.link-card__text { display: flex; flex-direction: column; gap: 2px; padding: 6px 10px 8px; min-width: 0; }
.link-card__site { font-size: var(--fs-caption); font-weight: var(--fw-semibold); color: var(--link); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bubble--out .link-card__site { color: var(--bubble-out-meta); }
.link-card__title { font-size: var(--fs-subhead); font-weight: var(--fw-semibold); line-height: var(--lh-tight); display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.link-card__desc { font-size: var(--fs-footnote); line-height: var(--lh-body); color: var(--bubble-in-meta); display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.bubble--out .link-card__desc { color: var(--bubble-out-meta); }
.link-card__watched { display: flex; align-items: center; gap: 4px; margin-top: 2px; font-size: var(--fs-caption); color: var(--bubble-in-meta); }
.bubble--out .link-card__watched { color: var(--bubble-out-meta); }
.link-card__mark { display: grid; }
/* A document the robot keeps (views/docs.js): the card on a version message, a button that opens the viewer. */
.doc-card { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 300px; max-width: 100%; margin: 2px 0 6px; padding: 8px 10px 10px; border: 0; border-left: 3px solid var(--quote-bar); border-radius: 10px; background: var(--quote-in-bg); color: inherit; font: inherit; text-align: left; cursor: pointer; }
.doc-card__kind { display: flex; align-items: center; gap: 4px; font-size: var(--fs-caption); font-weight: var(--fw-semibold); color: var(--robot-link); }
.doc-card__mark { display: grid; }
.doc-card__title { font-size: var(--fs-subhead); font-weight: var(--fw-semibold); line-height: var(--lh-tight); overflow-wrap: anywhere; }
.doc-card__version { display: flex; flex-wrap: wrap; gap: 0 6px; font-size: var(--fs-footnote); line-height: var(--lh-body); color: var(--robot-meta); }
.doc-card__v { font-weight: var(--fw-semibold); }
.doc-card__note { overflow-wrap: anywhere; }
.doc-card__lines { display: flex; flex-direction: column; align-self: stretch; min-width: 0; margin-top: 4px; font-size: var(--fs-footnote); line-height: var(--lh-body); color: var(--robot-meta); }
.doc-card__lines:empty { display: none; }
.doc-card__lines span { display: block; min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-card__open { display: inline-flex; align-items: center; gap: 2px; min-height: 28px; margin-top: 4px; font-size: var(--fs-subhead); font-weight: var(--fw-semibold); color: var(--robot-link); }
.doc-card__open svg { width: 16px; height: 16px; }
@media (hover: hover) { .doc-card:hover .doc-card__title { text-decoration: underline; } }
/* The viewer: the version scrubber first, with 44px steps and a thumb a thumb can find, then the text. */
.doc-view .sheet__body { display: flex; flex-direction: column; }
.doc-view__wait { margin: var(--space-3) 0; color: var(--text-muted); }
.doc-view__scrub { display: flex; align-items: center; gap: var(--space-1); margin: 0 calc(-1 * var(--space-2)); }
.doc-view__step { color: var(--link); }
.doc-view__step[disabled] { color: var(--text-muted); opacity: 0.45; }
.doc-view__track { flex: 1; min-width: 0; }
.doc-view__range { -webkit-appearance: none; appearance: none; display: block; width: 100%; height: 44px; margin: 0; padding: 0; border: 0; background: transparent; cursor: pointer; touch-action: pan-y; }
.doc-view__range::-webkit-slider-runnable-track { height: 4px; border: 0; border-radius: 2px; background: var(--border); }
.doc-view__range::-moz-range-track { height: 4px; border: 0; border-radius: 2px; background: var(--border); }
.doc-view__range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 28px; height: 28px; margin-top: -12px; border: 0; border-radius: 50%; background: var(--accent); box-shadow: var(--elev-1); }
.doc-view__range::-moz-range-thumb { width: 28px; height: 28px; border: 0; border-radius: 50%; background: var(--accent); box-shadow: var(--elev-1); }
.doc-view__range:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; border-radius: 4px; }
.doc-view__steps { display: flex; justify-content: space-between; margin-top: -6px; font-size: var(--fs-caption); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.doc-view__step-l, .doc-view__step-r { display: inline-flex; align-items: center; gap: 4px; }
.doc-view__dot { display: none; }
.doc-view__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0 var(--space-3); margin-top: var(--space-2); }
.doc-view__label { font-size: var(--fs-body); }
.doc-view__meta { font-size: var(--fs-footnote); color: var(--text-muted); }
.doc-view__note { margin: 2px 0 0; font-size: var(--fs-subhead); line-height: var(--lh-body); color: var(--text); overflow-wrap: anywhere; }
.doc-view__text { margin-top: var(--space-3); padding-top: var(--space-3); border-top: 1px solid var(--hairline); font-size: var(--fs-body); line-height: var(--lh-read); overflow-wrap: anywhere; }
.doc-view__text .md-h { font-weight: var(--fw-semibold); }
.doc-view__actions { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-4); }
.doc-view__download { gap: var(--space-2); }
@media (min-width: 900px) { .doc-view__actions { flex-direction: row-reverse; } .doc-view__actions .btn { flex: 1; } }
/* A web page the robot made: the site line carries the mark, and Open page reads as the action. */
.link-card--page .link-card__site { display: flex; align-items: center; gap: 4px; }
.link-card--page .link-card__title { -webkit-line-clamp: 3; line-clamp: 3; }
.link-card__open { display: inline-flex; align-items: center; gap: 2px; margin-top: 6px; font-size: var(--fs-subhead); font-weight: var(--fw-semibold); color: var(--link); }
.link-card__open svg { width: 16px; height: 16px; }
@media (hover: hover) { .link-card:hover .link-card__title { text-decoration: underline; } }
/* A bubble with a card is one fixed width, so the card and the text under it line up at any length. */
.bubble--link { width: 340px; }
.att-video { overflow: hidden; width: 300px; max-width: 100%; border-radius: calc(var(--bubble-radius) - 3px); background: #000; }
.att-video video { display: block; width: 100%; max-height: 420px; }
/* Embeds (views/embeds.js): pictures, gifs, videos, YouTube and Vimeo facades and page cards under the text. The
   time moves to a foot row under them. A picture carries the width and height the server measured, so the list
   does not jump when it loads. */
.bubble--embeds .embed { margin: 6px 0 0; }
.bubble--embeds .link-card { margin-bottom: 0; }
.embeds-foot { display: flex; justify-content: flex-end; min-height: 0; margin-top: 2px; }
.embeds-foot .bubble__meta { float: none; top: 0; margin: 0 -2px 0 0; }
.embed--image img, .embed--gif img { width: auto; max-width: 100%; height: auto; max-height: 360px; }
.embed--image, .embed--gif { max-width: 100%; }
.bubble__body .embed--image, .bubble__body .embed--gif { margin: 4px 0; }
@media (min-width: 1024px) { .embed--image img, .embed--gif img { max-height: 420px; } }
.att-image:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
/* The facade: a 16:9 frame with our copy of the thumbnail, a play disc that a thumb can find, the site and title on a
   scrim along the bottom. The tap swaps the button for the player, which keeps the frame's size. */
.embed--facade { width: 340px; max-width: 100%; }
.facade { position: relative; display: block; width: 100%; aspect-ratio: 16 / 9; margin: 0; padding: 0; overflow: hidden; border: 0; border-radius: calc(var(--bubble-radius) - 3px); background: var(--photo-bg); color: var(--photo-text); font: inherit; text-align: left; cursor: pointer; }
.facade__thumb { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; }
.facade__thumb--none { background: var(--skeleton-base); }
.facade__play { position: absolute; top: 50%; left: 50%; display: grid; place-items: center; width: 56px; height: 56px; transform: translate(-50%, -50%); border-radius: 50%; background: var(--photo-scrim); color: var(--photo-text); transition: transform var(--dur-1); }
.facade__play svg { width: 26px; height: 26px; margin-left: 3px; }
.facade:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
@media (hover: hover) { .facade:hover .facade__play { transform: translate(-50%, -50%) scale(1.08); } }
@media (prefers-reduced-motion: reduce) { .facade__play { transition: none; } .facade:hover .facade__play { transform: translate(-50%, -50%); } }
.facade__text { position: absolute; right: 0; bottom: 0; left: 0; display: flex; flex-direction: column; gap: 1px; padding: 18px 10px 8px; background: linear-gradient(to top, var(--photo-scrim), transparent); }
.facade__site { font-size: var(--fs-caption); font-weight: var(--fw-semibold); opacity: 0.9; }
.facade__title { font-size: var(--fs-subhead); font-weight: var(--fw-semibold); line-height: var(--lh-tight); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.facade--playing { cursor: default; }
.facade__frame { display: block; width: 100%; height: 100%; border: 0; }
/* A song, album or podcast (Spotify, Apple Music, SoundCloud): a row with the cover, the title, the artist and a play
   disc. Playing, the row becomes the player's own height (set inline per provider). */
.facade--audio { display: flex; align-items: center; gap: 10px; aspect-ratio: auto; min-height: 84px; padding: 8px; background: var(--quote-in-bg); color: inherit; }
.bubble--out .facade--audio { background: var(--quote-out-bg); }
.facade--audio .facade__thumb { position: static; flex: none; width: 68px; height: 68px; border-radius: 8px; }
.facade--audio .facade__thumb--none { display: block; }
.facade--audio .facade__text { position: static; flex: 1; min-width: 0; padding: 0; background: none; }
.facade--audio .facade__site { color: var(--link); }
.bubble--out .facade--audio .facade__site { color: var(--bubble-out-meta); }
.facade--audio .facade__title { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; }
.facade--audio .facade__line { font-size: var(--fs-footnote); color: var(--bubble-in-meta); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bubble--out .facade--audio .facade__line { color: var(--bubble-out-meta); }
.facade--audio .facade__play { position: static; flex: none; width: 44px; height: 44px; transform: none; background: var(--link); color: #fff; }
.facade--audio.facade--playing { display: block; padding: 0; }
@media (hover: hover) { .facade--audio:hover .facade__play { transform: scale(1.08); } }
/* A TikTok or Instagram post stands up: 4:5 before the tap, the player's own height after it. */
.facade--tall { aspect-ratio: 4 / 5; }
.facade--tall.facade--playing { aspect-ratio: auto; }
/* A post from X or Reddit, drawn in full: who, the text with its line breaks, a picture, when, and the way to the post. */
.post-card { display: flex; flex-direction: column; gap: 4px; width: 100%; padding: 8px 10px 0; border-radius: 10px; border-left: 3px solid var(--quote-bar); background: var(--quote-in-bg); }
.bubble--out .post-card { border-left-color: var(--quote-out-bar); background: var(--quote-out-bg); }
.post-card__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 6px; min-width: 0; font-size: var(--fs-caption); }
.post-card__name { font-weight: var(--fw-semibold); }
.post-card__handle, .post-card__site { color: var(--bubble-in-meta); }
.post-card__site::before { content: '·'; margin-right: 6px; }
.bubble--out .post-card__handle, .bubble--out .post-card__site { color: var(--bubble-out-meta); }
.post-card__title { margin: 0; font-size: var(--fs-subhead); font-weight: var(--fw-semibold); line-height: var(--lh-tight); overflow-wrap: anywhere; }
.post-card__text { margin: 0; font-size: var(--fs-subhead); line-height: var(--lh-body); white-space: pre-wrap; overflow-wrap: anywhere; user-select: text; -webkit-user-select: text; }
.post-card__img { display: block; margin: 2px 0; border-radius: 8px; overflow: hidden; background: var(--skeleton-base); }
.post-card__img img { display: block; width: 100%; height: auto; max-height: 360px; object-fit: cover; }
.post-card__foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.post-card__date { font-size: var(--fs-caption); color: var(--bubble-in-meta); }
.bubble--out .post-card__date { color: var(--bubble-out-meta); }
.post-card .embed__open { margin: 0; }
/* A Wikipedia card reads sideways: the thumbnail beside the lead paragraph, five lines of it. */
.link-card--side { display: flex; }
.link-card--side .link-card__img { flex: none; width: 96px; aspect-ratio: auto; }
.link-card--side .link-card__text { flex: 1; }
.link-card__desc--long { -webkit-line-clamp: 5; line-clamp: 5; }
.embed__open { display: inline-flex; align-items: center; gap: 2px; min-height: var(--hit); margin: -6px 0 -8px; font-size: var(--fs-footnote); font-weight: var(--fw-semibold); color: var(--link); text-decoration: none; }
.embed__open svg { width: 16px; height: 16px; }
.bubble--out .embed__open { color: var(--bubble-out-meta); }
.bubble--robot .embed__open { color: var(--robot-link); }
.bubble--incognito .embed__open { color: var(--incog-link); }
.link-card__title--url { font-weight: var(--fw-regular, 400); overflow-wrap: anywhere; }
.link-card:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

/* The robot turned the asker's summon down: one quiet line under their own message, visible to them only. */
.msg-refused { display: flex; align-items: flex-start; gap: 6px; max-width: var(--bubble-max); margin: 4px 2px 0; font-size: var(--fs-footnote); line-height: var(--lh-body); color: var(--text-muted); text-align: right; }
.msg-refused__mark { display: grid; flex: none; margin-top: 2px; }
/* An owner's view of a reported message (src/reports.mjs): how often and why, then Delete it or Keep it. */
.msg-reported { max-width: var(--bubble-max); margin: 4px 2px 0; padding: 6px 4px 2px 10px; border-left: 2px solid var(--danger); font-size: var(--fs-footnote); line-height: var(--lh-body); color: var(--text-muted); }
.msg-reported__text { display: flex; align-items: flex-start; gap: 6px; overflow-wrap: anywhere; }
.msg-reported__icon { display: grid; flex: none; margin-top: 2px; color: var(--danger); }
.msg-reported__acts { display: flex; gap: var(--space-1); margin-left: -8px; }
.msg-failed { display: flex; align-items: center; gap: var(--space-3); margin: 4px 2px 0; font-size: var(--fs-footnote); }
.msg-failed__retry { display: inline-flex; align-items: center; gap: 4px; min-height: 32px; padding: 0; border: 0; background: none; color: var(--danger); font-weight: var(--fw-semibold); }
.msg-failed__discard { min-height: 32px; padding: 0 4px; border: 0; background: none; color: var(--text-muted); }

/* Empty room card */
.room-empty { margin: auto 0; padding-top: var(--space-4); }
.empty { max-width: 360px; margin: var(--space-6) auto; list-style: none; text-align: left; }
.empty__art { color: var(--text-muted); margin-bottom: var(--space-3); }
.empty__title { font-size: var(--fs-title3); font-weight: var(--fw-semibold); line-height: var(--lh-tight); margin-bottom: 6px; }
.empty__text { font-size: var(--fs-subhead); color: var(--text-muted); }
.empty__text .code { color: var(--text); }
.empty__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-4); }
.empty__action { margin-top: var(--space-4); }
.empty__actions .empty__action { margin-top: 0; }
.empty--room { margin: var(--space-2) auto var(--space-4); padding: var(--space-5); border-radius: var(--radius-lg); background: var(--sheet-bg); box-shadow: var(--elev-1); border: 1px solid var(--hairline); }
.empty--room .empty__art { color: var(--text); }
.empty--rail { margin: var(--space-5) var(--space-2); }

/* Banners and jump. The band is chrome like the header, not wallpaper: on the wallpaper a message cut off at its edge
   looked like it sat under the banner card (first-timer review, 31-room-1440). The list starts at the band's bottom. */
.banners { position: relative; z-index: var(--z-banner); margin-top: var(--header-real-h, 56px); background: var(--surface-solid); }
.banners__prompt:not(:empty) { padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--hairline); }
/* The sentence keeps at least 8em beside the controls; below that the controls wrap under it (R02-2). */
.card-banner { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); max-width: calc(var(--chat-max) - 24px); margin: 0 auto; padding: var(--space-2) var(--space-3); border: 1px solid var(--hairline); border-radius: var(--radius-md); background: var(--sheet-bg); box-shadow: var(--elev-2); }
.install-banner__text, .push-banner__text { flex: 1 1 8em; min-width: 0; margin: 0; font-size: var(--fs-subhead); line-height: 1.3; }
.card-banner__glyph { display: grid; color: var(--link); }
/* The iPhone push prompt carries the save steps: the sentence takes the first row with the close button, and Show me how
   sits under it, in line with the text. */
.push-banner--steps .push-banner__text { flex-basis: calc(100% - 24px - var(--hit) - 2 * var(--space-2)); }
.push-banner--steps .icon-btn { order: 3; }
.push-banner--steps .btn { order: 4; margin-left: calc(24px + var(--space-2)); }
/* A banner or the connection line drops in under the header. */
.card-banner, .conn-banner { transition: opacity var(--dur-2) linear, transform var(--spring-snap-dur) var(--spring-snap); }
@starting-style { .card-banner, .conn-banner:not([hidden]) { opacity: 0; transform: translateY(-8px); } }
.jump-btn { position: absolute; z-index: var(--z-banner); right: max(var(--space-4), calc((100% - var(--chat-max)) / 2 + var(--space-4))); bottom: calc(var(--composer-h, 64px) + var(--space-3)); display: grid; place-items: center; width: var(--hit); height: var(--hit); padding: 0; border: 1px solid var(--hairline); border-radius: 50%; background: var(--sheet-bg); color: var(--text); box-shadow: var(--elev-1);
  transition: opacity var(--dur-1) linear, transform var(--spring-pop-dur) var(--spring-pop), display var(--dur-2) allow-discrete; }
/* The jump button pops up when the reader leaves the bottom and shrinks away when they return. */
.jump-btn[hidden] { opacity: 0; transform: scale(0.5); transition: opacity var(--dur-1) linear, transform var(--dur-2) var(--ease-in-out), display var(--dur-2) allow-discrete; }
@starting-style { .jump-btn:not([hidden]) { opacity: 0; transform: scale(0.5); } }
.jump-btn__count { position: absolute; top: -8px; left: 50%; transform: translateX(-50%); min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--radius-pill); background: var(--accent); color: var(--accent-text); font-size: var(--fs-caption); font-weight: var(--fw-bold); line-height: 20px; text-align: center; }
.room--drop::after { content: "Drop to send"; position: absolute; inset: var(--space-2); z-index: 30; display: grid; place-items: center; border: 2px dashed var(--accent); border-radius: var(--radius-lg); background: var(--accent-soft); color: var(--link); font-weight: var(--fw-semibold); }

/* Composer */
.composer {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: var(--z-header);
  padding: 6px max(var(--space-2), env(safe-area-inset-right)) calc(6px + env(safe-area-inset-bottom)) max(var(--space-2), env(safe-area-inset-left));
  background: var(--surface); -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur); border-top: 1px solid var(--hairline);
}
.composer > * { max-width: var(--chat-max); margin-left: auto; margin-right: auto; }
.composer__row { display: flex; align-items: flex-end; gap: 2px; }
.composer__fieldwrap { flex: 1; min-width: 0; display: flex; border: 1px solid var(--border); border-radius: 22px; background: var(--field-bg); margin: 2px 4px; }
.composer__fieldwrap:focus-within { border-color: var(--focus-ring); box-shadow: 0 0 0 1px var(--focus-ring); }
.composer__field { flex: 1; min-width: 0; height: 40px; min-height: 40px; padding: 9px 14px; border: 0; border-radius: 22px; background: transparent; color: var(--field-text); font-size: max(16px, 1rem); line-height: 1.35; resize: none; overflow-y: hidden; }
.composer__field:focus-visible { outline: none; }
.composer__field::placeholder { color: var(--field-placeholder); opacity: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.composer__field--scroll { overflow-y: auto; }
.composer__send { position: relative; display: grid; place-items: center; width: var(--hit); height: var(--hit); flex: none; padding: 0; border: 0; background: transparent; color: var(--send-icon); }
.composer__send::before { content: ""; position: absolute; inset: 4px; border-radius: 50%; background: var(--send-bg); }
.composer__send .icon { position: relative; }
/* Send, mic and camera trade places with a quick spring; the field fades back after a voice note. */
.composer__send, .composer__mic, .composer__camera { transition: transform var(--spring-snap-dur) var(--spring-snap), opacity var(--dur-1) linear; }
@starting-style { .composer__send, .composer__mic, .composer__camera { transform: scale(0.4); opacity: 0; } }
.composer__fieldwrap { transition: opacity var(--dur-2) linear; }
@starting-style { .composer__fieldwrap { opacity: 0; } }
/* Touch: camera while empty, send once there is text. Mouse and keyboard: send always, dimmed while empty. Where the
   browser can record, the mic takes the send button's place while the field is empty, on every device. */
.composer__camera { display: none; }
.composer--empty .composer__send { opacity: 0.45; }
@media (pointer: coarse) {
  .composer--empty .composer__camera { display: inline-grid; }
  .composer--empty .composer__send { display: none; }
}
.composer__mic { position: relative; display: none; place-items: center; width: var(--hit); height: var(--hit); flex: none; padding: 0; border: 0; background: transparent; color: var(--send-icon);
  touch-action: none; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.composer__mic::before { content: ""; position: absolute; inset: 4px; border-radius: 50%; background: var(--send-bg); transition: transform var(--spring-pop-dur) var(--spring-pop), background-color var(--dur-1) linear; }
.composer__mic .icon { position: relative; }
.composer--voice.composer--empty .composer__mic, .composer--recording .composer__mic { display: grid; }
.composer--voice.composer--empty .composer__send, .composer--recording .composer__send { display: none; }
/* Holding: the button grows under the finger and turns red, like the dot. */
.composer--holding .composer__mic::before { transform: scale(1.25); background: var(--danger); }
.composer--holding.composer--cancel-armed .composer__mic::before { background: var(--text-muted); }
.composer--recording .composer__attach, .composer--recording .composer__fieldwrap, .composer--recording .composer__camera { display: none; }
.recorder { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; height: 48px; margin: 0 4px 0 0; overflow: hidden;
  transition: opacity var(--dur-2) linear, transform var(--spring-snap-dur) var(--spring-snap); }
/* The recorder slides in from the mic; a deleted note slides out to the left under the trash can. */
@starting-style { .recorder:not([hidden]) { opacity: 0; transform: translateX(32px); } }
.composer--cancelled .recorder { opacity: 0; transform: translateX(-48px); transition: opacity var(--dur-2) linear, transform var(--dur-2) var(--ease-in-out); }

.recorder__cancel { flex: none; color: var(--danger); }
.recorder__dot { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--danger); animation: rec-pulse 1.2s ease-in-out infinite; }
@keyframes rec-pulse { 50% { opacity: 0.25; } }
.recorder__time { flex: none; min-width: 2.6em; font-variant-numeric: tabular-nums; font-weight: var(--fw-semibold); }
.recorder__time--late { color: var(--danger); }
.recorder__meter { flex: 1; min-width: 40px; max-width: 160px; display: flex; align-items: center; gap: 2px; height: 28px; overflow: hidden; }
.recorder__meter i { flex: none; width: 3px; height: 100%; border-radius: 2px; background: var(--text-muted); transform: scaleY(0.12); transition: transform 90ms linear; }
.recorder__hint { position: relative; z-index: 1; flex: none; margin-left: auto; padding-left: 8px; font-size: var(--fs-footnote); color: var(--text-muted); white-space: nowrap; background: var(--surface-solid); }
.recorder__hint:empty { display: none; }
.composer--cancel-armed .recorder__hint { color: var(--danger); font-weight: var(--fw-semibold); }
.composer--holding .recorder__meter { flex: 0 1 120px; }
.composer--cancel-armed .recorder__meter { visibility: hidden; }
@media (prefers-reduced-motion: reduce) { .recorder__dot { animation: none; } .recorder__meter i { transition: none; } }
.composer__hint { padding: 0 var(--space-3) 4px; font-size: var(--fs-caption); color: var(--text-muted); }
.composer--robot .composer__hint { color: var(--text); }
/* When the robot answers in this room, one quiet line above the field; every message gets the robot's own colour. */
.robot-mode-row { padding: 0 var(--space-2) 4px; }
.robot-mode { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; min-height: 28px; margin: 0; padding: 2px 10px 2px 8px; border: 1px solid var(--hairline); border-radius: var(--radius-pill); background: transparent; color: var(--text-muted); font-size: var(--fs-caption); font-weight: var(--fw-medium); text-align: left; }
.robot-mode__mark, .robot-mode__chev { display: grid; flex: none; }
.robot-mode__text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.robot-mode[data-mode="every"], .robot-mode[data-mode="helps"] { border-color: var(--robot-border); background: var(--robot-bg); color: var(--robot-text); }
.robot-mode:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.joinin-sheet__ask { margin-top: var(--space-4); }
.joinin-sheet .notify-level--on[disabled] { opacity: 1; }
.robot-tip { display: flex; align-items: center; gap: var(--space-2); padding: 0 0 2px var(--space-3); font-size: var(--fs-footnote); color: var(--text-muted); }
.robot-tip b { color: var(--text); font-weight: var(--fw-semibold); }
.robot-tip__mark { display: grid; color: var(--text-muted); }
.robot-tip__text { flex: 1; min-width: 0; }
.robot-tip__close { width: 36px; height: 36px; color: var(--text-muted); }
@media (pointer: coarse) { .robot-tip__close { width: var(--hit); height: var(--hit); } }
/* The link preview above the message box (views/embeds.js): one 56px row for the skeleton and every kind, so the
   box never moves while it loads; the thumbnail is 48px square, an image shows itself, a video gets a play badge. */
.embed-preview { display: flex; align-items: center; gap: var(--space-2); height: 56px; margin: 0 auto 4px; padding: 4px 0 4px 4px; border: 1px solid var(--hairline); border-radius: var(--radius-md); background: var(--quote-in-bg); }
.embed-preview:not([hidden]) { transition: opacity var(--dur-2) linear, transform var(--spring-snap-dur) var(--spring-snap); }
@starting-style { .embed-preview:not([hidden]) { opacity: 0; transform: translateY(6px); } }
.embed-preview__thumb { position: relative; flex: none; display: grid; place-items: center; width: 48px; height: 48px; overflow: hidden; border-radius: var(--radius-sm); background: var(--skeleton-base); color: var(--text-muted); }
.embed-preview[data-kind="image"] .embed-preview__thumb, .embed-preview[data-kind="gif"] .embed-preview__thumb { width: 72px; }
.embed-preview__thumb img { width: 100%; height: 100%; object-fit: cover; }
.embed-preview__glyph { display: grid; }
.embed-preview__play { position: absolute; inset: 0; display: grid; place-items: center; color: #fff; }
.embed-preview__play::before { content: ""; position: absolute; width: 26px; height: 26px; border-radius: 50%; background: rgba(0, 0, 0, 0.55); }
.embed-preview__play .icon { position: relative; }
.embed-preview__badge { position: absolute; right: 3px; bottom: 3px; padding: 0 4px; border-radius: 4px; background: rgba(0, 0, 0, 0.6); color: #fff; font-size: 10px; font-weight: var(--fw-semibold); line-height: 16px; }
.embed-preview__main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.embed-preview__title { font-size: var(--fs-subhead); font-weight: var(--fw-semibold); line-height: var(--lh-tight); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.embed-preview__site { font-size: var(--fs-caption); color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.embed-preview__site:empty { display: none; }
.embed-preview__close { flex: none; color: var(--text-muted); }
.embed-preview__skel-thumb { display: block; width: 100%; height: 100%; border-radius: 0; }
.embed-preview__skel-line { display: block; width: 70%; height: 12px; margin: 0; }
.embed-preview__skel-line--short { width: 35%; height: 10px; }
.composer--recording .embed-preview { display: none; }
.reply-bar { display: flex; align-items: center; gap: var(--space-2); margin-bottom: 6px; padding: 4px 0 4px 10px; border-left: 3px solid var(--accent); transition: opacity var(--dur-2) linear, transform var(--spring-snap-dur) var(--spring-snap); }
.reply-bar:not([hidden]), .composer__hint:not([hidden]), .robot-tip:not([hidden]) { transition: opacity var(--dur-2) linear, transform var(--spring-snap-dur) var(--spring-snap); }
@starting-style { .reply-bar:not([hidden]), .composer__hint:not([hidden]), .robot-tip:not([hidden]) { opacity: 0; transform: translateY(6px); } }
.reply-bar__glyph { display: grid; color: var(--link); }
.reply-bar__main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.reply-bar__label { font-size: var(--fs-footnote); font-weight: var(--fw-semibold); color: var(--link); }
.reply-bar__text { font-size: var(--fs-subhead); color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.reply-bar__close { color: var(--text-muted); }

/* Formatting row: on a desktop it stays open; on a touch screen or a narrow window the Aa button in the field opens
   it above the keyboard. */
.format-bar { display: flex; gap: 2px; padding: 0 2px 4px; overflow-x: auto; scrollbar-width: none; }
.format-bar__btn { width: 36px; height: 32px; color: var(--text-muted); }
.composer__format { display: none; width: 40px; height: 40px; align-self: flex-end; border-radius: 50%; color: var(--text-muted); }
.composer__format[aria-expanded="true"] { color: var(--link); }
@media (pointer: coarse), (max-width: 899px) {
  .format-bar:not(.format-bar--open) { display: none; }
  .format-bar__btn { width: var(--hit); height: 38px; }
  .composer__format { display: inline-grid; }
}
.composer--recording .format-bar, .composer--recording .composer__format { display: none; }

/* ---------- Sheets ---------- */
.sheet-layer { position: fixed; inset: 0; z-index: var(--z-scrim); display: flex; align-items: flex-end; justify-content: center; }
/* Sheets enter with a keyframe animation from the moment they are inserted, so no class flip has to wait for a frame.
   They rise on the sheet spring and leave on the iOS sheet curve; a drag hands its speed to a spring (ui.js). */
.scrim { position: absolute; inset: 0; background: var(--scrim); transition: opacity var(--dur-2) linear; animation: scrim-in var(--dur-2) linear; }
@keyframes scrim-in { from { opacity: 0; } }
@keyframes fade-in { from { opacity: 0; } }
.scrim--closing { opacity: 0; }
.sheet-layer--closing { pointer-events: none; }
.sheet {
  position: relative; z-index: 1; display: flex; flex-direction: column; width: 100%; max-height: 90%;
  padding-bottom: env(safe-area-inset-bottom); border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  background: var(--sheet-bg); color: var(--text); box-shadow: var(--elev-2);
  transition: transform var(--dur-3) var(--ease-sheet); animation: sheet-in var(--spring-sheet-dur) var(--spring-sheet);
}
@keyframes sheet-in { from { transform: translateY(100%); } }
.sheet:focus-visible { outline: none; }
.sheet--closing { transform: translateY(100%); }
.sheet__grabber { position: relative; flex: none; width: 36px; height: 5px; margin: 8px auto 0; border-radius: 3px; background: var(--border); touch-action: none; }
/* The grabber's touch area is a 44px band, not its 5px pill. */
.sheet__grabber::after { content: ""; position: absolute; inset: -14px -60px -20px; }
.sheet__head { flex: none; display: flex; align-items: center; gap: var(--space-2); min-height: 52px; padding: var(--space-2) var(--space-2) 0 var(--space-4); touch-action: none; }
.sheet__title { flex: 1; min-width: 0; font-size: var(--fs-title3); font-weight: var(--fw-semibold); line-height: var(--lh-tight); }
.sheet__close { color: var(--text-muted); margin-left: auto; }
.sheet__back { flex: none; margin-left: calc(-1 * var(--space-3)); }
.sheet__body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: var(--space-2) var(--space-4) var(--space-5); }
.sheet__actions { margin-top: var(--space-5); }
@media (min-width: 900px) {
  .sheet-layer { align-items: center; padding: var(--space-5); }
  .sheet { max-width: var(--sheet-max); max-height: min(720px, 90%); border-radius: var(--radius-lg); padding-bottom: 0; transition: transform var(--dur-2) var(--ease-out), opacity var(--dur-2); animation: dialog-in var(--spring-sheet-dur) var(--spring-sheet), fade-in var(--dur-2) linear; }
  .sheet--closing { transform: translateY(8px) scale(0.97); opacity: 0; }
  .sheet__grabber { display: none; }
  .sheet__head { padding-top: var(--space-3); }
  @keyframes dialog-in { from { transform: translateY(16px) scale(0.96); } }
}

.sheet__head--bare { position: absolute; top: 0; right: 0; min-height: 0; padding: var(--space-1); clip-path: inset(50%); }
.sheet__head--bare:focus-within { clip-path: none; z-index: 1; }
/* All twelve reactions in two rows of six, nothing hidden behind a sideways scroll. */
.action-sheet__reactions { display: grid; grid-template-columns: repeat(6, var(--hit)); justify-content: space-between; gap: var(--space-1) 0; margin: var(--space-2) 0 var(--space-3); padding: 0 0 var(--space-2); border-bottom: 1px solid var(--hairline); }
.action-sheet__emoji { width: var(--hit); height: var(--hit); padding: 0; border: 0; border-radius: 50%; background: transparent; font-size: 1.5rem; line-height: 1; }
.action-sheet__emoji--mine { background: var(--accent-soft); }
@media (hover: hover) { .action-sheet__emoji:hover { background: var(--hairline); } }
.action-sheet__item { display: flex; align-items: center; gap: var(--space-3); width: 100%; min-height: 52px; padding: 0 var(--space-2); border: 0; border-radius: var(--radius-md); background: transparent; color: var(--text); font-size: var(--fs-body); text-align: left; }
.action-sheet__glyph { display: grid; color: var(--text-muted); }
.action-sheet__item--danger, .action-sheet__item--danger .action-sheet__glyph { color: var(--danger); }
@media (hover: hover) { .action-sheet__item:hover { background: var(--hairline); } }
.action-sheet__confirm { margin: var(--space-2) var(--space-2) var(--space-4); font-size: var(--fs-body); font-weight: var(--fw-semibold); }
.action-sheet__confirmrow, .settings-leave__row { display: flex; gap: var(--space-2); }
.action-sheet__confirmrow .btn, .settings-leave__row .btn { flex: 1; }

.attach-sheet__option { display: flex; align-items: center; gap: var(--space-3); width: 100%; min-height: 56px; padding: var(--space-2); border: 0; border-radius: var(--radius-md); background: transparent; color: var(--text); text-align: left; }
.attach-sheet__glyph { display: grid; place-items: center; width: 40px; height: 40px; flex: none; border-radius: 10px; background: var(--accent-soft); color: var(--link); }
.attach-sheet__text { display: flex; flex-direction: column; min-width: 0; font-size: var(--fs-body); }
.attach-sheet__hint { font-size: var(--fs-footnote); color: var(--text-muted); }
@media (hover: hover) { .attach-sheet__option:hover { background: var(--hairline); } }
/* The Group tools row sits apart from the everyday rows, its tile plain, and opens a page inside the sheet
   (views/sheets.js openAttachSheet): a back button in the title band, one row per tool that opens to how it works,
   who sees what and its Start button. */
.sheet__back { flex: none; margin-left: calc(-1 * var(--space-3)); }
.attach-sheet__option--more { margin-top: var(--space-2); border-top: 1px solid var(--hairline); border-radius: 0 0 var(--radius-md) var(--radius-md); }
.attach-sheet__option--more .attach-sheet__glyph { background: var(--hairline); color: var(--text-muted); }
.attach-sheet__chev { display: grid; flex: none; margin-left: auto; color: var(--text-muted); }
.tool { border-bottom: 1px solid var(--hairline); }
.tool:last-child { border-bottom: 0; }
.tool__head { display: flex; align-items: center; gap: var(--space-3); width: 100%; min-height: 56px; padding: var(--space-3) 0; border: 0; background: transparent; color: var(--text); text-align: left; }
.tool__text { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tool__name { font-size: var(--fs-body); font-weight: var(--fw-medium); }
.tool__when { font-size: var(--fs-footnote); line-height: var(--lh-body); color: var(--text-muted); }
.tool__chev { display: grid; flex: none; color: var(--text-muted); transition: transform var(--dur-1); }
.tool--open .tool__chev { transform: rotate(180deg); }
.tool__detail { padding: 0 0 var(--space-4); }
.tool__label { margin: var(--space-2) 0 var(--space-0); font-size: var(--fs-footnote); font-weight: var(--fw-semibold); color: var(--text-muted); }
.tool__steps { margin: 0; padding-left: 1.25em; font-size: var(--fs-subhead); line-height: var(--lh-body); }
.tool__steps li + li { margin-top: var(--space-0); }
.tool__sees { margin: 0; font-size: var(--fs-subhead); line-height: var(--lh-body); }
.tool__start { margin-top: var(--space-3); }
@media (prefers-reduced-motion: reduce) { .tool__chev { transition: none; } }

.members-sheet__brief { margin-bottom: var(--space-4); padding: var(--space-2) var(--space-3); border-radius: var(--radius-md); background: var(--hairline); }
.members-sheet__brieflabel { display: block; font-size: var(--fs-footnote); font-weight: var(--fw-semibold); color: var(--text-muted); }
.members-sheet__brieftext { margin: 2px 0 0; font-size: var(--fs-body); line-height: var(--lh-body); overflow-wrap: anywhere; }
.members-sheet__count { font-size: var(--fs-footnote); color: var(--text-muted); margin-bottom: var(--space-2); }
.members-sheet__list { list-style: none; }
.member-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); min-height: 56px; padding: var(--space-2) 0; }
.member-row + .member-row { border-top: 1px solid var(--hairline); }
.member-row__main { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.member-row__name { display: flex; align-items: center; gap: 6px; min-width: 0; font-size: var(--fs-body); font-weight: var(--fw-semibold); }
.member-row__name > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.member-row__intro { font-size: var(--fs-subhead); color: var(--text); overflow-wrap: anywhere; }
.member-row__status { display: flex; align-items: center; gap: 6px; font-size: var(--fs-footnote); color: var(--text-muted); }
.member-row__remove { flex: none; }
/* An owner's actions on a row sit under the name, lined up with it, so a long name keeps its width at 390px. */
.member-row__actions { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-2); flex: 1 0 100%; padding-left: calc(var(--avatar) + var(--space-3) - var(--space-2)); margin-top: calc(-1 * var(--space-1)); }
.member-row__actions .btn--sm { padding-inline: var(--space-2); }
.member-row__confirm { flex: 1 0 100%; padding: var(--space-2) 0 var(--space-1); }
.member-row__q { margin-bottom: var(--space-3); font-size: var(--fs-subhead); }
/* After Remove: the offer of a new code (and a lock, in a public room), at the top of the sheet. */
.members-sheet__offer { margin-bottom: var(--space-4); padding: var(--space-3); border-radius: var(--radius-md); background: var(--quote-in-bg); }
.members-sheet__offertext { font-size: var(--fs-subhead); }
.members-sheet__offerrow { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }
.members-sheet__foot { margin-top: var(--space-4); padding-top: var(--space-4); border-top: 1px solid var(--hairline); }
.members-sheet__code { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
.members-sheet__codelabel { font-size: var(--fs-subhead); color: var(--text-muted); }
.members-sheet__hint { margin: 6px 0 var(--space-4); font-size: var(--fs-footnote); color: var(--text-muted); }
.members-sheet__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.members-sheet__actions .btn { flex: 1; }

.avatar { display: grid; place-items: center; width: var(--avatar); height: var(--avatar); flex: none; border-radius: 50%; color: var(--avatar-c, var(--text-muted)); background: color-mix(in srgb, var(--avatar-c, var(--text-muted)) 18%, var(--sheet-bg)); font-size: var(--fs-footnote); font-weight: var(--fw-semibold); line-height: 1; }
/* The robot's face in the rail and at the foot of its run: a solid gold disc with a dark ring and the mark cut dark,
   so it is the most visible thing in a row of pastel faces. */
.avatar--robot { background: var(--robot-avatar-bg); color: var(--robot-avatar-fg); border: 1.5px solid var(--robot-avatar-fg); }
.avatar--robot .mark__fold { fill: var(--robot-avatar-fg); }
.avatar--room { width: 44px; height: 44px; font-size: var(--fs-subhead); }

/* Settings */
.settings-group { margin-bottom: var(--space-5); }
.settings-group__title { margin-bottom: var(--space-1); font-size: var(--fs-footnote); font-weight: var(--fw-semibold); color: var(--text-muted); }
.settings-group__hint { margin-bottom: var(--space-3); font-size: var(--fs-footnote); color: var(--text-muted); }
.settings-row { display: flex; align-items: center; gap: var(--space-3); width: 100%; min-height: 56px; padding: var(--space-3) 0; border: 0; border-bottom: 1px solid var(--hairline); background: transparent; color: var(--text); text-align: left; }
.settings-row--button[disabled] { cursor: default; }
.settings-row--stack { flex-direction: column; align-items: stretch; gap: var(--space-2); }
.settings-row__glyph { display: grid; flex: none; color: var(--text-muted); }
.settings-row__main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.settings-row__label { font-size: var(--fs-body); font-weight: var(--fw-medium); }
.settings-row__desc { font-size: var(--fs-footnote); color: var(--text-muted); }
.settings-row__control { display: flex; align-items: center; gap: var(--space-2); flex: none; }
.settings-row__state { font-size: var(--fs-subhead); color: var(--text-muted); }
.settings-row__glyph--danger, .settings-row__label--danger { color: var(--danger); }
/* What the robot was told, as members read it: the owner's words, kept as written. */
.settings-instr { margin-top: var(--space-2); padding: var(--space-3); border-radius: var(--radius-md); background: var(--quote-in-bg); font-size: var(--fs-subhead); white-space: pre-wrap; overflow-wrap: anywhere; }
.clear-sheet__lead { font-size: var(--fs-subhead); }
.clear-sheet__head { margin-top: var(--space-4); font-size: var(--fs-footnote); font-weight: var(--fw-semibold); color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.clear-sheet__list { margin-top: var(--space-2); padding-left: 1.2em; font-size: var(--fs-subhead); }
.clear-sheet__list li + li { margin-top: 4px; }
.clear-sheet__actions { display: grid; gap: var(--space-2); }
/* Report, inside the action sheet: the optional reason, then Report or Cancel. */
.action-sheet__report .field { margin: 0 var(--space-2) var(--space-4); }
/* Lock the room, a switch on the owner's This room page, above the room code. */
.settings-lock { margin-top: var(--space-2); }
.settings-lock .settings-row__label { cursor: pointer; }
/* A locked room's join page: the lock beside the line that says so. */
.join__locked { display: flex; align-items: flex-start; gap: var(--space-2); text-align: left; }
.join__lock { display: grid; flex: none; margin-top: 2px; color: var(--text-muted); }
.settings-row__chev { display: grid; color: var(--text-muted); }
.settings-inline { display: flex; gap: var(--space-2); }
.settings-inline .field__input { min-height: 44px; }
.settings-owner .field { margin-bottom: var(--space-4); }
.settings-code { margin-top: var(--space-5); padding-top: var(--space-4); border-top: 1px solid var(--hairline); }
/* After a settings row, whose own hairline already divides them. */
.settings-row + .settings-code { margin-top: 0; border-top: 0; }
.settings-code__desc { margin: 2px 0 var(--space-3); }
.settings-leave__q { margin-bottom: var(--space-3); font-size: var(--fs-subhead); }
/* The Look page: a segmented light-or-dark row, then a two-up grid of live previews. Each preview span carries the
   look's own tokens through data-look and data-scheme, so it is the real pack, not a picture of it. */
.scheme-picker { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; margin-bottom: var(--space-4); padding: 2px; border-radius: var(--radius-md); background: var(--quote-in-bg); }
.scheme-pick { min-height: 36px; padding: 0 8px; border: 0; border-radius: 10px; background: transparent; color: var(--text); font-size: var(--fs-subhead); font-weight: var(--fw-medium); }
.scheme-pick--selected { background: var(--sheet-bg); box-shadow: var(--elev-1); font-weight: var(--fw-semibold); }
.theme-picker { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4) var(--space-3); }
@media (min-width: 600px) { .theme-picker { grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); } }
.theme-swatch { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: 0; border: 0; background: transparent; color: var(--text); font-size: var(--fs-footnote); font-weight: var(--fw-medium); text-align: left; }
.theme-swatch__preview { position: relative; display: block; width: 100%; aspect-ratio: 4 / 3; margin-bottom: 6px; overflow: hidden; border: 1px solid var(--hairline); border-radius: var(--radius-md); background: var(--wallpaper); }
.theme-swatch__bar { position: absolute; top: 0; left: 0; right: 0; height: 18%; background: var(--header-bg, var(--surface-solid)); border-bottom: 1px solid var(--hairline); }
.theme-swatch__in, .theme-swatch__out, .theme-swatch__robot { position: absolute; display: flex; flex-direction: column; gap: 3px; padding: 5px 7px; border-radius: min(var(--bubble-radius), 10px); box-shadow: var(--bubble-shadow, var(--elev-1)); }
.theme-swatch__in { left: 8%; top: 26%; width: 56%; background: var(--bubble-in-bg); color: var(--bubble-in-text); border-bottom-left-radius: min(var(--bubble-radius-tail), 3px); }
.theme-swatch__out { right: 8%; top: 50%; width: 48%; background: var(--bubble-out-bg); color: var(--bubble-out-text); border-bottom-right-radius: min(var(--bubble-radius-tail), 3px); }
.theme-swatch__robot { left: 8%; bottom: 8%; width: 60%; background: var(--robot-bg); color: var(--robot-name); border: 1px solid var(--robot-border); box-shadow: none; border-bottom-left-radius: min(var(--bubble-radius-tail), 3px); }
.theme-swatch__line { display: block; height: 3px; border-radius: 2px; background: currentColor; opacity: 0.55; }
.theme-swatch__line--short { width: 60%; }
.theme-swatch__check { position: absolute; top: 6px; right: 6px; display: none; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--accent); color: var(--accent-text); }
.theme-swatch__name { font-size: var(--fs-subhead); font-weight: var(--fw-medium); }
.theme-swatch__hint { font-size: var(--fs-caption); font-weight: var(--fw-regular); color: var(--text-muted); }
.theme-swatch--selected .theme-swatch__preview { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.theme-swatch--selected .theme-swatch__check { display: grid; }
.theme-swatch--selected .theme-swatch__name { font-weight: var(--fw-semibold); }

/* Save-to-phone guide */
.ios-guide__tile { display: grid; grid-template-columns: 60px 1fr; column-gap: var(--space-4); align-items: center; margin-bottom: var(--space-5); }
.ios-guide__icon { grid-row: span 2; width: 60px; height: 60px; border-radius: 14px; box-shadow: var(--elev-1); }
.ios-guide__label { font-size: var(--fs-footnote); font-weight: var(--fw-semibold); }
.ios-guide__caption { font-size: var(--fs-footnote); color: var(--text-muted); }
.ios-guide__steps + .ios-guide__caption { margin-top: var(--space-4); }
.ios-guide__steps { list-style: none; counter-reset: step; }
.ios-guide__steps li { counter-increment: step; display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-3) 0; border-bottom: 1px solid var(--hairline); font-size: var(--fs-body); }
.ios-guide__steps li::before { content: counter(step); display: grid; place-items: center; width: 28px; height: 28px; flex: none; border-radius: 50%; background: var(--accent-soft); color: var(--link); font-size: var(--fs-subhead); font-weight: var(--fw-bold); }
.ios-guide__text { flex: 1; padding-top: 3px; }
.ios-guide__glyph { display: grid; color: var(--link); padding-top: 3px; }

/* Toast */
.toast-host { position: fixed; left: 0; right: 0; bottom: calc(96px + env(safe-area-inset-bottom)); z-index: var(--z-toast); display: flex; justify-content: center; padding: 0 var(--space-4); pointer-events: none; }
.toast { display: flex; align-items: center; gap: var(--space-2); max-width: 100%; padding: 10px 16px; border-radius: var(--radius-pill); background: var(--sheet-bg); color: var(--text); box-shadow: var(--elev-3); border: 1px solid var(--hairline); font-size: var(--fs-subhead); font-weight: var(--fw-medium); transition: opacity var(--dur-1) linear, transform var(--spring-bubble-dur) var(--spring-bubble); }
@starting-style { .toast { opacity: 0; transform: translateY(16px) scale(0.94); } }
.toast--out { opacity: 0; transform: translateY(8px) scale(0.98); transition: opacity var(--dur-2) linear, transform var(--dur-2) var(--ease-in-out); }
.toast__icon { display: grid; color: var(--success); }
.toast--error .toast__icon { color: var(--danger); }

/* Viewer */
.viewer { position: fixed; inset: 0; z-index: 70; display: grid; place-items: center; }
/* The black backdrop is its own layer so it can fade while the photo moves (sheets.js openViewer). */
.viewer__bg { position: absolute; inset: 0; background: var(--photo-bg); }
.viewer--closing { pointer-events: none; }
.viewer__bar { position: absolute; top: 0; left: 0; right: 0; z-index: 1; display: flex; align-items: center; gap: var(--space-2); padding: calc(var(--space-2) + env(safe-area-inset-top)) var(--space-2) var(--space-2) var(--space-4); background: linear-gradient(var(--photo-scrim), transparent); color: var(--photo-text); }
.viewer__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-subhead); }
.viewer__btn { color: var(--photo-text); }
.viewer__img { position: relative; max-width: 100%; max-height: 100%; object-fit: contain; touch-action: pinch-zoom; }

/* ---------- Pages: explore and new ---------- */
.page { display: flex; flex-direction: column; height: 100%; background: var(--page-bg); }
.page-header { flex: none; display: flex; align-items: center; min-height: calc(var(--header-h) + env(safe-area-inset-top)); padding: env(safe-area-inset-top) var(--space-2) 0 max(var(--space-1), env(safe-area-inset-left)); background: var(--surface-solid); border-bottom: 1px solid var(--hairline); }
.page-header__title { display: none; }
@media (min-width: 900px) { .page-header { display: none; } }
.page__scroll { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.page__body { max-width: 720px; margin: 0 auto; padding: var(--space-4) var(--gutter) calc(var(--space-6) + env(safe-area-inset-bottom)); }
.page__body--narrow { max-width: 560px; }
@media (min-width: 900px) { .page__body { padding-top: var(--space-7); } }
.page__title { margin: var(--space-2) 0; font-size: var(--fs-title1); font-weight: var(--fw-bold); line-height: var(--lh-tight); letter-spacing: -0.01em; }
.page__lede { max-width: 60ch; margin-bottom: var(--space-5); font-size: var(--fs-body); color: var(--text-muted); }
.explore__actions { margin-bottom: var(--space-5); }
.room-list { display: flex; flex-direction: column; gap: var(--space-3); list-style: none; }
/* Pick a room: the themed public rooms (src/seed.mjs THEMED) as a grid of tiles, two across on a phone, three from 600px. */
.pick { margin-bottom: var(--space-5); }
.pick__title, .explore__more { margin: 0 0 var(--space-3); font-size: var(--fs-title3); font-weight: var(--fw-bold); line-height: var(--lh-tight); }
.explore__more[hidden] { display: none; }
.pick__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); list-style: none; }
@media (min-width: 600px) { .pick__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.pick__tile { display: flex; flex-direction: column; gap: 4px; height: 100%; padding: var(--space-3); border: 1px solid var(--hairline); border-radius: var(--radius-md); background: var(--sheet-bg); color: var(--text); text-decoration: none; transition: box-shadow var(--dur-1); }
@media (hover: hover) { .pick__tile:hover { box-shadow: var(--elev-1); } }
.pick__tile--joined { border-color: var(--link); }
.pick__glyph { display: grid; place-items: center; width: 36px; height: 36px; margin-bottom: 4px; border-radius: 10px; background: var(--accent-soft); color: var(--link); }
.pick__name { font-size: var(--fs-body); font-weight: var(--fw-semibold); line-height: var(--lh-tight); }
.pick__desc { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; font-size: var(--fs-footnote); line-height: var(--lh-body); color: var(--text-muted); }
.pick__meta { margin-top: auto; padding-top: 4px; font-size: var(--fs-caption); color: var(--text-muted); }
.room-card { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-4); border: 1px solid var(--hairline); border-radius: var(--radius-md); background: var(--sheet-bg); color: var(--text); text-decoration: none; transition: box-shadow var(--dur-1); }
@media (hover: hover) { .room-card:hover { box-shadow: var(--elev-1); } }
.room-card__glyph { display: grid; place-items: center; width: 40px; height: 40px; flex: none; border-radius: 10px; background: var(--accent-soft); color: var(--link); }
.room-card__main { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }
.room-card__name { font-size: var(--fs-body); font-weight: var(--fw-semibold); line-height: var(--lh-tight); }
.room-card__desc { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; font-size: var(--fs-subhead); color: var(--text-muted); }
.room-card__meta { font-size: var(--fs-caption); color: var(--text-muted); }
.room-card__tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.room-card__arrow { display: grid; align-self: center; color: var(--text-muted); }
.room-card__open { align-self: center; font-size: var(--fs-subhead); font-weight: var(--fw-semibold); color: var(--link); }
.code-form { margin-top: var(--space-6); padding-top: var(--space-5); border-top: 1px solid var(--hairline); }
.code-form__label { display: block; margin-bottom: var(--space-2); font-size: var(--fs-subhead); font-weight: var(--fw-semibold); }
.code-form__row { display: flex; gap: var(--space-2); }
.code-form__row .field__input { flex: 1; min-width: 0; }
.code-form .field__hint, .code-form .field__error { margin-top: var(--space-2); }

.setup { --bubble-max: min(86%, 440px); }
.setup__thread { display: flex; flex-direction: column; padding-top: var(--space-2); }
.setup .bubble--robot .bubble__body { padding-right: 12px; }
.setup__mine { display: flex; align-items: flex-end; gap: 6px; border: 0; font: inherit; text-align: left; cursor: pointer; }
.setup__mine--skipped .bubble__body { font-style: italic; color: var(--bubble-out-meta); }
.setup__edit { display: grid; padding-bottom: 3px; color: var(--bubble-out-meta); }
.setup__mine:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.setup__controls { display: flex; flex-direction: column; gap: var(--space-2); margin: var(--space-2) 0 var(--space-1); min-width: 0; }
.setup__types { display: grid; gap: 8px; width: 100%; }
.setup__type { display: flex; align-items: flex-start; gap: 12px; width: 100%; min-height: var(--hit); padding: 10px 14px; border: 1px solid var(--robot-border); border-radius: var(--radius-md); background: var(--robot-bg); color: var(--robot-text); text-align: left; }
.setup__type .setup__glyph { display: inline-grid; flex: none; padding-top: 1px; color: var(--robot-link); }
.setup__typetext { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.setup__typename { font-size: var(--fs-subhead); font-weight: var(--fw-semibold); color: var(--robot-link); }
.setup__typeblurb { font-size: var(--fs-footnote); line-height: var(--lh-tight, 1.3); color: var(--robot-meta, var(--text-muted)); }
@media (hover: hover) { .setup__type:hover { background: color-mix(in srgb, var(--robot-border) 45%, var(--robot-bg)); } }
.setup__type:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.setup__type[aria-pressed="true"] { background: color-mix(in srgb, var(--robot-border) 70%, var(--robot-bg)); }
.setup__chips .choice-chip[aria-pressed="true"]::before { background: color-mix(in srgb, var(--robot-border) 70%, var(--robot-bg)); }
.setup__glyph { display: grid; }
.setup__say { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.setup__input { flex: 1; min-width: 0; }
.setup__next { flex: none; }
.setup__final { margin-top: var(--space-3); padding: var(--space-4); border: 1px solid var(--hairline); border-radius: var(--radius-lg); background: var(--sheet-bg); }
.setup__final .field { margin-bottom: var(--space-4); }
.new-room__error { margin-bottom: var(--space-3); }
.new-room__note { margin-top: var(--space-3); font-size: var(--fs-footnote); color: var(--text-muted); }

/* ---------- Join ---------- */
.join { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: safe center; height: 100%; overflow-y: auto; background: var(--wallpaper); padding: calc(var(--space-2) + env(safe-area-inset-top)) var(--gutter) calc(var(--space-5) + env(safe-area-inset-bottom)); }
/* In the flow above the card, so it scrolls away with the form instead of floating over it. */
.join__home { position: static; align-self: flex-start; flex: none; margin: 0 0 var(--space-3) calc(-1 * var(--space-2)); display: inline-flex; align-items: center; height: var(--hit); padding: 0 12px 0 4px; border-radius: var(--radius-md); color: var(--link); text-decoration: none; background: var(--surface); -webkit-backdrop-filter: var(--blur); backdrop-filter: var(--blur); }
.join__home span:first-child { display: grid; }
.join__card { width: 100%; max-width: 420px; padding: var(--space-5); border: 1px solid var(--hairline); border-radius: var(--radius-lg); background: var(--sheet-bg); box-shadow: var(--elev-2); margin: auto 0; }
.join__mark { color: var(--text); margin-bottom: var(--space-4); }
.join__room { font-size: var(--fs-title2); font-weight: var(--fw-semibold); line-height: var(--lh-tight); overflow-wrap: anywhere; }
.join__meta { margin-top: 4px; font-size: var(--fs-subhead); color: var(--text-muted); }
.join__lede { margin: var(--space-4) 0; font-size: var(--fs-body); }
.join__brief { margin-top: var(--space-2); font-size: var(--fs-subhead); color: var(--text); }
.join__intro { margin-top: calc(-1 * var(--space-2)); }
.join__lede .spinner { margin-right: 6px; }
.join__notice { display: flex; align-items: flex-start; gap: var(--space-2); margin: 0 0 var(--space-4); padding: var(--space-3); border-radius: var(--radius-md); background: var(--page-bg); font-size: var(--fs-subhead); color: var(--text-muted); }
.join__notice span:first-child { display: grid; padding-top: 1px; }
.join__form .field { margin-bottom: var(--space-4); }
.join__change { width: 100%; margin-top: var(--space-2); }
.join__skeleton { display: flex; flex-direction: column; }

/* ---------- Rail ---------- */
.rail { display: flex; flex-direction: column; height: 100%; background: var(--surface-solid); }
.rail__header { display: flex; align-items: center; gap: var(--space-1); min-height: calc(var(--header-h) + env(safe-area-inset-top)); padding: env(safe-area-inset-top) var(--space-2) 0 var(--space-4); }
.rail__brand { flex: 1; display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.rail__mark { display: grid; color: var(--text); }
.rail__title { font-size: var(--fs-title3); font-weight: var(--fw-bold); }
@media (min-width: 900px) { .rail__close { display: none; } }
.rail__tools { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-1) var(--space-3) var(--space-2); }
.rail__explore { display: flex; align-items: center; gap: var(--space-2); min-height: var(--hit); padding: 0 var(--space-1); border-radius: var(--radius-md); color: var(--link); font-size: var(--fs-subhead); font-weight: var(--fw-semibold); text-decoration: none; }
.rail__explore-glyph { display: grid; }
.rail__list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; list-style: none; padding: 0 var(--space-2) calc(var(--space-4) + env(safe-area-inset-bottom)); }
.rail__item { display: flex; align-items: center; gap: var(--space-3); min-height: 68px; padding: var(--space-2); border-radius: var(--radius-md); color: var(--text); text-decoration: none; }
@media (hover: hover) { .rail__item:hover, .rail__explore:hover { background: var(--hairline); } }
.rail__item--active, .rail__item--active:hover { background: var(--accent-soft); }
.rail__main { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.rail__row { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.rail__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-body); font-weight: var(--fw-semibold); }
.rail__time { flex: none; font-size: var(--fs-caption); color: var(--text-muted); }
.rail__item--unread .rail__time { color: var(--link); font-weight: var(--fw-semibold); }
.rail__preview { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-subhead); color: var(--text-muted); }
.rail__none { padding: var(--space-4); font-size: var(--fs-subhead); color: var(--text-muted); list-style: none; }
.rail__foot { flex: none; padding: var(--space-1) var(--space-3) calc(var(--space-2) + env(safe-area-inset-bottom)); border-top: 1px solid var(--hairline); }
.rail__devices { width: 100%; border: 0; background: transparent; font-family: inherit; text-align: left; cursor: pointer; }
.rail__have-code { justify-content: center; width: 100%; margin-top: var(--space-3); border: 0; background: transparent; }

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .skeleton::after, .typing__dots i, .caret { animation: none; }
  .typing__dots i { opacity: 1; }
  .spinner { animation-duration: 2.4s; }
  .msg-row--highlight { animation-duration: 1.2s; }
  .btn:active:not([disabled]) { transform: none; }
  /* Springs are zeroed in themes.css, so what moved now just appears; sheets and the QR view fade in instead. */
  .sheet, .qr-view { animation: fade-in var(--dur-1) linear; }
}

/* ---------- Show on screen (views/present.js) ----------
   A projector at 1440 to 1920 wide: the join panel on the left, the chat on the right at 1.5 to 1.75 times its
   size, so body text reads at 24 to 28px. The rail, the header and the banners go; the composer comes back on demand. */
.app--presenter { grid-template-columns: minmax(0, 1fr); }
.app--presenter .app__rail { display: none; }
.room--presenter { --present-w: clamp(320px, 28vw, 560px); --present-zoom: 1.5; --present-pad: clamp(24px, 2.5vw, 48px); background: var(--page-bg); }
@media (min-width: 1680px) { .room--presenter { --present-zoom: 1.625; } }
@media (min-width: 1880px) { .room--presenter { --present-zoom: 1.75; } }
.room--presenter .room-header, .room--presenter .banners__prompt { display: none; }
.room--presenter .banners { margin: 0 0 0 var(--present-w); }
.room--presenter .msg-list, .room--presenter.room--band .msg-list { left: var(--present-w); top: var(--banners-h, 0px); padding: var(--space-4) 0 var(--space-6); --bubble-max: 86%; }
.room--presenter.room--typing .msg-list { padding-bottom: calc(var(--composer-h, 64px) + var(--space-3)); }
.room--presenter .msg-list__col { zoom: var(--present-zoom); max-width: none; padding: 0 var(--space-5); }
.room--presenter .att-image { max-width: 520px; }
.room--presenter .att-image img { max-height: 440px; }
.room--presenter .bubble--robot .att-image img { max-height: 760px; }
.room--presenter .voice, .room--presenter .transcript { width: 380px; }
.room--presenter .transcript__text { display: block; -webkit-line-clamp: unset; line-clamp: none; }
.room--presenter .transcript__more { display: none; }
.room--presenter .composer { display: none; left: var(--present-w); }
.room--presenter.room--typing .composer { display: block; }
.room--presenter .jump-btn { right: var(--space-5); bottom: var(--space-5); }
.room--presenter.room--typing .jump-btn { bottom: calc(var(--composer-h, 64px) + var(--space-3)); }

.presenter {
  position: absolute; top: 0; bottom: 0; left: 0; z-index: var(--z-header); width: var(--present-w);
  display: flex; flex-direction: column; gap: var(--space-3); padding: var(--present-pad); overflow: hidden auto;
  background: var(--surface-solid); border-right: 1px solid var(--hairline); color: var(--text);
}
.presenter__brand { display: flex; align-items: center; gap: var(--space-2); font-size: var(--fs-subhead); font-weight: var(--fw-semibold); color: var(--text-muted); }
.presenter__mark { display: grid; color: var(--text); }
.presenter__room { font-size: clamp(1.5rem, 1.9vw, 2.25rem); font-weight: var(--fw-bold); line-height: var(--lh-tight); overflow-wrap: anywhere;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.presenter__count { margin-top: calc(-1 * var(--space-2)); font-size: clamp(1rem, 1.1vw, 1.25rem); color: var(--text-muted); }
.presenter__join { display: flex; flex-direction: column; margin: auto 0; }
.presenter__label { margin: var(--space-3) 0 var(--space-1); font-size: clamp(0.9375rem, 1vw, 1.125rem); font-weight: var(--fw-semibold); color: var(--text-muted); }
.presenter__label:first-child { margin-top: 0; }
.presenter__qr { width: min(100%, 50vh); aspect-ratio: 1; overflow: hidden; border: 1px solid var(--hairline); border-radius: var(--radius-lg); background: var(--qr-light); }
.presenter__qr svg, .qr-view__qr svg { width: 100%; height: 100%; }
.presenter__link { font-family: var(--font-mono); font-size: clamp(1rem, 1.3vw, 1.5rem); font-weight: var(--fw-semibold); line-height: var(--lh-tight); overflow-wrap: anywhere; }
.presenter__code { font-size: clamp(3rem, 5vw, 6rem); line-height: 1; letter-spacing: 0.06em; }
.presenter__controls { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-2); margin: 0 calc(-1 * var(--space-3)); }
.presenter__key { margin-left: var(--space-2); padding: 0 6px; border: 1px solid var(--border); border-radius: var(--radius-xs); font: inherit; font-size: var(--fs-caption); color: var(--text-muted); }

/* The QR view: one tap on the header code. Full screen on a phone, so someone can scan it off the screen. */
.qr-view {
  position: fixed; inset: 0; z-index: var(--z-scrim); display: grid; place-items: center; overflow-y: auto;
  padding: calc(var(--space-6) + env(safe-area-inset-top)) var(--space-4) calc(72px + env(safe-area-inset-bottom));
  background: var(--page-bg); color: var(--text); animation: scrim-in var(--dur-2) linear;
}
.qr-view--closing { opacity: 0; pointer-events: none; transition: opacity var(--dur-2) linear; }
/* Its toasts sit under the buttons, in the space the view keeps free at the bottom. */
.has-qr-view .toast-host { bottom: calc(var(--space-3) + env(safe-area-inset-bottom)); }
.qr-view__close { position: absolute; top: calc(var(--space-2) + env(safe-area-inset-top)); right: var(--space-2); color: var(--text-muted); }
.qr-view__inner { display: flex; flex-direction: column; align-items: center; width: 100%; max-width: 520px; text-align: center; }
.qr-view__room { margin-bottom: var(--space-4); font-size: var(--fs-title2); font-weight: var(--fw-semibold); line-height: var(--lh-tight); overflow-wrap: anywhere; }
.qr-view__qr { width: min(100%, 48vh, 440px); aspect-ratio: 1; overflow: hidden; border: 1px solid var(--hairline); border-radius: var(--radius-lg); background: var(--qr-light); box-shadow: var(--elev-1); }
.qr-view__label { margin-top: var(--space-4); font-size: var(--fs-subhead); color: var(--text-muted); }
.qr-view__link { font-family: var(--font-mono); font-size: var(--fs-body); font-weight: var(--fw-semibold); overflow-wrap: anywhere; }
.qr-view__code { font-size: clamp(2.75rem, 13vw, 4.5rem); line-height: 1.1; letter-spacing: 0.06em; }
.qr-view__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-2); margin-top: var(--space-5); }
/* Narrower than a projector (a phone cast to a TV): the join panel is a band above the chat, QR code on the left and
   the code, the link and the controls beside it. */
@media (max-width: 899px) {
  .room--presenter { --present-w: 0px; --present-zoom: 1.15; --present-top: 156px; }
  .room--presenter .msg-list, .room--presenter.room--band .msg-list { top: calc(var(--present-top) + var(--banners-h, 0px)); }
  .room--presenter .banners { margin-top: var(--present-top); }
  .presenter { right: 0; bottom: auto; width: auto; height: var(--present-top); display: grid; grid-template-columns: 124px minmax(0, 1fr);
    grid-template-rows: auto auto 1fr; gap: 2px var(--space-3); align-content: start; padding: var(--space-4); border-right: 0; border-bottom: 1px solid var(--hairline); overflow: hidden; }
  .presenter__brand, .presenter__room, .presenter__count, .presenter__label { display: none; }
  .presenter__join { display: contents; }
  .presenter__qr { grid-column: 1; grid-row: 1 / span 3; width: 124px; }
  .presenter__code { grid-column: 2; grid-row: 1; font-size: 2.25rem; }
  .presenter__link { grid-column: 2; grid-row: 2; font-size: var(--fs-footnote); }
  .presenter__controls { grid-column: 2; grid-row: 3; align-self: end; flex-wrap: nowrap; margin: 0 0 0 calc(-1 * var(--space-3)); gap: 0; }
  .presenter__key { display: none; }
}

/* Camera on a laptop or desktop (views/webcam.js): live preview, Take photo, Record video. Always dark, like a
   camera app, so the preview reads true in either theme. */
.webcam {
  position: fixed; inset: 0; z-index: var(--z-scrim); display: grid; place-items: center;
  padding: var(--space-4); background: #0B0D12; color: #F3F4F6; animation: scrim-in var(--dur-2) linear;
}
.webcam__inner { display: flex; flex-direction: column; align-items: center; gap: var(--space-4); width: min(100%, 960px); }
.webcam__frame { position: relative; width: 100%; overflow: hidden; border-radius: var(--radius-lg); background: #000; }
.webcam__preview { display: block; width: 100%; max-height: 70vh; object-fit: contain; transform: scaleX(-1); }
.webcam__timer { position: absolute; top: var(--space-3); left: var(--space-3); padding: 4px 10px; border-radius: var(--radius-pill); background: rgba(0, 0, 0, 0.6); font-variant-numeric: tabular-nums; font-weight: var(--fw-semibold); }
.webcam__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-2); }
.webcam__dot { width: 12px; height: 12px; border-radius: 50%; background: #E5484D; }
.webcam--recording .webcam__dot { animation: rec-pulse 1s ease-in-out infinite; }
.webcam--recording .webcam__frame { box-shadow: 0 0 0 3px #E5484D; }
@media (prefers-reduced-motion: reduce) { .webcam--recording .webcam__dot { animation: none; } }

/* Notifications: mentions, announcements, levels (views/mentions.js, room.js buildAnnounce, settings.js notifyLevels) */
.mention-list { position: absolute; bottom: calc(100% + 6px); left: max(var(--space-2), calc((100% - var(--chat-max)) / 2 + var(--space-2))); z-index: 2;
  width: min(320px, calc(100% - 2 * var(--space-2))); max-height: min(300px, 40vh); overflow-y: auto; margin: 0; padding: 4px; list-style: none;
  border: 1px solid var(--hairline); border-radius: var(--radius-md); background: var(--sheet-bg); color: var(--text); box-shadow: var(--elev-2); }
.mention-opt { display: flex; align-items: center; gap: 10px; min-height: var(--hit); padding: 4px 10px; border-radius: 9px; cursor: pointer; }
.mention-opt[aria-selected="true"] { background: var(--accent-soft); }
@media (hover: hover) { .mention-opt:hover { background: var(--accent-soft); } }
.mention-opt__face { display: grid; place-items: center; flex: none; width: 28px; height: 28px; border-radius: 50%; color: #FFFFFF; font-size: var(--fs-footnote); font-weight: var(--fw-bold); }
.mention-opt__face--robot { background: var(--robot-bg); color: var(--text); border: 1px solid var(--robot-border); }
.mention-opt__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: var(--fw-medium); }
.mention-opt__hint { flex: none; color: var(--text-muted); font-size: var(--fs-caption); }

.announce-bar { display: flex; align-items: center; gap: var(--space-2); margin-bottom: 6px; padding: 4px 0 4px 10px; border-left: 3px solid var(--accent); }
.announce-bar__glyph { display: grid; color: var(--link); }
.announce-bar__main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.announce-bar__label { font-size: var(--fs-footnote); font-weight: var(--fw-semibold); color: var(--link); }
.announce-bar__text { font-size: var(--fs-caption); color: var(--text-muted); }
.composer--announce .composer__send::before { background: var(--accent); }

.announce-pin { display: flex; align-items: center; gap: var(--space-1); max-width: var(--chat-max); margin: 0 auto; padding: 0 var(--space-1) 0 var(--space-3); border-bottom: 1px solid var(--hairline); background: var(--sheet-bg); }
.announce-pin[hidden] { display: none; }
.announce-pin__open { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--space-2); min-height: 52px; padding: 6px 0; border: 0; background: transparent; color: var(--text); text-align: left; }
.announce-pin__glyph { display: grid; flex: none; color: var(--link); }
.announce-pin__main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.announce-pin__label { font-size: var(--fs-caption); font-weight: var(--fw-semibold); color: var(--link); }
.announce-pin__text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-subhead); }
.announce-pin__close { flex: none; color: var(--text-muted); }
.announce-pin--brief .announce-pin__glyph, .announce-pin--brief .announce-pin__label { color: var(--text-muted); }
.announce-pin--full .announce-pin__text { white-space: normal; overflow: visible; }

.bubble--announce { box-shadow: inset 0 0 0 2px var(--accent); }
.announce-tag { display: flex; align-items: center; gap: 4px; margin-bottom: 2px; font-size: var(--fs-caption); font-weight: var(--fw-semibold); color: var(--link); }
.bubble--out .announce-tag { color: inherit; opacity: 0.9; }

.notify-levels { display: flex; flex-direction: column; gap: 6px; }
.notify-level { display: flex; align-items: flex-start; gap: var(--space-3); width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-md); background: transparent; color: var(--text); text-align: left; }
.notify-level--on { border-color: var(--accent); background: var(--accent-soft); }
.notify-level__dot { position: relative; flex: none; width: 20px; height: 20px; margin-top: 1px; border: 2px solid var(--border); border-radius: 50%; }
.notify-level--on .notify-level__dot { border-color: var(--accent); }
.notify-level--on .notify-level__dot::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--accent); }
.notify-level__main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.notify-level__label { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: var(--fs-body); font-weight: var(--fw-medium); }
.notify-level__hint { font-size: var(--fs-footnote); color: var(--text-muted); }

/* ---- Private robot answers (views/private.js) -------------------------------------------------------------------
   The same quiet card as the robot's, in one other hue: slate violet, in every look, light and dark. Two signals and
   no more: the lavender card, and on the name line next to "Robot" a tinted lock chip "Only you can see this".
   Nothing else in the app is violet, so the difference is unmistakable without a dark fill or a different shape. */
.bubble--incognito { background: var(--incog-bg); color: var(--incog-text); border-color: var(--incog-border); }
/* The robot's name stays gold on the private card: the lavender fill and the chip already say private. */
.bubble--incognito .robot-tag { display: inline-flex; vertical-align: middle; margin: 0 8px 4px 0; }
.bubble--incognito .md-list li::marker { color: var(--incog-link); }
.bubble--incognito .bubble__meta, .bubble--incognito .robot-note, .bubble--incognito .robot-elapsed, .bubble--incognito .typing__dots, .bubble--incognito .robot-flag,
.bubble--incognito .transcript--status, .bubble--incognito.bubble--robot-failed .bubble__body { color: var(--incog-muted); }
.bubble--incognito .bubble__body a, .bubble--incognito .source-chip__pill { color: var(--incog-link); }
.bubble--incognito .source-chip__pill { border-color: var(--incog-border); }
.bubble--incognito .md-quote, .bubble--incognito .reply-quote { border-left-color: var(--incog-accent); }
.bubble--incognito .md-code, .bubble--incognito .bubble__body code, .bubble--incognito .md-table th, .bubble--incognito .reply-quote { background: color-mix(in srgb, var(--incog-text) 8%, transparent); }
.bubble--incognito .reply-quote__name { color: var(--incog-muted); }
.private-tag { display: inline-flex; align-items: center; gap: 4px; vertical-align: middle; margin: 0 16px 4px 0; padding: 2px 8px 2px 6px; border-radius: var(--radius-pill); background: var(--incog-raised); color: var(--incog-link); font-size: var(--fs-caption); font-weight: var(--fw-semibold); line-height: var(--lh-tight); white-space: nowrap; }
.private-tag__glyph { display: inline-grid; }
.private-tag__glyph svg { width: 13px; height: 13px; }
.private-q { margin: 2px 0 6px; padding: 2px 0 2px 10px; border-left: 3px solid var(--border); font-size: var(--fs-footnote); line-height: var(--lh-tight); }
.private-q__label { display: block; font-weight: var(--fw-semibold); color: var(--incog-muted); }
.private-q__text { display: block; overflow-wrap: anywhere; white-space: pre-wrap; }
/* Share to room and Dismiss sit inside the card, under a hairline, so the whole private answer is one surface. */
.private-actions { clear: both; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 8px 0 3px; padding-top: 8px; border-top: 1px solid var(--incog-border); }
.private-actions__note { padding: 0 4px; font-size: var(--fs-caption); color: var(--incog-muted); }
.private-actions .btn { min-height: 36px; }
.private-actions .btn--secondary { background: var(--incog-raised); color: var(--incog-text); }
@media (hover: hover) { .private-actions .btn--secondary:hover { background: color-mix(in srgb, var(--incog-accent) 18%, var(--incog-raised)); } }
.private-actions .btn--ghost { margin-left: auto; padding: 0 10px; color: var(--incog-muted); }
.private-actions .btn .icon { width: 18px; height: 18px; }
/* The answer's files sit inside the card at the room's media sizes (.att-video, .att-image), with a download link. */
.private-media { display: grid; gap: 8px; margin: 6px 0 2px; }
.private-media__item { display: grid; gap: 4px; justify-items: start; }
.private-media .att-image { cursor: default; }
.private-media__caption { font-size: var(--fs-footnote); color: var(--incog-muted); line-height: var(--lh-tight); }
.private-media__dl { font-size: var(--fs-caption); font-weight: var(--fw-semibold); color: var(--incog-link); text-decoration: none; overflow-wrap: anywhere; }
.private-media__dl:hover { text-decoration: underline; }

/* The robot pill above the field (views/robot-aim.js): the robot's own quiet card. Who the message is for, Private or
   Public, and what that means. The pill never changes colour wholesale: Private shows on the chosen segment, on the
   note under it and as a lock badge on the message field. */
.robot-aim { margin: 0 4px 6px; padding: 4px 4px 6px 10px; border: 1px solid var(--hairline); border-radius: var(--radius-lg); background: var(--robot-bg); color: var(--robot-text); }
.robot-aim[hidden], .robot-aim__close[hidden], .robot-aim__chips[hidden] { display: none; }
.robot-aim:not([hidden]) { transition: opacity var(--dur-2) linear, transform var(--spring-snap-dur) var(--spring-snap); }
@starting-style { .robot-aim:not([hidden]) { opacity: 0; transform: translateY(6px); } }
.robot-aim__head { display: flex; align-items: center; gap: var(--space-2); min-height: 36px; }
.robot-aim__mark { display: inline-grid; flex: none; color: var(--robot-name); }
.robot-aim__mark .mark__fold { fill: var(--robot-fold); }
/* The title is the way to the robot sheet: every question, About you and Introductions, one tap from the pill. */
.robot-aim__title { display: inline-flex; flex: 1; min-width: 0; align-items: center; gap: 2px; min-height: 36px; padding: 0 2px; border: 0; border-radius: var(--radius-sm); background: transparent; color: inherit; font-size: var(--fs-subhead); font-weight: var(--fw-semibold); text-align: left; }
.robot-aim__title > span { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.robot-aim__title .icon { color: var(--robot-meta); }
.robot-aim__title:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
/* The switch: one segmented control on a neutral grey track, both options always shown and readable, the chosen one
   a thumb. Public chosen is a sheet-coloured thumb with the people glyph and text in the link blue; Private chosen is
   the private answer's violet with white text and the lock, so the state is the colour of its result. */
.robot-aim__switch { display: inline-flex; flex: none; padding: 2px; border-radius: var(--radius-pill); background: color-mix(in srgb, var(--text) 10%, transparent); }
.robot-aim__opt { display: inline-flex; align-items: center; gap: 4px; min-height: 32px; padding: 0 10px; border: 0; border-radius: var(--radius-pill); background: transparent; color: var(--text); font-size: var(--fs-footnote); font-weight: var(--fw-semibold); transition: background-color var(--dur-1) linear, color var(--dur-1) linear; }
.robot-aim__opt[aria-pressed="true"] { background: var(--sheet-bg); color: var(--link); box-shadow: var(--elev-1); }
.robot-aim__opt[data-value="private"][aria-pressed="true"] { background: var(--incog-fill); color: var(--incog-on-fill); box-shadow: none; }
.robot-aim__opt:focus-visible, .robot-aim__chip:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.robot-aim__glyph { display: inline-grid; }
.robot-aim__close { width: 36px; height: 36px; border-radius: 50%; color: var(--robot-meta); }
.robot-aim__note { display: flex; align-items: center; gap: 4px; margin: 0 0 0 28px; font-size: var(--fs-caption); color: var(--robot-meta); }
.robot-aim__incog { display: none; flex: none; }
/* Private before Send: the switch and the lock badge on the field say it, so the plain note line stays hidden
   (robot-aim.js shows the note only for the held, the count and the used-up texts) and the pill stays as it is. */
.robot-aim__note[hidden] { display: none; }
.robot-aim--private .robot-aim__note { font-weight: var(--fw-semibold); color: var(--incog-link); }
.robot-aim--private .robot-aim__incog { display: inline-grid; }
.composer__fieldwrap { position: relative; }
.composer--private .composer__fieldwrap { border-color: var(--incog-accent); box-shadow: 0 0 0 1px var(--incog-accent); }
.composer--private .composer__fieldwrap:focus-within { border-color: var(--incog-accent); box-shadow: 0 0 0 1px var(--incog-accent); }
.composer--private .composer__fieldwrap::before { content: ""; position: absolute; left: 12px; top: 12px; width: 16px; height: 16px; background: var(--incog-accent); pointer-events: none;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='5' y='10.5' width='14' height='10' rx='2'/><path d='M8 10.5V8a4 4 0 0 1 8 0v2.5'/></svg>") center / contain no-repeat;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='5' y='10.5' width='14' height='10' rx='2'/><path d='M8 10.5V8a4 4 0 0 1 8 0v2.5'/></svg>") center / contain no-repeat; }
.composer--private .composer__field { padding-left: 34px; }
/* Two questions at most, so the row fits at 390px without sliding; a long pair wraps. The rest sit in the robot sheet. */
.robot-aim__chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 0; padding: 0 4px 0 28px; }
.robot-aim__chip { display: inline-flex; flex: none; align-items: center; gap: 4px; min-height: 36px; padding: 0 12px; border: 1px solid var(--robot-border); border-radius: var(--radius-pill); background: var(--sheet-bg); color: var(--robot-link); font-size: var(--fs-subhead); font-weight: var(--fw-semibold); white-space: nowrap; }
.robot-aim__chip:disabled { opacity: 0.5; }
@media (hover: hover) { .robot-aim__chip:not(:disabled):hover { background: color-mix(in srgb, var(--robot-border) 35%, var(--sheet-bg)); } }
.robot-aim--private .robot-aim__chip { border-color: var(--incog-border); color: var(--incog-link); }

/* The robot sheet: one-tap private asks. */
.robot-card__lead { display: flex; align-items: flex-start; gap: var(--space-2); margin: 0 0 var(--space-3); color: var(--text-muted); font-size: var(--fs-subhead); }
.robot-card__lock { display: inline-grid; flex: none; padding-top: 2px; }
.robot-card__list { display: flex; flex-direction: column; gap: var(--space-2); }
.robot-card__ask { display: flex; align-items: center; gap: var(--space-3); width: 100%; min-height: 52px; padding: 10px 14px; border: 1px solid var(--robot-border); border-radius: var(--radius-md); background: var(--robot-bg); color: var(--robot-text); font-size: var(--fs-body); font-weight: var(--fw-semibold); text-align: left; }
.robot-card__ask:disabled { opacity: 0.5; }
@media (hover: hover) { .robot-card__ask:not(:disabled):hover { background: color-mix(in srgb, var(--robot-border) 45%, var(--robot-bg)); } }
.robot-card__mark { display: inline-grid; flex: none; color: var(--robot-name); }
.robot-card__mark .mark__fold { fill: var(--robot-fold); }
.robot-card__left, .robot-card__hint { margin: var(--space-3) 0 0; font-size: var(--fs-footnote); color: var(--text-muted); }
.robot-card__error { color: var(--danger); }
.composer__robot { flex: none; color: var(--robot-name); -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
.composer__robot .mark__fold { fill: var(--robot-fold); }
.composer__robot[aria-pressed="true"] { border-radius: 50%; background: var(--robot-bg); box-shadow: inset 0 0 0 1px var(--robot-border); }
.composer--recording .composer__robot { display: none; }

/* ---- Work it out rooms (views/mediate.js) ---------------------------------------------------------------------------
   The robot's Where we stand and common ground cards are wider robot bubbles; their own inputs sit on the manila,
   on the sheet fill so they read as fields. The robot keeps its colour: nothing here is manila that is not the robot. */
.bubble--card { width: min(92%, 480px); max-width: min(92%, 480px); padding: 8px 12px 6px; }
.mcard { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.mcard__label { margin: 0; font-size: var(--fs-caption); font-weight: var(--fw-bold); letter-spacing: 0.04em; text-transform: uppercase; color: var(--robot-name); }
.mcard__foot { margin: 0; font-size: var(--fs-caption); color: var(--robot-meta); }
.mcard__field { background: var(--sheet-bg); border-color: var(--robot-border); color: var(--text); font-size: max(16px, var(--fs-body)); }
textarea.mcard__field { min-height: 76px; }
.mcard .btn--ghost { color: var(--robot-link); }
.mcard .btn--secondary { background: color-mix(in srgb, var(--robot-border) 55%, var(--robot-bg)); color: var(--robot-text); }
.mcard .btn--sm .spinner { margin-right: 6px; }
.standing__part { display: flex; flex-direction: column; gap: 2px; }
.standing__title { display: flex; align-items: center; gap: 6px; margin: 0; font-size: var(--fs-footnote); font-weight: var(--fw-semibold); color: var(--robot-name); }
.standing__glyph { display: inline-grid; }
.standing__list { margin: 0; padding-left: 1.2em; line-height: var(--lh-body); }
.standing__list li + li { margin-top: 2px; }
.standing__list b { font-weight: var(--fw-semibold); }
.standing__none { margin: 0; font-style: italic; color: var(--robot-meta); }
.round__q { margin: 0; font-size: var(--fs-body); font-weight: var(--fw-semibold); line-height: var(--lh-tight); overflow-wrap: anywhere; }
.round__how { display: flex; align-items: flex-start; gap: 6px; margin: 0; font-size: var(--fs-footnote); color: var(--robot-meta); }
.round__lock { display: inline-grid; flex: none; padding-top: 1px; }
.round__row, .round__owner { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.round__owner { padding-top: var(--space-2); border-top: 1px solid var(--robot-border); }
.round__mine { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 6px 8px; border-left: 3px solid var(--robot-fold); border-radius: 6px; background: color-mix(in srgb, var(--robot-border) 40%, transparent); }
.round__minelabel { display: flex; align-items: center; gap: 4px; font-size: var(--fs-caption); font-weight: var(--fw-semibold); color: var(--robot-name); }
.round__minetext { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; font-size: var(--fs-subhead); }
.round__change { height: 32px; min-height: 32px; margin-left: -10px; padding: 0 10px; }
.round__progress, .round__hint { margin: 0; font-size: var(--fs-footnote); color: var(--robot-meta); }
.round__wait, .round__working { display: flex; align-items: center; gap: var(--space-2); margin: 0; font-size: var(--fs-subhead); color: var(--robot-meta); }
.round__error { margin: 0; font-size: var(--fs-footnote); color: var(--danger); }
.round__statement { margin: 0; padding: 8px 10px; border-left: 3px solid var(--robot-fold); border-radius: 6px; background: var(--sheet-bg); color: var(--text); }
.round__statement p { margin: 0; line-height: var(--lh-read); overflow-wrap: anywhere; }
.round__version { display: block; margin-bottom: 2px; font-size: var(--fs-caption); font-weight: var(--fw-semibold); color: var(--text-muted); }
.round--locked .round__statement { border-left-width: 4px; font-weight: var(--fw-medium); }
.round__ask { margin: 0; font-size: var(--fs-subhead); font-weight: var(--fw-semibold); }
.score { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; }
.score__opt { display: grid; place-items: center; height: var(--hit); padding: 0; border: 1px solid var(--robot-border); border-radius: var(--radius-md); background: var(--sheet-bg); color: var(--text); font-size: var(--fs-body); font-weight: var(--fw-semibold); }
.score__opt--on { border-color: var(--accent); background: var(--accent); color: var(--accent-text); }
.score__opt:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.score__ends { display: flex; justify-content: space-between; margin-top: -4px; font-size: var(--fs-caption); color: var(--robot-meta); }
.round__prev { font-size: var(--fs-footnote); color: var(--robot-meta); }
.round__prev summary { min-height: 32px; display: flex; align-items: center; cursor: pointer; }
.round__prev summary::marker { content: ""; }
.round__prev summary::before { content: "+"; display: inline-block; width: 1em; font-weight: var(--fw-bold); }
.round__prev[open] summary::before { content: "\2212"; }
.round__prevtext { margin: 0 0 6px; color: var(--robot-text); }
.spread { display: flex; flex-direction: column; gap: 4px; }
.spread__line { margin: 0; font-size: var(--fs-footnote); }
.spread__label { color: var(--robot-meta); }
.spread__line--private { display: flex; align-items: flex-start; gap: 6px; color: var(--robot-meta); }
.spread__meter { height: 8px; max-width: 260px; border-radius: var(--radius-pill); background: color-mix(in srgb, var(--robot-border) 70%, transparent); overflow: hidden; }
.spread__fill { display: block; height: 100%; border-radius: inherit; background: var(--robot-name); }
.round__unsent { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 6px 8px; border: 1px dashed var(--robot-meta); border-radius: 6px; }
.round__unsentwhy { margin: 0; font-size: var(--fs-footnote); font-weight: var(--fw-semibold); color: var(--robot-name); }
.round__minetext { user-select: text; }

/* The sheet before a heated message goes out: the robot's read on manila, the suggestion as the writer's own words. */
.heat__heard { display: flex; gap: var(--space-2); align-items: flex-start; padding: 10px 12px; border: 1px solid var(--robot-border); border-radius: var(--radius-md); background: var(--robot-bg); color: var(--robot-text); }
.heat__mark { display: inline-grid; flex: none; padding-top: 2px; color: var(--robot-name); }
.heat__mark .mark__fold { fill: var(--robot-fold); }
.heat__label { margin: 0 0 2px; font-size: var(--fs-footnote); font-weight: var(--fw-semibold); color: var(--text-muted); }
.heat__heard .heat__label { color: var(--robot-name); }
.heat__text { margin: 0; line-height: var(--lh-body); overflow-wrap: anywhere; white-space: pre-wrap; }
.heat__mine { margin-top: var(--space-3); padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--page-bg); color: var(--text); }
.heat__suggest { margin-top: var(--space-3); padding: 10px 12px; border-radius: var(--radius-md); background: var(--bubble-out-bg); color: var(--bubble-out-text); }
.heat__suggest .heat__label { color: inherit; opacity: 0.8; }
.heat__actions { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-4); }
.heat__note { margin: var(--space-3) 0 0; font-size: var(--fs-footnote); color: var(--text-muted); }
.round-sheet__lead { margin: 0 0 var(--space-4); color: var(--text-muted); font-size: var(--fs-subhead); line-height: var(--lh-body); }
.round-sheet__form .btn { margin-top: var(--space-3); }

/* The composer's row: Where do we stand and Find common ground, while the field is empty. */
.mediate-bar { display: flex; gap: var(--space-2); padding: 6px var(--space-3) 2px; overflow-x: auto; scrollbar-width: none; }
.mediate-bar[hidden] { display: none; }
.mediate-bar::-webkit-scrollbar { display: none; }
.mediate-bar__btn { display: inline-flex; flex: none; align-items: center; gap: 6px; min-height: 36px; padding: 0 12px; border: 1px solid var(--robot-border); border-radius: var(--radius-pill); background: var(--robot-bg); color: var(--robot-text); font-size: var(--fs-footnote); font-weight: var(--fw-semibold); white-space: nowrap; }
.mediate-bar__btn[hidden] { display: none; }
.mediate-bar__btn:disabled { opacity: 0.7; }
.mediate-bar__btn:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.mediate-bar__glyph { display: inline-grid; color: var(--robot-name); }
@media (pointer: coarse) { .mediate-bar__btn { min-height: 40px; } }
@media (hover: hover) { .mediate-bar__btn:not(:disabled):hover { background: color-mix(in srgb, var(--robot-border) 45%, var(--robot-bg)); } }
.announce-pin--mediate .announce-pin__glyph, .announce-pin--mediate .announce-pin__label { color: var(--robot-name); }
.composer--checking .composer__field { opacity: 0.7; }

/* Decide together (views/decide.js): the session card. Ideas without names, the vote as bars with a zero baseline and
   the count on the bar, the leader alone in the accent colour (Few; Knaflic), next steps people take on. */
.round__changed { margin: 0; font-size: var(--fs-footnote); color: var(--robot-text); }
.decide__add { display: flex; gap: var(--space-2); align-items: center; }
.decide__add .mcard__field { flex: 1; min-width: 0; }
.decide__add .btn { flex: none; }
.decide__mine, .decide__wall, .decide__groupideas { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 4px; }
.decide__mine li { display: flex; align-items: center; gap: var(--space-2); padding: 4px 4px 4px 8px; border-left: 3px solid var(--robot-fold); border-radius: 6px; background: color-mix(in srgb, var(--robot-border) 40%, transparent); }
.decide__minetext { flex: 1; min-width: 0; font-size: var(--fs-subhead); overflow-wrap: anywhere; }
.decide__x { flex: none; height: 32px; min-height: 32px; padding: 0 10px; }
.decide__wall li { display: flex; align-items: center; gap: var(--space-2); min-height: 36px; padding: 6px 4px 6px 10px; border: 1px solid var(--robot-border); border-radius: var(--radius-md); background: var(--sheet-bg); color: var(--text); font-size: var(--fs-subhead); line-height: var(--lh-tight); }
.decide__wall li > span { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.decide__idea--mine { border-color: var(--robot-fold) !important; }
.decide__hide { flex: none; width: 32px; height: 32px; min-width: 32px; min-height: 32px; color: var(--robot-meta); }
.decide__more { align-self: flex-start; margin-left: -10px; }
.decide__group { margin: 6px 0; }
.decide__grouplabel { margin: 0 0 2px; font-weight: var(--fw-semibold); color: var(--robot-text); }
.decide__groupideas li { padding-left: 10px; border-left: 2px solid var(--robot-border); }
.decide__stepshead { margin: var(--space-1) 0 0; font-size: var(--fs-caption); font-weight: var(--fw-bold); letter-spacing: 0.04em; text-transform: uppercase; color: var(--robot-name); }
.decide__steps { margin: 0; padding: 0; list-style: none; counter-reset: step; display: flex; flex-direction: column; gap: 6px; }
.decide__step { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; padding: 8px 10px; border-radius: var(--radius-md); background: var(--sheet-bg); color: var(--text); counter-increment: step; }
.decide__steptext { font-size: var(--fs-subhead); line-height: var(--lh-tight); overflow-wrap: anywhere; }
.decide__steptext::before { content: counter(step) ". "; font-weight: var(--fw-semibold); color: var(--text-muted); }
.decide__owner { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; font-size: var(--fs-footnote); font-weight: var(--fw-semibold); color: var(--robot-name); }
.decide__ownerglyph { display: inline-grid; }
.decide__take { min-height: 36px; }
.vote { display: flex; flex-direction: column; gap: 6px; }
.vote__opt { display: flex; flex-direction: column; gap: 4px; width: 100%; min-height: var(--hit); padding: 8px 10px; border: 1px solid var(--robot-border); border-radius: var(--radius-md); background: var(--sheet-bg); color: var(--text); text-align: left; font: inherit; }
button.vote__opt { cursor: pointer; }
.vote__opt--on { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.vote__opt:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.vote__top { display: flex; align-items: center; gap: var(--space-2); }
.vote__radio { display: grid; place-items: center; flex: none; width: 22px; height: 22px; border: 2px solid var(--border); border-radius: 50%; color: var(--accent-text); }
.vote__opt--on .vote__radio { border-color: var(--accent); background: var(--accent); }
.vote__label { flex: 1; min-width: 0; font-weight: var(--fw-semibold); line-height: var(--lh-tight); overflow-wrap: anywhere; }
.vote__count { flex: none; font-variant-numeric: tabular-nums; font-weight: var(--fw-bold); }
.vote__meta { font-size: var(--fs-caption); color: var(--text-muted); }
.vote__track { display: block; height: 6px; border-radius: var(--radius-pill); background: color-mix(in srgb, var(--robot-border) 70%, transparent); overflow: hidden; }
.vote__fill { display: block; height: 100%; border-radius: inherit; background: var(--text-muted); transition: width 300ms ease; }
.vote__fill--lead { background: var(--accent); }
@media (prefers-reduced-motion: reduce) { .vote__fill { transition: none; } }
.tool-bar[hidden] { display: none; }

/* The projector's stage (views/stage.js): an open round or session in place of the chat, type readable from the back
   of a room at 1920 by 1080. */
.stage { position: absolute; top: 0; right: 0; bottom: 0; left: var(--present-w, 0px); z-index: 2; overflow: hidden auto;
  padding: clamp(32px, 3.5vw, 72px) clamp(32px, 4vw, 88px); background: var(--page-bg); color: var(--text); }
.stage[hidden] { display: none; }
.room--staged .msg-list, .room--staged .jump-btn, .room--staged .banners { visibility: hidden; }
.stage__inner { display: flex; flex-direction: column; justify-content: safe center; gap: clamp(16px, 1.6vw, 32px); max-width: 1500px; min-height: 100%; margin: 0 auto; }
.stage__kind { margin: 0; font-size: clamp(1rem, 1.4vw, 1.75rem); font-weight: var(--fw-bold); letter-spacing: 0.06em; text-transform: uppercase; color: var(--accent); }
.stage__q { margin: 0; font-size: clamp(2rem, 3.3vw, 4.25rem); font-weight: var(--fw-bold); line-height: 1.12; letter-spacing: -0.01em; overflow-wrap: anywhere; }
.stage__counter { display: flex; flex-direction: column; gap: 12px; }
.stage__count { margin: 0; font-size: clamp(1.5rem, 2.4vw, 3rem); line-height: 1.1; color: var(--text-muted); }
.stage__count b { font-size: clamp(3.5rem, 6.5vw, 8rem); font-weight: var(--fw-bold); line-height: 1; color: var(--text); font-variant-numeric: tabular-nums; }
.stage__count--line { font-size: clamp(1.25rem, 1.9vw, 2.375rem); }
.stage__count--line b { font-size: inherit; }
.stage__progress { display: block; height: 14px; max-width: 900px; border-radius: var(--radius-pill); background: color-mix(in srgb, var(--text-muted) 22%, transparent); overflow: hidden; }
.stage__progress > span, .stage__meterbar > span, .stage__track > span { display: block; height: 100%; border-radius: inherit; background: var(--accent); }
.stage__how { display: flex; align-items: center; gap: 14px; margin: 0; font-size: clamp(1.25rem, 1.8vw, 2.25rem); color: var(--text-muted); }
.stage__how svg { flex: none; }
.stage__working { display: flex; align-items: center; gap: 18px; margin: 0; font-size: clamp(1.5rem, 2.2vw, 2.75rem); font-weight: var(--fw-semibold); color: var(--text-muted); }
.stage__dots { transform: scale(1.8); transform-origin: left center; margin-right: 18px; }
.stage__statement { padding: clamp(20px, 2vw, 40px) clamp(24px, 2.4vw, 48px); border-left: 8px solid var(--accent); border-radius: var(--radius-lg); background: var(--surface-solid); }
.stage__statement--final { border-left-width: 12px; }
.stage__version { margin: 0 0 8px; font-size: clamp(1rem, 1.3vw, 1.625rem); font-weight: var(--fw-bold); text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); }
.stage__text { margin: 0; font-size: clamp(1.625rem, 2.35vw, 3rem); line-height: 1.3; overflow-wrap: anywhere; }
.stage__text--long { font-size: clamp(1.375rem, 1.85vw, 2.375rem); }
.stage__text--longer { font-size: clamp(1.25rem, 1.6vw, 2rem); }
.stage__row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 24px clamp(32px, 4vw, 80px); }
.stage__row > * { flex: 1 1 360px; min-width: 0; }
.stage__counter--compact .stage__count b { font-size: clamp(2.5rem, 4vw, 5rem); }
.stage__counter--compact .stage__count { font-size: clamp(1.25rem, 1.9vw, 2.375rem); }
.stage__how--small { font-size: clamp(1rem, 1.35vw, 1.75rem); }
.stage__changed { margin: 0; font-size: clamp(1.25rem, 1.8vw, 2.25rem); line-height: 1.3; }
.stage__meter { display: flex; flex-direction: column; gap: 14px; }
.stage__meterline { margin: 0; font-size: clamp(1.75rem, 2.8vw, 3.5rem); line-height: 1.1; }
.stage__meterline b { font-weight: var(--fw-bold); }
.stage__meterbar { display: block; height: clamp(20px, 2vw, 40px); border-radius: var(--radius-pill); background: color-mix(in srgb, var(--text-muted) 22%, transparent); overflow: hidden; }
.stage__meter--small .stage__meterline { font-size: clamp(1.125rem, 1.6vw, 2rem); color: var(--text-muted); }
.stage__meter--small .stage__meterbar { height: 12px; max-width: 900px; }
.stage__meter--small .stage__meterbar > span { background: var(--text-muted); }
.stage__meterlabel { font-weight: var(--fw-semibold); }
.stage__private { display: flex; align-items: center; gap: 12px; margin: 0; font-size: clamp(1.25rem, 1.8vw, 2.25rem); color: var(--text-muted); }
.stage__wall { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 290px), 1fr)); gap: 12px; margin: 0; padding: 0; list-style: none; }
.stage__wall li { padding: 12px 18px; border: 1px solid var(--hairline); border-radius: var(--radius-lg); background: var(--surface-solid); font-size: clamp(1.125rem, 1.4vw, 1.75rem); font-weight: var(--fw-semibold); line-height: 1.2; overflow-wrap: anywhere; }
.stage__wall li.stage__more { border-style: dashed; background: transparent; color: var(--text-muted); }
.stage__wall li:first-child { border-color: var(--accent); }
.stage__wall--dim { opacity: 0.45; }
.stage__bars { display: flex; flex-direction: column; gap: clamp(12px, 1.2vw, 24px); margin: 0; padding: 0; list-style: none; }
.stage__bar { display: flex; flex-direction: column; gap: 8px; }
.stage__barhead { display: flex; align-items: baseline; gap: 24px; margin: 0; font-size: clamp(1.375rem, 2vw, 2.5rem); font-weight: var(--fw-semibold); line-height: 1.15; }
.stage__barlabel { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.stage__barcount { flex: none; font-weight: var(--fw-bold); font-variant-numeric: tabular-nums; }
.stage__barmeta { font-size: 0.6em; font-weight: var(--fw-regular, 400); color: var(--text-muted); white-space: nowrap; }
.stage__track { display: block; height: clamp(14px, 1.3vw, 26px); border-radius: var(--radius-pill); background: color-mix(in srgb, var(--text-muted) 18%, transparent); overflow: hidden; }
.stage__track > span { background: var(--text-muted); }
.stage__bar--lead .stage__track > span { background: var(--accent); }
.stage__bar--lead .stage__barlabel, .stage__bar--lead .stage__barcount { color: var(--accent); }
.stage__steps { display: flex; flex-direction: column; gap: 14px; margin: 0; padding: 0; list-style: none; counter-reset: sstep; }
.stage__steps li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 24px; padding: 16px 24px; border-radius: var(--radius-lg); background: var(--surface-solid); counter-increment: sstep; }
.stage__steptext { flex: 1; min-width: 0; font-size: clamp(1.375rem, 2vw, 2.5rem); line-height: 1.2; }
.stage__steptext::before { content: counter(sstep) ". "; font-weight: var(--fw-bold); color: var(--text-muted); }
.stage__stepowner { font-size: clamp(1.125rem, 1.6vw, 2rem); font-weight: var(--fw-semibold); color: var(--text-muted); }
.stage__step--taken .stage__stepowner { color: var(--accent); }
.stage__toggle[hidden] { display: none; }
@media (max-width: 899px) { .stage { top: var(--present-top, 156px); left: 0; } }

/* ---- Introductions (views/intros.js) --------------------------------------------------------------------------------
   The join page's "Help the robot introduce you", the About you stack it shares with the profile sheet, what the robot
   took from it, the owner's Introduce everyone, and the note's match cards. All on the sheet fill; only the robot's own
   words are manila. */
.join__profile { margin: 0 0 var(--space-4); border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--page-bg); }
.join__profile-sum { display: flex; align-items: center; gap: var(--space-2); min-height: var(--hit); padding: 10px 14px; cursor: pointer; list-style: none; font-size: var(--fs-subhead); font-weight: var(--fw-semibold); color: var(--link); }
.join__profile-sum::-webkit-details-marker { display: none; }
.join__profile-sum::after { content: ''; width: 8px; height: 8px; margin-left: auto; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg) translateY(-2px); transition: transform 0.15s; }
.join__profile[open] .join__profile-sum::after { transform: rotate(-135deg) translateY(-2px); }
.join__profile-title { min-width: 0; }
.join__profile-opt { font-weight: var(--fw-regular); color: var(--text-muted); font-size: var(--fs-footnote); }
.join__profile-lede { margin: 0 14px var(--space-3); font-size: var(--fs-footnote); color: var(--text-muted); }
.join__profile .pstack { padding: 0 14px 14px; }
.join__profile-sum:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; border-radius: var(--radius-md); }

.pstack { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.pstack__list { display: flex; flex-direction: column; gap: var(--space-2); margin: 0; padding: 0; list-style: none; }
.pstack__list[hidden] { display: none; }
.pitem { display: flex; align-items: flex-start; gap: var(--space-3); padding: 10px 6px 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--sheet-bg); min-width: 0; }
.pitem--failed, .pitem--unsent { border-color: color-mix(in srgb, var(--danger) 45%, var(--border)); }
.pitem__glyph { display: inline-grid; flex: none; padding-top: 2px; color: var(--link); }
.pitem__main { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.pitem__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-subhead); font-weight: var(--fw-semibold); color: var(--text); }
.pitem__status { display: flex; align-items: center; gap: 6px; font-size: var(--fs-footnote); color: var(--text-muted); }
.pitem__status .spinner { width: 14px; height: 14px; }
.pitem__ok { display: inline-grid; color: var(--link); }
.pitem--failed .pitem__status, .pitem--unsent .pitem__status { color: var(--danger); font-weight: var(--fw-semibold); }
.pitem__note { font-size: var(--fs-footnote); color: var(--text); overflow-wrap: anywhere; }
.pitem__retry { align-self: flex-start; margin-top: 2px; padding: 0 8px; }
.pitem__remove { flex: none; margin: -6px 0; color: var(--text-muted); }
.pstack__adds { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.pstack__adds[hidden] { display: none; }
.pstack__plus { gap: 4px; padding: 0 12px; cursor: pointer; }
.pstack__plus .icon { width: 18px; height: 18px; }
.pstack__file { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.pstack__adds:has(+ * + .pstack__file:focus-visible) .pstack__plus:first-child, .pstack__file:focus-visible { outline: 2px solid var(--focus-ring); }
.pstack__hint { margin-top: calc(-1 * var(--space-1)); }
.pstack__panel { display: flex; flex-direction: column; gap: 6px; }
.pstack__panel[hidden] { display: none; }
.pstack__inline { display: flex; gap: var(--space-2); align-items: center; min-width: 0; }
.pstack__inline .field__input { flex: 1; min-width: 0; }
.pstack__inline--end { justify-content: flex-end; }
.pstack__inline .btn { flex: none; height: 44px; }
.pstack__text { resize: vertical; min-height: 84px; }
.pstack__linkedin { margin-top: 4px; padding: var(--space-3); border-radius: var(--radius-md); background: var(--sheet-bg); border: 1px solid var(--border); font-size: var(--fs-subhead); }
.pstack__linkedin[hidden] { display: none; }
.pstack__lirow { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.pstack__problem { font-size: var(--fs-subhead); color: var(--danger); }
.pstack__consent { display: flex; align-items: flex-start; gap: 6px; font-size: var(--fs-footnote); color: var(--text-muted); }
.pstack__lock { display: inline-grid; flex: none; padding-top: 2px; }
.kept { display: flex; flex-direction: column; gap: 6px; padding: var(--space-3); border-radius: var(--radius-md); background: var(--page-bg); }
.kept__title { display: flex; align-items: center; gap: 6px; font-size: var(--fs-footnote); font-weight: var(--fw-semibold); color: var(--text-muted); text-transform: none; }
.kept__title .spinner { width: 14px; height: 14px; }
.kept__text { font-size: var(--fs-subhead); color: var(--text); overflow-wrap: anywhere; }
.kept__from, .kept__fix { font-size: var(--fs-footnote); color: var(--text-muted); overflow-wrap: anywhere; }

.profile-status__glyph { display: inline-grid; flex: none; color: var(--link); }
.intros-section { display: flex; flex-direction: column; gap: var(--space-4); margin-top: var(--space-5); padding-top: var(--space-4); border-top: 1px solid var(--hairline); }
.intros-section__title { margin: 0 0 var(--space-2); font-size: var(--fs-subhead); font-weight: var(--fw-semibold); color: var(--text); }
.intros-section__line { display: flex; align-items: center; gap: 6px; margin-bottom: var(--space-3); font-size: var(--fs-subhead); color: var(--text-muted); }
.intros-section__line .spinner { width: 16px; height: 16px; }
.intros-section__row { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.intros-section__row .btn .icon { width: 18px; height: 18px; }
.intros-owner { display: flex; flex-direction: column; gap: var(--space-3); }
.intros-owner__lead, .intros-owner__hint, .intros-owner__skipped { font-size: var(--fs-footnote); color: var(--text-muted); }
.intros-owner__status { display: flex; flex-direction: column; gap: 6px; font-size: var(--fs-subhead); }
.intros-owner__status:empty { display: none; }
.intros-owner__busy { display: flex; align-items: center; gap: var(--space-2); }
.intros-owner__done { display: flex; align-items: flex-start; gap: 6px; font-weight: var(--fw-semibold); }
.intros-owner__failed { color: var(--danger); }
.intros-owner__go .icon { width: 20px; height: 20px; }
.intros-owner__confirm p { margin-bottom: var(--space-3); font-size: var(--fs-subhead); }
.intros-owner__choices { flex-wrap: wrap; }

.member-row__wants { font-size: var(--fs-footnote); color: var(--text-muted); overflow-wrap: anywhere; }
.profile-sheet__stacktitle { margin-top: var(--space-2); }
.profile-sheet__remove { margin-top: var(--space-4); }

/* The note's matches: who, how strong (a small label), why. */
.icards { display: flex; flex-direction: column; gap: var(--space-3); }
.icards__head { font-weight: var(--fw-semibold); }
.icard { display: flex; flex-direction: column; gap: 2px; }
.icard__top { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
/* Text 6:1 (light) and 8.9:1 (dark) on the manila; the outline in the robot's name colour shows at 3:1 or more, where
   the old border colour was 1.4:1 and the Good chip all but vanished. Strong is filled, Good outlined, a hello dashed. */
.icard__strength { display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border-radius: var(--radius-pill); font-size: var(--fs-caption); font-weight: var(--fw-semibold); border: 1.5px solid var(--robot-name); color: var(--robot-name); background: transparent; }
.icard__strength--strong { background: var(--robot-name); color: var(--robot-bg); }
.icard__strength--hello { border-style: dashed; }
.icard__name { padding: 0; border: 0; background: none; color: inherit; font: inherit; font-weight: var(--fw-semibold); text-align: left; text-decoration: underline; text-decoration-color: color-mix(in srgb, currentColor 35%, transparent); text-underline-offset: 3px; cursor: pointer; min-height: 32px; }
.icard__intro { font-size: var(--fs-footnote); color: var(--robot-name); }
.icard__more { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; margin-top: 4px; padding: 8px 10px; border-radius: var(--radius-sm); background: color-mix(in srgb, var(--robot-border) 40%, var(--robot-bg)); }
.icard__more[hidden] { display: none; }
.icard__line { font-size: var(--fs-footnote); }
.icard__k { font-weight: var(--fw-semibold); }
.pitem__choices { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.pitem--choose { border-color: var(--link); }
.pitem--choose .pitem__status { color: var(--link); font-weight: var(--fw-semibold); }
.intros-section__line--problem { color: var(--danger); }
.intros-owner__time { font-variant-numeric: tabular-nums; }
.intros-owner__retry { align-self: flex-start; }
/* ---- Intro chats (views/introchats.js) --------------------------------------------------------------------------
   The dial: one row of three plain choices, wrapping its words rather than the row, with what the picked one does
   under it. Start a chat sits under each match's why; the request and opened-chat cards are the private bubble. */
.dial { display: flex; gap: 3px; padding: 3px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--page-bg); }
.dial__opt { flex: 1 1 0; min-width: 0; min-height: var(--hit); padding: 6px 6px; border: 0; border-radius: 9px; background: transparent; color: var(--text-muted); font-size: var(--fs-footnote); font-weight: var(--fw-semibold); line-height: var(--lh-tight); text-align: center; cursor: pointer; }
.dial__opt--on { background: var(--sheet-bg); color: var(--text); box-shadow: var(--elev-1); }
.dial__opt:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
.icard__chat { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin-top: 6px; }
.icard__chat .btn { min-height: 36px; }
/* A link styled as a button inside the robot's bubble keeps the button's colour, not the bubble's link colour. */
.bubble--robot .bubble__body a.btn { text-decoration: none; }
.bubble--robot .bubble__body a.btn--secondary { color: var(--link); }
.room-header__code[hidden] { display: none; }
.icard__chat .btn .icon { width: 18px; height: 18px; }
.icard__chat .btn .spinner { width: 16px; height: 16px; }
.icard__asked { display: inline-flex; align-items: center; gap: 4px; height: 28px; padding: 0 10px; border-radius: var(--radius-pill); background: color-mix(in srgb, var(--robot-border) 55%, var(--robot-bg)); color: var(--robot-name); font-size: var(--fs-footnote); font-weight: var(--fw-semibold); }
.icard__asked .icon { width: 16px; height: 16px; }
.icard__chatnote { flex: 1 1 12em; font-size: var(--fs-footnote); line-height: var(--lh-tight); color: var(--robot-meta); }
.introchat { display: flex; flex-direction: column; gap: 4px; }
.introchat__title { font-weight: var(--fw-semibold); }
.introchat__k { font-weight: var(--fw-semibold); }
.introchat__hint { font-size: var(--fs-footnote); color: var(--robot-meta); }
.introchats-group__chats { margin-top: var(--space-2); }
.introchats-group__list { display: flex; flex-direction: column; gap: 6px; margin: 0; padding: 0; list-style: none; }
.introchats-group__chat { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); min-height: var(--hit); padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--radius-md); color: var(--text); text-decoration: none; font-weight: var(--fw-medium); }
.introchats-group__chev { display: inline-grid; color: var(--text-muted); }
.introchats-group .dial-field { margin-bottom: 0; }
/* The owner's Introduce everyone chip is theirs: never on the projector the room watches. */
.room--presenter .choice-chip[data-action="introduce"] { display: none; }

/* ---- Room options: the Robot group in Settings, the style picker, join questions (views/robot-options.js) ---- */
.robot-sub { padding: var(--space-3) 0; border-bottom: 1px solid var(--hairline); }
.robot-sub__title { margin: 0 0 var(--space-2); font-size: var(--fs-subhead); font-weight: var(--fw-semibold); color: var(--text); }
.robot-sub__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.robot-sub__nested { margin-top: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); }
.robot-sub .settings-row:last-child { border-bottom: 0; }
.robot-style { display: flex; align-items: center; gap: var(--space-3); padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--radius-md); }
.robot-style__main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.robot-style__name { font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--text); }
.robot-style__line { font-size: var(--fs-footnote); color: var(--text-muted); }
.style-preview { margin-top: var(--space-2); font-size: var(--fs-footnote); color: var(--text-muted); }
.style-preview summary { display: inline-flex; align-items: center; min-height: var(--hit); cursor: pointer; color: var(--robot-link); font-weight: var(--fw-semibold); }
.style-preview summary:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; border-radius: 4px; }
.style-preview__text { margin: 0; padding: var(--space-3); border-radius: var(--radius-md); background: var(--quote-in-bg); color: var(--text); font-size: var(--fs-subhead); line-height: var(--lh-read); overflow-wrap: anywhere; }
.option-item { display: flex; flex-direction: column; }
.option-item .style-preview { margin: 0 0 var(--space-1) 44px; }
.style-sheet__lead { margin: 0 0 var(--space-3); font-size: var(--fs-subhead); color: var(--text-muted); }
.style-sheet__words { margin-top: var(--space-4); }
.style-sheet .notify-level[disabled], .robot-options .notify-level[disabled] { opacity: 0.5; }
.jq-list { display: flex; flex-direction: column; gap: 6px; margin: 0; padding: 0; list-style: none; }
.jq-item { display: flex; align-items: center; gap: var(--space-2); padding: 6px 4px 6px 12px; border: 1px solid var(--border); border-radius: var(--radius-md); }
.jq-item__main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.jq-item__prompt { font-size: var(--fs-subhead); color: var(--text); overflow-wrap: anywhere; }
.jq-item__who { font-size: var(--fs-caption); color: var(--text-muted); }
.jq-item__remove { flex: none; }
.jq-sub { border-bottom: 0; }

/* ---- Settings (views/settings.js): a menu that fits one phone screen, and pages that open inside the same sheet ---- */
/* One height for every page, so going in and back never makes the sheet jump. */
.sheet.settings-sheet { height: 90%; }
.settings-me { display: flex; align-items: center; gap: var(--space-3); width: 100%; padding: var(--space-2) 0 var(--space-4); border: 0; border-bottom: 1px solid var(--hairline); background: transparent; color: var(--text); text-align: left; }
.settings-me:focus-visible, .settings-nav:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; border-radius: var(--radius-md); }
.settings-me__main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.settings-me__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-title3); font-weight: var(--fw-semibold); line-height: var(--lh-tight); }
.settings-me__desc { font-size: var(--fs-footnote); color: var(--text-muted); }
.settings-notify { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-4) 0; border-bottom: 1px solid var(--hairline); }
.settings-notify__head { display: flex; align-items: center; gap: var(--space-3); }
.settings-notify__desc { font-size: var(--fs-footnote); color: var(--text-muted); }
.settings-nav__label { flex: 1; min-width: 0; }
.settings-nav__value { flex: none; max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-subhead); color: var(--text-muted); }
.settings-row__mark { width: 24px; height: 24px; }
.settings-list > :last-child { border-bottom: 0; }
.settings-group--end { display: flex; flex-direction: column; margin: 0; padding-top: var(--space-1); border-top: 1px solid var(--hairline); }
.settings-group--end .settings-row { border-bottom: 0; }
.settings-end-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); column-gap: var(--space-3); }
.settings-end-pair .settings-row { gap: var(--space-2); }
.settings-end-pair .settings-row__chev { display: none; }
/* Leave lines up with the labels above it, not centred under them. */
.settings-group--end .settings-leave > .btn--ghost { justify-content: flex-start; padding-left: 36px; }
/* Leave, then Privacy and Terms on the same line; the Leave question takes the whole line once it opens. */
.settings-end-row { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--space-4); }
.settings-end-row > .settings-leave { flex: 1 1 auto; min-width: 0; }
.settings-end-row > .settings-leave:has(.settings-leave__q) { flex-basis: 100%; }
.settings-legal { flex: none; display: flex; gap: var(--space-4); margin: 0; font-size: var(--fs-footnote); }
.settings-legal a { display: inline-flex; align-items: center; min-height: 44px; color: var(--text-muted); }
.settings-you { display: flex; align-items: center; gap: var(--space-4); margin-bottom: var(--space-5); }
.settings-you__face { position: relative; display: grid; flex: none; padding: 0; border: 0; border-radius: 50%; background: transparent; }
.settings-you__face:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.settings-you__edit { position: absolute; right: -4px; bottom: -4px; display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--sheet-bg); background: var(--accent); color: var(--accent-text); }
.settings-you__hint { margin: 0; font-size: var(--fs-footnote); color: var(--text-muted); }
.settings-you__name .settings-inline .field__input { flex: 1; min-width: 0; }
.settings-page .settings-code { margin-top: var(--space-4); }
/* A segmented choice whose labels may take two lines (When the robot joins in). */
.segmented--wrap .segmented__opt { height: auto; min-height: 44px; padding: 6px 8px; text-align: center; line-height: var(--lh-tight); }
.choice-seg__hint { margin-top: var(--space-2); min-height: 2.6em; }
.share-sheet__screen { margin-top: var(--space-2); gap: var(--space-2); }

/* How the robot acts: the type's styles as cards. The sample line is the robot speaking, so it sits on manila. */
.robot-acts { padding-bottom: var(--space-5); }
.robot-acts > .robot-sub__title { margin-bottom: var(--space-3); }
.style-cards { display: flex; flex-direction: column; gap: var(--space-2); }
.style-card { display: flex; flex-direction: column; align-items: stretch; gap: 4px; width: 100%; padding: var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-md); background: transparent; color: var(--text); text-align: left; font: inherit; }
button.style-card { cursor: pointer; }
button.style-card:not(.style-card--on):hover { border-color: var(--text-muted); }
.style-card:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.style-card--on { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.style-card--busy { opacity: 0.6; }
.style-card[disabled]:not(.style-card--busy) { opacity: 1; }
.style-card__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.style-card__name { font-size: var(--fs-body); font-weight: var(--fw-semibold); }
.style-card__tag { display: inline-flex; align-items: center; gap: 2px; flex: none; color: var(--accent); font-size: var(--fs-footnote); font-weight: var(--fw-semibold); }
.style-card__check { display: grid; }
.style-card__line { font-size: var(--fs-footnote); color: var(--text-muted); }
.style-card__says { align-self: flex-start; max-width: 100%; margin-top: var(--space-1); padding: 6px 10px; border: 1px solid var(--robot-border); border-radius: var(--radius-xs) var(--radius-md) var(--radius-md) var(--radius-md); background: var(--robot-bg); color: var(--robot-text); font-size: var(--fs-subhead); line-height: var(--lh-body); overflow-wrap: anywhere; }
.robot-acts .style-preview { margin-top: var(--space-2); }

/* The Robot sheet (views/robot-card.js): a tap on the robot's tag or face on a message, or its row in the members
   sheet. Headings and short lines so it scans; each tool row carries On, Off or Links only in words, never colour alone. */
button.robot-tag { padding: 4px 6px; margin: -3px 10px -1px -6px; border: 0; border-radius: var(--radius-sm); background: none; font: inherit; font-size: var(--fs-footnote); font-weight: var(--fw-semibold); line-height: var(--lh-tight); cursor: pointer; }
button.robot-tag:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 0; }
button.msg-face { padding: 0; font: inherit; cursor: pointer; }
button.msg-face:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.member-row__open { display: flex; flex: 1; align-items: center; gap: var(--space-3); min-width: 0; padding: 0; border: 0; border-radius: var(--radius-sm); background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.member-row__open:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.member-row__chev { display: grid; flex: none; color: var(--text-muted); }
.robot-about .robot-sub__title { margin: var(--space-3) 0 var(--space-0); }
.robot-about .robot-sub__title:first-child { margin-top: var(--space-1); }
.robot-about__style { font-weight: var(--fw-semibold); }
.robot-about__p { margin: 0; font-size: var(--fs-subhead); line-height: var(--lh-body); overflow-wrap: anywhere; }
.robot-can { margin: 0; padding: 0; list-style: none; }
.robot-can__row { display: flex; align-items: center; gap: var(--space-3); min-height: 36px; padding: 3px 0; }
.robot-can__row + .robot-can__row { border-top: 1px solid var(--hairline); }
.robot-can__glyph { display: grid; flex: none; color: var(--text); }
.robot-can__main { display: flex; flex: 1; flex-direction: column; gap: 1px; min-width: 0; }
.robot-can__label { font-size: var(--fs-subhead); }
.robot-can__note { font-size: var(--fs-footnote); color: var(--text-muted); overflow-wrap: anywhere; }
.robot-can__state { flex: none; font-size: var(--fs-footnote); font-weight: var(--fw-semibold); }
.robot-can__row:not([data-state="on"]) .robot-can__label, .robot-can__row:not([data-state="on"]) .robot-can__glyph, .robot-can__row:not([data-state="on"]) .robot-can__state { color: var(--text-muted); }
.robot-about__why, .robot-about__owners { margin: var(--space-2) 0 0; font-size: var(--fs-footnote); color: var(--text-muted); }
.robot-about__owners { margin-top: var(--space-4); }
.robot-about .sheet__actions { margin-top: var(--space-4); }
/* On a desktop the settings dialog is wider and the styles sit two to a row, so the choice reads at a glance. */
@media (min-width: 900px) {
  .sheet.settings-sheet { max-width: 640px; height: min(760px, 90%); max-height: min(760px, 90%); }
  .style-cards { display: grid; grid-template-columns: 1fr 1fr; align-items: stretch; }
}

/* The room type hint: one line, Switch, and a close button. */
.type-hint { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-3); padding: var(--space-2) var(--space-1) var(--space-2) var(--space-3); border-radius: var(--radius-md); background: var(--accent-soft); }
.type-hint__glyph { display: grid; flex: none; color: var(--accent); }
.type-hint__text { flex: 1; min-width: 0; margin: 0; font-size: var(--fs-subhead); }
.type-hint .btn { flex: none; }
.type-hint__close { flex: none; }

/* Add your own words and More robot settings: disclosures in the robot group. */
.robot-disclosure { border-top: 1px solid var(--hairline); }
.robot-disclosure__summary { display: flex; align-items: center; gap: var(--space-2); min-height: var(--hit); padding: var(--space-2) 0; cursor: pointer; list-style: none; font-size: var(--fs-body); font-weight: var(--fw-medium); }
.robot-disclosure__summary::-webkit-details-marker { display: none; }
.robot-disclosure__summary::after { content: ""; width: 8px; height: 8px; margin-left: auto; margin-right: 4px; border-right: 2px solid var(--text-muted); border-bottom: 2px solid var(--text-muted); transform: rotate(45deg); transition: transform var(--dur-1) var(--ease-out); }
.robot-disclosure[open] > .robot-disclosure__summary::after { transform: rotate(-135deg); }
.robot-disclosure__summary:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; border-radius: 4px; }
.robot-disclosure__body { padding-bottom: var(--space-3); }
.robot-disclosure__value { margin-left: auto; font-size: var(--fs-subhead); font-weight: var(--fw-regular, 400); color: var(--text-muted); }
.robot-disclosure__summary:has(.robot-disclosure__value)::after { margin-left: var(--space-2); }
.robot-disclosure__body > .robot-sub:last-child { border-bottom: 0; }
.robot-words .settings-row { border-bottom: 0; }
.member-row__answer { font-size: var(--fs-footnote); color: var(--text); overflow-wrap: anywhere; }
.member-row__q, .member-row__only { color: var(--text-muted); }
.join__questions { display: flex; flex-direction: column; gap: var(--space-4); }
.join__chips { margin: 2px 0 2px -2px; }
.join__chips .choice-chip[aria-checked="true"]::before { border-color: var(--accent); background: var(--accent-soft); }
.setup__change { display: inline-flex; align-items: center; min-height: var(--hit); margin: -12px 0; padding: 0 4px; border: 0; background: transparent; color: var(--robot-link); font: inherit; font-weight: var(--fw-semibold); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.setup__change:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; border-radius: 4px; }
.heat__ask { margin: var(--space-3) 0 0; font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--text); }
.agreement__terms { margin: 0; padding: 8px 10px 8px 30px; border-left: 3px solid var(--robot-fold); border-radius: 6px; background: var(--sheet-bg); color: var(--text); line-height: var(--lh-read); }
.agreement__terms li { overflow-wrap: anywhere; }
.agreement__terms li + li { margin-top: 4px; }

/* Pull to refresh (views/pull.js): a round chip with the robot mark comes down with the finger, turns once at the
   point a lift refreshes, spins while it works and widens to say "Up to date". Touch only. */
.pull { position: fixed; z-index: 45; display: flex; align-items: center; gap: var(--space-2); height: 40px; min-width: 40px; padding: 0 9px;
  border: 1px solid var(--robot-border); border-radius: var(--radius-pill); background: var(--robot-bg); color: var(--robot-text);
  box-shadow: var(--elev-2); opacity: 0; pointer-events: none; transform: translate(-50%, 0); white-space: nowrap; }
.pull__mark { display: inline-grid; color: var(--robot-name); }
.pull__mark .mark__fold { fill: var(--robot-fold); }
.pull__label { font-size: var(--fs-footnote); font-weight: var(--fw-semibold); }
.pull__label:empty { display: none; }
.pull--done .pull__label { padding-right: 4px; }
.pull--busy .pull__mark { animation: pull-spin 0.9s linear infinite; }
@keyframes pull-spin { to { rotate: 360deg; } }
@media (prefers-reduced-motion: reduce) { .pull--busy .pull__mark { animation: none; opacity: 0.6; } }

/* New version (update.js): a calm pill under the header when a newer build is ready but a reload now would drop
   something in progress. One tap reloads. Sheets cover it. */
.update-pill { position: fixed; top: calc(env(safe-area-inset-top) + 64px); left: 50%; z-index: 30; transform: translateX(-50%);
  display: flex; align-items: center; gap: var(--space-2); min-height: 36px; padding: 0 14px; border: 1px solid var(--hairline);
  border-radius: var(--radius-pill); background: var(--sheet-bg); color: var(--text); box-shadow: var(--elev-2);
  font: inherit; font-size: var(--fs-footnote); white-space: nowrap; cursor: pointer; }
.update-pill__go { font-weight: var(--fw-semibold); color: var(--accent); }
.update-pill__go::before { content: '·'; margin-right: var(--space-2); color: var(--text-muted); font-weight: normal; }
body:has([aria-modal="true"]) .update-pill { display: none; }

/* ---------- Avatars (views/avatars.js, avatars.js) ----------
   A character fills the same circle the initials use; the initials stay underneath, so a picture that fails to load
   leaves them showing. The robot keeps its mark and rooms keep their initials. */
.avatar--pic { position: relative; overflow: hidden; background: var(--sheet-bg); }
.avatar__img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; border-radius: 50%; }
.avatar--lg { --avatar: 44px; font-size: var(--fs-subhead); }
.avatar--xl { --avatar: 56px; font-size: var(--fs-body); }

/* Faces in the room: incoming rows get a column for the sender's face, drawn at the foot of the last bubble of each
   run, so every bubble of a run lines up beside it (Telegram's group layout). Your own messages carry none. */
.msg-list { --face: 28px; }
.msg-list .msg-row--in, .msg-list .msg-row--robot { display: grid; grid-template-columns: var(--face) minmax(0, 1fr); column-gap: 6px; justify-items: start; }
.msg-list .msg-row--in > *, .msg-list .msg-row--robot > * { grid-column: 2; }
.msg-list .msg-row > .msg-face { grid-column: 1; grid-row: 1; align-self: end; --avatar: var(--face); font-size: var(--fs-caption); }
.msg-face.avatar--robot svg { width: 18px; height: 18px; }

/* The picker: one grid per style, then your initials. The one you have now is ringed and checked. */
.avatar-sheet__lede { margin-bottom: var(--space-4); font-size: var(--fs-subhead); color: var(--text-muted); }
.avatar-sheet__group + .avatar-sheet__group { margin-top: var(--space-5); }
.avatar-sheet__style { margin-bottom: var(--space-2); font-size: var(--fs-footnote); font-weight: var(--fw-semibold); color: var(--text-muted); }
.avatar-sheet__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); gap: var(--space-1); }
.avatar-tile { position: relative; display: grid; place-items: center; height: 72px; padding: 0; border: 0; border-radius: var(--radius-md); background: none; color: inherit; cursor: pointer; }
@media (hover: hover) { .avatar-tile:hover { background: var(--hairline); } }
.avatar-tile:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.avatar-tile--on .avatar { box-shadow: 0 0 0 2px var(--sheet-bg), 0 0 0 4px var(--focus-ring); }
.avatar-tile__check { position: absolute; right: calc(50% - 34px); bottom: 2px; display: grid; place-items: center; width: 22px; height: 22px; border: 2px solid var(--sheet-bg); border-radius: 50%; background: var(--accent); color: var(--accent-text); }
.avatar-tile__check .icon { width: 14px; height: 14px; }

/* The join page: your character above your name, and the way in for a device that is already in this room. */
.join__face { display: flex; align-items: center; gap: var(--space-3); width: 100%; margin: 0 0 var(--space-4); padding: 6px 12px 6px 6px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--page-bg); color: var(--text); font: inherit; text-align: left; cursor: pointer; }
.join__face:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.join__face-pic { display: grid; flex: none; }
.join__face-text { display: flex; flex-direction: column; min-width: 0; }
.join__face-label { font-size: var(--fs-subhead); font-weight: var(--fw-semibold); }
.join__face-hint { font-size: var(--fs-footnote); color: var(--link); }
.join__device { margin-top: var(--space-4); font-size: var(--fs-footnote); line-height: var(--lh-body); color: var(--text-muted); }
.join__device button { display: inline-block; padding: 6px 0; border: 0; background: transparent; color: var(--link); text-align: left; }
.link-page__back { margin-top: var(--space-3); }

/* Settings: your character beside its row text. The About you sheet's one line in rooms without introductions. */
.settings-row__face { display: grid; flex: none; }
.profile-sheet__lede { margin-bottom: var(--space-3); font-size: var(--fs-subhead); color: var(--text-muted); }

/* "Tell the robot who you are" (views/profile-nudge.js): one card above the composer, the robot's mark, Add, close. The
   co-owner line (views/coowner-nudge.js) has the same shape under its own classes. */
.profile-nudge, .coowner-nudge { display: flex; align-items: center; gap: var(--space-3); margin: 0 auto var(--space-2); padding: 8px 4px 8px 12px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--sheet-bg); box-shadow: var(--elev-1); }
.profile-nudge[hidden], .coowner-nudge[hidden] { display: none; }
.profile-nudge__mark, .coowner-nudge__mark { display: grid; flex: none; color: var(--text); }
.profile-nudge__mark .mark__fold, .coowner-nudge__mark .mark__fold { fill: var(--robot-fold); }
.profile-nudge__main, .coowner-nudge__main { flex: 1; min-width: 0; }
.profile-nudge__title, .coowner-nudge__title { font-size: var(--fs-subhead); font-weight: var(--fw-semibold); line-height: var(--lh-tight); }
.profile-nudge__text, .coowner-nudge__text { margin-top: 2px; font-size: var(--fs-footnote); line-height: var(--lh-body); color: var(--text-muted); }
.profile-nudge__add, .coowner-nudge__add { flex: none; }
.profile-nudge__close, .coowner-nudge__close { flex: none; width: 36px; height: 36px; color: var(--text-muted); }
@media (pointer: coarse) { .profile-nudge__close, .coowner-nudge__close { width: var(--hit); height: var(--hit); } }
.profile-nudge:not([hidden]), .coowner-nudge:not([hidden]) { transition: opacity var(--dur-2) linear, transform var(--spring-snap-dur) var(--spring-snap); }
@starting-style { .profile-nudge:not([hidden]), .coowner-nudge:not([hidden]) { opacity: 0; transform: translateY(6px); } }
/* The guest's "Start your own AI group chat" card as the first row of the phone's room list. */
.rail__creator { padding: var(--space-2) 0 var(--space-1); }
.rail__creator .profile-nudge { margin: 0; }

/* Touch screens get a 44px hit area on the small pills without changing how they look (HIG: 44x44 pt hit regions,
   design review 2026-10-06): an invisible layer above and below each one takes the tap. */
@media (pointer: coarse) {
  .robot-aim__opt, .robot-aim__chip { position: relative; }
  .robot-aim__opt::after { content: ''; position: absolute; inset: -6px 0; }
  .robot-aim__chip::after { content: ''; position: absolute; inset: -4px 0; }
  .room-header__code::after { content: ''; position: absolute; inset: -5px 0; }
  .robot-aim__close, .composer__format { width: var(--hit); height: var(--hit); }
}

/* ---- Files (views/files.js): everything shared to the room, by day. Chips and search stay put; the list scrolls under them. ---- */
.sheet.files-sheet { height: 90%; }
.files-sheet .sheet__body { display: flex; flex-direction: column; overflow: hidden; padding-bottom: 0; }
.files { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.files-top { flex: none; padding-bottom: var(--space-3); border-bottom: 1px solid var(--hairline); }
.files-chips { display: flex; gap: var(--space-2); margin: 0 calc(-1 * var(--space-4)) var(--space-3); padding: 2px var(--space-4); overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.files-chips::-webkit-scrollbar { display: none; }
.files-chip { flex: none; min-height: 36px; padding: 0 14px; border: 1px solid var(--border); border-radius: var(--radius-pill); background: transparent; color: var(--text); font-size: var(--fs-subhead); font-weight: var(--fw-medium); white-space: nowrap; }
.files-chip[aria-selected="true"] { border-color: var(--accent); background: var(--accent); color: var(--accent-text); font-weight: var(--fw-semibold); }
.files-chip:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.files-scroll { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding-bottom: calc(var(--space-5) + env(safe-area-inset-bottom)); }
.files-count { min-height: 1.2em; margin: var(--space-3) 0 0; font-size: var(--fs-footnote); color: var(--text-muted); }
.files-day { padding-bottom: var(--space-3); }
.files-day__label { position: sticky; top: 0; z-index: 1; margin: 0; padding: var(--space-3) 0 var(--space-2); background: var(--sheet-bg); font-size: var(--fs-footnote); font-weight: var(--fw-semibold); color: var(--text-muted); }
.files-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 3px; }
@media (min-width: 600px) { .files-grid { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); } }
.files-tile { position: relative; display: block; aspect-ratio: 1; min-width: 0; padding: 0; border: 0; border-radius: var(--radius-xs); overflow: hidden; background: var(--skeleton-base); color: var(--text); cursor: zoom-in; }
.files-tile img { display: block; width: 100%; height: 100%; object-fit: cover; }
.files-tile:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; }
.files-tile--video { display: grid; place-items: center; background: var(--quote-in-bg); cursor: pointer; }
.files-tile__play { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; background: var(--sheet-bg); color: var(--text); box-shadow: var(--elev-1); }
.files-tile__dur { position: absolute; right: 6px; bottom: 6px; padding: 1px 6px; border-radius: var(--radius-xs); background: var(--sheet-bg); font-size: var(--fs-caption); font-weight: var(--fw-medium); }
.files-grid + .files-rows { margin-top: var(--space-2); }
.files-row { display: flex; align-items: center; gap: var(--space-1); border-bottom: 1px solid var(--hairline); }
.files-row:last-child { border-bottom: 0; }
.files-row__main { display: flex; flex: 1; align-items: center; gap: var(--space-3); min-width: 0; min-height: 56px; padding: var(--space-2) 0; border: 0; background: transparent; color: var(--text); text-align: left; text-decoration: none; }
.files-row__main:focus-visible, .files-row__chat:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: -2px; border-radius: var(--radius-sm); }
.files-row__icon { display: grid; place-items: center; flex: none; width: 40px; height: 40px; border-radius: 8px; background: var(--quote-in-bg); color: var(--text); font-size: var(--fs-caption); font-weight: var(--fw-bold); letter-spacing: 0.02em; overflow: hidden; }
.files-row__icon--link { color: var(--text-muted); }
.files-row__icon--doc { background: var(--robot-bg); border: 1px solid var(--robot-border); color: var(--robot-text); }
.files-row__icon--img img { display: block; width: 100%; height: 100%; object-fit: cover; }
.files-row__text { display: flex; flex: 1; flex-direction: column; gap: 2px; min-width: 0; }
.files-row__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-body); font-weight: var(--fw-medium); }
.files-row__meta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-footnote); color: var(--text-muted); }
.files-row__chat { flex: none; color: var(--text-muted); }
@media (hover: hover) { .files-row__main:hover { color: var(--link); } .files-row__chat:hover { color: var(--link); } }
.files-more { margin: var(--space-3) 0; }
.files-status { display: flex; align-items: center; justify-content: center; gap: var(--space-2); margin: var(--space-3) 0; font-size: var(--fs-footnote); color: var(--text-muted); }
.files-sentinel { height: 1px; }
.empty--files { margin-top: var(--space-6); text-align: center; }
.empty--files .empty__art { display: flex; justify-content: center; }

/* ---- Sign in with Google (views/signin.js): the sheet, the button, the /new gate and the You page row ---- */
.btn--google { gap: var(--space-2); border: 1px solid var(--hairline); background: var(--sheet-bg); color: var(--text); }
.btn--google__g { display: inline-flex; flex: none; }
.signin-sheet__why { margin: var(--space-2) 0 var(--space-2); font-size: var(--fs-body); line-height: var(--lh-tight); }
.signin-sheet__note { margin: 0 0 var(--space-4); font-size: var(--fs-footnote); color: var(--text-muted); }
.signin-sheet .btn + .btn, .signin-sheet .field__error + .btn { margin-top: var(--space-2); }
.new-gate { margin-bottom: var(--space-4); padding: var(--space-4); border: 1px solid var(--hairline); border-radius: var(--radius-md); background: var(--sheet-bg); }
.new-gate__title { margin: 0 0 var(--space-2); font-size: var(--fs-title3); font-weight: var(--fw-semibold); line-height: var(--lh-tight); }
.new-gate__why { margin: 0 0 var(--space-3); font-size: var(--fs-subhead); color: var(--text-muted); }
.new-gate__or { margin: var(--space-4) 0 var(--space-2); font-size: var(--fs-subhead); font-weight: var(--fw-semibold); color: var(--text-muted); }
.new-gate__rooms { margin: 0 0 var(--space-3); padding: 0; }
.new-gate__none { font-size: var(--fs-footnote); color: var(--text-muted); }
.new-gate__more { margin: 0 0 var(--space-5); font-size: var(--fs-footnote); }
.setup__thread--locked { opacity: 0.45; }
.settings-account__g svg { width: 20px; height: 20px; }
.settings-account__email { word-break: break-all; }
