:root {
  --bg: #0f1419;
  --panel: #1a2332;
  --text: #e7ecf1;
  --muted: #a7b6c5;
  --accent: #3d8fd1;
  --danger: #c94c4c;
  --ok: #3d9a5c;
  --warn: #c9a227;
  --chip: #2a3a4d;
  /* Faint internal hairline: row/list separators and the schedule's
     hour/minute grid rules. Lighter than the old #1a222c so it reads on
     dark panels, but fainter than the #2a3544 outer border so the
     border > internal-rule hierarchy still holds. */
  --line: #27313e;

  /* Action-icon size: one token sizes every action glyph app-wide
     (see .ic in _icons.html); the App Settings catalogue reads it too,
     so they always match. Raise toward 1.35rem for bigger icons. */
  --ic-size: 1.1rem;

  /* Button design tokens — every button-shaped element (real <button>
     AND tab-style <a> in .app-nav) reads its hover/focus/disabled
     behavior from these. Variants only swap colors; sizes only swap
     padding/radius/font-size. The hover *model* never changes. */
  --btn-hover-tint: rgba(255, 255, 255, 0.06);
  --btn-transition: background-color 0.12s, color 0.12s, border-color 0.12s, opacity 0.12s;
  --btn-focus-ring: 2px solid var(--accent);
  --btn-disabled-opacity: 0.55;
  /* Canonical action-button dimensions — the compact "Members" (.row-btn)
     look. Every standard labeled button reads its size from these so the
     whole app stays homogeneous; variants still only swap colors. */
  --btn-font-size: 0.9rem;
  --btn-padding: 0.35rem 0.7rem;
  --btn-radius: 6px;
  /* Uniform minimum width so labeled action buttons line up like a grid
     (≈ the "Approve" button). Short labels pad out to this; longer ones
     grow past it — tune this one value to taste. Icon / toggle / stepper /
     toolbar buttons opt out (see the min-width:0 reset below + .icon-btn). */
  --btn-min-width: 6rem;

  /* Typography + top-line dials. App Settings → Appearance overrides these
     (and the colour + --btn-* tokens above) via the injected :root block
     before </head>. Defaults mirror the hardcoded look, so an unset value
     changes nothing. --topline-font sizes EVERY item on the top nav line
     (tabs, tribe chip, account label, Logout) so they stay uniform.
     --field-font-size sizes every text field and dropdown so edit boxes
     and selects stay uniform (App Settings → Appearance → Fields). */
  --ui-font: "Segoe UI", system-ui, sans-serif;
  --topline-font: 0.9rem;
  --field-font-size: 0.95rem;
  --nav-padding: 0.45rem 0.9rem;
}
* { box-sizing: border-box; }
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
body {
  font-family: var(--ui-font, "Segoe UI", system-ui, sans-serif);
  background: var(--bg);
  color: var(--text);
  margin: 0;
  min-height: 100vh;
  line-height: 1.45;
}
.wrap { max-width: 88rem; margin: 0 auto; padding: 1.25rem 1rem 2rem; }
a { color: var(--text); }
a:hover { color: var(--accent); }
/* Text fields and dropdowns don't inherit the page font on their own — the
   browser renders them in its native control font at an inconsistent size.
   Pin every <input>/<select>/<textarea> to the app font and one shared size
   token so edit boxes and selects match. The Font control drives --ui-font;
   App Settings → Appearance → Fields drives --field-font-size. (Page rules
   set only box styling — padding/border/colour — not font.) */
