/* ==========================================================================
   Forge chair tool + admin dashboard styles.
   Layout uses semantic tokens from tokens.css so a theme swap is one file.
   ========================================================================== */

/* ---- Button reset ---------------------------------------------------- */
/* Every <button> starts flat; the component classes below define the look.
   Without this, bare buttons (segmented controls, icon buttons, the overlay
   close) inherit the browser's grey bevel + 2px outset border. */
button {
  appearance: none; -webkit-appearance: none;
  margin: 0; padding: 0;
  font: inherit; color: inherit;
  background: transparent; border: 0;
  cursor: pointer;
}
button:disabled { cursor: default; }

/* ---- Buttons (shared) ------------------------------------------------ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--sans); font-weight: 600; font-size: 15px; line-height: 1;
  padding: 12px 18px; border-radius: var(--r-pill); cursor: pointer;
  border: 1px solid transparent; background: transparent; color: var(--fg);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), transform 120ms var(--ease), box-shadow var(--dur) var(--ease);
  white-space: nowrap;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn svg { flex: none; }
.btn--primary { background: var(--accent); color: var(--on-accent); box-shadow: var(--shadow-2); }
.btn--primary:hover { background: var(--gold-soft); }
.btn--secondary { background: var(--bg-surface); color: var(--fg); border-color: var(--border-strong); box-shadow: var(--shadow-1); }
.btn--secondary:hover { background: var(--bg-sunken); }
/* Muted/grey variant for the chair's own moves (not member lines). A grey
   outline gives it definition against the very light fill. */
.btn--muted { background: var(--bg-surface-2); color: var(--fg); border-color: var(--border-strong); }
.btn--muted:hover { background: var(--cream-3); color: var(--fg); }
.btn--ghost { background: transparent; color: var(--fg-muted); border-color: var(--border); }
.btn--ghost:hover { background: var(--bg-sunken); }
.btn--danger { background: var(--red-soft); color: var(--red); }
.btn--danger:hover { background: #f7d5d1; }
.btn--big { font-size: 18px; padding: 16px 30px; }
.btn:disabled { opacity: .5; cursor: default; transform: none; }

.iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: var(--r-pill); color: var(--fg-muted);
  cursor: pointer; background: transparent; position: relative;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.iconbtn:hover { background: var(--bg-sunken); color: var(--fg); }
.iconbtn:disabled { opacity: .35; cursor: default; }
.iconbtn.is-active { background: var(--accent-wash); color: var(--accent-deep); }
.iconbtn .badge {
  position: absolute; top: 2px; right: 2px; min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: 9px; background: var(--accent); color: var(--on-accent);
  font: 600 10px/17px var(--mono); text-align: center;
}
/* Custom hover tooltip (below the button) — clearer than the native title. */
.iconbtn[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute; top: calc(100% + 7px); left: 50%; transform: translateX(-50%) translateY(-4px);
  background: var(--navy); color: #fff; font: 500 12px/1 var(--sans); white-space: nowrap;
  padding: 6px 9px; border-radius: var(--r-sm); box-shadow: var(--shadow-2);
  opacity: 0; pointer-events: none; transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
  z-index: 50;
}
.iconbtn[data-tooltip]:hover::after { opacity: 1; transform: translateX(-50%) translateY(0); }
.iconbtn[data-tooltip]:disabled::after { display: none; }

/* Dock action tooltip ("Tooltip" cue mode): the member line to listen for,
   shown ABOVE the button (the dock is pinned to the bottom of the screen).
   Wraps, since some lines are full sentences. The button label isn't
   selectable, so a stray text-highlight can't trigger (and then strand) the
   cue on touch. */
.btn[data-cue] { position: relative; -webkit-user-select: none; user-select: none; }
.btn[data-cue]::after {
  content: attr(data-cue);
  position: absolute; bottom: calc(100% + 9px); left: 50%; transform: translateX(-50%) translateY(4px);
  background: var(--navy); color: #fff; font: italic 500 13px/1.4 var(--serif); white-space: normal;
  width: max-content; max-width: 300px; text-align: center;
  padding: 8px 12px; border-radius: var(--r-sm); box-shadow: var(--shadow-2);
  opacity: 0; pointer-events: none; transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
  z-index: 60;
}
/* Little caret pointing down at the button. */
.btn[data-cue]::before {
  content: ''; position: absolute; bottom: calc(100% + 3px); left: 50%; transform: translateX(-50%) translateY(4px);
  border: 6px solid transparent; border-top-color: var(--navy);
  opacity: 0; pointer-events: none; transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
  z-index: 60;
}
/* Real pointer (desktop mouse): reveal on hover. */
@media (hover: hover) and (pointer: fine) {
  .btn[data-cue]:hover::after,
  .btn[data-cue]:hover::before { opacity: 1; transform: translateX(-50%) translateY(0); }
}
/* Touch/coarse pointer: there is no hover, and an emulated one sticks until the
   next tap. Reveal on press instead — hold to peek, release to act (slide off
   to cancel) — so the cue never gets stranded on screen. */
@media (hover: none), (pointer: coarse) {
  .btn[data-cue]:active::after,
  .btn[data-cue]:active::before { opacity: 1; transform: translateX(-50%) translateY(0); }
}
/* Narrow viewports (phones, and narrow windows): anchor the cue to the dock —
   centered and capped to the viewport — so a button near the edge can never push
   the tooltip off-screen (which would let the page scroll sideways). The caret is
   dropped since the bubble no longer sits over one specific button. This is scoped
   by width, not pointer type, because the overflow is a narrow-screen geometry
   problem regardless of how the tooltip is triggered (hover or press). */
@media (max-width: 719px) {
  .dock { position: relative; }
  .btn[data-cue] { position: static; }
  /* The press/hover "lift" applies a transform, and ANY transform makes the
     button the containing block for its own ::after — re-anchoring the tooltip
     to the off-center button and letting it run off-screen. Drop the lift on cue
     buttons so the tooltip anchors to the dock (centered, viewport-capped). */
  .btn[data-cue]:hover, .btn[data-cue]:active { transform: none; }
  .btn[data-cue]::after {
    left: 50%; right: auto; bottom: calc(100% + 6px);
    max-width: calc(100vw - 24px);
  }
  .btn[data-cue]::before { display: none; }
}

/* ---- App shell ------------------------------------------------------- */
/* #root must fill the viewport so .app's height:100% resolves — this pins the
   action dock to the bottom (its top-fade gradient is designed for that) and
   centers the podium line, instead of collapsing to content height. */
#root { height: 100%; }
.app { display: flex; flex-direction: column; height: 100%; }
.hdr {
  height: var(--header-h); flex: none; display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 0 12px; background: var(--bg-surface); border-bottom: 1px solid var(--border);
  position: relative; z-index: 20;
}
/* undo/redo (left) · Forge mark (absolute center) · actions (right) */
.hdr-left { display: flex; align-items: center; gap: 2px; }
.hdr-right { display: flex; align-items: center; gap: 2px; }
.hdr-logo { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); display: flex; pointer-events: none; }
.hdr-clock { display: inline-flex; align-items: center; gap: 6px; color: var(--fg-subtle); font: 500 13px/1 var(--mono); margin-right: 4px; }
.hdr-clock .live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--green); box-shadow: 0 0 0 0 rgba(52,168,83,.5); animation: pulse 2.4s infinite; }
@keyframes pulse { 0%{box-shadow:0 0 0 0 rgba(52,168,83,.45)} 70%{box-shadow:0 0 0 7px rgba(52,168,83,0)} 100%{box-shadow:0 0 0 0 rgba(52,168,83,0)} }
.offline-chip { display: none; align-items: center; gap: 6px; font: 500 12px/1 var(--mono); color: var(--amber); background: var(--amber-soft); padding: 6px 10px; border-radius: var(--r-pill); }
body.is-offline .offline-chip { display: inline-flex; }

