/* AROUND THE FIRE — one room per gathering. Campfire's bones, Gather's
   calm: a flat log of faces and words, no bubbles, no sides, no
   reactions. Times read in lodge time. */
@layer components {
  .chat { display: flex; flex-direction: column; gap: 12px; }

  .chat-intro {
    font-size: 13px;
    color: var(--ink-faint);
    line-height: 1.5;
    margin: 0;
  }
  .chat-intro b { color: var(--ink-soft); }

  /* The pane scrolls; the card around it stays put. */
  .chat-pane {
    border: 1px solid var(--hover-edge);
    border-radius: var(--radius-md);
    background: var(--paper);
    max-height: 55vh;
    min-height: 220px;
    overflow-y: auto;
    padding: 14px 16px;
  }

  .chat-messages { display: flex; flex-direction: column; gap: 14px; }

  .chat-msg { display: flex; gap: 10px; align-items: flex-start; }
  .chat-msg-face { flex: none; }
  .chat-msg-body { min-width: 0; }
  .chat-msg-meta { display: flex; align-items: baseline; gap: 8px; }
  .chat-msg-name { font-weight: var(--weight-semibold); font-size: 13px; color: var(--ink); }
  .chat-msg-time { font-size: 11px; color: var(--ink-faint); }
  .chat-msg-text { font-size: 14px; color: var(--ink-soft); line-height: 1.5; overflow-wrap: anywhere; }
  .chat-msg-text p { margin: 0 0 4px; }
  .chat-msg-text p:last-child { margin-bottom: 0; }
  /* Rich bodies: images and file attachments stay chat-sized. */
  .chat-msg-text figure { margin: 4px 0; }
  .chat-msg-text img { max-width: min(360px, 100%); height: auto; border-radius: var(--radius-md); display: block; }
  .chat-msg-text action-text-attachment { display: block; max-width: min(420px, 100%); }
  .chat-msg-text pre { background: var(--hover-wash); padding: 8px 10px; border-radius: var(--radius-md); overflow-x: auto; }

  /* ── The soundboard — "/tony" lands as a compact sound card. ── */
  .chat-sound {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    border: 1px solid var(--hover-edge);
    border-radius: var(--radius-md);
    background: var(--paper-warm);
    padding: 8px 12px;
    max-width: 100%;
  }
  .chat-sound svg { width: 16px; height: 16px; flex: none; color: var(--ink-soft); }
  .chat-sound-label { font-style: italic; color: var(--ink); }
  .chat-sound-replay { margin-left: 4px; white-space: nowrap; }
  .chat-sound-miss { display: block; font-size: 0.85em; font-style: italic; color: var(--ink-soft); }

  /* ── The composer — one field, Basecamp-style: the editor and its
     tools share a border; Send sits beside. The Lexxy element itself
     is styled in the UNLAYERED block at the end of this file (Lexxy's
     own stylesheet is unlayered, so layered rules can't reach it). ── */
  .chat-composer { display: flex; gap: 8px; align-items: flex-end; }
  .chat-field {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: flex-end;
    gap: 2px;
    border: 1px solid var(--hover-edge);
    border-radius: 12px;
    background: var(--paper);
    padding: 3px 6px 3px 12px;
  }
  .chat-field:focus-within { border-color: var(--ink-faint); }
  .chat--recording .chat-field { border-color: var(--required); }

  .chat-file-input {
    position: absolute;
    width: 1px; height: 1px;
    opacity: 0;
    pointer-events: none;
  }

  .chat-composer-tools { display: flex; align-items: center; gap: 2px; flex: none; padding-bottom: 2px; }
  .chat-tool {
    background: none; border: 0; cursor: pointer;
    color: var(--ink-faint);
    padding: 8px;
    line-height: 0;
    border-radius: var(--radius-md);
  }
  .chat-tool:hover { color: var(--ink); background: var(--hover-wash); }
  .chat-tool svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
  .chat-send { flex: none; }

  /* Recording state: the mic becomes a stop square, the timer counts,
     the ✕ discards. --required is the one honest red. */
  .chat-tool--mic .chat-stop-icon { display: none; }
  .chat--recording .chat-tool--mic { color: var(--required); }
  .chat--recording .chat-tool--mic .chat-mic-icon { display: none; }
  .chat--recording .chat-tool--mic .chat-stop-icon { display: block; }
  .chat-rec-timer { font-size: 12px; color: var(--required); font-variant-numeric: tabular-nums; }
  .chat-rec-cancel { font-size: 13px; line-height: 1; }

  .chat-voice { display: block; width: min(300px, 100%); margin: 2px 0; }

  /* The card on the gathering views — the chat seen from across the
     room: the last few things said, one click steps in. */
  .chat-card-door {
    display: block;
    padding: 16px 18px;
    margin: 20px 0;
    border: 1px solid var(--hover-edge);
    border-radius: var(--radius-md);
    background: var(--paper);
    text-decoration: none;
  }
  .chat-card-door:hover { background: var(--hover-wash); text-decoration: none; }
  .chat-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
  .chat-card-title { font-weight: var(--weight-bold); color: var(--ink); font-size: 15px; }
  .chat-card-verb {
    color: var(--ink); font-size: 13px; font-weight: var(--weight-semibold);
    text-decoration: underline; text-underline-offset: 3px; white-space: nowrap;
  }
  .chat-card-msgs { margin-top: 10px; display: flex; flex-direction: column; gap: 7px; }
  .chat-card-msg { display: flex; align-items: center; gap: 8px; min-width: 0; }
  .chat-card-msg .avatar { flex: none; }
  .chat-card-msg-name { font-weight: var(--weight-semibold); font-size: 13px; color: var(--ink); flex: none; }
  .chat-card-msg-body {
    font-size: 13px; color: var(--ink-soft); flex: 1; min-width: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .chat-card-msg-time { font-size: 11px; color: var(--ink-faint); flex: none; }
  .chat-card-foot { margin-top: 10px; font-size: 12px; color: var(--ink-faint); }
  .chat-card-blank { margin: 8px 0 0; font-size: 13px; color: var(--ink-faint); line-height: 1.5; }

  /* Folder tab: give the room the full card. */
  .chat-card { padding: 18px 20px; }

  /* ── DORMANT — the placeholder hosts and organizers see where the
     chat would be, while the guest list is still hidden (Neal,
     Aug 3). Quiet on purpose: one line, one door to the switch. The
     dashed edge is the host-tools grammar for "yours only". ──────── */
  .chat-dormant {
    border: 1px dashed var(--hover-edge);
    border-radius: var(--radius-md);
    background: var(--paper);
    padding: 18px 20px;
    display: flex;
    flex-direction: column;
    gap: 8px;
  }
  .chat-dormant-line { margin: 0; font-size: 13px; color: var(--ink-faint); line-height: 1.5; }
  .chat-dormant-door { font-size: 13px; }
  /* In the dock's column the card sits flush inside the frame. */
  .chat-dock .chat-dormant { margin: 12px; }
  /* Full screen: the card sits in the reading column, near the top. */
  .chat-screen--dormant .chat-dormant {
    margin: 24px max(22px, calc((100vw - 900px) / 2)) 0;
    max-width: 560px;
  }

  /* ── THE ROOM, FULL SCREEN — Campfire's shape: thin header with the
     way back, messages filling the viewport, composer pinned to the
     bottom. One reading column, centered. ───────────────────────── */
  .chat-screen {
    position: fixed;
    inset: 0 0 56px 0;  /* the footer bar runs beneath (same as the dock) */
    z-index: 60;
    background: var(--desk);
    display: flex;
    flex-direction: column;
    gap: 0;
    padding: 0;
  }
  .chat-screen-head {
    flex: none;
    display: flex;
    align-items: baseline;
    gap: 16px;
    padding: 14px max(22px, calc((100vw - 900px) / 2)) 12px;
    background: var(--paper);
    border-bottom: 1px solid var(--hover-edge);
  }
  .chat-screen-crumbs { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
  .chat-screen-back {
    color: var(--ink-faint); font-size: 14px; text-decoration: none;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .chat-screen-back:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
  .chat-crumb-sep { color: var(--ink-faint); font-size: 13px; }
  .chat-screen-title { font-family: var(--display); font-size: 18px; color: var(--ink); white-space: nowrap; }

  .chat-screen-body {
    flex: 1;
    min-height: 0;
    display: flex;
  }
  .chat-screen-pane {
    flex: 1;
    max-height: none;
    min-height: 0;
    border: 0;
    border-radius: 0;
    background: var(--desk);
    padding: 20px max(22px, calc((100vw - 900px) / 2)) 24px;
  }
  /* Who's here — desktop only; the phone keeps every pixel for words. */
  .chat-screen-side {
    display: none;
    width: 232px;
    flex: none;
    overflow-y: auto;
    border-left: 1px solid var(--hover-edge);
    padding: 20px 18px;
    background: var(--desk);
  }
  @media (min-width: 1100px) { .chat-screen-side { display: block; } }
  .chat-side-h {
    margin: 0 0 12px;
    font-size: var(--cap-md);
    letter-spacing: var(--tracking-cap-tight);
    text-transform: uppercase;
    font-weight: var(--weight-semibold);
    color: var(--ink-faint);
  }
  .chat-side-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
  .chat-side-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
  .chat-side-name {
    font-size: 13px; color: var(--ink-soft);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .chat-screen-foot {
    flex: none;
    background: var(--paper);
    border-top: 1px solid var(--hover-edge);
    padding: 12px max(22px, calc((100vw - 900px) / 2)) 14px;
  }

  /* ── THE LONG TABLE — the docked column, home of pings & groups.
     A real column on the right while open: page content shifts left
     (margin on body), the column holds the tray list or a room
     full-height. Under 900px it overlays instead — a phone can't
     split. The column is data-turbo-permanent: it (and its cable
     subscription) rides along across page navigation. */
  .chat-dock {
    position: fixed;
    top: 0; right: 0; bottom: 56px;  /* the footer bar runs beneath (BC's geometry) */
    width: var(--chat-dock-w, 340px);
    background: var(--paper);
    border-left: 1px solid var(--hover-edge);
    box-shadow: -10px 0 28px rgba(0, 0, 0, 0.10);
    z-index: 130;
    display: flex;
    flex-direction: column;
  }
  .chat-dock[hidden] { display: none; }
  .chat-dock #chat-dock-room {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
  }
  .chat-dock-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px;
    padding: 10px 14px 8px;
    border-bottom: 1px solid var(--hover-edge);
    flex: none;
  }
  .chat-dock-title { font-weight: var(--weight-bold); color: var(--ink); font-size: 13.5px; }
  .chat-dock-sub { font-size: 12px; color: var(--ink-faint); margin-top: 1px; }
  .chat-dock-close {
    background: none; border: 0; cursor: pointer;
    color: var(--ink-faint); font-size: 15px; line-height: 1; padding: 6px;
  }
  .chat-dock-close:hover { color: var(--ink); }

  /* The room fills the column: pane grows, composer pins to the foot. */
  .chat-dock .chat {
    flex: 1; min-height: 0;
    padding: 12px 14px 14px;
  }
  .chat-dock .chat-pane {
    flex: 1;
    max-height: none;
    min-height: 0;
  }

  /* The split: page content makes room while the dock is open. The
     avatar lives bottom-LEFT now (Jul 16) — it stays put. */
  body.chat-dock-open { margin-right: var(--chat-dock-w, 340px); }

  @media (max-width: 900px) {
    .chat-dock { width: min(420px, 94vw); }
    body.chat-dock-open { margin-right: 0; }          /* overlay, not split */
  }
}

/* ── LEXXY OVERRIDES — UNLAYERED ON PURPOSE ──────────────────────────
   Lexxy's own stylesheet is unlayered, and unlayered CSS beats every
   @layer rule regardless of specificity. These must live outside the
   layer (and this file loads after lexxy.css) to win. Two traps:
   `--lexxy-color-canvas` resolves to white AT :root before any remap
   can reach it, and the default editor height is 8 lines. */

.chat-composer lexxy-editor {
  /* Repaint Lexxy in lodge tokens — declared here (not :root) so the
     values resolve per theme. */
  --lexxy-color-canvas: transparent;
  --lexxy-color-ink: var(--ink);
  --lexxy-color-ink-medium: var(--ink-soft);
  --lexxy-color-ink-light: var(--ink-faint);
  --lexxy-color-ink-lighter: var(--hover-edge);
  --lexxy-color-ink-lightest: var(--hover-wash);
  --lexxy-color-ink-inverted: var(--paper);
  --lexxy-editor-rows: 1lh;      /* one quiet line; grows as you type */
  --lexxy-editor-padding: 0px;

  flex: 1;
  min-width: 0;
  /* flex:1 widens the <lexxy-editor> host, but its inner editable doesn't
     stretch on its own — text wrapped to ~content width in the dock (Neal,
     Jul 31). width:100% fills it, same as the announcement comment form. */
  width: 100%;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--ink);
  font-size: 14px;
  line-height: 1.45;
  padding: 7px 0;
  max-height: 40vh;
  overflow-y: auto;
}
.chat-composer lexxy-editor:focus-within { outline: none; box-shadow: none; }

/* The block toolbar stays out of the chat bar — markdown shortcuts,
   paste, and drag/drop still work. */
.chat-composer lexxy-toolbar { display: none; }

/* The A — formatting toggle. Off: toolbar hidden (rule above). On: the
   toolbar shows at the editor's top, Enter makes paragraphs, and the A
   reads pressed. Unlayered like the rest of the Lexxy overrides. */
.chat-a {
  font-family: var(--sans);
  font-size: 14px;
  font-weight: var(--weight-bold);
  line-height: 1;
  border-bottom: 2px solid currentColor;
  padding-bottom: 1px;
}
.chat-tool--rich[aria-pressed="true"] {
  color: var(--ink);
  background: var(--hover-wash);
}
.chat-composer--rich lexxy-toolbar {
  display: flex;
  flex-wrap: wrap;
  border-block-end: 1px solid var(--hover-edge);
  margin-bottom: 4px;
}

/* Rich mode gets real estate: with the A on, the writing area opens to
   seven lines (still grows beyond, capped at 40vh) instead of the chat
   bar's single line. */
.chat-composer--rich lexxy-editor {
  --lexxy-editor-rows: 7lh;
}

/* The level meter — a small bar that breathes with the mic input while
   recording. Live proof the mic hears you. */
/* Author display beats the [hidden] UA default — restate it. */
.chat-rec-level[hidden] { display: none; }
.chat-rec-level {
  display: inline-flex;
  align-items: flex-end;
  width: 5px;
  height: 16px;
  border-radius: 2px;
  background: var(--hover-wash);
  overflow: hidden;
}
.chat-rec-level i {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--required);
  transform: scaleY(0.12);
  transform-origin: bottom;
  transition: transform 90ms linear;
}

