/* Hanken Grotesk — self-hosted (strict no-CDN rule; OFL.txt alongside the font).
   Variable weight axis 100–900; we use 400–800. Relative url() so WhiteNoise's
   manifest storage rewrites it to the hashed file in production. */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/hanken-grotesk/HankenGrotesk-Variable.c501f578bf3f.woff2") format('woff2');
}

:root {
  /* Brand & neutrals */
  --brand:      #0b6e99;   /* teal — links, primary buttons, placed person */
  --brand-ink:  #095a7e;   /* hover / pressed brand */
  --ink:        #0e1620;   /* headings */
  --body:       #1b2733;   /* body text */
  --muted:      #5b6b7a;   /* secondary text, table labels */
  --card:       #ffffff;
  --subtle:     #f4f7f9;   /* table header, inset panels */
  --page:       #f6f8fa;   /* page background */
  --row-line:   #eef2f5;   /* table row divider */
  --hairline:   #dde4ea;   /* card & control borders */
  --deck-dark:  #0e1620;   /* dark bars (locked banner) */

  /* Status — each a solid + soft-tint pair */
  --ok:         #12864a;  --ok-soft:     #e3f5e9;  /* confirmed / worked / full */
  --warn:       #b5730a;  --warn-soft:   #fdf3e0;  /* in progress / unfilled */
  --danger:     #c22f3a;  --danger-soft: #fdecea;  /* no-show / error */

  /* UI redesign convention (#151): clickable controls use the rounded input,
     button, or pill radii; new static cards, tiles, badges, tables, and overlay
     panels use --r-static. Dense tables have exactly two soft exceptions:
     level pins use 6px and qualification codes use 4px. Native checkboxes stay
     square so multi-select controls do not read as radio buttons. */
  --r-static: 0; --r-code: 4px; --r-pin: 6px; --r-input: 8px; --r-chip: 9px;
  --r-btn: 10px; --r-card: 12px;
  --r-pill: 999px;

  /* Existing spacing — 4px grid */
  --sp-tight: 8px; --sp-base: 12px; --sp-comfy: 14px; --sp-section: 22px;
  /* Opt-in compact-screen scale; legacy screens keep the values above until
     their redesign lands. */
  --sp-row-compact: 2px; --sp-row-comfortable: 6px; --sp-overlay: 8px;
  --sp-card-compact: 10px; --sp-section-compact: 10px;

  /* Elevation */
  --border-flat: 1px solid var(--hairline);
  --shadow-raised: 0 6px 24px rgba(14, 22, 32, 0.14);

  --font: 'Hanken Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI',
          Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }
body {
  margin: 0;
  font-family: var(--font);
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--body);
  background: var(--page);
}

.topbar {
  display: flex; align-items: center; gap: 1.5rem;
  background: var(--card); border-bottom: var(--border-flat);
  padding: 0.6rem 1.25rem;
}
.brand { font-weight: 800; color: var(--brand); text-decoration: none; font-size: 1.1rem; letter-spacing: -0.01em; }

/* Desktop navigation (#84): two fixed rows, permission-filtered server-side. */
.topbar--authenticated { display: block; padding: 0; border: 0; }
.nav-row-1 { display: flex; align-items: center; gap: 16px; height: 58px;
  padding: 0 24px; background: var(--card); }
.nav-wordmark { flex: 0 0 auto; font-size: 1.15rem; font-weight: 800;
  color: var(--brand); letter-spacing: -0.01em; text-decoration: none; }