/* ---- Broadcast announcement ------------------------------------------ */
/* Chair-facing banner under the header (flex:none so it never eats the stage). */
.broadcast-bar { flex: none; display: flex; align-items: center; gap: 10px; padding: 10px 16px;
  background: var(--accent-wash); border-bottom: 1px solid var(--gold-line); color: var(--fg);
  font-size: 14px; font-weight: 500; z-index: 10; }
.broadcast-bar .bc-ico { display: inline-flex; color: var(--accent-deep); flex: none; }
.broadcast-bar .bc-msg { flex: 1; min-width: 0; line-height: 1.35; }
.broadcast-bar .bc-x { flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: var(--r-pill); color: var(--fg-subtle); }
.broadcast-bar .bc-x:hover { background: var(--gold-line); color: var(--fg); }
/* When an admin posts or replaces the announcement, flash the banner once so a
   chair mid-session notices the new text. (Auto-disabled under reduced motion.) */
.broadcast-bar--flash { animation: bcFlash 1.7s var(--ease) 1; }
.broadcast-bar--flash .bc-ico { animation: bcNudge 1.7s var(--ease) 1; transform-origin: center; }
@keyframes bcFlash {
  0%   { background: var(--accent-wash); box-shadow: 0 0 0 0 var(--gold-line); }
  10%  { background: var(--gold-soft);   box-shadow: 0 0 0 4px var(--gold-line); }
  28%  { background: var(--accent-wash); box-shadow: 0 0 0 0 rgba(0,0,0,0); }
  46%  { background: var(--gold-soft); }
  64%  { background: var(--accent-wash); }
  82%  { background: var(--gold-soft); }
  100% { background: var(--accent-wash); }
}
@keyframes bcNudge {
  0%, 100%      { transform: translateX(0) rotate(0); }
  10%, 34%, 58% { transform: translateX(-2px) rotate(-9deg); }
  22%, 46%      { transform: translateX(2px) rotate(9deg); }
  70%           { transform: none; }
}
/* Admin composer: the announcement currently showing to chairs. */
.announce-current { background: var(--accent-wash); border: 1px solid var(--gold-line); border-radius: var(--r-md);
  padding: 12px 14px; margin-bottom: 14px; }
.announce-current .ac-label { font: 500 10.5px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--accent-deep); margin-bottom: 6px; }
.announce-current .ac-msg { font-size: 14px; color: var(--fg); line-height: 1.4; }
/* Announce button reflects an active broadcast. */
.btn--ghost.is-active { border-color: var(--accent); color: var(--accent-deep); background: var(--accent-wash); }

/* ---- Body row (stage + sidebar) ------------------------------------- */
.body-row { flex: 1; display: flex; min-height: 0; position: relative; }
.stage-wrap { flex: 1; display: flex; flex-direction: column; min-width: 0; transition: margin-right var(--dur) var(--ease); }
.body-row.sidebar-open .stage-wrap { margin-right: var(--sidebar-w); }

/* ---- Podium stage ---------------------------------------------------- */
/* The bill bar (flex:none) pins to the top; .stage-inner uses margin:auto to
   center the script/cues in the space that remains (margin:auto degrades to a
   scrollable top-align when content is too tall, unlike justify-content). */
/* No top padding on the stage: the sticky bar must pin flush to top:0, else
   scrolled script would show through the padding strip above it. Top breathing
   room lives on the bar (and on .stage-inner for bill-free states). */
.stage { flex: 1; display: flex; flex-direction: column; align-items: center;
  padding: 0 28px 24px; overflow-y: auto; text-align: center; }
.stage-inner { width: 100%; max-width: 720px; margin: auto; padding: 28px 0; }

/* Sticky bill bar — pinned flush under the header on both surfaces; page-colored
   (top padding included) so the script scrolls cleanly beneath it. */
.bill-bar { flex: none; width: 100%; display: flex; justify-content: center;
  position: sticky; top: 0; z-index: 6; background: var(--bg-page); padding: 28px 0 16px; }