/* ── Pings & rooms (M2) — the tray page. ─────────────────────────── */
@layer components {
  .rooms-rows { margin-top: 20px; text-align: left; }
  .chat-crumb { text-align: left; margin-bottom: 12px; font-size: 13px; }
  .chat-crumb a { color: var(--ink-faint); text-decoration: none; }
  .chat-crumb a:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
  .rooms-link { color: var(--ink); text-decoration: none; }
  .rooms-link:hover { text-decoration: underline; text-underline-offset: 3px; }
  .rooms-unread {
    display: inline-block; margin-left: 8px;
    background: var(--pink, #FF00C7); color: #fff;
    font-size: 11px; font-weight: var(--weight-bold);
    border-radius: 999px; padding: 1px 8px; vertical-align: 2px;
  }
  .rooms-start { display: flex; gap: 8px; margin-top: 8px; align-items: center; }
  .rooms-start--group { flex-direction: column; align-items: stretch; }
  .rooms-pick { max-width: 280px; }
  .rooms-pick-multi { min-height: 120px; }
}

/* ── The pill + the tray (pings & groups, M2). ───────────────────── */
@layer components {
  .rooms-pill {
    position: fixed;
    right: 18px; bottom: 18px;
    z-index: 125;
    display: inline-flex; align-items: center; gap: 7px;
    background: var(--ink); color: var(--paper);
    border: 0; border-radius: 999px;
    padding: 9px 16px;
    font-size: 13px; font-weight: var(--weight-semibold);
    cursor: pointer;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
  }
  .rooms-pill:hover { transform: translateY(-1px); }
  .rooms-pill-badge {
    background: var(--pink); color: #fff;
    border-radius: 999px; padding: 1px 7px;
    font-size: 11px; font-weight: var(--weight-bold);
  }
  /* Author display beats [hidden] — restate (the meter lesson). */
  .rooms-pill-badge[hidden] { display: none; }
  /* The pill yields to the open column. */
  body.chat-dock-open .rooms-pill { display: none; }

  .tray-list { flex: 1; min-height: 0; overflow-y: auto; padding: 6px 0; }
  .tray-row {
    display: flex; align-items: center; gap: 9px;
    padding: 6px 14px;
    text-decoration: none;
  }
  .tray-row .avatar-sm { width: 28px; height: 28px; font-size: 10px; }
  .tray-row:hover { background: var(--hover-wash); text-decoration: none; }
  .tray-row .avatar { flex: none; }
  .tray-group-mark {
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--hover-wash); color: var(--ink-soft);
    font-weight: var(--weight-bold);
  }
  .tray-row-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
  .tray-row-name { font-weight: var(--weight-semibold); font-size: 13px; color: var(--ink); }
  .tray-row-line {
    font-size: 11.5px; color: var(--ink-faint);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .tray-blank { padding: 16px; }
  .tray-back {
    color: var(--ink-faint); text-decoration: none;
    font-size: 17px; margin-right: 6px;
  }
  .tray-back:hover { color: var(--ink); }
}

/* In-tray creation — the ＋ links, the type-to-narrow pickers. */
@layer components {
  .tray-new {
    display: flex; gap: 14px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--hover-edge);
    background: var(--paper);
  }
  .tray-new-link {
    color: var(--ink); font-size: 13px; font-weight: var(--weight-semibold);
    text-decoration: none;
  }
  .tray-new-link:hover { text-decoration: underline; text-underline-offset: 3px; }

  .tray-picker { display: flex; flex-direction: column; flex: 1; min-height: 0; padding: 10px 12px; gap: 8px; }
  .tray-filter, .tray-group-name { width: 100%; }
  .tray-picker-list { border: 1px solid var(--hover-edge); border-radius: var(--radius-md); }
  .tray-row-form { display: block; }
  .tray-row--button {
    width: 100%; text-align: left;
    background: none; border: 0; cursor: pointer;
    font: inherit;
  }
  .tray-row--check { cursor: pointer; }
  .tray-row--check input { flex: none; }
  .tray-picker-foot { flex: none; padding-top: 4px; }
  .tray-alert { margin: 10px 12px 0; }
}