input, select, textarea {
  font-family: var(--ui-font, "Segoe UI", system-ui, sans-serif);
  font-size: var(--field-font-size, 0.95rem);
}
.app-nav {
  display: flex;
  gap: 0.35rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
  align-items: center;
}
.app-nav a {
  font: inherit;
  font-size: var(--topline-font);
  padding: var(--nav-padding);
  border-radius: 8px;
  text-decoration: none;
  color: var(--muted);
  border: 1px solid #2a3544;
  background: transparent;
  transition: var(--btn-transition);
}
.app-nav a.active {
  color: var(--text);
  background: var(--panel);
  border-color: var(--accent);
}
h1 { font-size: 1.35rem; font-weight: 600; margin: 0 0 0.25rem; }
.sub { color: var(--muted); font-size: 0.875rem; margin-bottom: 1.25rem; }
section {
  background: var(--panel);
  border-radius: 10px;
  padding: 1rem 1.1rem;
  margin-bottom: 1rem;
}
h2 { font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); margin: 0 0 0.75rem; }
section:has(.people-grid-wrap) {
  overflow-x: auto;
}
.group-status {
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.group-status.is-unblocked { color: var(--ok); }
.group-status.is-blocked { color: var(--danger); }
.group-status.is-mixed { color: var(--warn); }
.group-status.is-empty {
  color: var(--muted);
  font-style: italic;
  font-weight: 400;
  font-size: 0.65rem;
  letter-spacing: 0;
  text-transform: none;
  text-decoration: underline;
}
.group-status.is-unknown { color: var(--muted); }
.group-status.is-unthrottled { color: var(--ok); }
.group-status.is-throttled { color: var(--warn); }
.row { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin-bottom: 0.5rem; }
.row:last-child { margin-bottom: 0; }
button {
  font: inherit;
  font-size: var(--btn-font-size);
  cursor: pointer;
  border: none;
  border-radius: var(--btn-radius);
  padding: var(--btn-padding);
  min-width: var(--btn-min-width);
  background: var(--accent);
  color: #fff;
  transition: var(--btn-transition);
}
button.block { background: var(--danger); }
button.unblock { background: var(--ok); }
button.neutral { background: #3a4a5e; }
button.warn { background: var(--warn); color: #111; }
button.ghost { background: transparent; border: 1px solid #3a4a5e; color: var(--text); }

/* Unified hover, focus, and disabled — applies to every button-shaped
   element across the app. Hover uses a translucent overlay rather than
   filter:brightness so it reads identically on filled, ghost, and
   transparent (tab) backgrounds. Variants only set color tokens; this
   rule sets the *behavior*. */
button:hover,
.app-nav a:hover {
  background-image: linear-gradient(var(--btn-hover-tint), var(--btn-hover-tint));
}
.app-nav a:hover,
.log-panel-actions button:hover {
  color: var(--text);
}
button:focus-visible,
.app-nav a:focus-visible {
  outline: var(--btn-focus-ring);
  outline-offset: 1px;
}
button:disabled,
button[aria-disabled="true"] {
  opacity: var(--btn-disabled-opacity);
  cursor: not-allowed;
}
/* Icon-only, toggle, stepper and toolbar buttons keep their natural width —
   they are not part of the uniform CTA grid. (.icon-btn opts out in
   _icons.html so standalone pages are covered too.) */
.log-panel-actions button,
.ahn-ft-sync,
.btn-people, .count-action, .jump-btn, .expand-toggle, .schedule-clear-btn,
.btn-row, .device-name-reset, .deny-btn, .rename-btn,
.monitor-bar button, .filter-chip button,
.sched-zoom button, .add-entry-btn, .bump-spinner button, .bump-granularity, .bump-arrow,
.slice-popover-actions button, .btn-pause, .btn-chime-test,
.mem-list button, .assign-form button {
  min-width: 0;
}
.chips { display: flex; flex-wrap: wrap; gap: 0.35rem; margin: 0.5rem 0 0.75rem; }
.chip {
  font-size: 0.8rem;
  padding: 0.2rem 0.5rem;
  border-radius: 4px;
  background: var(--chip);
  color: var(--text);
}
.log-type-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.85rem;
  align-items: center;
  margin: 0.35rem 0 0.75rem;
  padding: 0;
  border: 0;
}
.log-type-filters .log-type-check {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.82rem;
  cursor: pointer;
  user-select: none;
}
.log-type-check input {
  margin: 0;
  accent-color: var(--accent);
}
.log-type-check-label { color: var(--text); }
.log-tribe-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.85rem;
  align-items: center;
  margin: 0 0 0.75rem;
  padding: 0;
  border: 0;
}
.log-filter-legend {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--muted);
  padding: 0 0.35rem 0 0;
  margin: 0;
}
.status-line { font-size: 0.9rem; margin: 0.35rem 0 0.75rem; }
.status-line.on { color: var(--ok); }
.status-line.off { color: var(--muted); }
.log-panel { position: relative; }
.log-panel h2 { margin-bottom: 0.5rem; }
.log-panel-poll-status {
  position: absolute;
  top: 0;
  right: 0;
  margin: 0;
  max-width: min(22rem, 60%);
  text-align: right;
  line-height: 1.35;
}
.log-panel-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}
.log-panel-head h2 {
  margin: 0;
}
.log-panel-head .watcher-log-title {
  margin: 0;
}
.log-panel-head form {
  flex-shrink: 0;
}
.log-panel-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  align-items: center;
  justify-content: flex-end;
}
/* Match the .app-nav tab look at the top of the page so log-panel
   buttons read as a quiet toolbar, not a row of CTAs. Hover/focus
   behavior comes from the global button rules above. */