.bill-bar .bill-chip { margin-bottom: 0; }
/* With the bar present, its own padding gives the gap above the script. */
.bill-bar + .stage-inner { padding-top: 8px; }

.bill-chip { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 22px; max-width: 100%;
  padding: 7px 8px 7px 16px; border-radius: var(--r-pill); background: var(--bg-surface);
  border: 1px solid var(--border); box-shadow: var(--shadow-1); }
.bill-chip .num { font: 600 13px/1 var(--mono); letter-spacing: .04em; color: var(--fg); flex: none; }
.bc-main { display: flex; align-items: center; gap: 10px; min-width: 0; }
.bill-chip .ttl { font-size: 13px; color: var(--fg-subtle); max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bill-chip .spn { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 500; color: var(--fg-muted);
  white-space: nowrap; padding-left: 10px; border-left: 1px solid var(--border); }
.bill-chip .spn-ic { display: inline-flex; color: var(--fg-faint); }
.bill-chip .doc { display: inline-flex; align-items: center; gap: 5px; padding: 5px 11px; border-radius: var(--r-pill); flex: none;
  background: var(--accent-wash); color: var(--accent-deep); font: 600 12px/1 var(--sans); }
.bill-chip .doc:hover { background: var(--gold-line); }
.bill-chip .doc.is-empty { opacity: .45; }

.kicker { font: 500 10.5px/1 var(--mono); letter-spacing: .18em; text-transform: uppercase; color: var(--fg-faint); margin-bottom: 14px; }

.script {
  font-family: var(--serif); font-style: italic; font-weight: 500;
  font-size: var(--script-size); line-height: 1.32; color: var(--fg);
  letter-spacing: .003em; margin: 0 auto; max-width: 22em;
  animation: rise var(--dur) var(--ease);
}
@keyframes rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
.script .tok { font-style: normal; font-weight: 600; color: var(--accent-deep);
  background: var(--accent-wash); padding: 0 .28em; border-radius: 6px; white-space: nowrap; }
/* Filled names stay tappable to change or clear them. */
.script .tok--name { cursor: pointer; }
.script .tok--name:hover { background: var(--gold-line); }
/* Blanks render anywhere a scripted line appears (podium + "I'm lost") */
.blank { display: inline-block; min-width: 2.2em; border-bottom: 2px solid var(--gold-line);
  margin: 0 .12em; vertical-align: .12em; height: .95em; }
/* Name blanks carry a faint upright placeholder ("Rep. Name" / "Witness") that
   sits on the dashed line, so it's clear what goes there before it's filled. */
.blank--name { min-width: 4.5em; height: auto; vertical-align: baseline; border-bottom-style: dashed;
  color: var(--fg-faint); font-style: normal; font-weight: 500; padding: 0 .12em; }
.script .blank--name { cursor: pointer; }
.script .blank--name:hover { border-bottom-color: var(--accent-deep); background: var(--accent-wash); }
/* Locked name (e.g. the sponsor in lay-out/close): a fixed "say aloud"
   placeholder — not tappable, so no pointer cursor or hover highlight. */
.script .blank--fixed { cursor: default; }
.script .blank--fixed:hover { border-bottom-color: var(--gold-line); background: transparent; }

.script-note { margin: 14px auto 0; max-width: 30em; font: 400 14px/1.5 var(--sans); color: var(--fg-subtle); }
.src-flag { margin: 12px auto 0; max-width: 30em; font: 500 12px/1.45 var(--sans); color: var(--amber);
  display: inline-flex; gap: 7px; align-items: flex-start; text-align: left; }

.ui-prompt { font-family: var(--serif); font-size: 26px; font-weight: 600; color: var(--fg-muted); margin-bottom: 6px; }

/* "What others say" cues — short lines others speak, shown as labeled bubbles
   positioned above the chair's line (if said first) or below (if said after),
   so the screen reads top-to-bottom in the order things happen. */
.cues { display: flex; flex-direction: column; gap: 8px; max-width: 26em; margin: 16px auto; width: 100%; }
.cue { position: relative; background: var(--bg-cue); border: 1px solid var(--border-cue); border-radius: 14px; padding: 9px 16px; text-align: center; }
/* Understated sans-serif so the chair's eye never lands here to read aloud. */
.cue .role { font: 600 11px/1 var(--sans); color: var(--fg-cue); opacity: .75; margin-bottom: 3px; }
.cue .line { font-family: var(--sans); font-style: normal; font-weight: 400; font-size: 15px; line-height: 1.45; color: var(--fg-cue); }
.cue .line .tok { font-style: normal; font-weight: inherit; color: inherit; background: none; padding: 0; border-radius: 0; }
/* Outlined speech-bubble tail on the cue nearest the chair's line: ::before is
   the border triangle, ::after the fill 1px inside it, so the outline shows. */
.cue::before, .cue::after { content: ''; position: absolute; left: 50%; width: 0; height: 0; display: none; }
.cues--after .cue:first-child::before, .cues--after .cue:first-child::after,
.cues--before .cue:last-child::before, .cues--before .cue:last-child::after { display: block; }
.cues--after .cue:first-child::before { top: -9px; margin-left: -8px; border-left: 8px solid transparent; border-right: 8px solid transparent; border-bottom: 9px solid var(--border-cue); }
.cues--after .cue:first-child::after  { top: -8px; margin-left: -7px; border-left: 7px solid transparent; border-right: 7px solid transparent; border-bottom: 8px solid var(--bg-cue); }
.cues--before .cue:last-child::before { bottom: -9px; margin-left: -8px; border-left: 8px solid transparent; border-right: 8px solid transparent; border-top: 9px solid var(--border-cue); }
.cues--before .cue:last-child::after  { bottom: -8px; margin-left: -7px; border-left: 7px solid transparent; border-right: 7px solid transparent; border-top: 8px solid var(--bg-cue); }

/* ---- Action dock ----------------------------------------------------- */
.dock { flex: none; display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 10px; padding: 18px 24px calc(78px + env(safe-area-inset-bottom));
  background: linear-gradient(to top, var(--bg-page) 55%, transparent);
  border-top: 1px solid transparent; }
.dock .btn--primary { order: -1; }

/* Calendar (choose bill) list */
.cal-list { display: flex; flex-direction: column; gap: 10px; width: 100%; max-width: 460px; margin: 22px auto 0; text-align: left; }
.cal-item { display: flex; align-items: center; gap: 12px; padding: 14px 16px; border-radius: var(--r-md);
  background: var(--bg-surface); border: 1px solid var(--border); box-shadow: var(--shadow-1); cursor: pointer;
  transition: border-color var(--dur), transform 120ms; }
.cal-item:hover { border-color: var(--accent); transform: translateY(-1px); }
.cal-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; text-align: left; }
.cal-top { display: flex; align-items: center; gap: 8px; }
.cal-item .num { font: 600 13px/1 var(--mono); color: var(--fg); }
.cal-item .ttl { font-size: 14px; color: var(--fg-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-item .spn { font-size: 12px; color: var(--fg-subtle); }
.cal-item .go { color: var(--fg-faint); flex: none; }

/* ---- Status pill (shared: sidebar, calendar, admin) ------------------ */
.pill { display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; border-radius: var(--r-pill);
  font: 600 11px/1.5 var(--sans); white-space: nowrap; }
.pill::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .9; }
.pill.s-upnext   { color: var(--status-upnext-fg);   background: var(--status-upnext-bg); }
.pill.s-hearing  { color: var(--status-hearing-fg);  background: var(--status-hearing-bg); }
.pill.s-amending { color: var(--status-amending-fg); background: var(--status-amending-bg); }
.pill.s-voting   { color: var(--status-voting-fg);   background: var(--status-voting-bg); }
.pill.s-passed   { color: var(--status-passed-fg);   background: var(--status-passed-bg); }
.pill.s-failed   { color: var(--status-failed-fg);   background: var(--status-failed-bg); }
.pill.s-tabled   { color: var(--status-tabled-fg);   background: var(--status-tabled-bg); }
.pill.s-pending  { color: var(--status-pending-fg);  background: var(--status-pending-bg); }

/* ---- Sidebar (desktop) / becomes sheet on mobile -------------------- */
.sidebar {
  position: absolute; top: 0; right: 0; bottom: 0; width: var(--sidebar-w);
  background: var(--bg-surface); border-left: 1px solid var(--border);
  transform: translateX(100%); transition: transform var(--dur) var(--ease);
  display: flex; flex-direction: column; z-index: 15;
}
.body-row.sidebar-open .sidebar { transform: translateX(0); box-shadow: var(--shadow-3); }
.sidebar-head { flex: none; display: flex; align-items: center; gap: 10px; padding: 16px 18px; border-bottom: 1px solid var(--border); }
.sidebar-head .t { font-family: var(--serif); font-weight: 600; font-size: 18px; flex: 1; }
.sidebar-body { flex: 1; overflow-y: auto; padding: 12px 14px 20px; }
.bill-row { display: flex; align-items: center; gap: 10px; padding: 12px; border-radius: var(--r-md);
  background: var(--bg-surface); border: 1px solid var(--border); margin-bottom: 8px; }
.bill-row.is-current { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.bill-row .drag-handle { color: var(--fg-faint); cursor: grab; touch-action: none; display: flex; }
.bill-row .info { flex: 1; min-width: 0; }
.bill-row .info .top { display: flex; align-items: center; gap: 8px; }
.bill-row .info .num { font: 600 12px/1 var(--mono); color: var(--fg); }
.bill-row .info .ttl { font-size: 13px; color: var(--fg-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 3px; }
.bill-row .info .spn { font-size: 12px; color: var(--fg-subtle); margin-top: 2px; }
.bill-row .actions { display: flex; gap: 2px; }
.drag-placeholder { border: 2px dashed var(--gold-line); border-radius: var(--r-md); background: var(--accent-wash); margin-bottom: 8px; }
.bill-row.dragging { box-shadow: var(--shadow-3); }

/* ---- Overlays (modal on desktop, sheet on mobile) ------------------- */
.ov-scrim { position: fixed; inset: 0; background: var(--bg-overlay); z-index: 100;
  display: flex; align-items: center; justify-content: center; padding: 24px; opacity: 0;
  transition: opacity var(--dur) var(--ease); }
.ov-scrim.ov-in { opacity: 1; }
.ov-scrim.ov-closing { opacity: 0; }
.ov-scrim--sheet { align-items: flex-end; padding: 0; }
.ov-modal { width: 100%; max-width: 460px; background: var(--bg-surface); border-radius: var(--r-lg);
  box-shadow: var(--shadow-3); max-height: 86vh; display: flex; flex-direction: column;
  transform: scale(.97); opacity: 0; transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease); }
.ov-modal.ov-in { transform: scale(1); opacity: 1; }
.ov-modal.ov--wide { max-width: 720px; }
.ov-modal.ov-closing { transform: scale(.97); opacity: 0; }
.ov-sheet { width: 100%; background: var(--bg-surface); border-radius: 20px 20px 0 0;
  box-shadow: var(--shadow-3); max-height: 92vh; display: flex; flex-direction: column;
  transform: translateY(100%); transition: transform var(--dur) var(--ease); padding-bottom: env(safe-area-inset-bottom); }
.ov-sheet.ov-in { transform: translateY(0); }
.ov-sheet.ov-closing { transform: translateY(100%); }
.ov-grabber { width: 40px; height: 4px; border-radius: 2px; background: var(--border-strong); margin: 10px auto 2px; }
.ov-head { display: flex; align-items: flex-start; gap: 12px; padding: 20px 20px 8px; flex-wrap: wrap; }
.ov-sheet .ov-head { padding-top: 6px; }
.ov-head-txt { flex: 1; min-width: 0; }
.ov-title { font-family: var(--serif); font-weight: 600; font-size: 22px; letter-spacing: -.3px; }
.ov-subtitle { font-size: 13px; color: var(--fg-subtle); margin-top: 3px; }
.ov-close { flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: var(--r-pill); color: var(--fg-faint);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease); }
.ov-close:hover { background: var(--bg-sunken); color: var(--fg); }
.ov-body { padding: 8px 20px 16px; overflow-y: auto; }
.ov-foot { display: flex; gap: 10px; justify-content: flex-end; padding: 14px 20px 20px; flex-wrap: wrap; }
.ov-sheet .ov-foot .btn, .ov-sheet .ov-foot { }
.ov-sheet .ov-foot { position: sticky; bottom: 0; background: var(--bg-surface); }

/* ---- Info button + settings ----------------------------------------- */
.info-btn { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px;
  border-radius: 50%; color: var(--fg-faint); vertical-align: middle; }
.info-btn:hover { color: var(--accent-deep); background: var(--accent-wash); }
.info-explain { font-size: 15px; line-height: 1.55; color: var(--fg-muted); }
.info-explain p { margin: 0 0 9px; }
.info-explain p:last-child { margin-bottom: 0; }
.info-explain code { font: 500 12.5px/1.4 var(--mono); background: var(--bg-sunken);
  padding: 1px 5px; border-radius: 4px; color: var(--fg); white-space: nowrap; }
.setting-row { padding: 14px 0; border-bottom: 1px solid var(--border); }
.setting-row:last-child { border-bottom: 0; }
.setting-label { display: flex; align-items: center; gap: 7px; font-weight: 600; font-size: 14px; margin-bottom: 10px; }
.setting-control { }

/* Segmented control */
.seg { display: inline-flex; background: var(--bg-surface-2); border-radius: var(--r-sm); padding: 3px; gap: 2px; width: 100%; }
.seg button { flex: 1; padding: 9px 6px; border-radius: 6px; font: 500 13px/1 var(--sans); color: var(--fg-muted);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
.seg button:hover:not(.on) { color: var(--fg); }
.seg button.on { background: var(--bg-surface); color: var(--fg); font-weight: 600; box-shadow: var(--shadow-1); }

/* ---- Collapsible ----------------------------------------------------- */
.clp { border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden; margin-bottom: 12px; background: var(--bg-surface); }
.clp-head { display: flex; align-items: center; gap: 8px; width: 100%; padding: 13px 15px; text-align: left; }
.clp-title { flex: 1; font-weight: 600; font-size: 14px; }
.clp-badge { font: 600 11px/1 var(--mono); color: var(--fg-subtle); background: var(--bg-sunken); padding: 4px 8px; border-radius: var(--r-pill); }
.clp-chevron { color: var(--fg-faint); transition: transform var(--dur) var(--ease); }
.clp--open .clp-chevron { transform: rotate(180deg); }
.clp-body { display: none; padding: 0 15px 15px; }
.clp--open .clp-body { display: block; }

/* ---- Form fields ----------------------------------------------------- */
.field { margin-bottom: 14px; }
.field label { display: block; font: 500 11px/1 var(--mono); letter-spacing: .07em; text-transform: uppercase; color: var(--fg-subtle); margin-bottom: 6px; }
.input, .textarea, select.input { width: 100%; font: 400 15px/1.4 var(--sans); color: var(--fg);
  padding: 11px 13px; border: 1px solid var(--border-strong); border-radius: var(--r-sm); background: var(--bg-surface); }
.input:focus, .textarea:focus, select.input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-wash); }
.textarea { min-height: 74px; resize: vertical; }