.nav-tabs { display: flex; align-items: center; gap: 3px; padding: 4px;
  background: #f0f3f5; border-radius: 10px; }
.nav-tab { padding: 8px 16px; border-radius: 8px; color: var(--muted);
  font-size: 0.86rem; font-weight: 700; text-decoration: none; }
.nav-tab:hover { color: var(--ink); }
.nav-tab--active { color: var(--brand); background: var(--card);
  box-shadow: 0 2px 6px rgba(14, 22, 32, 0.12); }
.nav-tab--active:hover { color: var(--brand); }
.nav-account { position: relative; margin-left: auto; }
.nav-account-btn { display: flex; align-items: center; gap: 8px;
  padding: 5px 12px 5px 6px; border: 1px solid var(--hairline);
  border-radius: var(--r-pill); background: var(--card); color: var(--body); }
.nav-account-btn:hover { background: var(--card); border-color: #c7cfd6; }
.nav-account-name { max-width: 110px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; color: var(--ink); font-size: 0.85rem; font-weight: 700; }
.nav-caret { color: var(--muted); font-size: 0.65rem; }
.nav-avatar { display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: var(--r-pill);
  background: var(--muted); color: #fff; font-size: 0.66rem; font-weight: 800; }
.nav-account-menu { position: absolute; z-index: 20; top: 42px; right: 0;
  min-width: 190px; padding: 8px; background: var(--card);
  border: 1px solid var(--hairline); border-radius: 10px;
  box-shadow: 0 10px 28px rgba(14, 22, 32, 0.16); }
.nav-account-menu[hidden] { display: none; }
.nav-account-menu-item { display: block; width: 100%; padding: 9px 12px;
  border: 0; border-radius: 7px; background: none; color: var(--body);
  font-size: 0.88rem; font-weight: 600; line-height: 1.5; text-align: left;
  text-decoration: none; }
.nav-account-menu-item--primary { color: var(--brand); font-weight: 800; }
.nav-account-menu-item:hover { background: var(--subtle); color: var(--body); }
.nav-account-menu-item--primary:hover { color: var(--brand); }
.nav-account-logout { margin: 0; }
.nav-row-2 { display: flex; align-items: center; height: 42px; padding: 0 24px;
  background: var(--subtle); border-top: 1px solid var(--row-line);
  border-bottom: 1px solid var(--hairline); }
.nav-row-2 nav { display: flex; align-items: center; gap: 22px; }
.nav-sub { color: var(--muted); font-size: 0.83rem; font-weight: 600;
  text-decoration: none; }
.nav-sub:hover { color: var(--ink); }
.nav-sub--active { color: var(--brand); font-weight: 700; }
.nav-sub--active:hover { color: var(--brand); }
.nav-tab:focus-visible, .nav-sub:focus-visible, .nav-account-btn:focus-visible,
.nav-account-menu-item:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
/* Attention count on a nav tab/sub-item (e.g. pending member approvals). */
.nav-badge { display: inline-block; min-width: 1.1rem; padding: 0 5px;
  border-radius: var(--r-pill); background: var(--danger); color: #fff;
  font-size: 0.7rem; font-weight: 700; line-height: 1.25rem; text-align: center;
  vertical-align: middle; }

main { max-width: 1100px; margin: 1.5rem auto; padding: 0 1.25rem; }

h1 { font-size: 1.5rem; font-weight: 800; letter-spacing: -0.01em; color: var(--ink); }
h2 { font-size: 1.15rem; font-weight: 700; color: var(--ink); }
h3 { font-size: 1rem; font-weight: 700; color: var(--ink); }
a { color: var(--brand); }
.muted { color: var(--muted); }
.small { font-size: 0.84rem; }

.page-head { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 1rem; }
.search { display: flex; gap: 0.5rem; }

.card {
  background: var(--card); border: var(--border-flat); border-radius: var(--r-card);
  padding: var(--sp-section); margin-bottom: 1.25rem;
}
.card.narrow { max-width: 480px; }
/* Compose card (Messaging editor): wide enough to write an email in, and the
   subject/name inputs stay readable rather than stretching the full width. */
.card.compose { max-width: 860px; }
.card.compose input[type="text"] { max-width: 520px; }
.columns { display: flex; gap: 1.25rem; align-items: flex-start; flex-wrap: wrap; }
.columns .card { flex: 1 1 300px; }
.columns .card.grow { flex: 2 1 480px; }

table.data { width: 100%; border-collapse: separate; border-spacing: 0;
  background: var(--card); border: var(--border-flat); border-radius: var(--r-card); overflow: hidden; }
table.data th, table.data td { text-align: left; vertical-align: top; padding: 12px 18px; }
/* Header band: thead, or the leading th row of thead-less tables */
table.data thead th, table.data tr:first-child th { background: var(--subtle); color: var(--muted);
  font-size: 0.73rem; text-transform: uppercase; letter-spacing: 0.04em; font-weight: 700;
  white-space: nowrap; }
table.data td { padding: 13px 18px; border-top: 1px solid var(--row-line); font-size: 0.92rem; }
table.data tr:first-child td { border-top: none; }
/* Footer/summary th rows (e.g. a "Total" row) keep the row divider */
table.data tbody tr:not(:first-child) th { border-top: 1px solid var(--row-line); }
/* Density is explicitly opt-in so screens migrate without changing legacy
   tables. Keep horizontal padding intact; only row height changes. */
table.data[data-density="comfortable"] th,
table.data[data-density="comfortable"] td { padding-block: var(--sp-row-comfortable); }
table.data[data-density="compact"] th,
table.data[data-density="compact"] td { padding-block: var(--sp-row-compact); }

.chip {
  display: inline-block; padding: 3px 11px; border-radius: var(--r-pill);
  font-size: 0.76rem; font-weight: 600; margin: 0.1rem 0.15rem 0.1rem 0; white-space: nowrap;
}
.chip.ok { background: var(--ok-soft); color: var(--ok); }
.chip.warn { background: var(--warn-soft); color: var(--warn); }
.chip.danger { background: var(--danger-soft); color: var(--danger); }
/* Generic neutral info chip (e.g. a sign-up's "Submitted" status). Renamed from
   .chip.level — that name collided with the level-pin scale below, and its blue
   read as Level 5 once the pins took the real Swimming Canada colours. */
.chip.info { background: #e8f0fe; color: #25467a; }
.chip.locked { background: var(--deck-dark); color: #fff; font-weight: 700; }
/* Roster "Positions" column (#68, three states since #82 — Sherry): one green
   scale where shade = sign-off progress. ALL states can work the role
   (eligibility = has the course); the shade only says how far the sign-offs
   are. Solid = signed off · soft + dark ring = sign-offs started · soft =
   course done. The ring is an inset box-shadow, not a border, so pill
   geometry doesn't shift between states. */
.chip.pos-done { background: var(--ok); color: #fff; font-weight: 700; }
.chip.pos-mid { background: var(--ok-soft); color: var(--ok); font-weight: 700;
  box-shadow: inset 0 0 0 2px var(--ok); }
.chip.pos-wip { background: var(--ok-soft); color: var(--ok); }
.chip.pos-done, .chip.pos-mid, .chip.pos-wip { border-radius: var(--r-code); }

/* Level pins (#24): mirror the real Swimming Canada official pins, so the colour
   means what officials already recognise on deck —
   L1 #ea1d3e/white · L2 #fff/#33404d with #c4ccd4 border ·
   L3 #f6641e/#1b2733 · L4 #166534/white · L5 #1e3a8a/white. These exact values
   are domain truth, not styling; see docs/HANDOFF-federation.md for the colour
   source. Never substitute semantic status tokens.
   Pins use the deliberate 6px soft-square exception and are never pill-shaped —
   shape is load-bearing so a green L4 pin never reads as a green status chip.
   Solid = board/glare surfaces;
   .lvlpin--soft = dense laptop tables (same hue, tinted bg + dark same-hue ink).
   L2 is white and ALWAYS carries its border or it vanishes on light surfaces. */
.lvlpin {
  display: inline-block; min-width: 1.4em; text-align: center;
  padding: 2px 8px; border-radius: var(--r-pin); font-size: 0.72rem;
  font-weight: 800; letter-spacing: 0.01em;
}
/* L1/L3 hues are the native macOS Digital Color Meter readings off the real
   pins (Ben, 2026-07-04): red rgb(234,29,62), orange rgb(246,100,30). The
   brighter, clearly-separated red vs orange is the point — they were too close
   before. Orange takes dark ink (white on it is only ~3.1:1); red keeps white. */
.lvlpin.level-1 { background: #ea1d3e; color: #fff; }
.lvlpin.level-2 { background: #ffffff; color: #33404d; border: 1.5px solid #c4ccd4; }
.lvlpin.level-3 { background: #f6641e; color: #1b2733; }
.lvlpin.level-4 { background: #166534; color: #fff; }
.lvlpin.level-5 { background: #1e3a8a; color: #fff; }
.lvlpin--soft.level-1 { background: #fde4e7; color: #b21230; }
.lvlpin--soft.level-2 { background: #ffffff; color: #33404d; border: 1px solid #c4ccd4; }
.lvlpin--soft.level-3 { background: #ffe6d5; color: #b34410; }
.lvlpin--soft.level-4 { background: #dcfce7; color: #166534; }
.lvlpin--soft.level-5 { background: #dbeafe; color: #1e3a8a; }
.lvlpin--sub { background: #1b2733; color: #fff; min-width: 1.4em; }

/* Colour→level key; render wherever pins appear unlabelled (board, roster).
   Doubles as the colour-blind / glare fallback. */
.lvl-legend { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  font-size: 0.8rem; color: var(--muted); margin: 0.35rem 0 0.9rem; }

.flash.locked-banner { background: var(--deck-dark); color: #fff; border-color: var(--deck-dark); }

/* Attendance confirmation (M5 step 3): muted by default, bold-coloured when chosen */
.att-set button { margin-right: 0.3rem; background: var(--row-line); color: var(--muted);
  padding: 7px 14px; font-size: 0.85rem; font-weight: 600; border-radius: var(--r-input); }
.att-set button:hover { background: var(--hairline); color: var(--body); }
.att-set button.on-worked { background: var(--ok); color: #fff; font-weight: 700; }
.att-set button.on-worked:hover { background: var(--ok); color: #fff; }
.att-set button.on-noshow { background: var(--warn); color: #fff; font-weight: 700; }
.att-set button.on-noshow:hover { background: var(--warn); color: #fff; }
.att-progress { font-size: 1.05rem; margin-bottom: 0.4rem; }
.att-meter { margin-bottom: 1.1rem; }

.cred { display: block; font-size: 0.85rem; }

input, select, textarea {
  font: inherit; padding: 0.5rem 0.7rem; border: var(--border-flat);
  border-radius: var(--r-input); width: 100%; background: var(--card);
}
input[type="checkbox"] { border-radius: var(--r-static); }
textarea { resize: vertical; min-height: 4.5rem; }
form div { margin-bottom: 0.75rem; }
label { display: block; font-size: 0.9rem; margin-bottom: 0.5rem; }
button {
  font: inherit; font-weight: 700; font-size: 0.9rem;
  background: var(--brand); color: #fff; border: none;
  border-radius: var(--r-btn); padding: 0.55rem 1.1rem; cursor: pointer;
}
button:hover { background: var(--brand-ink); }
button.linklike { background: none; color: var(--brand); padding: 0; font-weight: 600; text-decoration: underline; }
button.linklike:hover { background: none; color: var(--brand-ink); }
button.linklike.danger { color: var(--danger); }
button.btn-danger { background: var(--danger); }
button.btn-danger:hover { background: #a5232d; }
/* One PRIMARY action per view (the next lifecycle step); everything else is
   secondary. Base <button> is the primary look; .btn-secondary quiets it. */
button.btn-secondary { background: var(--card); color: var(--brand);
  border: 1.5px solid var(--brand); padding: calc(0.55rem - 1.5px) calc(1.1rem - 1.5px); }
button.btn-secondary:hover { background: var(--subtle); color: var(--brand-ink); }
/* Buttons inside table rows: compact, never mid-word wrapped */
table.data button { white-space: nowrap; padding: 7px 14px; font-size: 0.85rem; }
.row-actions { display: flex; gap: 0.9rem; align-items: center; }
.row-actions form { display: inline; margin: 0; }

details.slotlist { margin-top: 0.75rem; }
details.slotlist > summary {
  cursor: pointer; font-weight: 600; color: var(--muted);
  padding: 0.3rem 0; user-select: none;
}
details.slotlist > summary:hover { color: var(--ink); }
details.slotlist[open] > summary { margin-bottom: 0.4rem; }
button.toggle { background: var(--row-line); color: var(--muted); font-weight: 600; padding: 0.25rem 0.75rem; font-size: 0.85rem; border-radius: var(--r-input); }
button.toggle:hover { background: var(--hairline); color: var(--body); }
button.toggle.on { background: var(--ok-soft); color: var(--ok); font-weight: 700; }
button.toggle.on:hover { background: var(--ok-soft); }

.inline-form { max-width: 420px; }

.selfmark { color: var(--warn); font-weight: 700; margin-left: 0.1rem; }

.rowform { display: inline-flex; align-items: center; gap: 0.4rem; margin: 0; }
.rowform div { margin: 0; }
/* Text inputs in an inline row (e.g. the unlock "reason") must not grab the
   global width:100% and push the button onto a second line. */
.rowform input[type="text"] { width: auto; min-width: 13rem; }
/* Let the header action cluster wrap instead of stretching one control full-width */
.page-head > .rowform { flex-wrap: wrap; gap: 0.5rem; justify-content: flex-end; }
input.tiny { width: 4rem; padding: 0.25rem 0.4rem; }
.inlinecheck { display: inline-flex; align-items: center; gap: 0.25rem; margin: 0; font-size: 0.85rem; }
.inlinecheck input { width: auto; }
.reqgrid { display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; margin-bottom: 0.75rem; }
.reqitem { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.9rem; background: var(--row-line); border-radius: var(--r-input); padding: 0.25rem 0.6rem; }

/* Assignment board: the scroll wrapper owns horizontal movement; the pool is
   its sibling so document scrolling can keep that sidebar sticky. */
.board-root { position: relative; }
.board-shell { display: grid; grid-template-columns: minmax(0, 1fr) 260px;
  align-items: start; gap: var(--sp-card-compact); }
.board-scroll { max-width: 100%; overflow-x: auto; border: var(--border-flat);
  border-radius: var(--r-static); background: var(--card); }
.board-scroll:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; }
.board-matrix { width: max(100%, calc(155px + var(--board-session-width)));
  table-layout: fixed; border-collapse: separate; border-spacing: 0; font-size: 0.86rem; }
.board-label-column { width: 155px; }
.board-session-column { width: 168px; }
.board-matrix th, .board-matrix td { width: 168px; min-width: 168px; max-width: 168px;
  padding: var(--sp-row-comfortable) 8px;
  border-right: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline);
  vertical-align: middle; text-align: left; background: var(--card); }
.board-matrix thead th { background: var(--subtle); text-align: center;
  font-weight: 750; white-space: nowrap; }
.board-matrix tr > :last-child { border-right: 0; }
.board-matrix tbody:last-child tr:last-child > * { border-bottom: 0; }
.board-matrix .board-frozen { position: sticky; left: 0; z-index: 3; min-width: 155px;
  max-width: 155px; background: var(--card); box-shadow: 1px 0 0 var(--hairline); }
.board-matrix thead .board-frozen { z-index: 5; background: var(--subtle); }
.board-position-band > th, .board-position-band > td { background: var(--row-line);
  color: var(--ink); font-weight: 800; }
.board-position-band .board-frozen { background: var(--row-line); }
.board-row-label { color: var(--muted); font-weight: 600; }
.board-session-meta { display: block; margin-top: 2px; color: var(--muted);
  font-size: 0.72rem; font-weight: 500; }
.board-cell { position: relative; height: 46px; }
.board-cell--blank { background: var(--subtle); }
.board-cell.is-armed-target { background: var(--ok-soft); box-shadow: inset 0 0 0 2px var(--ok); }
.dropzone { display: grid; list-style: none; margin: 0; padding: 0; min-height: 34px;
  min-width: 0; }
.dropzone > * { grid-area: 1 / 1; }
.board-open-item { min-width: 0; list-style: none; }
.dropzone:has(.person) .board-open-item { visibility: hidden; }
.person { display: flex; align-items: center; gap: 5px; margin: 0; padding: 3px;
  width: 100%; min-width: 0; min-height: 34px; border-radius: var(--r-chip);
  background: var(--brand); color: #fff;
  font-size: 0.84rem; font-weight: 650; list-style: none; }
.person.unverified { background: var(--warn); }
.board-drag-handle { flex: 0 0 auto; padding: 4px 2px; font-size: 1rem;
  line-height: 1; cursor: grab; user-select: none; }
.board-person-button, .board-arm-button { display: flex; flex: 1; align-items: center;
  min-width: 0; padding: 4px 5px; border: 0; background: transparent; color: inherit;
  font: inherit; text-align: left; cursor: pointer; }
.board-person-button > span, .board-arm-button > span,
.board-picker-choice > span, .board-picker [data-board-person-display] {
  display: flex; align-items: center; gap: 6px; min-width: 0; }
.board-person-button > span > span:last-child, .board-arm-button > span > span:last-child {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.board-open-button { width: 100%; padding: 7px 9px; border: 1.5px dashed #d9b25f;
  background: var(--warn-soft); color: #8a6210; font-weight: 750; text-align: left; }
.board-open-label { color: var(--muted); }
.board-pool { position: sticky; top: 12px; max-height: calc(100vh - 24px); overflow-y: auto;
  padding: var(--sp-card-compact); border: var(--border-flat); border-radius: var(--r-static);
  background: var(--card); }
.board-pool h2 { margin: 0 0 var(--sp-card-compact); }
.board-pool label { display: block; margin-bottom: var(--sp-card-compact);
  color: var(--muted); font-size: 0.78rem; font-weight: 700; }
.board-pool select { margin-top: 3px; }
.board-pool-list { min-height: 64px; margin: var(--sp-card-compact) 0 0; padding: 0;
  list-style: none; }
.board-pool-person { margin-bottom: 5px; background: var(--subtle); color: var(--body);
  border: 1px solid var(--hairline); }
.board-pool-person[hidden] { display: none; }
.board-pool-person:has(.board-arm-button[aria-pressed="true"]) { border-color: var(--brand);
  background: #eaf3f5; box-shadow: inset 0 0 0 1px var(--brand); }
.board-arm-status { min-height: 2.4em; margin: var(--sp-card-compact) 0 0;
  color: var(--brand-ink); font-size: 0.8rem; font-weight: 700; }
.board-picker { z-index: 40; min-width: 230px; max-width: 320px; }
.board-picker h3 { margin: 0 0 var(--sp-overlay); font-size: 0.86rem; }
.board-picker-choice, .board-picker-action { display: flex; align-items: center; gap: 6px;
  width: 100%; margin: 2px 0; padding: 7px 8px; border: 0; background: transparent;
  color: var(--body); font-size: 0.84rem; font-weight: 650; text-align: left; }
.board-picker-choice:hover, .board-picker-action:hover { background: var(--subtle); }
.board-picker-actions { display: flex; gap: 6px; margin-top: var(--sp-overlay); }
.board-picker-actions .board-picker-action { justify-content: center; border: var(--border-flat); }
.board-picker-actions .remove { color: var(--danger); }
.board-picker .lvlpin { flex-shrink: 0; }
.board-picker-substitute { display: flex; gap: 6px; margin-top: var(--sp-overlay);
  padding-top: var(--sp-overlay); border-top: var(--border-flat); }
.board-picker-substitute input { flex: 1; padding: 5px 8px; border: var(--border-flat);
  border-radius: var(--r-static); font-size: 0.84rem; background: var(--bg); color: var(--body); }
.board-picker-substitute .board-picker-action { flex-shrink: 0; border: var(--border-flat);
  justify-content: center; min-width: 56px; }
.meter { height: 8px; background: var(--row-line); border-radius: var(--r-pill);
  overflow: hidden; width: 240px; max-width: 50%; }
.meter > i { display: block; height: 100%; border-radius: var(--r-pill); background: var(--warn); }
.meter.full > i { background: var(--ok); }
/* Inline meter inside a <summary> — the collapsed "Staffing needed" bar (#2). */
.summary-meter { display: inline-block; vertical-align: middle; margin-left: 0.5rem; }

/* Volunteer points report (#5): summary tiles + per-official magnitude bars.
   Bars use the brand hue (identity/magnitude), NOT the status amber/green —
   they aren't progress toward a target; numbers stay in text tokens. */
.stat-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 0.75rem; margin: 1rem 0; max-width: 34rem; }
.stat-tile { background: var(--card); border: var(--border-flat);
  border-radius: var(--r-card); padding: 0.75rem 1rem; display: flex;
  flex-direction: column; gap: 0.1rem; }
.stat-value { font-size: 1.6rem; font-weight: 800; color: var(--ink); line-height: 1.2; }
.stat-label { font-size: 0.8rem; color: var(--muted); }
td.bar-col, th.bar-col { width: 30%; }
.points-meter { display: inline-block; vertical-align: middle; width: 100%; max-width: none; }
.points-meter > i { background: var(--brand); }

/* "Staffing needed" tiles (#71): per-position fill bar + editable needed qty.
   Reuses .meter (full-width here). Kept off .reqgrid, which the availability
   sign-up page still uses. */
.staff-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: 0.6rem; margin-bottom: 0.75rem; }
.staff-tile { background: var(--subtle); border: var(--border-flat);
  border-radius: var(--r-input); padding: 0.5rem 0.6rem; }
.staff-head { display: flex; align-items: center; justify-content: space-between;
  gap: 0.4rem; margin-bottom: 0.45rem; }
.staff-code { font-weight: 700; font-size: 0.85rem; color: var(--ink); }
.staff-qty { display: inline-flex; align-items: center; margin: 0; white-space: nowrap; }
.staff-qty .tiny { width: 3.4rem; padding: 0.15rem 0.35rem; text-align: center; }
.staff-tile .meter { width: 100%; max-width: none; }

.grid-session { margin-bottom: 1.5rem; }
.print-only { display: none; }

/* Posted grid — "Your assignments" (#104 D3): a signed-in official's own spots,
   surfaced above the full grid. Useful on desktop too, phone-first by nature. */
.myassign { border-left: 3px solid var(--brand); }
.myassign h2 { margin-top: 0; }
.myassign-list { list-style: none; margin: 0; padding: 0; }
.myassign-list li { padding: 0.6rem 0; border-top: 1px solid var(--row-line);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.15rem 0.75rem; }
.myassign-list li:first-child { border-top: none; }
.myassign-what { font-weight: 700; color: var(--ink); }
.myassign-when { color: var(--muted); font-size: 0.85rem; }
/* Repeated role label: hidden in the grouped desktop grid, shown once the table
   stacks into per-lane cards on a phone (see the .stack block below). */
.rolerep { display: none; }
@media print {
  .topbar, .no-print, form { display: none !important; }
  .print-only { display: block; }
  main { margin: 0; max-width: none; }
  table.data { border: 1px solid #999; }
}

.flash { padding: 11px 16px; border-radius: var(--r-chip); margin-bottom: 1rem;
  font-size: 0.9rem; font-weight: 500; background: #e8f0fe; color: #25467a; }
.flash.error { background: var(--danger-soft); color: var(--danger); }
.flash.success { background: var(--ok-soft); color: var(--ok); }
.flash.warn { background: var(--warn-soft); color: var(--warn); }
ul.flags li { margin-bottom: 0.3rem; }

/* Messaging: Quill 2.0.3 rich-text editor (Team Messaging, #17 redesign).
   Vendored js/quill.min.js + css/quill.snow.css (BSD-3), pinned — same no-CDN
   discipline as htmx/SortableJS. These overrides tie the snow theme to the app
   tokens; body min-heights use max(px, vh) so the editor is generous on tall
   screens but never collapses if a context reports 0 viewport height. */
.ql-toolbar.ql-snow { border-color: var(--hairline); border-top-left-radius: var(--r-input); border-top-right-radius: var(--r-input); background: var(--subtle); }
.ql-container.ql-snow { border-color: var(--hairline); border-bottom-left-radius: var(--r-input); border-bottom-right-radius: var(--r-input); font-family: var(--font); font-size: 0.95rem; }
.ql-editor { min-height: max(320px, 40vh); transition: min-height 0.15s ease; }
/* Grow while actually writing (feedback: the editor should take up more of
   the screen when selected). Focus lives on the contenteditable inside. */
.ql-container:focus-within .ql-editor { min-height: max(480px, 62vh); }
.ql-snow a { color: var(--brand); }

/* --- Staging banner (Phase 5) --------------------------------------------
   Shown only when SITE_ENV=staging. Amber rather than red: this is a standing
   condition, not an error, and a red bar on every page stops being read within
   a day. Sticky so it survives scrolling — the moment it can be scrolled away
   is the moment someone forgets which site they are on. */
.envbar {
  position: sticky;
  top: 0;
  z-index: 999;
  background: var(--warn);
  color: #fff;
  padding: .45rem 1rem;
  font-size: .875rem;
  line-height: 1.35;
  text-align: center;
  letter-spacing: .01em;
}
.envbar strong { letter-spacing: .06em; }

/* A tinted page background as a second, peripheral signal — you register it
   before you have read anything. */
body.staging { background: #fffaf0; }

@media print { .envbar { display: none !important; } }

/* ==========================================================================
   RESPONSIVE LAYER — Mobile / PWA Phase 1, item 1 (#104)
   ------------------------------------------------------------------------
   Additive override layer (PLAN-mobile-pwa.md D1): the desktop rules above are
   untouched; everything mobile lives here, at the end, and overrides by MATCHING
   the desktop selector's specificity (never !important — that would poison a
   future mobile-first migration). Two breakpoints, deliberately few:

     900px — the "nothing breaks" tier. Every `table.data` becomes horizontally
             scrollable instead of forcing the page wide (kills the 641–900px
             overflow dead zone the audit flagged). Card max-widths reset; page
             padding tightens. The nav hamburger (item 2) lands at this width too.
     640px — the phone tier. Tables that OPT IN with `.stack` (data-label on each
             <td>, added per-screen in items 3–6) reflow from rows into labelled
             cards. Un-converted tables keep the 900px scroll fallback, so no
             screen is ever broken mid-migration.
   ========================================================================== */

/* "Best on desktop" notice (item 8, D6): admin/coordinator screens stay
   desktop-first this track; a phone gets this small dismissible note instead of
   responsive work. Hidden by default, shown only on narrow screens. Nothing
   *breaks* regardless — the 900px table scroll safety net above handles that. */
.desktop-notice { display: none; }
@media (max-width: 640px) {
  .desktop-notice {
    display: flex; align-items: center; gap: 0.6rem; margin-bottom: 1rem;
    padding: 0.6rem 0.85rem; background: var(--warn-soft); color: var(--warn);
    border: 1px solid #f0dcae; border-radius: var(--r-chip); font-size: 0.85rem;
  }
  .desktop-notice-x {
    margin-left: auto; padding: 0 0.4rem; background: none; color: inherit;
    border: none; font-size: 1.3rem; line-height: 1; cursor: pointer;
  }
  .desktop-notice-x:hover { background: none; color: var(--warn); }
}

/* Safe-area insets (item 7): when installed as a standalone PWA with
   viewport-fit=cover, keep the top bars and page clear of the notch / rounded
   corners. No-op in a normal browser (insets resolve to 0).

   NOTE: `main` and `.nav-row-1` are re-padded by the mobile media queries below
   (shorthand `padding`, later in source order), which would wipe a longhand
   inset set here. Their inset handling therefore lives INSIDE those media
   queries, folded into a `max()` against the per-breakpoint mobile value so the
   tight phone padding is the floor and only the notch widens it. Elements not
   overridden at mobile widths (.envbar top, .topbar, .nav-row-2) stay here. */
@supports (padding: max(0px, env(safe-area-inset-left))) {
  .envbar { padding-top: max(0.45rem, env(safe-area-inset-top)); }
  .topbar { padding-left: max(1.25rem, env(safe-area-inset-left));
    padding-right: max(1.25rem, env(safe-area-inset-right)); }
  .nav-row-2 { padding-left: max(24px, env(safe-area-inset-left));
    padding-right: max(24px, env(safe-area-inset-right)); }
}

/* Hamburger (item 2). Hidden on desktop; the three bars are drawn in CSS (one
   <span> + its ::before/::after) so no icon asset is needed. */
.nav-burger { display: none; }
.nav-burger-bars, .nav-burger-bars::before, .nav-burger-bars::after {
  display: block; width: 20px; height: 2px; background: currentColor; border-radius: 2px;
}
.nav-burger-bars { position: relative; }
.nav-burger-bars::before { content: ""; position: absolute; top: -6px; left: 0; }
.nav-burger-bars::after { content: ""; position: absolute; top: 6px; left: 0; }

/* Generic square floating panel, introduced by the roster redesign (#152).
   The assignment board reuses this same hidden-toggle overlay in #155. */
.overlay-anchor { position: relative; margin: 0; }
.ui-overlay { position: absolute; z-index: 30; top: calc(100% + 6px); left: 0;
  min-width: 220px; max-height: 70vh; overflow-y: auto; padding: var(--sp-overlay);
  background: var(--card); border: var(--border-flat); border-radius: var(--r-static);
  box-shadow: var(--shadow-raised); }
.ui-overlay[hidden] { display: none; }
.ui-overlay fieldset { margin: 0 0 var(--sp-overlay); padding: 0 0 var(--sp-overlay);
  border: 0; border-bottom: 1px solid var(--row-line); }
.ui-overlay legend { margin-bottom: 4px; color: var(--ink); font-weight: 700; }
.ui-overlay .overlay-choice { display: flex; align-items: center; gap: 7px;
  margin: 0; padding: 4px; white-space: nowrap; }
.ui-overlay .overlay-choice input { width: auto; margin: 0; }
.ui-icon { display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px; color: currentColor; }
.ui-icon svg { width: 14px; height: 14px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }

/* Officials roster (#152): compact, laptop-first, and isolated from legacy
   tables so unchanged screens keep their existing spacing and corners. */
.roster-page { background: var(--card); border: var(--border-flat);
  border-radius: var(--r-static); padding: var(--sp-card-compact); }
.roster-heading { display: flex; justify-content: space-between; align-items: center;
  gap: var(--sp-section-compact); margin-bottom: var(--sp-section-compact); }
.roster-heading h1, .roster-heading p { margin: 0; }
.roster-toolbar { display: flex; align-items: center; gap: var(--sp-overlay);
  margin: 0 0 6px; }
.roster-toolbar > input[type="search"] { max-width: 300px; }
.roster-toolbar .roster-control { display: inline-flex; align-items: center; gap: 6px;
  color: var(--body); border-color: var(--hairline); }
.roster-display-anchor { margin-left: auto; }
.roster-display-anchor .ui-overlay { right: 0; left: auto; }
.roster-filter-overlay { min-width: 280px; }
.roster-display-overlay { min-width: 230px; }
.roster-fixed-column { color: var(--muted); }
.roster-filter-chips { margin: 4px 0; }
.filter-chip { display: inline-flex; align-items: center; gap: 5px; padding: 4px 9px;
  border-radius: var(--r-pill); background: var(--subtle); font-size: 0.82rem; }
.filter-chip a { color: var(--muted); text-decoration: none; font-weight: 800; }
.roster-qualification-key { display: flex; align-items: center; flex-wrap: wrap;
  gap: 4px; margin: 4px 0 6px; }
.roster-table-wrap { overflow-x: auto; }
table.data.roster-table { border-radius: var(--r-static); min-width: 700px; }
table.data.roster-table th, table.data.roster-table td { padding-inline: 9px;
  vertical-align: middle; white-space: nowrap; }
table.data.roster-table thead th { background: var(--card); color: var(--body);
  text-transform: none; letter-spacing: 0; font-size: 0.76rem; }
.roster-check { width: 30px; text-align: center; }
.roster-check input { width: auto; margin: 0; accent-color: var(--brand); }
.roster-name a { color: var(--ink); font-weight: 700; text-decoration: none; }
.roster-positions { display: inline-flex; align-items: center; gap: 2px; }
.roster-positions .chip { margin: 0; padding: 1px 5px; font-size: 0.7rem; }
.position-more { padding: 2px 6px; border: var(--border-flat); border-radius: var(--r-pill);
  background: var(--card); color: var(--brand); font-size: 0.7rem; font-weight: 600; }
.position-more:hover { background: var(--subtle); color: var(--brand-ink); }
.roster-bulk-bar { position: sticky; bottom: 8px; z-index: 10; display: flex;
  align-items: center; gap: var(--sp-overlay); margin: var(--sp-overlay) 0;
  padding: var(--sp-overlay); background: var(--card); border: var(--border-flat);
  border-radius: var(--r-static); box-shadow: var(--shadow-raised); }
.roster-bulk-bar[hidden] { display: none; }
.roster-bulk-bar [data-email-hint] { margin-left: auto; }
.roster-footer { display: flex; justify-content: space-between; gap: var(--sp-overlay);
  padding-top: 6px; color: var(--muted); font-size: 0.82rem; }

@media (max-width: 900px) {
  main { margin: 1rem auto; padding: 0 0.85rem; }

  /* --- Mobile nav (D4) ---------------------------------------------------
     Row 1 becomes a wrapping bar: [burger] [wordmark] … [account]. The primary
     tabs and the whole sub-nav bar collapse; the burger reveals them stacked
     full-width. Account dropdown is untouched (its own toggle). */
  .nav-row-1 { flex-wrap: wrap; height: auto; gap: 10px 12px; padding: 10px 14px; }
  .nav-burger {
    order: -1; display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; padding: 0; color: var(--ink);
    background: var(--card); border: 1px solid var(--hairline); border-radius: var(--r-input);
  }
  .nav-burger:hover { background: var(--subtle); }
  .nav-burger:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
  .nav-account { order: 0; }          /* stays on the first line, pushed right */
  .nav-row-1 .nav-tabs { display: none; order: 1; }
  .nav-row-2 { display: none; }

  /* Open state: tabs stack below row 1; the sub-nav bar unfolds as a column. */
  .topbar--authenticated[data-nav-open] .nav-tabs {
    display: flex; flex-basis: 100%; flex-direction: column; gap: 4px;
    align-items: stretch;   /* desktop rule centres on the cross-axis; in a
                               column that would centre each tab — reset it so
                               tabs fill the width and read left-aligned */
    background: none; padding: 4px 0;
  }
  .topbar--authenticated[data-nav-open] .nav-tab {
    display: flex; align-items: center; min-height: 44px; padding: 0 12px;
    border-radius: var(--r-input);
  }
  .topbar--authenticated[data-nav-open] .nav-row-2 {
    display: block; height: auto; padding: 6px 14px 10px;
  }
  .topbar--authenticated[data-nav-open] .nav-row-2 nav {
    flex-direction: column; align-items: stretch; gap: 0; width: 100%;
  }
  .topbar--authenticated[data-nav-open] .nav-sub {
    display: flex; align-items: center; min-height: 44px;
  }

  /* Safety net: a wide data table scrolls inside itself rather than stretching
     the whole page. Applies to EVERY table.data — in-scope, admin, or not yet
     converted — so a phone never meets horizontal page scroll (D1 dead-zone fix,
     D6 admin overflow guard). `display:block` is what makes overflow-x scroll a
     <table>; the table keeps its normal internal layout. */
  table.data { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  table.data td, table.data th { overflow-wrap: break-word; }

  /* Card max-widths that exceed a phone viewport collapse to full width. */
  .card.narrow, .card.compose { max-width: none; }
  .card.compose input[type="text"] { max-width: none; }
  .columns .card, .columns .card.grow { flex-basis: 100%; }

  /* Safe-area insets for the two elements the shorthand padding above resets:
     the mobile value is the floor, only the notch widens it. Placed after those
     rules (and guarded) so it wins without env() breaking non-supporting UAs. */
  @supports (padding: max(0px, env(safe-area-inset-left))) {
    main { padding-left: max(0.85rem, env(safe-area-inset-left));
      padding-right: max(0.85rem, env(safe-area-inset-right)); }
    .nav-row-1 { padding-left: max(14px, env(safe-area-inset-left));
      padding-right: max(14px, env(safe-area-inset-right)); }
  }
}

@media (max-width: 640px) {
  main { padding: 0 0.75rem; }
  /* Re-assert the inset floor at this tighter value (the 900px rule above is
     overridden by the shorthand on the line above). */
  @supports (padding: max(0px, env(safe-area-inset-left))) {
    main { padding-left: max(0.75rem, env(safe-area-inset-left));
      padding-right: max(0.75rem, env(safe-area-inset-right)); }
  }
  .card { padding: var(--sp-comfy); }

  /* Comfortable touch targets — GATED to the phone breakpoint so the dense
     desktop layout the override layer is protecting is never regressed. Buttons
     become flex so the label centres once the box grows to 44px. */
  button,
  button.toggle,
  .att-set button,
  table.data button,
  .nav-account-menu-item {
    min-height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
  }
  .nav-account-menu-item { justify-content: flex-start; }
  input, select { min-height: 44px; }

  /* ---- Opt-in table → card stacking (D2) --------------------------------
     A table.data.stack drops its chrome; each <tr> becomes a card and each
     <td> a "Label: value" row driven by the td's data-label attribute. The
     column headers (thead, or a leading all-<th> row) are hidden — the labels
     carry them. This block is source-ordered AFTER the 900px scroll rule so it
     wins where both match. */
  table.data.stack {
    display: block; overflow: visible;
    border: none; border-radius: 0; background: none;
  }
  table.data.stack thead,
  table.data.stack tr:first-child th { display: none; }
  table.data.stack tbody { display: block; }
  table.data.stack tr {
    display: block; margin-bottom: 0.75rem; padding: 0.35rem 0.75rem;
    background: var(--card); border: var(--border-flat); border-radius: var(--r-card);
  }
  /* Block cell with an inline "Label: value" — value wraps freely (long names,
     tank labels). NOT a space-between flex row: a long value is an anonymous
     flex item with min-width:auto, refuses to shrink, and widens the card past
     the viewport (the bug this pattern is written to avoid). */
  table.data.stack td {
    display: block; padding: 0.45rem 0.25rem; text-align: left;
    border-top: 1px solid var(--row-line); overflow-wrap: anywhere;
  }
  table.data.stack tr td:first-child { border-top: none; }
  table.data.stack td::before {
    content: attr(data-label) ": "; color: var(--muted); font-weight: 700;
  }
  /* A cell with an empty data-label (e.g. a full-width action cell) spans the
     card without a dangling label. */
  table.data.stack td[data-label=""]::before { content: none; }
  /* Row-action buttons go full width and stop being nowrap-cramped on a phone —
     except link-style buttons (e.g. "cancel"), which stay inline text. */
  table.data.stack button:not(.linklike) { white-space: normal; width: 100%; }
  /* The role, blank in the desktop group, reappears on every stacked lane card. */
  table.data.stack .rolerep { display: inline; }
}

/* --- #107 credential tick screen (My qualifications) ---------------------- */
.qual-list { list-style: none; padding: 0; margin: 0 0 1.5rem; }
.qual-row { padding: 0.55rem 0; border-bottom: 1px solid var(--row-line); }
.qual-tick { display: inline-flex; align-items: center; gap: 0.55rem; cursor: pointer; }
.qual-tick input[type="checkbox"] { width: 1.15rem; height: 1.15rem; accent-color: var(--brand); }
.qual-tick input[disabled] { cursor: not-allowed; }
.qual-name { font-weight: 700; color: var(--ink); }
.qual-learn { margin-left: 0.75rem; }
.qual-locked { margin-left: 0.6rem; font-style: italic; }
.qual-detail { margin: 0.45rem 0 0.2rem 1.85rem; padding-left: 0.85rem;
  border-left: 2px solid var(--hairline); }
.qual-signoff { display: flex; align-items: center; gap: 0.7rem; padding: 0.22rem 0; }
.qual-sub { display: inline-flex; align-items: center; gap: 0.45rem; min-width: 8.5rem; }
.qual-sub input[type="checkbox"] { width: 1rem; height: 1rem; accent-color: var(--brand); }
.qual-date { max-width: 10.5rem; }

/* --- #153 official detail ------------------------------------------------- */
.official-detail { max-width: 1180px; }
.official-detail-heading { display: flex; align-items: end; justify-content: space-between;
  gap: var(--sp-base); margin-bottom: var(--sp-card-compact); }
.official-detail-heading h1, .official-detail-heading p { margin-bottom: 0; }
.detail-tabs { display: flex; gap: 4px; margin-bottom: var(--sp-section-compact);
  padding: 4px; border-bottom: var(--border-flat); }
.detail-tabs [role="tab"] { padding: 8px 14px; border: 0;
  border-radius: var(--r-input) var(--r-input) 0 0; background: transparent;
  color: var(--muted); }
.detail-tabs [role="tab"][aria-selected="true"] { color: var(--brand);
  background: var(--card); box-shadow: inset 0 -2px 0 var(--brand); }
.detail-tabs [role="tab"]:focus-visible { outline: 2px solid var(--brand);
  outline-offset: 1px; }
.official-detail [data-detail-panel][hidden],
.official-detail [data-profile-values][hidden],
.official-detail [data-profile-fields][hidden] { display: none; }
.detail-profile-grid, .detail-account-grid { display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-card-compact); }
.detail-card { min-width: 0; padding: var(--sp-card-compact); background: var(--card);
  border: var(--border-flat); border-radius: var(--r-static); }
.detail-card-heading { display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-tight); }
.detail-card h2 { margin-top: 0; }
.detail-card-heading h2 { margin-bottom: 0; }
.detail-fields { margin: var(--sp-card-compact) 0 0; }
.detail-fields > div { display: grid; grid-template-columns: minmax(95px, 0.45fr) 1fr;
  gap: var(--sp-tight); padding-block: var(--sp-row-comfortable);
  border-top: 1px solid var(--row-line); }
.detail-fields dt { color: var(--muted); font-weight: 700; }
.detail-fields dd { margin: 0; overflow-wrap: anywhere; }
.detail-edit-fields { display: grid; gap: var(--sp-tight); margin-top: var(--sp-card-compact); }
.detail-edit-fields label:not(.detail-check) { display: grid; gap: 3px; }
.detail-check { display: flex; align-items: center; gap: var(--sp-tight); }
.detail-edit-fields button { justify-self: start; }
.detail-level-edit { margin-top: var(--sp-section-compact); padding-top: var(--sp-card-compact);
  border-top: var(--border-flat); }
.detail-level-edit h3 { margin: 0 0 var(--sp-tight); }
.detail-actions { display: flex; align-items: center; gap: var(--sp-tight); }
.detail-qual-table { width: 100%; border-radius: var(--r-static); }
.detail-qual-table th, .detail-qual-table td { white-space: nowrap; }
.detail-qual-table th:first-child, .detail-qual-table td:first-child { white-space: normal; }
.qual-cell-form { display: inline-flex; align-items: center; gap: 5px; margin: 0; }
.detail-qual-actions { margin-top: var(--sp-card-compact); }
.qual-cell-form input[type="date"] { width: 9.2rem; padding: 4px 5px; }
.learn-star { padding: 2px 6px; border: 0; background: transparent;
  color: #a7b0b8; font-size: 1.15rem; line-height: 1; }
.learn-star.on { color: var(--warn); }
.detail-card .detail-status-chip, .detail-card .lvlpin { border-radius: var(--r-static); }

@media (max-width: 760px) {
  .official-detail-heading { display: block; }
  .detail-tabs { overflow-x: auto; }
  .detail-tabs [role="tab"] { white-space: nowrap; }
  .detail-profile-grid, .detail-account-grid { grid-template-columns: 1fr; }
}

/* --- #154 meet manage ----------------------------------------------------- */
.meet-manage-page .card, .meet-manage-page table.data,
.meet-manage-page .staff-tile { border-radius: var(--r-static); }
.manage-actions button { padding: 6px 11px; border-radius: var(--r-pill); }
.manage-overview-grid { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(280px, 0.65fr);
  gap: var(--sp-card-compact); align-items: start; }
.manage-static-card { padding: var(--sp-card-compact); }
.leadership-list { border-top: var(--border-flat); }
.leadership-row { display: grid; grid-template-columns: minmax(150px, 0.8fr) minmax(220px, 1.4fr) 36px;
  gap: var(--sp-tight); align-items: center; padding-block: var(--sp-row-comfortable);
  border-bottom: 1px solid var(--row-line); }
.leadership-picker form, .leadership-access form, .manager-chip form { margin: 0; }
.leadership-picker .official-combobox label { position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.official-combobox { position: relative; }
.official-combobox input[type="text"] { width: 100%; }
.official-combobox-options { position: absolute; z-index: 30; top: calc(100% + 4px); left: 0; right: 0;
  max-height: 240px; overflow-y: auto; padding: 4px; background: var(--card);
  border: var(--border-flat); border-radius: var(--r-static); box-shadow: var(--shadow-raised); }
.official-combobox-options[hidden] { display: none; }
.official-combobox-options [role="option"] { display: block; width: 100%; padding: 7px 9px;
  border: 0; border-radius: var(--r-static); background: var(--card); color: var(--body);
  text-align: left; font-weight: 500; }
.official-combobox-options [role="option"]:hover,
.official-combobox-options [role="option"].active { background: var(--subtle); color: var(--ink); }
.official-combobox-options [role="option"][hidden] { display: none; }
.official-combobox-options [data-combobox-empty] { margin: 6px 8px; }
.access-shield { display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0; border: 0; background: transparent;
  color: #a7b0b8; font-size: 1.25rem; line-height: 1; text-decoration: none; }
button.access-shield:hover { background: transparent; color: var(--brand); }
.access-shield.on { color: var(--brand); }
.other-managers { margin-top: var(--sp-section-compact); }
.other-managers h3 { margin-bottom: var(--sp-tight); }
.manager-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: var(--sp-tight); }
.manager-chip { display: inline-flex; align-items: center; gap: 4px; padding: 3px 5px 3px 8px;
  background: var(--subtle); border: var(--border-flat); border-radius: var(--r-static);
  font-size: 0.84rem; font-weight: 600; }
.manager-chip .access-shield { width: 24px; height: 24px; font-size: 1rem; }
.manager-add-form { max-width: 360px; }
.meet-summary-list { margin: 0; }
.meet-summary-list > div { display: grid; grid-template-columns: 95px 1fr; gap: var(--sp-tight);
  padding-block: var(--sp-row-comfortable); border-top: 1px solid var(--row-line); }
.meet-summary-list dt { color: var(--muted); font-weight: 700; }
.meet-summary-list dd { margin: 0; overflow-wrap: anywhere; }
.session-staffing-summary { display: flex; align-items: center; gap: var(--sp-tight);
  margin-bottom: var(--sp-tight); color: var(--muted); font-weight: 700; }
.session-board-cta { margin: var(--sp-card-compact) 0 0; }
.session-board-cta a { display: inline-block; padding: 6px 11px; border: 1.5px solid var(--brand);
  border-radius: var(--r-pill); font-weight: 700; text-decoration: none; }
.session-board-cta a:hover { background: var(--subtle); }