.log-panel-actions button {
  font-size: 0.9rem;
  padding: 0.45rem 0.9rem;
  border-radius: 8px;
  color: var(--muted);
  border: 1px solid #2a3544;
  background: transparent;
}
.log-prune-form {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
}
.log-prune-days-input {
  width: 2.65rem;
  min-width: 2.25rem;
  flex-shrink: 0;
  padding: 0.22rem 0.35rem;
  font: inherit;
  font-size: 0.78rem;
  border-radius: 4px;
  border: 1px solid #2a3544;
  background: var(--bg);
  color: var(--text);
  box-sizing: border-box;
}
.log-prune-day-suffix {
  font-size: 0.78rem;
  color: var(--muted);
  user-select: none;
  flex-shrink: 0;
}
pre.monitor-log,
pre.watcher-log {
  margin: 0;
  padding: 0.85rem;
  background: #0b0e12;
  border-radius: 8px;
  font-size: 0.72rem;
  line-height: 1.35;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  border: 1px solid #2a3544;
  overflow-y: auto;
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
}
pre.monitor-log {
  max-height: min(70vh, 42rem);
  min-height: 14rem;
}
pre.watcher-log {
  margin-top: 0.5rem;
  max-height: min(55vh, 34rem);
  min-height: 10rem;
}
.dash-log {
  margin: 0;
  padding: 0.4rem 0.5rem;
  background: #0b0e12;
  border: 1px solid #2a3544;
  border-radius: 8px;
  max-height: min(70vh, 42rem);
  min-height: 14rem;
  overflow-y: auto;
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 0.72rem;
  line-height: 1.35;
}
.dash-row {
  padding: 0.18rem 0.35rem;
  border-radius: 4px;
  word-break: break-word;
}
.dash-row + .dash-row { border-top: 1px dashed var(--line); }
.dash-row[data-exit="0"] .dash-exit { color: #6fae6f; }
.dash-row[data-exit="1"] .dash-exit,
.dash-row[data-exit="2"] .dash-exit { color: #d97a6c; }
.dash-row[data-exit="0"] .dash-headline { color: #cfd7df; }
.dash-row[data-exit]:not([data-exit="0"]) .dash-headline { color: #ffb4a8; }
/* Replay sits in a fixed trailing action cell pinned to the right edge of a
   broadcast row. Every row reserves the same right gutter so the time / op /
   headline columns line up whether or not the row carries a Replay button. */
.dash-row { position: relative; padding-right: 1.9rem; }
.dash-row .icon-btn {
  position: absolute;
  top: 0.06rem;
  right: 0.2rem;
  --ic-size: 0.95rem;
  padding: 0.1rem 0.3rem;
}
.dash-time { color: var(--muted); margin-right: 0.55rem; }
.dash-type {
  display: inline-block;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 0.05rem 0.35rem;
  margin-right: 0.45rem;
  border-radius: 3px;
  vertical-align: baseline;
  color: #c8d4e0;
  background: #243040;
  border: 1px solid #3a4a5e;
}
.dash-type[data-log-type="banner"] { color: #e8c4ff; background: #2a2040; border-color: #5a4080; }
.dash-type[data-log-type="speaker"] { color: #b8e0ff; background: #1a3048; border-color: #3a6088; }
.dash-type[data-log-type="router"] { color: #ffd4a8; background: #302818; border-color: #705030; }
.dash-type[data-log-type="weather"] { color: #a8f0d8; background: #183028; border-color: #307060; }
.dash-type[data-log-type="system"] { color: #c0c8d0; background: #222830; border-color: #404850; }
.dash-type[data-log-type="whitelist"] { color: #ffb4b4; background: #3a2020; border-color: #804040; }
.dash-tribe {
  display: inline-block;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 0.05rem 0.35rem;
  margin-right: 0.45rem;
  border-radius: 3px;
  vertical-align: baseline;
  color: #ffe8b8;
  background: #2a2818;
  border: 1px solid #605830;
}
.dash-op { color: #8fb4ff; margin-right: 0.55rem; }
.dash-exit { margin-right: 0.55rem; }
.dash-headline { color: #cfd7df; }
.dash-row:not(.dash-row-detailed)::before {
  content: "▸";
  display: inline-block;
  width: 0.9rem;
  visibility: hidden;
}
.dash-row-detailed { cursor: pointer; }
.dash-row-detailed > summary {
  list-style: none;
  display: block;
  cursor: pointer;
}
.dash-row-detailed > summary::-webkit-details-marker { display: none; }
.dash-row-detailed > summary::before {
  content: "▸";
  display: inline-block;
  width: 0.9rem;
  color: var(--muted);
  transition: transform 0.15s ease;
}
.dash-row-detailed[open] > summary::before { content: "▾"; color: #ffb4a8; }
.dash-extra-body {
  margin: 0.35rem 0 0.1rem 1.5rem;
  padding: 0.5rem 0.7rem;
  background: #15191f;
  border-left: 2px solid #d97a6c;
  border-radius: 0 4px 4px 0;
  white-space: pre-wrap;
  color: #d8d2c8;
  font-size: 0.7rem;
}
.dash-log-empty {
  padding: 0.85rem;
  color: var(--muted);
  font-style: italic;
}
.watcher-log-title {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  margin: 0.75rem 0 0.25rem;
}
.log-hint { font-size: 0.72rem; color: var(--muted); margin-top: 0.5rem; }
pre.out {
  margin: 0;
  margin-top: 0.5rem;
  padding: 0.85rem;
  background: #0b0e12;
  border-radius: 8px;
  font-size: 0.8rem;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  border: 1px solid #2a3544;
  max-height: min(50vh, 28rem);
  overflow-y: auto;
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
}
.empty { color: var(--muted); font-size: 0.9rem; }
details.more { margin-top: 0.5rem; }
details.more summary { cursor: pointer; color: var(--muted); font-size: 0.85rem; }
.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}
.section-head h2 { margin: 0; }
.section-head form { display: inline; }
.flash { padding: 0.65rem 0.85rem; border-radius: 8px; margin-bottom: 1rem; font-size: 0.9rem; }
.flash.ok { background: #1a3d2a; border: 1px solid var(--ok); color: #b8e6c8; }
.flash.err { background: #3d1a1a; border: 1px solid var(--danger); color: #f0c0c0; }
.flash.warn { background: #3d3416; border: 1px solid var(--warn); color: #f3e6b8; }
.flash.warn a { color: inherit; text-decoration: underline; }
/* Client-rendered twin of the server flash strip: AJAX form results land
   here so the outcome shows up in the same place as a redirect's flash. */
.flash-row { display: flex; align-items: flex-start; gap: 0.6rem; }
.flash-row .flash-text { flex: 1 1 auto; min-width: 0; }
.flash-close {
  flex: 0 0 auto;
  font: inherit;
  line-height: 1;
  padding: 0 0.2rem;
  min-width: 0;
  border: 0;
  background: transparent;
  color: inherit;
  opacity: 0.7;
  cursor: pointer;
}
/* background-image: the app-wide button:hover tint would box the bare ×. */
.flash-close:hover { opacity: 1; background-image: none; }
/* Busy affordance for forms posted in the background (data-nz-ajax). */
.nz-spin {
  display: inline-block;
  width: 0.75em;
  height: 0.75em;
  margin-right: 0.4em;
  vertical-align: -0.05em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: nz-spin 0.7s linear infinite;
}
@keyframes nz-spin { to { transform: rotate(360deg); } }
.icon-btn .nz-spin { margin-right: 0; }
/* The pressed button stays legible while it spins — beat button:disabled. */
button.nz-busy, button.nz-busy:disabled { opacity: 1; cursor: progress; }
tr.nz-row-busy > td:not(.col-actions) { opacity: 0.5; }
@media (prefers-reduced-motion: reduce) {
  .nz-spin { animation: none; }
}
.ahn-reset-pwd {
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  max-width: min(24rem, calc(100vw - 2rem));
}
.ahn-reset-pwd::backdrop { background: rgba(0, 0, 0, 0.55); }
.ahn-reset-pwd-inner { padding: 1rem 1.1rem 1.1rem; }
.ahn-reset-pwd-inner h3 { margin: 0 0 0.35rem; font-size: 1.05rem; }
.ahn-reset-pwd-sub { margin: 0 0 0.75rem; color: var(--muted); font-size: 0.88rem; }
.ahn-reset-pwd-label {
  display: block;
  font-size: 0.85rem;
  color: var(--muted);
  margin-bottom: 0.75rem;
}
.ahn-reset-pwd-label input {
  display: block;
  width: 100%;
  margin-top: 0.35rem;
  padding: 0.45rem 0.55rem;
  border-radius: 6px;
  border: 1px solid #2a3544;
  background: var(--bg);
  color: var(--text);
  box-sizing: border-box;
}
.ahn-reset-pwd-err {
  margin: 0 0 0.65rem;
  font-size: 0.82rem;
  color: #f0c0c0;
}
.ahn-reset-pwd-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.45rem;
  flex-wrap: wrap;
}
.inbox-badge {
  display: inline-block;
  min-width: 1.15rem;
  padding: 0 0.35rem;
  margin-left: 0.3rem;
  border-radius: 999px;
  background: var(--danger);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 600;
  text-align: center;
  line-height: 1.15rem;
}
.tribe-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: var(--topline-font);
  color: var(--muted);
  padding: 0.2rem 0.55rem;
  border-radius: 6px;
  background: var(--chip);
  text-decoration: none;
}
.tribe-chip:hover { color: var(--text); }
.tribe-chip svg { display: block; flex: 0 0 auto; }
/* In-progress notification chip + panel (the "notification in progress"
   banner control — populated by the #ahn-notif fetch widget below). The
   chip is always present (a notification bell) so the affordance is
   discoverable; it sits muted/idle when nothing is in progress and lights
   up (pulsing dot + count) when there are live notifications or — for a
   leader — extinguish requests to decide. */
.notif-chip-wrap { position: relative; display: inline-flex; flex: 0 0 auto; }
/* Idle: nothing in progress. Muted banner, no pulse, no count badge. */
.notif-chip-wrap.idle .notif-chip {
  background: rgba(167, 182, 197, 0.10);
  border-color: var(--line);
  border-left-color: var(--muted);
  color: var(--muted);
}
.notif-chip-wrap.idle .notif-dot { animation: none; background: var(--muted); }
.notif-chip-wrap.idle .notif-count { display: none; }
/* Banner-style presentation (was a pill button): a horizontal bar with a
   soft amber fill and a left accent stripe, matching the app's banner
   language (.flash / .inprogress-banner) so the notifications affordance
   reads as a banner, not a button. Still the same clickable widget that
   opens the in-progress panel; the accent turns muted when idle. */
.notif-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: var(--topline-font);
  color: var(--text);
  padding: 0.4rem 0.7rem;
  border-radius: 8px;
  background: rgba(201, 162, 39, 0.14);
  border: 1px solid var(--warn);
  border-left: 4px solid var(--warn);
  cursor: pointer;
  white-space: nowrap;
  flex: 0 0 auto;
}
.notif-chip:hover { background: rgba(201, 162, 39, 0.24); }
.notif-chip-wrap.idle .notif-chip:hover { background: rgba(167, 182, 197, 0.18); }
.notif-dot {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 999px;
  background: var(--warn);
  flex: 0 0 auto;
  animation: notif-pulse 1.6s ease-in-out infinite;
}
.notif-dot.alert { background: var(--danger); }
@keyframes notif-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.7); }
}
@media (prefers-reduced-motion: reduce) {
  .notif-dot { animation: none; }
}
.notif-count {
  min-width: 1.15rem;
  padding: 0 0.3rem;
  border-radius: 999px;
  background: var(--warn);
  color: #1a1300;
  font-size: 0.7rem;
  font-weight: 700;
  text-align: center;
  line-height: 1.15rem;
}
.notif-panel {
  position: absolute;
  top: calc(100% + 0.4rem);
  right: 0;
  z-index: 50;
  width: min(22rem, 90vw);
  max-height: 70vh;
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
  padding: 0.5rem;
  display: none;
  text-align: left;
}
.notif-panel.open { display: block; }
.notif-card {
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 0.5rem 0.6rem;
  margin-bottom: 0.5rem;
}
.notif-card:last-child { margin-bottom: 0; }
.notif-card .title { font-weight: 600; color: var(--text); }
.notif-card .meta {
  font-size: 0.78rem;
  color: var(--muted);
  margin-top: 0.15rem;
}
.notif-section-label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  margin: 0.2rem 0 0.4rem;
}
.notif-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.5rem;
}
.notif-btn {
  font: inherit;
  font-size: 0.78rem;
  padding: 0.25rem 0.55rem;
  border-radius: 5px;
  border: 1px solid var(--line);
  background: var(--chip);
  color: var(--text);
  cursor: pointer;
}
.notif-btn:hover { border-color: var(--text); }
.notif-btn:disabled { opacity: 0.5; cursor: default; }
.notif-btn.danger { border-color: var(--danger); color: #f0b5b5; }
.notif-btn.ok { border-color: var(--ok); color: #b6e2c4; }
.notif-empty { color: var(--muted); font-size: 0.85rem; padding: 0.3rem; }
/* Site-wide in-progress banner — the only live notification surface (no
   header dropdown). Color tone shifts with punch band / urgency. */
.inprogress-banner {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  margin: 0 0 0.75rem;
  padding: 0.65rem 0.85rem;
  border: 1px solid var(--danger);
  border-left-width: 4px;
  border-radius: 10px;
  background: rgba(220, 80, 80, 0.12);
  color: var(--text);
  font-size: 0.95rem;
}
.inprogress-banner[data-tone="sweet"] {
  border-color: #c9a227;
  background: linear-gradient(135deg, rgba(201, 162, 39, 0.18), rgba(61, 154, 92, 0.1));
}
.inprogress-banner[data-tone="ontime"] {
  border-color: var(--ok);
  background: rgba(61, 154, 92, 0.12);
}
.inprogress-banner[data-tone="late"] {
  border-color: var(--warn);
  background: rgba(220, 160, 60, 0.14);
}
.inprogress-banner[data-tone="wait"] {
  border-color: var(--warn);
  background: rgba(220, 160, 60, 0.1);
}
.inprogress-banner[data-tone="decision"] {
  border-color: var(--accent);
  background: rgba(100, 140, 220, 0.12);
}
.inprogress-banner[hidden] { display: none; }
/* Member confirm stack — one card per open punch (Prep + Sleep, etc.). */
.inprogress-stack {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0 0 0.75rem;
}
.inprogress-stack[hidden] { display: none; }
.inprogress-stack-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  font-size: 0.78rem;
  color: var(--muted);
}
.inprogress-stack-head strong { color: var(--text); font-size: 0.85rem; }
.inprogress-card {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: 0.65rem 0.85rem;
  border: 1px solid var(--danger);
  border-left-width: 4px;
  border-radius: 10px;
  background: rgba(220, 80, 80, 0.12);
  color: var(--text);
  font-size: 0.95rem;
}
.inprogress-card[data-tone="sweet"] {
  border-color: #c9a227;
  background: linear-gradient(135deg, rgba(201, 162, 39, 0.18), rgba(61, 154, 92, 0.1));
}
.inprogress-card[data-tone="ontime"] {
  border-color: var(--ok);
  background: rgba(61, 154, 92, 0.12);
}
.inprogress-card[data-tone="late"] {
  border-color: var(--warn);
  background: rgba(220, 160, 60, 0.14);
}
.inprogress-card[data-tone="wait"] {
  border-color: var(--warn);
  background: rgba(220, 160, 60, 0.1);
}
.inprogress-card[data-tone="urgent"] {
  border-color: var(--danger);
  background: rgba(220, 80, 80, 0.12);
}
.inprogress-card-row {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
}
.inprogress-card .inprogress-banner-dot { margin-top: 0.35rem; }
.inprogress-card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
}
.inprogress-banner-row {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
}
/* Punch clock + action buttons sit on their own rows so "I am ready" never
   rides beside (and over) the timing band on a narrow phone. */
.inprogress-banner-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
}
.inprogress-banner-dot {
  flex: 0 0 auto;
  width: 10px; height: 10px;
  margin-top: 0.35rem;
  border-radius: 50%;
  background: var(--danger);
  animation: notif-pulse 1.6s ease-in-out infinite;
}
.inprogress-banner[data-tone="sweet"] .inprogress-banner-dot { background: #c9a227; }
.inprogress-banner[data-tone="ontime"] .inprogress-banner-dot { background: var(--ok); }
.inprogress-banner[data-tone="late"] .inprogress-banner-dot,
.inprogress-banner[data-tone="wait"] .inprogress-banner-dot { background: var(--warn); }
.inprogress-banner[data-tone="decision"] .inprogress-banner-dot { background: var(--accent); animation: none; }
.inprogress-banner-body { flex: 1 1 auto; min-width: 0; }
.inprogress-banner-text { line-height: 1.35; }
.inprogress-btn {
  border: 1px solid var(--line);
  background: transparent;
  color: var(--text);
  border-radius: 8px;
  padding: 0.35rem 0.7rem;
  font-size: 0.85rem;
  cursor: pointer;
  white-space: nowrap;
}
.inprogress-btn:hover { border-color: var(--text); }
.inprogress-btn:disabled { opacity: 0.5; cursor: default; }
.inprogress-btn.ready { border-color: var(--ok); color: #b6e2c4; }
.inprogress-btn.danger { border-color: var(--danger); color: #f0b5b5; }
.inprogress-btn-link {
  border: none;
  background: none;
  color: var(--muted);
  font-size: 0.8rem;
  padding: 0.2rem 0.35rem;
  cursor: pointer;
  text-decoration: underline;
}
.inprogress-btn-link:hover { color: var(--text); }
.inprogress-checklist {
  list-style: none;
  margin: 0.45rem 0 0.15rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.inprogress-checklist li {
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  font-size: 0.82rem;
  color: var(--text);
  line-height: 1.3;
}
.inprogress-checklist input { margin-top: 0.15rem; }
.inprogress-checklist-hint {
  margin: 0.25rem 0 0;
  font-size: 0.75rem;
  color: var(--muted);
}
/* Punch-timing band visual (−10 … +10 min vs scheduled start). */
.punch-clock { margin-top: 0.45rem; }
.punch-clock[hidden] { display: none; }
.punch-clock-track {
  position: relative;
  height: 1.35rem;
  border-radius: 999px;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--chip);
}
.punch-clock-burn {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 0;
  pointer-events: none;
  background: linear-gradient(90deg,
    rgba(255, 120, 60, 0.35),
    rgba(220, 60, 60, 0.55));
  mix-blend-mode: screen;
  transition: width 0.35s ease;
}
.punch-clock-track.is-dead .punch-clock-burn {
  background: linear-gradient(90deg,
    rgba(220, 80, 80, 0.5),
    rgba(140, 30, 30, 0.75));
  animation: punch-burn 1.2s ease-in-out infinite alternate;
}
.punch-clock-track.is-sweet {
  box-shadow: 0 0 12px rgba(201, 162, 39, 0.35);
}
@keyframes punch-burn {
  from { opacity: 0.65; }
  to { opacity: 1; }
}
.punch-clock-segs {
  display: flex;
  height: 100%;
  position: relative;
  z-index: 1;
}
.punch-seg {
  flex: 1 1 25%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  opacity: 0.55;
  transition: opacity 0.25s, filter 0.25s;
  position: relative;
  overflow: hidden;
}
.punch-seg-fill {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 0;
  pointer-events: none;
  opacity: 0.45;
  transition: width 0.35s ease;
}
.punch-seg-early .punch-seg-fill { background: rgba(184, 212, 240, 0.55); }
.punch-seg-sweet .punch-seg-fill { background: rgba(255, 248, 220, 0.65); }
.punch-seg-ontime .punch-seg-fill { background: rgba(212, 245, 222, 0.6); }
.punch-seg-late .punch-seg-fill { background: rgba(255, 200, 140, 0.55); }
.punch-seg-early { background: linear-gradient(180deg, #3a5a7a, #2a4058); color: #b8d4f0; }
.punch-seg-sweet { background: linear-gradient(180deg, #c9a227, #8a6918); color: #fff8dc; }
.punch-seg-ontime { background: linear-gradient(180deg, #3d9a5c, #2a6840); color: #d4f5de; }
.punch-seg-late { background: linear-gradient(180deg, #c97830, #8a4510); color: #ffe8cc; }
.punch-seg.is-active { opacity: 1; filter: saturate(1.2) brightness(1.15); }
.punch-seg.is-active .punch-seg-fill { opacity: 0.7; }
.punch-seg.is-passed { opacity: 0.35; filter: grayscale(0.4); }
.punch-seg-mult { pointer-events: none; position: relative; z-index: 1; }
.punch-clock-needle {
  position: absolute;
  top: -3px; bottom: -3px;
  width: 3px;
  margin-left: -1.5px;
  z-index: 4;
  background: #e85c4a;
  box-shadow: 0 0 6px rgba(232, 92, 74, 0.85), 0 0 10px rgba(220, 60, 60, 0.45);
  transition: left 0.35s ease;
  pointer-events: none;
}
.punch-clock-elapsed {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 5;
  font-size: 0.68rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: #fff;
  text-shadow: 0 0 4px rgba(0, 0, 0, 0.85), 0 1px 2px rgba(0, 0, 0, 0.9);
  white-space: nowrap;
  pointer-events: none;
  transition: left 0.35s ease;
}
.punch-needle-cap {
  position: absolute;
  top: -5px;
  left: 50%;
  transform: translateX(-50%);
  width: 9px; height: 9px;
  border-radius: 50%;
  background: #e85c4a;
  box-shadow: 0 0 8px rgba(232, 92, 74, 0.9);
}
.punch-clock[data-band="toolate"] .punch-clock-needle,
.punch-clock[data-band="toolate"] .punch-needle-cap {
  background: var(--danger);
  box-shadow: 0 0 8px rgba(220, 80, 80, 0.9);
}
.punch-clock-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem 1.25rem;
  margin-top: 0.35rem;
  font-size: 0.8rem;
}
.punch-stat-label {
  color: var(--muted);
  font-weight: 600;
}
.punch-stat strong {
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.punch-clock-caption {
  margin-top: 0.15rem;
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--muted);
}
.punch-clock-ticks {
  position: relative;
  height: 1rem;
  margin-top: 0.15rem;
  font-size: 0.62rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.punch-tick {
  position: absolute;
  transform: translateX(-50%);
  white-space: nowrap;
}
.punch-clock-compact .punch-clock-track { height: 1.1rem; }
.punch-clock-compact .punch-clock-elapsed { font-size: 0.6rem; }
.punch-clock-compact .punch-clock-stats { font-size: 0.72rem; }
.punch-clock-compact .punch-clock-caption { font-size: 0.68rem; }
@media (prefers-reduced-motion: reduce) {
  .inprogress-banner-dot { animation: none; }
  .punch-clock-track.is-dead .punch-clock-burn { animation: none; }
  .punch-clock-burn, .punch-clock-needle { transition: none; }
}
/* Chief/Co-Chief late-task punch stack (Zen, past +5 min on others' confirms). */
.chief-punch-stack {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0 0 0.75rem;
}
.chief-punch-stack[hidden] { display: none; }
.chief-punch-stack-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  font-size: 0.78rem;
  color: var(--muted);
}
.chief-punch-stack-head strong { color: var(--text); font-size: 0.85rem; }
.chief-punch-card {
  border: 1px solid var(--warn);
  border-left-width: 4px;
  border-radius: 10px;
  padding: 0.55rem 0.75rem;
  background: rgba(220, 160, 60, 0.1);
}
.chief-punch-card[data-band="late"] {
  border-color: var(--warn);
  background: rgba(220, 160, 60, 0.12);
}
.chief-punch-card[data-band="toolate"] {
  border-color: var(--danger);
  background: rgba(220, 80, 80, 0.12);
}
.chief-punch-card-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.chief-punch-card-info { flex: 1 1 8rem; min-width: 0; }
.chief-punch-card-title { font-weight: 600; font-size: 0.92rem; line-height: 1.3; }
.chief-punch-card-sub { font-size: 0.75rem; color: var(--muted); margin-top: 0.1rem; }
.chief-punch-card-block {
  font-size: 0.75rem;
  margin-top: 0.25rem;
  color: var(--muted);
}
.chief-punch-card-block.is-blocked { color: #ffb4b4; }
.chief-punch-card-block.is-granted { color: #b6e2c4; }
.chief-punch-card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.45rem;
}
.chief-punch-btn-col {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  align-items: flex-start;
}
.chief-punch-btn {
  border: 1px solid var(--ok);
  background: rgba(61, 154, 92, 0.15);
  color: #b6e2c4;
  border-radius: 8px;
  padding: 0.35rem 0.75rem;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.chief-punch-btn:hover { border-color: var(--text); color: var(--text); }
.chief-punch-btn:disabled { opacity: 0.5; cursor: default; }
.chief-punch-audit {
  margin-top: 0.15rem;
  padding-top: 0.45rem;
  border-top: 1px dashed var(--line);
  font-size: 0.72rem;
  color: var(--muted);
}
.chief-punch-audit summary {
  cursor: pointer;
  user-select: none;
  color: var(--muted);
}
.chief-punch-audit summary:hover { color: var(--text); }
.chief-punch-audit ul {
  margin: 0.35rem 0 0;
  padding-left: 1.1rem;
  list-style: disc;
}
.chief-punch-audit li { margin: 0.15rem 0; }
/* Cross-reference "open the referenced thing" affordance. A small inline
   icon-link that sits next to a name or a <select> and opens that entity's
   own detail/edit screen. Muted until hover, like .jump-btn. Shared so
   every screen links a cross-reference the same way. */
.ref-open {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  margin-left: 0.3rem;
  padding: 0.1rem;
  border-radius: 4px;
  color: var(--muted);
  text-decoration: none;
  vertical-align: middle;
  transition: var(--btn-transition);
}
.ref-open:hover { color: var(--accent); }
.ref-open:focus-visible { outline: var(--btn-focus-ring); outline-offset: 1px; }
.ref-open[hidden] { display: none; }
.ref-open svg { display: block; }