/* Prefix/suffix affix group — HB | 151 · Rep. | Hughes · name | Committee */
.affix { display: flex; align-items: stretch; }
.affix .input { min-width: 0; }
.affix-pre, .affix-suf { display: inline-flex; align-items: center; white-space: nowrap; padding: 0 12px;
  background: var(--bg-surface-2); color: var(--fg-subtle); font: 500 14px/1 var(--sans);
  border: 1px solid var(--border-strong); }
.affix-pre { border-right: 0; border-radius: var(--r-sm) 0 0 var(--r-sm); }
.affix-suf { border-left: 0; border-radius: 0 var(--r-sm) var(--r-sm) 0; }
.input--has-pre { border-top-left-radius: 0; border-bottom-left-radius: 0; }
.input--has-suf { border-top-right-radius: 0; border-bottom-right-radius: 0; }

/* Doc-link field + Share button */
.doc-row { display: flex; gap: 8px; align-items: stretch; }
.doc-row .input { flex: 1; min-width: 0; }
.doc-row .doc-share { flex: none; width: 46px; height: auto; border-radius: var(--r-sm);
  border: 1px solid var(--border-strong); color: var(--fg-muted); }
.doc-row .doc-share:hover { background: var(--bg-sunken); color: var(--fg); border-color: var(--accent); }