/* ── MOBILE PASS (Campfire doctrine: fluid always, few breakpoints,
   respect the phone's own edges). ─────────────────────────────────── */
@layer components {
  /* Focused flows own their bottom edge — the pill and the support
     mark step aside in the room and mid-wizard (the pill was sitting
     on Send and Next). */
  body:has(.chat-screen) .rooms-pill,
  body:has(.wizard-shell) .rooms-pill,
  body:has(.chat-screen) .support-link,
  body:has(.wizard-shell) .support-link { display: none; }

  /* Standalone-iOS edges: the home indicator and the notch get their
     space everywhere it matters. */
  .rooms-pill { bottom: max(18px, env(safe-area-inset-bottom)); }
  .chat-screen-head {
    padding-top: max(14px, env(safe-area-inset-top));
  }
  .chat-screen-foot {
    padding-bottom: max(14px, env(safe-area-inset-bottom));
  }
  .chat-dock { padding-bottom: env(safe-area-inset-bottom); }
}

/* ── The waterline ──────────────────────────────────────────────
   "New since you were here" — drawn once, where the reader left off
   (rooms only; chats and first visits go without). Attention magenta,
   whisper weight. */
@layer components {
  .chat-waterline {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 2px 0;
    color: var(--pink);
    font-size: var(--cap-md);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-cap);
    text-transform: uppercase;
    white-space: nowrap;
  }
  .chat-waterline::before,
  .chat-waterline::after {
    content: "";
    flex: 1;
    border-top: 1px solid color-mix(in srgb, var(--pink) 40%, transparent);
  }
}