/* Name picker chips */
.name-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.name-chips .chip { padding: 8px 14px; border-radius: var(--r-pill); border: 1px solid var(--border-strong);
  background: var(--bg-surface); font-size: 14px; font-weight: 500; cursor: pointer; }
.name-chips .chip:hover { border-color: var(--accent); background: var(--accent-wash); }

/* ---- Toast ----------------------------------------------------------- */
.toast-host { position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%); z-index: 300;
  display: flex; flex-direction: column; gap: 8px; align-items: center; pointer-events: none; }
.toast { pointer-events: auto; display: flex; align-items: center; gap: 14px; background: var(--navy);
  color: #fff; padding: 12px 16px; border-radius: var(--r-pill); box-shadow: var(--shadow-3);
  font-size: 14px; opacity: 0; transform: translateY(12px); transition: opacity var(--dur), transform var(--dur); }
.toast--in { opacity: 1; transform: translateY(0); }
.toast-action { color: var(--gold-soft); font-weight: 700; font-size: 14px; }

/* ---- "I'm lost" panel ------------------------------------------------ */
.lost-sec { margin-bottom: 18px; }
.lost-sec .h { font: 500 10.5px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--fg-faint); margin-bottom: 8px; }
.lost-now { font-size: 15px; line-height: 1.55; color: var(--fg-muted); }
/* Give the status badge room to breathe, and center it on the bill-name line
   (an inline-flex pill baseline-aligns low otherwise). */
.lost-now .pill { margin-left: 10px; vertical-align: middle; }
.lost-say { font-family: var(--serif); font-style: italic; font-size: 21px; line-height: 1.35; color: var(--fg);
  background: var(--accent-wash); border-left: 3px solid var(--accent); padding: 14px 16px; border-radius: 0 var(--r-md) var(--r-md) 0; }
.lost-say .tok { font-style: normal; font-weight: 600; color: var(--accent-deep); }
.lost-actions { display: flex; flex-direction: column; gap: 8px; }
.lost-action { display: flex; gap: 10px; align-items: baseline; font-size: 14px; color: var(--fg-muted); }
.lost-action .k { flex: none; font-weight: 700; color: var(--fg); min-width: 130px; }

/* Floating pill buttons — "I'm Lost" (bottom-right) and "Adjourn" (bottom-left).
   Identical look; kept apart from the frequently-used dock actions. They sit
   under overlays (z below .ov-scrim). */
.lost-fab, .adjourn-fab {
  position: fixed; bottom: calc(20px + env(safe-area-inset-bottom)); z-index: 30;
  display: inline-flex; align-items: center; gap: 9px;
  padding: 12px 18px 12px 15px; border-radius: var(--r-pill);
  background: var(--bg-surface); color: var(--fg); border: 1px solid var(--gold-line);
  box-shadow: var(--shadow-2); font-family: var(--sans); font-weight: 600; font-size: 15px; line-height: 1;
  transition: transform 120ms var(--ease), box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease), right var(--dur) var(--ease);
}
.lost-fab { right: 20px; }
.adjourn-fab { left: 20px; }
.lost-fab svg, .adjourn-fab svg { color: var(--accent-deep); flex: none; }
.lost-fab:hover, .adjourn-fab:hover { transform: translateY(-2px); box-shadow: var(--shadow-3); border-color: var(--accent); }
.lost-fab:active, .adjourn-fab:active { transform: translateY(0); }
/* Slide "I'm Lost" clear of the desktop Bills sidebar when it's open. */
.body-row.sidebar-open ~ .lost-fab { right: calc(20px + var(--sidebar-w)); }
@media (max-width: 719px) {
  .lost-fab, .adjourn-fab { bottom: calc(14px + env(safe-area-inset-bottom)); padding: 11px 15px 11px 13px; font-size: 14px; }
  .lost-fab { right: 14px; }
  .adjourn-fab { left: 14px; }
}

/* ---- Login ----------------------------------------------------------- */
.login { min-height: 100%; display: flex; align-items: center; justify-content: center; padding: 24px; }
/* Sign-in: the animated brand pattern behind the card (navy #16242B fallback,
   matching the image's own field, under it). Column layout stacks logo / card /
   admin link. */
.login--signin { flex-direction: column; min-height: 100dvh;
  background: var(--navy) url('../img/PatternAnimatedBackground.svg') center / cover no-repeat; }
/* On the sign-in, paint the whole browser canvas navy so iOS Safari's status
   and URL-bar areas (and overscroll) show navy, not white, around the image. */
html.signin, html.signin body { background: var(--navy); }
.login-logo { display: flex; justify-content: center; margin-bottom: 24px; }
.login--signin .login-card h1 { font-size: 26px; }
/* Discreet admin entry under the card, readable on the dark pattern. */
.login-admin { margin-top: 20px; display: inline-flex; align-items: center; gap: 8px;
  color: rgba(255,255,255,.82); font: 600 14px/1 var(--sans);
  padding: 10px 16px; border-radius: var(--r-pill);
  background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.18);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease); }
.login-admin:hover { background: rgba(255,255,255,.15); color: #fff; border-color: rgba(255,255,255,.32); }
.login-admin svg { color: var(--accent); }
.login-card { width: 100%; max-width: 420px; background: var(--bg-surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--shadow-2); padding: 32px 30px; text-align: center; }
.login-card .logo { display: flex; justify-content: center; margin-bottom: 18px; }
.login-card h1 { font-family: var(--serif); font-weight: 600; font-size: 30px; margin: 0 0 6px; letter-spacing: -.4px; }
.login-card .sub { color: var(--fg-subtle); font-size: 14px; margin-bottom: 22px; }
.login-card .field { text-align: left; }

/* ---- Reference links menu ------------------------------------------- */
.reslink { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-radius: var(--r-md);
  border: 1px solid var(--border); background: var(--bg-surface); margin-bottom: 8px; font-weight: 500; color: var(--fg); }
.reslink:hover { border-color: var(--accent); }
.reslink .ext { margin-left: auto; color: var(--fg-faint); }
/* Destructive row (e.g. "Reset everything") reads red and hovers red. */
.reslink--danger { color: var(--red); }
.reslink--danger:hover { border-color: var(--red); background: var(--red-soft); }

/* ==========================================================================
   Admin dashboard
   ========================================================================== */
.admin { max-width: 1200px; margin: 0 auto; padding: 24px 24px 60px; }
/* Header: 3-column grid — Announce pinned left, logo centered in its own
   column, add-buttons + three-dot pinned right. A grid (vs. an absolutely
   centered logo) means the columns never overlap as the window narrows. */
.admin-top { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 10px; margin-bottom: 16px; min-height: 44px; }
.admin-announce { justify-self: start; }
.admin-logo { justify-self: center; display: inline-flex; }
.admin-right { justify-self: end; display: flex; align-items: center; gap: 10px; min-width: 0; }
.admin-actions { display: flex; align-items: center; gap: 10px; }
.admin-grid { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 20px; align-items: start; }
.card { background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--shadow-1); padding: 18px 20px; }
.card h2 { font-family: var(--serif); font-weight: 600; font-size: 19px; margin: 0 0 14px; }
.chart-donut { display: flex; justify-content: center; margin: 6px 0 16px; }
.chart-donut-num { font: 700 30px/1 var(--sans); fill: var(--fg); }
.chart-donut-lbl { font: 500 11px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; fill: var(--fg-faint); }
.chart-legend-row { display: flex; align-items: center; gap: 9px; padding: 5px 0; font-size: 13px; }
.chart-legend-dot { width: 11px; height: 11px; border-radius: 3px; flex: none; }
.chart-legend-lbl { flex: 1; color: var(--fg-muted); }
.chart-legend-val { color: var(--fg-subtle); font: 500 12px/1 var(--mono); }