/* The unlit chat — one honest line where the words will go. */
@layer components {
  .chat-empty {
    color: var(--ink-faint);
    font-size: 14px;
    text-align: center;
    margin: 40px 0;
  }
}

/* ── Lexxy on the board (comments, message composers) — same unlayered
   token remap as the chat so dark mode repaints the editor; here it
   keeps a bordered-field shape rather than the chat's bare line. ── */
.ann-comment-form lexxy-editor,
.ann-edit-body lexxy-editor,
.ann-edit-form lexxy-editor,
.board-compose-form lexxy-editor {
  --lexxy-color-canvas: transparent;
  --lexxy-color-ink: var(--ink);
  --lexxy-color-ink-medium: var(--ink-soft);
  --lexxy-color-ink-light: var(--ink-faint);
  --lexxy-color-ink-lighter: var(--hover-edge);
  --lexxy-color-ink-lightest: var(--hover-wash);
  --lexxy-color-ink-inverted: var(--paper);

  background: transparent;
  color: var(--ink);
  border: 1px solid var(--hover-edge);
  border-radius: 8px;
}
.ann-comment-form lexxy-toolbar,
.ann-edit-body lexxy-toolbar,
.ann-edit-form lexxy-toolbar,
.board-compose-form lexxy-toolbar {
  background: transparent;
  color: var(--ink-soft);
  border-block-end: 1px solid var(--hover-edge);
}