.committee-block { margin-bottom: 22px; border-radius: var(--r-md); transition: box-shadow var(--dur) var(--ease), background var(--dur) var(--ease); }
/* The empty-state card ("No committees yet") sits in the same column as the
   committee/trash blocks — give it the same spacing so it doesn't butt up
   against the Trash section below it. */
.committees > .card { margin-bottom: 22px; }
.committee-block .ch { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.committee-block .ch .nm { font-family: var(--serif); font-weight: 600; font-size: 18px; }
.committee-block .ch .count { font: 600 11px/1 var(--mono); color: var(--fg-subtle); background: var(--bg-sunken); padding: 4px 8px; border-radius: var(--r-pill); flex: none; }
.committee-block .ch .meta { font: 500 12px/1 var(--mono); color: var(--fg-subtle); }
.committee-block .ch .spacer { flex: 1; }
/* Chevron toggle — points down when open, right when collapsed. */
.ch-toggle { flex: none; }
.ch-toggle svg { transition: transform var(--dur) var(--ease); }
.committee-block.is-collapsed .ch-toggle svg { transform: rotate(-90deg); }
.committee-block.is-collapsed .cb-body { display: none; }
/* Unassigned folder reads as a holding area, not a real committee. */
.committee-block--unassigned .ch .nm { color: var(--fg-subtle); }
.committee-block--unassigned { border: 1px dashed var(--border-strong); padding: 4px 12px 8px; }
/* Drop-target highlight while dragging a bill onto a committee. */
.committee-block.drop-target { background: var(--accent-wash); box-shadow: 0 0 0 2px var(--accent); }
.admin-bill .drag-handle { color: var(--fg-faint); cursor: grab; touch-action: none; display: inline-flex; margin-right: 2px; }
.admin-bill.is-drag-src { opacity: .35; }
/* Floating clone that follows the pointer during a cross-committee drag. */
.admin-bill--ghost { position: fixed; z-index: 9999; pointer-events: none; box-shadow: var(--shadow-3);
  border-color: var(--accent); transform: rotate(1.5deg); opacity: .96; }
.admin-bills { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; }
.admin-bill { display: flex; flex-direction: column; gap: 8px; padding: 13px 15px; border: 1px solid var(--border);
  border-radius: var(--r-md); background: var(--bg-surface); }
.admin-bill .top { display: flex; align-items: center; gap: 8px; }
.admin-bill .num { font: 600 12px/1 var(--mono); }
.admin-bill .ttl { font-size: 14px; color: var(--fg-muted); font-weight: 500; }
.admin-bill .spn { font-size: 12px; color: var(--fg-subtle); }
.admin-bill .foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 2px; }

/* ---- Activity feed (admin + pop-out) -------------------------------- */
.feed-card { margin-top: 18px; padding: 0; overflow: hidden; }
.feed-head { display: flex; align-items: center; gap: 6px; padding: 12px 12px 10px 8px; }
/* Beat the higher-specificity `.card h2 { margin: 0 0 14px }` — that bottom
   margin, centered in the flex row, floated "Activity" above the icons. */
.feed-head .feed-title { font-family: var(--serif); font-weight: 600; font-size: 17px; margin: 0; line-height: 1; }
.feed-card.is-collapsed .feed-body { display: none; }
.feed-body { padding: 0 14px 14px; }
.feed-filter { margin-bottom: 10px; font-size: 13px; padding: 8px 10px; }
.feed-list { display: flex; flex-direction: column; gap: 2px; max-height: 360px; overflow-y: auto; }
.feed-item { display: flex; align-items: baseline; gap: 8px; padding: 6px 4px; border-bottom: 1px solid var(--border); font-size: 13px; }
.feed-item:last-child { border-bottom: 0; }
.feed-item .fi-ico { color: var(--fg-faint); flex: none; align-self: center; display: inline-flex; }
/* Bill events use a small ring — thin outline, no fill (like the original dot) —
   tinted to the bill's CURRENT status (set inline), so the feed reflects where a
   bill stands now, not when it was logged. */
.feed-item .fi-dot { width: 8px; height: 8px; border-radius: 50%; border: 1.5px solid currentColor; box-sizing: border-box; }
.feed-item .fi-text { flex: 1; min-width: 0; color: var(--fg-muted); line-height: 1.35; }
.feed-item .fi-time { flex: none; color: var(--fg-faint); font: 500 11px/1 var(--mono); white-space: nowrap; }
.feed-empty { padding: 14px 4px; color: var(--fg-faint); font-size: 13px; text-align: center; }
/* Right-click affordance on activity rows. */
.feed-item { cursor: default; border-radius: var(--r-sm); }
.feed-item.is-ctx-target { background: var(--accent-wash); }
/* Context (right-click) menu for the activity log. */
.ctx-menu { position: fixed; z-index: 3000; min-width: 210px; padding: 5px;
  background: var(--bg-surface); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--shadow-3); }
.ctx-menu button { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  padding: 9px 11px; border: 0; border-radius: var(--r-sm); background: none; cursor: pointer;
  font: 500 13px/1.2 var(--sans); color: var(--fg-muted); }
.ctx-menu button svg { flex: none; color: var(--fg-faint); }
.ctx-menu button:hover { background: var(--bg-sunken); color: var(--fg); }
.ctx-menu button.danger { color: var(--red); }
.ctx-menu button.danger svg { color: var(--red); }
.ctx-menu button.danger:hover { background: var(--red-soft); color: var(--red); }
/* Attention alerts sit at the top of the feed. */
.feed-alert { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: var(--r-sm); margin-bottom: 6px; font-size: 13px; line-height: 1.35; }
.feed-alert .fa-ico { flex: none; display: inline-flex; }
.feed-alert .fa-text { flex: 1; min-width: 0; }
.feed-alert--warn { background: var(--amber-soft); color: var(--gold-deep); }
.feed-alert--warn .fa-ico { color: var(--gold-deep); }
.feed-alert--urgent { background: var(--red-soft); color: var(--red); }
.feed-alert--urgent .fa-ico { color: var(--red); }
/* Subtle green dot next to a committee whose chair is signed in. */
.presence-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--green); flex: none;
  box-shadow: 0 0 0 3px var(--green-soft); }
/* Checkbox row (alert settings) */
.chk-row { display: flex; align-items: center; gap: 9px; font-size: 14px; color: var(--fg-muted); cursor: pointer; }
.chk-row input { width: 16px; height: 16px; flex: none; }
/* Pop-out feed window (feed.html) */
.feed-popout { padding: 14px 16px 20px; max-width: 640px; margin: 0 auto; }
.feed-popout-head { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.feed-popout-head .fp-title { display: inline-flex; align-items: center; gap: 8px; font-family: var(--serif); font-weight: 600; font-size: 20px; flex: 1; }
.feed-popout-head .fp-title svg { color: var(--accent-deep); }
.feed-popout .feed-list { max-height: none; }

/* ---- Bill history (bottom of the bill editor) ----------------------- */
.hist-list { display: flex; flex-direction: column; }
.hist-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--border); font-size: 13px; }
.hist-row:last-child { border-bottom: 0; }
.hist-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); flex: none; }
.hist-label { flex: 1; color: var(--fg-muted); }
.hist-time { color: var(--fg-faint); font: 500 12px/1 var(--mono); white-space: nowrap; }

/* ---- Trash block (admin) ------------------------------------------- */
.committee-block--trash { border: 1px dashed var(--border-strong); padding: 4px 12px 8px; }
.committee-block--trash .tr-head-ico { display: inline-flex; color: var(--fg-subtle); }
.committee-block--trash .nm { color: var(--fg-subtle); }
.trash-list { display: flex; flex-direction: column; gap: 6px; }
.trash-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--bg-surface); }
.trash-row .tr-ico { color: var(--fg-faint); flex: none; display: inline-flex; }
.trash-row .tr-label { flex: 1; min-width: 0; font-size: 13px; color: var(--fg-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- Responsive ------------------------------------------------------ */
/* Stack the admin header (Announce · logo · three-dot on row 1; add-buttons on
   row 2) before the centered logo would collide with the right-side buttons
   (~826px). Wider screens keep the single-row centered layout via the base grid. */
@media (max-width: 860px) {
  .admin-top { display: flex; position: static; flex-wrap: wrap; gap: 12px 8px; }
  /* Flatten the right wrapper so its children join the flex row directly. */
  .admin-right { display: contents; }
  .admin-logo { order: 2; margin: 0 auto; justify-self: auto; }
  .admin-announce { order: 1; }
  .admin-more { order: 3; }
  .admin-actions { order: 4; flex-basis: 100%; margin-left: 0; }
  .admin-actions .btn { flex: 1 1 calc(50% - 5px); white-space: normal; }
}

@media (max-width: 719px) {
  :root { --header-h: 56px; }
  /* Bill bar stays pinned (its own sticky sibling); script re-centers via the
     shared .stage-inner margin:auto — no mobile-specific top-align needed. */
  .stage { padding: 0 18px 18px; }
  .bill-bar { padding: 16px 0 12px; }
  .stage-inner { padding: 18px 0; }
  .script { max-width: 100%; }
  /* Sponsor stacks under the title so the chip fits a narrow screen. */
  .bc-main { flex: 1; flex-direction: column; align-items: flex-start; gap: 1px; }
  .bill-chip .ttl { max-width: 100%; }
  .bill-chip .spn { border-left: 0; padding-left: 0; font-size: 11px; }
  .hdr { padding: 0 6px; gap: 6px; }
  .hdr-clock { display: none; }
  .iconbtn { width: 38px; height: 38px; }
  .hide-mobile { display: none !important; }
  .body-row.sidebar-open .stage-wrap { margin-right: 0; }
  /* On mobile the sidebar never uses the desktop panel — bills open as a bottom sheet instead */
  .sidebar { display: none; }
  /* Reserve a bottom strip so the fixed "I'm Lost" button never covers the
     last action button (the dock is pinned to the bottom on mobile). */
  .dock { padding-bottom: calc(84px + env(safe-area-inset-bottom)); align-items: stretch; }
  /* Primary spans the top row; the rest pack two-per-row beneath it.
     Allow labels to wrap so a button can shrink to half-width (nowrap would
     force each onto its own row). */
  .dock .btn { flex: 1 1 calc(50% - 5px); white-space: normal; line-height: 1.15; min-height: 46px; }
  .dock .btn--primary { flex-basis: 100%; }
  .admin-grid { grid-template-columns: minmax(0, 1fr); }
  .ov-foot .btn { flex: 1; }
  /* Tighter page padding on phones (header stacking lives in the 860px query). */
  .admin { padding: 18px 16px 48px; }
  /* Committee heading wraps cleanly: name + count on the first row, the meta
     drops to its own line, action buttons stay on the right. */
  .committee-block .ch { flex-wrap: wrap; gap: 8px; }
  .committee-block .ch .nm { font-size: 16px; }
  .committee-block .ch .meta { order: 6; flex-basis: 100%; }
  /* Collapsed committee: hide the "Chair: …" line so the header stays compact. */
  .committee-block.is-collapsed .ch .meta { display: none; }
  .committee-block .ch .ch-toggle { margin-left: -8px; }
}
@media (min-width: 720px) {
  .hide-desktop { display: none !important; }
}