/* The message page's comment composer waits its turn: no toolbar until
   the writer is in it (or has words in it). Unlayered so it beats
   lexxy's own stylesheet. */
.ann-comment-form lexxy-toolbar { display: none; }
.ann-comment-form:focus-within lexxy-toolbar,
.ann-comment-form:has(lexxy-editor:not(.lexxy-editor--empty)) lexxy-toolbar { display: flex; }

/* ── THE @ MENU (Neal, Aug 6) ────────────────────────────────────────
   Lexxy hangs its prompt popover INSIDE <lexxy-editor>, so it inherits
   the token remaps above — including --lexxy-color-canvas: transparent,
   which is right for a writing line and wrong for a menu floating over
   the messages behind it. Give it paper of its own. Unlayered, like
   every other Lexxy override in this file, because lexxy's own rules
   are unlayered and would otherwise win regardless of specificity. */
.lexxy-prompt-menu {
  background: var(--paper);
  border: 1px solid var(--hover-edge);
  box-shadow: 0 8px 28px rgb(0 0 0 / 16%);
  min-inline-size: 22ch;
  max-inline-size: min(30ch, 100%);
}

/* One line per person: face, then name. The name is allowed to run out
   of room rather than wrap the row to two lines. */
.mention-option {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.mention-option .avatar {
  width: 24px;
  height: 24px;
  font-size: 10px;
}
.mention-option-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The chat bar caps its editor at 40vh and scrolls it (the rule above),
   which also CLIPS the popover — lexxy hangs the menu inside
   <lexxy-editor>, and a one-line composer would crop a six-name menu to
   one line of itself. Let the box out of its cage for exactly as long as
   the menu is up. In practice the editor is a line or three tall while
   someone types a name, so lifting the cap costs nothing you'd see. */
.chat-composer lexxy-editor:has(.lexxy-prompt-menu--visible) {
  max-height: none;
  overflow: visible;
}

/* ── Dock footer controls (Jul 16, BC's geometry): while the dock is
   open the Chat pill yields to a count + ✕ riding the footer bar,
   bottom right, beneath the slide-out. ── */
.dock-footer-controls {
  display: none;
  position: fixed;
  right: 18px;
  bottom: 12px;
  z-index: 126;
  align-items: center;
  gap: 10px;
}
body.chat-dock-open .dock-footer-controls { display: inline-flex; }
body.chat-dock-open .rooms-pill { display: none; }
.dock-close {
  background: var(--ink); color: var(--paper);
  border: 0; border-radius: 999px;
  width: 30px; height: 30px;
  font-size: 13px; line-height: 1;
  cursor: pointer;
}
.dock-close:hover { transform: translateY(-1px); }

/* ── The dock's rich composer: grid, not a squeezed row — the editor
   (with its wrapped toolbar) spans the full width, tools left and
   Send right on the row beneath (the BC ping screen's shape). ── */
/* The editor lives inside .chat-field (shared border with its tools) —
   THAT is the grid item, spanning the full row; Send sits beneath. */
.chat-dock .chat-composer--rich {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 6px;
}
.chat-dock .chat-composer--rich .chat-field { grid-column: 1 / -1; min-width: 0; }
.chat-dock .chat-composer--rich .chat-send { justify-self: end; }
.chat-dock .chat-composer--rich lexxy-toolbar {
  gap: 0;
  font-size: 12px;
  flex-wrap: wrap;
}

/* ── Campfire Chat's ember (Jul 16 night): the door glows warm when
   you hover it — a breathing ring of firelight. ── */
@keyframes ember-breathe {
  0%, 100% { box-shadow: 0 0 0 1px rgba(194, 87, 31, 0.45), 0 0 18px 2px rgba(194, 87, 31, 0.28); }
  50%      { box-shadow: 0 0 0 1px rgba(224, 122, 61, 0.65), 0 0 26px 5px rgba(224, 122, 61, 0.4); }
}
.chat-card-door { transition: box-shadow 200ms ease; }
.chat-card-door:hover {
  animation: ember-breathe 1.6s ease-in-out infinite;
  border-color: rgba(194, 87, 31, 0.5);
}
@media (prefers-reduced-motion: reduce) {
  .chat-card-door:hover { animation: none; box-shadow: 0 0 0 1px rgba(194, 87, 31, 0.5), 0 0 18px 2px rgba(194, 87, 31, 0.3); }
}

/* The tray's top row sits flush with the nav bar's line. */
.tray-new--top {
  height: 64px;
  align-items: center;
  padding: 0 14px;
}

/* The resting comment row is just a face and a line (BC's alignment):
   no box until the writer arrives. One line tall, grows on focus. */
.ann-comment-form lexxy-editor {
  --lexxy-editor-rows: 1lh;
  border-color: transparent;
  transition: border-color 140ms ease;
}
.ann-comment-form:focus-within lexxy-editor,
.ann-comment-form:has(lexxy-editor:not(.lexxy-editor--empty)) lexxy-editor {
  --lexxy-editor-rows: 3lh;
  border-color: var(--hover-edge);
}

/* ── While you were away (Jul 16, the AI round): one quiet line above
   the backlog — the lodge catching you up, not a bot in the room. ── */
.wya-line {
  margin: 0 0 12px;
  padding: 9px 14px;
  border: 1px dashed color-mix(in srgb, #a85f33 45%, transparent);
  border-radius: 8px;
  font-size: 13px;
  font-style: italic;
  line-height: 1.5;
  color: var(--ink-soft);
}

/* The Lodge's calling card — one quiet standing hint in the chat. */
.home-hint {
  margin: 0 0 12px;
  font-size: 12.5px;
  color: var(--ink-faint);
  text-align: center;
}
.home-hint strong { color: var(--ink-soft); }

@layer components {
  /* An empty tray centers its one sentence instead of leaving a void
     under the toolbar (mobile punch-list). */
  .tray-blank {
    margin: auto;
    max-width: 280px;
    text-align: center;
    padding: 24px;
  }
}

/* ── The quiet ⋯ — edit or take back a said thing. The button sleeps
   until the message is hovered (desktop); on touch it sits faint but
   present. The menu is a small paper card — avatar-menu's language at
   message scale. message-menu (Stimulus) decides what a viewer SEES;
   the server authorizes what anyone can DO. ─────────────────────── */
@layer components {
  /* Each message now rides in a turbo-frame (the edit seam). Custom
     elements default to inline — restate block so the flex column's
     gap and the rise-in animation keep working. */
  turbo-frame.chat-msg-frame { display: block; }

  .chat-msg-actions { position: relative; flex: none; margin-left: auto; }
  .chat-msg-actions[hidden] { display: none; }

  .chat-msg-menu-btn {
    background: none; border: 0; cursor: pointer;
    color: var(--ink-faint);
    font-size: 15px; line-height: 1;
    padding: 3px 7px;
    border-radius: var(--radius-md);
  }
  .chat-msg-menu-btn:hover { color: var(--ink); background: var(--hover-wash); }
  @media (hover: hover) {
    .chat-msg .chat-msg-menu-btn { opacity: 0; }
    .chat-msg:hover .chat-msg-menu-btn,
    .chat-msg-menu-btn:focus-visible,
    .chat-msg-actions.open .chat-msg-menu-btn { opacity: 1; }
  }

  .chat-msg-menu {
    position: absolute; top: 26px; right: 0; z-index: 40;
    display: none; flex-direction: column; align-items: stretch; gap: 2px;
    min-width: 132px; padding: 4px;
    background: var(--paper);
    border: 1px solid var(--hover-edge);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
  }
  .chat-msg-menu.open { display: flex; }
  /* button_to wraps its button in a form — let the button be the row.
     [hidden] on the form must still win over display:contents. */
  .chat-msg-menu form { display: contents; }
  .chat-msg-menu form[hidden] { display: none; }
  .chat-msg-menu-item {
    display: block; width: 100%; text-align: left;
    font-size: 13px; color: var(--ink); text-decoration: none;
    background: none; border: 0; cursor: pointer;
    padding: 6px 10px;
    border-radius: 8px;
  }
  .chat-msg-menu-item:hover { background: var(--hover-wash); text-decoration: none; }
  .chat-msg-menu-item--remove { color: var(--required); }
  .chat-msg-menu-item[hidden] { display: none; }

  /* The muted mark a rewritten message wears. */
  .chat-msg-edited { font-size: 11px; color: var(--ink-faint); font-style: italic; }

  /* The rewrite, in place — the same bar, prefilled, sitting where the
     words were. Reuses .chat-composer so the Lexxy overrides (the
     unlayered block above) dress this editor too. */
  .chat-msg--editing { flex: 1; flex-wrap: wrap; }
  .chat-edit { flex: 1; min-width: 0; }
  .chat-edit-cancel { flex: none; padding: 8px 2px; font-size: 13px; }
  .chat-edit-error {
    flex-basis: 100%;
    margin: 0 0 6px;
    font-size: 12px;
    color: var(--required);
  }
}

@layer components {
  /* ── THE COMPOSER STACKS (Neal, Aug 11) ────────────────────────────
     The editor and its tools used to share one border. On a phone that
     left the typing area about half the width of the box — "Testing the
     view of this." wrapped to two lines while a paperclip, a mic and an A
     held the rest. A composer's whole job is to show you what you are
     writing, and it was spending half its width on buttons.

     Basecamp's ping composer is the reference: a plain box, tools in a row
     beneath it. The field gets the full width and the tools get a line of
     their own, where they are also easier to hit. */
  .chat-composer-stack {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
  }
  .chat-composer-stack .chat-field {
    flex: none;
    width: 100%;
    align-items: flex-start;
    padding: 8px 12px;
  }
  .chat-composer-stack .chat-composer-tools {
    padding-bottom: 0;
    padding-left: 2px;
    gap: 4px;
  }
  /* The recording meter and timer read left-to-right with the tools now
     rather than being squeezed against the text. */
  .chat-composer-stack .chat-rec-level { margin-right: 4px; }
}

  /* What @ actually does, said where somebody is doing it rather than only
     in Settings three pages away. (Chad, Aug 25) */
  .chat-mention-hint {
    margin: 6px 2px 0;
    font-size: 12px;
    line-height: 1.45;
    color: var(--ink-faint);
  }
