/* ================================================================
   DTTASA STRATEGIC ALLOCATION PORTAL
   Design: Obsidian Command Centre — Military Luxury
   ================================================================ */
:root {
  --void:    #0c1109;
  --deep:    #111a0e;
  --base:    #172213;
  --lift:    #1e2e1b;
  --panel:   rgba(255,255,255,0.10);
  --panel2:  rgba(255,255,255,0.23);
  --border:  rgba(255,255,255,0.23);
  --border2: rgba(255,255,255,0.34);
  --gold:    #f0c832;
  --gold2:   #f7d94e;
  --gdim:    rgba(212,175,55,0.12);
  --gglow:   rgba(212,175,55,0.3);
  --green:   #4cd657;
  --grdim:   rgba(67,177,75,0.12);
  --red:     #ff4848;
  --rdim:    rgba(232,64,64,0.12);
  --blue:    #4a9eff;
  --text:    #f2f7ee;
  --t2:      rgba(242,247,238,0.92);
  --t3:      rgba(242,247,238,0.68);
  --mono:    'IBM Plex Mono', monospace;
  --display: 'Cinzel', serif;
  --body:    'DM Sans', sans-serif;
  --sb:      260px;
  --hd:      70px;   /* the design, and the --hdh design token, both say 70 */
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* NO `overflow: auto` here. It makes BODY a scroll container, and then
   `position:sticky` on #hdr and .alloc-toolbar resolves inside a box that
   itself scrolls away: both slid off the top of the screen on scroll, which
   is what the VP reported as the toolbar getting swallowed. The viewport is
   the scroller, as it is in the design. */
html, body { width: 100%; height: auto; min-height: 100%; background: var(--void); color: var(--text); font-family: var(--body); -webkit-font-smoothing: antialiased; }

/* ================================================================
   SCANLINES + AMBIENT
   ================================================================ */
#root::before {
  content: ''; position: fixed; inset: 0; pointer-events: none; z-index: 99998;
  background: repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,0,0,0.02) 2px, rgba(0,0,0,0.02) 4px);
}
#root::after {
  content: ''; position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background: radial-gradient(ellipse at 15% 0%, rgba(67,177,75,0.04) 0%, transparent 55%),
              radial-gradient(ellipse at 90% 95%, rgba(212,175,55,0.04) 0%, transparent 55%);
}

/* ================================================================
   ROOT SHELL
   ================================================================ */
#root {
  position: relative; min-height: 100dvh; z-index: 50;
  display: flex; flex-direction: column; overflow: visible;
}

/* ================================================================
   HEADER
   ================================================================ */
#hdr {
  height: var(--hd); flex-shrink: 0;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 18px;   /* the design */
  background: rgba(4,8,4,.78);
  border-bottom: 1px solid rgba(255,255,255,.08);
  -webkit-backdrop-filter: blur(36px) saturate(160%); backdrop-filter: blur(36px) saturate(160%);
  -webkit-backdrop-filter: blur(36px) saturate(160%);
  position: sticky; top: 0; z-index: 200;
  animation: hdrSlide 0.6s cubic-bezier(0.16,1,0.3,1) both;
  box-shadow: inset 0 -1px 0 rgba(255,255,255,.05), 0 4px 24px rgba(0,0,0,.3);
}
@keyframes hdrSlide { from { transform: translateY(-100%); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
#hdr::after{content:'';position:absolute;inset:0;pointer-events:none;background:linear-gradient(90deg,transparent 0%,rgba(212,175,55,.04) 50%,transparent 100%);background-size:250% 100%;animation:hdrScan 7s linear infinite;}
@keyframes hdrScan{from{background-position:250% 0;}to{background-position:-250% 0;}}

.hdr-brand { display: flex; align-items: center; gap: 10px; }
.hdr-brand-img {
  height: 34px; width: auto; object-fit: contain; cursor: pointer; flex-shrink: 0;
  opacity: 0; animation: logoRevealHdr 0.8s cubic-bezier(0.23,1,0.32,1) 0.3s forwards;
  transition: filter 0.3s, transform 0.3s;
  filter: drop-shadow(0 0 0px rgba(212,175,55,0));
}
.hdr-brand-img:hover { filter: drop-shadow(0 0 8px rgba(212,175,55,0.5)); transform: scale(1.04); }
@keyframes logoRevealHdr { to { opacity: 1; } }
.hdr-brand-text { display: flex; flex-direction: column; gap: 2px; }
.hdr-brand-logo {
  font-family: var(--display); font-size: 22px; font-weight: 900; letter-spacing: 8px;
  background: linear-gradient(135deg, var(--green) 0%, var(--gold) 100%);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
.hdr-brand-sub { font-size: 13px; letter-spacing: 3.5px; color: var(--gold); opacity: 0.85; text-transform: uppercase; }

.hdr-status {
  display: flex; align-items: center; gap: 7px;
  background: var(--grdim); border: 1px solid rgba(67,177,75,0.25);
  padding: 5px 14px; border-radius: 20px;
  font-size: 13px; font-weight: 800; color: var(--green); letter-spacing: 2px;
}
.pip-live { width: 6px; height: 6px; border-radius: 50%; background: var(--green); box-shadow: 0 0 8px var(--green); animation: pipBlink 2s infinite; }
@keyframes pipBlink { 0%,100%{opacity:1;} 50%{opacity:0.2;} }

.hdr-right { display: flex; align-items: center; gap: 12px; }
.hdr-week-pill {
  font-family: var(--mono); font-size: 15px; font-weight: 700; color: var(--gold);
  border: 1px solid rgba(212,175,55,0.3); padding: 6px 14px; border-radius: 8px;
  background: var(--gdim); letter-spacing: 2px;
}
.hdr-clock { font-family: var(--mono); font-size: 13px; color: var(--t2); letter-spacing: 1px; }
.hdr-admin-chip {
  font-size: 13px; font-weight: 800; letter-spacing: 1px; color: var(--gold);
  background: var(--gdim); border: 1px solid rgba(212,175,55,0.2);
  padding: 5px 12px; border-radius: 6px;
}

/* ================================================================
   BODY LAYOUT
   ================================================================ */
#body { flex: 1; display: block; overflow: visible; position: relative; z-index: 2; }

/* ================================================================
   SIDEBAR
   ================================================================ */
#sidebar {
  position: fixed; top: var(--hd); left: 0; width: 260px; height: calc(100dvh - var(--hd)); z-index: 1000;
  background: rgba(4,8,4,.95); border-right: 1px solid rgba(255,255,255,.08);
  backdrop-filter: blur(24px) saturate(140%); -webkit-backdrop-filter: blur(24px) saturate(140%);
  display: flex; flex-direction: column;
  overflow: hidden;
  transform: translateX(-100%);
  transition: transform 0.35s cubic-bezier(0.16,1,0.3,1);
}

/* ================================================================
   FULLSCREEN GRID MODE
   ================================================================ */
/* The alloc view panel becomes a true fixed overlay above everything */
#view-alloc.grid-fullscreen {
  position: fixed !important;
  inset: 0 !important;
  z-index: 600 !important;
  background: var(--void) !important;
  display: flex !important;
  flex-direction: column !important;
  /* The PANEL scrolls. This was overflow:hidden with the grid given flex:1,
     which squeezed the whole rota into whatever space was left after the
     toolbar, the rail and the action bar: a small scrolling box to work
     inside. The VP asked for the controls to be ADDED, not the card to
     shrink, and is content to scroll the page to reach other people. */
  overflow-x: hidden !important;
  overflow-y: auto !important;
  animation: fsIn .38s cubic-bezier(.16,1,.3,1) both;
}
@keyframes fsIn { from { opacity:0; transform:scale(0.98); } to { opacity:1; transform:scale(1); } }
/* Full height, never a flex remainder: every person and every cell is drawn,
   and the panel above carries the scroll. */
#view-alloc.grid-fullscreen .grid-scroll { flex: 0 0 auto; height: auto !important; max-height: none !important; }

/* Exit fullscreen button — top-right corner */
#fs-exit-btn {
  display: none;
  position: fixed; top: 14px; right: 18px; z-index: 700;
  align-items: center; gap: 6px;
  background: rgba(255,255,255,0.08); border: 1px solid var(--border);
  border-radius: 20px; padding: 6px 14px 6px 10px;
  font-size: 13px; font-weight: 800; letter-spacing: 1px; color: var(--t3);
  cursor: pointer; transition: all .2s; text-transform: uppercase;
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
#fs-exit-btn:hover { background: var(--rdim); border-color: rgba(255,72,72,.4); color: var(--red); }
body.grid-fs #fs-exit-btn { display: flex; }

/* Lift #root above sidebar + hide sidebar so nothing bleeds through */
body.grid-fs #root    { z-index: 900 !important; background: var(--void); }
body.grid-fs #sidebar { display: none !important; }
body.grid-fs #hdr     { display: none !important; }

/* Fullscreen toggle button in toolbar */
.btn-fs-toggle {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 8px;
  background: var(--panel); border: 1px solid var(--border);
  font-size: 13px; font-weight: 700; letter-spacing: .5px; color: var(--t3);
  cursor: pointer; transition: all .2s; flex-shrink: 0;
}
.btn-fs-toggle:hover { background: var(--gdim); border-color: rgba(212,175,55,.35); color: var(--gold); }
.btn-fs-toggle i { font-size: 11px; }
body.grid-fs .btn-fs-toggle { background: var(--gdim); border-color: rgba(212,175,55,.4); color: var(--gold); }

.sidebar-inner { padding: 16px 14px 20px; flex: 1; display: flex; flex-direction: column; gap: 4px; overflow-y: auto; }
.sidebar-inner::-webkit-scrollbar { width: 3px; }
.sidebar-inner::-webkit-scrollbar-thumb { background: rgba(212,175,55,0.2); border-radius: 10px; }

.nav-section-label {
  font-size: 13px; font-weight: 800; letter-spacing: 3px; color: var(--t2);
  text-transform: uppercase; padding: 8px 8px 4px; margin-top: 6px;
}
.nav-item {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border-radius: 10px;
  font-size: 14px; font-weight: 600; color: var(--t2);
  cursor: pointer; border: 1px solid transparent;
  transition: all 0.25s cubic-bezier(.16,1,.3,1); letter-spacing: 0.3px;
  position: relative; overflow: hidden;
}
.nav-item::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 0;
  background: linear-gradient(90deg, rgba(212,175,55,0.1), transparent);
  transition: width 0.3s cubic-bezier(.16,1,.3,1);
}
.nav-item:hover::before { width: 100%; }
.nav-item:hover { color: var(--text); transform: translateX(3px); }
.nav-item.active { background: var(--gdim); border-color: rgba(212,175,55,0.2); color: var(--gold); }
.nav-item.active::before { width: 100%; }
.nav-item i { width: 16px; text-align: center; font-size: 15px; flex-shrink: 0; }
.nav-divider { height: 1px; background: var(--border); margin: 6px 0; }
.nav-item.danger { color: rgba(232,64,64,0.75); }
.nav-item.danger:hover { color: var(--red); background: var(--rdim); border-color: rgba(232,64,64,0.15); }

/* Archive sub-list */
.archive-sub {
  margin: 2px 0 4px 28px;
  max-height: 0; overflow: hidden;
  transition: max-height 0.4s cubic-bezier(0.16,1,0.3,1);
}
.archive-sub.open { max-height: 260px; overflow-y: auto; }
.archive-sub::-webkit-scrollbar { width: 3px; }
.archive-sub::-webkit-scrollbar-thumb { background: rgba(212,175,55,0.2); }
.archive-entry {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 10px; border-radius: 7px; cursor: pointer;
  font-size: 13px; font-weight: 700; letter-spacing: 0.5px;
  color: var(--t2); transition: all 0.2s;
  border: 1px solid transparent;
  margin-bottom: 3px;
}
.archive-entry:hover { background: var(--gdim); border-color: rgba(212,175,55,0.15); color: var(--gold); }
.archive-entry-del { color: rgba(232,64,64,0.4); cursor: pointer; padding: 4px 6px; border-radius: 4px; transition: 0.2s; }
.archive-entry-del:hover { color: var(--red); background: var(--rdim); }

.nav-spacer { flex: 1; }

/* Staggered entrance */
.nav-item { animation: navIn 0.55s cubic-bezier(0.16,1,0.3,1) both; }
.nav-item:nth-child(1){animation-delay:.08s}.nav-item:nth-child(2){animation-delay:.13s}
.nav-item:nth-child(3){animation-delay:.18s}.nav-item:nth-child(4){animation-delay:.23s}
.nav-item:nth-child(5){animation-delay:.28s}.nav-item:nth-child(6){animation-delay:.33s}
.nav-item:nth-child(7){animation-delay:.38s}.nav-item:nth-child(8){animation-delay:.43s}
@keyframes navIn { from { opacity:0; transform:translateX(-16px); } to { opacity:1; transform:translateX(0); } }

/* ================================================================
   MAIN WORKSPACE
   ================================================================ */
#workspace {
  display: block; overflow: visible;
}

/* View panels */
.view-panel { display: none; overflow: visible; height: auto; }
.view-panel.active { display: block; animation: panelIn 0.5s cubic-bezier(0.16,1,0.3,1) both; }
@keyframes panelIn { from { opacity:0; transform:translateY(14px); filter:blur(4px); } to { opacity:1; transform:translateY(0); filter:blur(0); } }

/* ================================================================
   ROTA ALLOCATION VIEW
   ================================================================ */
/* The design's main column: a flex column with a 14px gap. Ours was
   display:block with no gap at all, so the role banner, the hero and the
   legend all sat flush against each other at 0px. The .grid-fullscreen
   rule below already assumes flex and carries its own !important, so it
   still wins when the grid goes full screen. */
/* The display goes on .active ONLY. Written first as a bare `#view-alloc{
   display:flex }`, an ID rule, which beat `.view-panel{display:none}` and left
   BOTH views painted at once: the Live Network deck sat underneath the
   allocation grid instead of behind its own tab. The harness that measured
   this forced `#view-alloc{display:flex!important}` so it could see the grid,
   which is precisely why it never showed up. */
#view-alloc {
  padding: 0;
  flex-direction: column;
  gap: 14px;
}
#view-alloc.active { display: flex; }

/* Top toolbar */
.alloc-toolbar {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 24px; border-bottom: 1px solid var(--border);
  background: rgba(0,0,0,0.2); flex-shrink: 0; flex-wrap: wrap;
}
.tab-btn {
  padding: 8px 18px; border-radius: 20px; border: 1px solid var(--border);
  background: var(--panel); color: var(--t3); font-size: 13px; font-weight: 800;
  letter-spacing: 1.5px; cursor: pointer; transition: all 0.25s cubic-bezier(.16,1,.3,1);
  text-transform: uppercase;
}
.tab-btn.active { background: var(--gdim); border-color: rgba(212,175,55,0.3); color: var(--gold); }
.tab-btn:hover:not(.active) { border-color: var(--border2); color: var(--text); }

.week-nav { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.week-nav-btn {
  width: 34px; height: 34px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--panel); color: var(--t2); cursor: pointer; font-size: 13px;
  display: flex; align-items: center; justify-content: center;
  transition: all 0.25s cubic-bezier(.16,1,.3,1);
}
.week-nav-btn:hover { border-color: var(--gold); color: var(--gold); background: var(--gdim); transform: scale(1.1); box-shadow: 0 4px 14px rgba(212,175,55,0.2); }
.week-nav-btn:active { transform: scale(0.93); }
.week-display { font-family: var(--mono); font-size: 15px; font-weight: 700; color: var(--gold); letter-spacing: 2px; min-width: 120px; text-align: center; }

/* Grid scroll */
/* The design's grid has NO height and NO vertical scroll: .gridwrap is
   overflow-x:auto and nothing else, so the grid is as tall as its rows and
   the PAGE scrolls. Ours was height:68vh with overflow:auto, which is why a
   cursor over the grid ate the page scroll (VP 2026-08-04). Horizontal
   scrolling stays, because a week is wider than a phone. */
.grid-scroll {
  overflow-x: auto; overflow-y: hidden; position: relative;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin; scrollbar-color: rgba(212,175,55,0.3) transparent;
}
.grid-scroll::-webkit-scrollbar { width: 6px; height: 6px; }
.grid-scroll::-webkit-scrollbar-thumb { background: rgba(212,175,55,0.25); border-radius: 10px; }

/* Rota table */
.rota-tbl {
  width: 100%; border-collapse: separate; border-spacing: 0;
  font-size: 13px; min-width: 900px;
}
.rota-tbl thead th {
  position: sticky; top: 0; z-index: 30;
  padding: 14px 10px; text-align: center;
  font-size: 13px; font-weight: 800; letter-spacing: 2px; color: var(--gold);
  background: var(--deep); border-bottom: 1px solid rgba(212,175,55,0.25);
  white-space: nowrap;
}
.rota-tbl thead th.col-member {
  position: sticky; left: 0; top: 0; z-index: 40;
  text-align: left; min-width: 200px; padding-left: 16px;
  border-right: 2px solid rgba(212,175,55,0.25);
}
.rota-tbl tbody td { border-bottom: 1px solid rgba(255,255,255,0.03); padding: 6px; vertical-align: top; }
.rota-tbl tbody td.col-member {
  position: sticky; left: 0; z-index: 10;
  background: var(--base); border-right: 2px solid rgba(212,175,55,0.15);
  padding: 10px 14px; min-width: 220px;
}
.rota-tbl thead th.today-col { color: var(--gold2); border-bottom-color: var(--gold); }
.rota-tbl tbody td.today-col { background: rgba(212,175,55,0.03); }

/* ── User row demarcation ── */
.rota-tbl tbody tr.user-row td {
  border-top: 2px solid rgba(212,175,55,0.18);
}
.rota-tbl tbody tr.user-row-odd td {
  background: rgba(255,255,255,0.012);
}
/* SOLID, not 2.5% white. The design's .whocell is background:#141d10, a flat
   colour, which is what the VP meant by "thicker, does not make it
   transparent": a sticky cell with any alpha lets the columns slide visibly
   underneath it. #1a2316 is #141d10 composited with that same 2.5% white, so
   the zebra stripe looks the same and no longer shows through. */
.rota-tbl tbody tr.user-row-odd td.col-member {
  background: #1a2316;
}
.rota-tbl tbody tr.user-row td.col-member {
  border-left: 3px solid rgba(212,175,55,0.45);
  border-top: 2px solid rgba(212,175,55,0.18);
}
.rota-tbl tbody tr.row-sep td {
  height: 5px; padding: 0; border: none;
  background: linear-gradient(90deg, rgba(212,175,55,0.12) 0%, rgba(212,175,55,0.04) 40%, transparent 100%);
}

/* ── Net Owed column ── */
.rota-tbl thead th.col-net-owed {
  min-width: 80px; text-align: center; padding: 8px 10px;
  font-size: 13px; letter-spacing: 1.2px; color: var(--t3);
  border-left: 1px solid rgba(212,175,55,0.18);
}
.rota-tbl tbody td.col-net-owed {
  text-align: center; vertical-align: middle; padding: 6px 8px;
  border-left: 1px solid rgba(212,175,55,0.1);
}
.net-owed-val { font-family: var(--mono); font-size: 13px; font-weight: 800; display: block; text-align: center; }
.net-owed-owed   { color: var(--red); }
.net-owed-credit { color: var(--green); }
.net-owed-ok     { color: var(--gold); }

.member-name-cell { font-weight: 700; color: var(--gold); font-size: 14px; white-space: nowrap; }
.member-role-cell { font-size: 13px; color: var(--t2); margin-top: 2px; }
.member-balance {
  font-size: 13px; font-weight: 800; padding: 3px 8px; border-radius: 20px;
  display: inline-block; margin-top: 5px; letter-spacing: 1px;
}
.balance-ok  { background: var(--grdim); color: var(--green); border: 1px solid rgba(67,177,75,0.3); }
.balance-over { background: var(--rdim); color: var(--red); border: 1px solid rgba(232,64,64,0.3); animation: pulseRed 2s infinite; }
@keyframes pulseRed { 0%{box-shadow:0 0 0 0 rgba(232,64,64,0.4);} 70%{box-shadow:0 0 0 8px rgba(232,64,64,0);} 100%{box-shadow:0 0 0 0 rgba(232,64,64,0);} }
.hours-debt {
  font-size: 13px; font-weight: 800; padding: 2px 7px; border-radius: 20px;
  display: inline-block; margin-top: 3px; margin-left: 4px; letter-spacing: 0.8px;
}
.debt-owed { background: var(--rdim); color: var(--red); border: 1px solid rgba(232,64,64,0.3); }
.debt-credit { background: var(--grdim); color: var(--green); border: 1px solid rgba(67,177,75,0.3); }
.debt-clear  { background: rgba(255,255,255,0.04); color: var(--t3); border: 1px solid rgba(255,255,255,0.10); }
.debt-base   { font-size: 13px; font-weight: 800; padding: 2px 6px; border-radius: 20px; display: inline-block; letter-spacing: 0.6px; }
.debt-adj    { font-size: 13px; font-weight: 800; padding: 2px 6px; border-radius: 20px; display: inline-block; letter-spacing: 0.6px; margin-top: 2px; }

/* ── Carry-forward breakdown card ── */
.cf-card {
  margin-top: 7px; border-radius: 8px; padding: 7px 9px;
  animation: cfIn 0.4s cubic-bezier(.16,1,.3,1) both;
}
@keyframes cfIn { from{opacity:0;transform:translateY(5px) scale(0.97);} to{opacity:1;transform:translateY(0) scale(1);} }
.cf-card-owed   { background: rgba(232,64,64,0.09); border: 1px solid rgba(232,64,64,0.3); }
.cf-card-credit { background: rgba(67,177,75,0.09);  border: 1px solid rgba(67,177,75,0.3);  }
.cf-card-clear  { background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.1); }
.cf-row { display: flex; justify-content: space-between; align-items: center; padding: 2px 0; }
.cf-lbl { font-size: 13px; font-weight: 800; letter-spacing: 1.5px; color: var(--t2); text-transform: uppercase; }
.cf-val { font-family: var(--mono); font-size: 13px; font-weight: 800; color: var(--text); }
.cf-val-red   { font-family: var(--mono); font-size: 13px; font-weight: 800; color: var(--red); }
.cf-val-green { font-family: var(--mono); font-size: 13px; font-weight: 800; color: var(--green); }
.cf-val-gold  { font-family: var(--mono); font-size: 13px; font-weight: 800; color: var(--gold); }
.cf-val-dim   { font-family: var(--mono); font-size: 13px; font-weight: 700; color: var(--t3); font-style: italic; }
.cf-sep { height: 1px; background: rgba(255,255,255,0.12); margin: 4px 0; }
.cf-row-total .cf-lbl { color: var(--gold); letter-spacing: 2px; }
.cf-pbar-wrap { height: 3px; background: rgba(255,255,255,0.07); border-radius: 10px; margin: 4px 0; overflow: hidden; }
.cf-pbar { height: 100%; border-radius: 10px; background: linear-gradient(90deg, var(--red), var(--gold)); transition: width 0.9s cubic-bezier(0.16,1,0.3,1); }
.cf-pbar-ok { background: linear-gradient(90deg, var(--green), var(--gold)); }
.cf-hist { margin-top: 6px; border-top: 1px solid rgba(255,255,255,0.1); padding-top: 4px; }
.cf-hist-toggle {
  font-size: 13px; font-weight: 800; letter-spacing: 1.2px; text-transform: uppercase;
  color: var(--t3); cursor: pointer; list-style: none; padding: 2px 0;
  transition: color .2s;
}
.cf-hist-toggle::-webkit-details-marker { display: none; }
.cf-hist-toggle::before { content: '▸ '; }
details.cf-hist[open] .cf-hist-toggle::before { content: '▾ '; }
.cf-hist-toggle:hover { color: var(--gold); }

@keyframes deptLeadGlow{0%,100%{box-shadow:0 0 8px rgba(240,200,50,.4);}50%{box-shadow:0 0 16px rgba(240,200,50,.75),0 0 24px rgba(240,200,50,.25);}}
.dept-lead-badge { display:inline-flex; align-items:center; gap:3px; font-size:13px; font-weight:700; color:#000; background:var(--gold); border-radius:4px; padding:2px 6px; margin-left:6px; letter-spacing:.5px; vertical-align:middle; animation:deptLeadGlow 2.8s cubic-bezier(.16,1,.3,1) infinite; }

/* Allocation cell */
.alloc-cell {
  background: rgba(0,0,0,0.25); border-radius: 8px; padding: 8px;
  min-width: 120px; position: relative; transition: all 0.3s cubic-bezier(0.4,0,0.2,1);
  border-top: 3px solid #333;
  animation: cellIn 0.4s cubic-bezier(0.16,1,0.3,1) both;
}
.alloc-cell:hover:not(.locked) { background: rgba(255,255,255,0.06); transform: scale(1.02); box-shadow: 0 4px 16px rgba(0,0,0,0.3); }
@keyframes cellIn { from { opacity:0; transform:scale(0.95); } to { opacity:1; transform:scale(1); } }
.alloc-cell.locked { opacity: 0.85; cursor: not-allowed; }
.cell-lock-icon { position: absolute; top: 5px; right: 6px; color: var(--t3); font-size: 11px; opacity: 0.7; }
/* Published shift — locked (red, non-privileged users) */
/* Published shift — can override (gold open-lock, SA / Head of HR) */
.alloc-cell.flash { animation: cellFlash 0.6s cubic-bezier(.16,1,.3,1); }
@keyframes cellFlash { 0%{background:rgba(212,175,55,0);} 40%{background:rgba(212,175,55,0.2);} 100%{background:rgba(0,0,0,0.25);} }
.alloc-cell.leave-locked { cursor: default; }
.alloc-cell.leave-locked:hover { transform: none !important; box-shadow: none !important; background: rgba(0,0,0,0.25) !important; }
.ph-crown { display:block; text-align:center; font-size:12px; margin-top:2px; color:var(--gold); animation: phBob 2s cubic-bezier(.16,1,.3,1) infinite; }
@keyframes phBob { 0%,100%{transform:translateY(0);} 50%{transform:translateY(-2px);} }
.ph-col-wash { background: rgba(212,175,55,0.03) !important; }
.ph-warning-strip { font-size:13px; color:#FF8C00; font-weight:700; display:flex; align-items:center; gap:3px; margin-top:3px; white-space:nowrap; overflow:hidden; }
.ph-clear-strip { font-size:13px; color:var(--green); font-weight:700; display:flex; align-items:center; gap:3px; margin-top:3px; }
/* MISSED SHIFT — calculator finalised: user never clocked in (unattended) */
@keyframes urgentPulse { 0%,100%{opacity:1;} 50%{opacity:0.55;} }
.missed-strip { font-size:13px; font-weight:800; letter-spacing:.6px; color:var(--red); display:flex; align-items:center; gap:3px; margin-top:3px; text-transform:uppercase; animation: urgentPulse 1.8s cubic-bezier(.16,1,.3,1) infinite; }
.missed-col { background: rgba(232,64,64,0.04) !important; }
/* DEBT LOGGED — clocked in/out but with a deficit (late, early, break overrun) */
.debt-strip { font-size:13px; font-weight:800; letter-spacing:.6px; color:var(--gold); display:flex; align-items:center; gap:3px; margin-top:3px; text-transform:uppercase; }
.debt-strip.debt-balanced { color:var(--green); }
.debt-col { background: rgba(240,200,50,0.04) !important; }
/* UNSUBMITTED — past finalizable shift with no activity, awaiting calculator */
.unsubmitted-strip { font-size:13px; font-weight:800; letter-spacing:.6px; color:#FF8C00; display:flex; align-items:center; gap:3px; margin-top:3px; text-transform:uppercase; }
.unsubmitted-col { background: rgba(255,140,0,0.04) !important; }
/* ACTIVE — clocked in, not yet clocked out (live or stale past-midnight shift) */
.active-strip { font-size:13px; font-weight:800; letter-spacing:.6px; color:var(--blue); display:flex; align-items:center; gap:3px; margin-top:3px; text-transform:uppercase; animation: pipBlink 1.8s cubic-bezier(.16,1,.3,1) infinite; }
.active-col { background: rgba(74,158,255,0.04) !important; }
/* Credit badge: hoursOver reduces allocated target */
.balance-credit { background: rgba(76,214,87,0.12); color:var(--green); border: 1px solid rgba(76,214,87,0.3); }
/* Historical week card */
.cf-card-hist { background: rgba(240,200,50,0.06); border: 1px solid rgba(240,200,50,0.22); }

.shift-sel {
  width: 100%; background: transparent; border: none; color: var(--text);
  font-weight: 800; font-size: 13px; cursor: pointer; outline: none;
  margin-bottom: 6px; letter-spacing: 0.5px;
}
.shift-sel option { background: #0e160d; }

.time-row { display: flex; gap: 4px; }
.time-chip {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 4px;
  background: rgba(255,255,255,0.05); border-radius: 5px; padding: 5px 4px;
  cursor: pointer; border: 1px solid transparent; transition: all 0.2s; font-size: 13px;
}
.time-chip:hover { border-color: var(--gold); background: var(--gdim); }
.time-chip.locked-time { pointer-events: none; opacity: 0.5; }
.time-val { font-family: var(--mono); font-size: 13px; font-weight: 700; color: var(--gold); }
.time-lbl { font-size: 13px; color: var(--t2); font-weight: 700; letter-spacing: 1px; }

/* Row stagger */
.row-stagger { animation: rowIn 0.5s cubic-bezier(0.16,1,0.3,1) both; }
.row-stagger:nth-child(1){animation-delay:.05s}.row-stagger:nth-child(2){animation-delay:.09s}
.row-stagger:nth-child(3){animation-delay:.13s}.row-stagger:nth-child(4){animation-delay:.17s}
.row-stagger:nth-child(5){animation-delay:.21s}.row-stagger:nth-child(6){animation-delay:.25s}
.row-stagger:nth-child(7){animation-delay:.29s}.row-stagger:nth-child(8){animation-delay:.33s}
.row-stagger:nth-child(9){animation-delay:.37s}.row-stagger:nth-child(10){animation-delay:.41s}
@keyframes rowIn { from { opacity:0; transform:translateX(-12px); } to { opacity:1; transform:translateX(0); } }

/* Action bar */
.action-bar {
  padding: 16px 24px; border-top: 1px solid var(--border);
  background: rgba(0,0,0,0.3); display: flex; gap: 12px;
  align-items: center; flex-wrap: wrap; flex-shrink: 0;
}

/* ================================================================
   LIVE NETWORK VIEW
   ================================================================ */
#view-network {
  overflow-y: auto; padding: 28px 28px 48px;
}
#view-network::-webkit-scrollbar { width: 5px; }
#view-network::-webkit-scrollbar-thumb { background: rgba(212,175,55,0.2); border-radius: 10px; }

.network-header { margin-bottom: 24px; }
.network-header h2 { font-family: var(--display); font-size: 24px; letter-spacing: 3px; font-weight: 700; }
.network-header p { font-size: 13px; color: var(--t2); letter-spacing: 1px; margin-top: 4px; }

.network-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; margin-bottom: 24px; }
.net-card {
  background: var(--panel); border: 1px solid var(--border); border-radius: 16px; padding: 20px;
  transition: all 0.3s cubic-bezier(0.16,1,0.3,1);
  animation: cardIn 0.6s cubic-bezier(0.16,1,0.3,1) both;
}
.net-card:hover { border-color: rgba(212,175,55,0.25); transform: translateY(-3px); box-shadow: 0 12px 32px rgba(0,0,0,0.4); }
@keyframes cardIn { from { opacity:0; transform:translateY(20px); } to { opacity:1; transform:translateY(0); } }
.net-card:nth-child(1){animation-delay:.05s}.net-card:nth-child(2){animation-delay:.10s}
.net-card:nth-child(3){animation-delay:.15s}.net-card:nth-child(4){animation-delay:.20s}
.net-card:nth-child(5){animation-delay:.25s}.net-card:nth-child(6){animation-delay:.30s}

.net-card-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 14px; }
.net-metric { font-family: var(--mono); font-size: 26px; font-weight: 700; color: var(--text); margin-bottom: 4px; }
.net-sub { font-size: 13px; color: var(--t2); letter-spacing: 0.5px; }
.net-list { margin-top: 12px; display: flex; flex-direction: column; gap: 6px; }

.audit-stream {
  background: var(--panel); border: 1px solid var(--border); border-radius: 16px;
  overflow: hidden; margin-top: 16px;
}
.audit-stream-header {
  padding: 14px 20px; border-bottom: 1px solid var(--border);
  display: flex; justify-content: space-between; align-items: center;
}
.audit-stream-header h3 { font-size: 13px; font-weight: 800; letter-spacing: 3px; color: var(--gold); text-transform: uppercase; }
.audit-stream-body { max-height: 320px; overflow-y: auto; }
.audit-stream-body::-webkit-scrollbar { width: 4px; }
.audit-stream-body::-webkit-scrollbar-thumb { background: rgba(212,175,55,0.2); }
.audit-entry {
  padding: 12px 20px; border-bottom: 1px solid rgba(255,255,255,0.03);
  display: flex; gap: 14px; align-items: flex-start;
  animation: auditIn 0.4s cubic-bezier(0.16,1,0.3,1) both;
  transition: background 0.2s;
}
.audit-entry:hover { background: rgba(255,255,255,0.02); }
@keyframes auditIn { from { opacity:0; transform:translateX(-8px); } to { opacity:1; transform:translateX(0); } }
.audit-dot { width: 8px; height: 8px; border-radius: 50%; margin-top: 3px; flex-shrink: 0; }
.audit-dot.published { background: var(--green); box-shadow: 0 0 6px var(--green); }
.audit-dot.rejected  { background: var(--red); box-shadow: 0 0 6px var(--red); }
.audit-dot.general   { background: var(--gold); }
.audit-dot.submitted { background: var(--blue); }
.audit-info { flex: 1; }
.audit-action { font-size: 13px; font-weight: 700; letter-spacing: 0.5px; }
.audit-meta { font-size: 13px; color: var(--t2); margin-top: 2px; letter-spacing: 0.5px; }
.audit-time { font-family: var(--mono); font-size: 13px; color: var(--t2); flex-shrink: 0; margin-top: 2px; }

/* Shift distribution chart */
.shift-dist { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }

/* ================================================================
   BUTTONS
   ================================================================ */
.btn {
  border: none; padding: 12px 24px; border-radius: 50px; font-weight: 800;
  font-size: 13px; letter-spacing: 2px; cursor: pointer; text-transform: uppercase;
  transition: all 0.3s cubic-bezier(.16,1,.3,1);
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; gap: 8px;
}
.btn::after { content:''; position:absolute; top:50%; left:50%; width:0; height:0; border-radius:50%; background:rgba(255,255,255,0.12); transform:translate(-50%,-50%); transition:width .4s,height .4s; }
.btn:active::after { width:200px; height:200px; }
.btn-gold { background: var(--gold); color: var(--void); box-shadow: 0 6px 20px rgba(212,175,55,0.25); }
.btn-gold:hover { background: var(--gold2); transform: translateY(-2px) scale(1.03); box-shadow: 0 10px 28px rgba(212,175,55,0.4); }
.btn-green { background: var(--green); color: #fff; box-shadow: 0 6px 20px rgba(67,177,75,0.25); }
.btn-green:hover { transform: translateY(-2px) scale(1.03); box-shadow: 0 10px 28px rgba(67,177,75,0.4); }
.btn-outline { background: transparent; border: 1px solid var(--border2); color: var(--t2); }
.btn-outline:hover { border-color: var(--gold); color: var(--gold); background: var(--gdim); }
.btn-red { background: rgba(232,64,64,0.15); border: 1px solid rgba(232,64,64,0.4); color: var(--red); }
.btn-red:hover { background: rgba(232,64,64,0.25); }
.btn-ghost { background: var(--panel2); border: 1px solid var(--border); color: var(--t2); }
.btn-ghost:hover { border-color: var(--border2); color: var(--text); }
.btn-sm { padding: 8px 16px; font-size: 13px; }
.btn-icon { width: 34px; height: 34px; padding: 0; border-radius: 8px; justify-content: center; }
@media (pointer: coarse) { .btn-icon { width: 44px; height: 44px; } }
.btn-restricted { opacity: 0.28; cursor: not-allowed !important; pointer-events: none; filter: grayscale(0.5); }
.btn-processing { opacity: 0.7; cursor: not-allowed !important; pointer-events: none; }
.spinner-ico { display:inline-block; width:11px; height:11px; border:2px solid rgba(255,255,255,0.2); border-top-color:currentColor; border-radius:50%; animation:spin .7s linear infinite; }
@keyframes spin { to { transform:rotate(360deg); } }

/* ================================================================
   VAULT TIME PICKER OVERLAY
   ================================================================ */
#picker-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,.65);
  backdrop-filter: blur(24px) saturate(130%); -webkit-backdrop-filter: blur(24px) saturate(130%);
  z-index: 100000;
  display: none; align-items: center; justify-content: center;
  opacity: 0; transition: opacity 0.25s cubic-bezier(.16,1,.3,1);
}
#picker-overlay.show { display: flex; }
#picker-overlay.show.visible { opacity: 1; }
.picker-box {
  width: 380px; background: rgba(6,10,6,.78);
  border: 1px solid rgba(255,255,255,.08); border-radius: 24px; padding: 28px;
  backdrop-filter: blur(32px) saturate(160%); -webkit-backdrop-filter: blur(32px) saturate(160%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07), 0 0 60px rgba(212,175,55,0.15), 0 40px 80px rgba(0,0,0,0.7);
  animation: glassIn .65s cubic-bezier(.16,1,.3,1) both;
  position: relative; overflow: hidden;
}
.picker-box::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse at 50% 0%, rgba(212,175,55,0.03) 0%, transparent 60%);
}
@keyframes pickerIn { from{transform:scale(0.82) translateY(20px);opacity:0;} to{transform:scale(1) translateY(0);opacity:1;} }
@keyframes popIn   { from{transform:scale(0.85);opacity:0;} to{transform:scale(1);opacity:1;} }
.picker-preview {
  background: linear-gradient(135deg, rgba(212,175,55,0.1), rgba(212,175,55,0.05));
  border: 1px solid rgba(212,175,55,0.35); border-radius: 12px;
  padding: 16px; margin-bottom: 20px;
  font-family: var(--mono); font-size: 32px; font-weight: 700;
  color: var(--gold); text-align: center; letter-spacing: 6px;
  text-shadow: 0 0 20px rgba(212,175,55,0.4);
  transition: all 0.2s cubic-bezier(.16,1,.3,1);
}
.picker-period { display: flex; gap: 10px; margin-bottom: 16px; }
.period-btn { flex: 1; padding: 10px; border-radius: 10px; border: 1px solid var(--border2); background: var(--panel2); color: var(--text); cursor: pointer; font-weight: 800; font-size: 14px; letter-spacing: 1px; transition: all 0.25s cubic-bezier(.16,1,.3,1); }
.period-btn:hover { transform: translateY(-1px); }
.period-btn.am { background: rgba(67,177,75,0.18); color: var(--green); border-color: rgba(67,177,75,0.4); box-shadow: 0 4px 16px rgba(67,177,75,0.15); }
.period-btn.pm { background: rgba(212,175,55,0.18); color: var(--gold); border-color: rgba(212,175,55,0.4); box-shadow: 0 4px 16px rgba(212,175,55,0.15); }
.picker-grid { display: grid; grid-template-columns: repeat(4,1fr); gap: 8px; }
/* Minute grid: 6 columns, scrollable */
.picker-grid-min {
  display: grid; grid-template-columns: repeat(6,1fr); gap: 6px;
  max-height: 210px; overflow-y: auto; padding-right: 2px;
  scrollbar-width: thin; scrollbar-color: rgba(212,175,55,0.3) transparent;
}
.picker-grid-min::-webkit-scrollbar { width: 3px; }
.picker-grid-min::-webkit-scrollbar-thumb { background: rgba(212,175,55,0.3); border-radius: 10px; }
.pick-num {
  padding: 11px 4px; background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.1);
  border-radius: 8px; cursor: pointer; font-size: 15px; font-weight: 700;
  color: var(--text); text-align: center; font-family: var(--mono);
  transition: all 0.2s cubic-bezier(.16,1,.3,1);
  user-select: none; -webkit-user-select: none;
}
.pick-num:hover { border-color: rgba(212,175,55,0.5); color: var(--gold); background: var(--gdim); transform: scale(1.06); }
.pick-num:active { transform: scale(0.94); }
.pick-num.selected {
  background: linear-gradient(135deg, rgba(212,175,55,0.22), rgba(212,175,55,0.1));
  border-color: var(--gold); color: var(--gold); transform: scale(1.06);
  box-shadow: 0 0 16px rgba(212,175,55,0.35), inset 0 0 8px rgba(212,175,55,0.08);
  animation: pickPulse 0.35s cubic-bezier(.16,1,.3,1);
}
@keyframes pickPulse { 0%{transform:scale(0.88);} 60%{transform:scale(1.12);} 100%{transform:scale(1.06);} }
.picker-back {
  background: transparent; border: none; color: rgba(212,175,55,0.7); cursor: pointer;
  font-size: 13px; font-weight: 800; display: flex; align-items: center; gap: 7px;
  margin-bottom: 14px; letter-spacing: 1.5px; padding: 6px 0;
  transition: color 0.2s, transform 0.2s;
}
.picker-back:hover { color: var(--gold); transform: translateX(-3px); }
.picker-footer { display: flex; gap: 10px; margin-top: 20px; }

/* ================================================================
   CONFIRM MODAL (replaces browser confirm)
   ================================================================ */
#confirm-modal {
  position: fixed; inset: 0; background: rgba(0,0,0,.65); -webkit-backdrop-filter: blur(24px) saturate(130%); backdrop-filter: blur(24px) saturate(130%);
  -webkit-backdrop-filter: blur(24px) saturate(130%);
  z-index: 200000; display: none; align-items: center; justify-content: center;
}
#confirm-modal.show { display: flex; }
.confirm-box {
  width: 420px; background: rgba(6,10,6,.78); border: 1px solid rgba(255,255,255,.08);
  border-radius: 20px; padding: 36px; text-align: center;
  animation: glassIn .65s cubic-bezier(.16,1,.3,1) both;
  backdrop-filter: blur(32px) saturate(160%); -webkit-backdrop-filter: blur(32px) saturate(160%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07), 0 24px 60px rgba(0,0,0,.7), 0 0 60px rgba(212,175,55,0.1);
}
@keyframes glassIn{from{opacity:0;transform:translateY(20px) scale(.97);filter:blur(6px);}to{opacity:1;transform:none;filter:blur(0);}}
.confirm-icon { font-size: 36px; margin-bottom: 16px; }
.confirm-title { font-family: var(--display); font-size: 18px; letter-spacing: 3px; color: var(--gold); margin-bottom: 10px; }
.confirm-msg { font-size: 14px; color: var(--text); line-height: 1.7; margin-bottom: 28px; }
.confirm-footer { display: flex; gap: 12px; }

/* ================================================================
   AUTH MODAL
   ================================================================ */
#auth-modal {
  position: fixed; inset: 0; background: rgba(0,0,0,.65); -webkit-backdrop-filter: blur(24px) saturate(130%); backdrop-filter: blur(24px) saturate(130%);
  -webkit-backdrop-filter: blur(24px) saturate(130%);
  z-index: 200001; display: none; align-items: center; justify-content: center;
}
#auth-modal.show { display: flex; }
.auth-box {
  width: 380px; background: rgba(6,10,6,.78); border: 1px solid rgba(255,255,255,.08);
  border-radius: 20px; padding: 36px; text-align: center;
  animation: glassIn .65s cubic-bezier(.16,1,.3,1) both;
  backdrop-filter: blur(32px) saturate(160%); -webkit-backdrop-filter: blur(32px) saturate(160%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07), 0 24px 60px rgba(0,0,0,.7), 0 0 60px rgba(212,175,55,0.15);
}

/* ================================================================
   PUBLISH SUCCESS OVERLAY
   ================================================================ */
#publish-success {
  position: fixed; inset: 0; background: rgba(0,0,0,0.96); -webkit-backdrop-filter: blur(24px); backdrop-filter: blur(24px);
  z-index: 300000; display: none; align-items: center; justify-content: center;
}
#publish-success.show { display: flex; }
.success-box {
  width: min(600px, 92vw); background: linear-gradient(135deg, #0a0e0a, #0e160d);
  border: 1px solid rgba(212,175,55,0.35); border-radius: 24px; padding: 48px 40px;
  text-align: center; position: relative; overflow: hidden;
  animation: successReveal 0.7s cubic-bezier(0.16,1,0.3,1) both;
  box-shadow: 0 0 80px rgba(212,175,55,0.12), 0 40px 80px rgba(0,0,0,0.6);
}
@keyframes successReveal { from{opacity:0;transform:scale(0.9) translateY(20px);} to{opacity:1;transform:scale(1) translateY(0);} }
.success-box::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold), var(--green), var(--gold), transparent);
  animation: shimmerLine 2s linear infinite;
}
@keyframes shimmerLine { from{background-position:-100% 0;} to{background-position:200% 0;} }
.success-seal {
  width: 80px; height: 80px; border-radius: 50%;
  background: radial-gradient(circle, rgba(212,175,55,0.2), rgba(212,175,55,0.05));
  border: 2px solid rgba(212,175,55,0.4); display: flex; align-items: center; justify-content: center;
  margin: 0 auto 24px; font-size: 32px;
  animation: sealSpin 0.8s cubic-bezier(0.16,1,0.3,1) 0.3s both;
}
@keyframes sealSpin { from{transform:scale(0) rotate(-90deg);} to{transform:scale(1) rotate(0);} }
.success-kicker { font-size: 13px; letter-spacing: 4px; color: var(--green); text-transform: uppercase; font-weight: 800; margin-bottom: 10px; }
.success-title { font-family: var(--display); font-size: 24px; font-weight: 900; letter-spacing: 3px; color: var(--gold); margin-bottom: 8px; }
.success-week { font-family: var(--mono); font-size: 16px; color: var(--text); margin-bottom: 20px; letter-spacing: 2px; }
.success-divider { height: 1px; background: linear-gradient(90deg, transparent, rgba(212,175,55,0.3), transparent); margin: 20px 0; }
.success-stats { display: grid; grid-template-columns: repeat(3,1fr); gap: 16px; margin-bottom: 24px; }
.success-stat { display: flex; flex-direction: column; gap: 4px; }
.success-stat-label { font-size: 13px; letter-spacing: 2px; color: var(--t3); text-transform: uppercase; font-weight: 800; }
.success-stat-val { font-family: var(--mono); font-size: 22px; font-weight: 700; color: var(--gold); }
.success-message { font-size: 14px; color: var(--t2); line-height: 1.7; margin-bottom: 24px; }
.success-ref { font-family: var(--mono); font-size: 13px; color: var(--t3); letter-spacing: 1px; }

/* ================================================================
   PROCESSING OVERLAY
   ================================================================ */
#processing {
  position: fixed; inset: 0; background: rgba(5,9,5,0.92); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  z-index: 500000; display: none; flex-direction: column; align-items: center; justify-content: center;
}
#processing.show { display: flex; }
.loader-ring {
  width: 72px; height: 72px; margin-bottom: 28px; position: relative;
}
.loader-ring::before {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  border: 2px solid rgba(212,175,55,0.1); border-top-color: var(--gold);
  animation: spin 0.9s cubic-bezier(0.4,0,0.2,1) infinite;pointer-events:none;}
.loader-ring::after {
  content: ''; position: absolute; inset: 10px; border-radius: 50%;
  border: 2px solid transparent; border-bottom-color: var(--green);
  animation: spin 1.8s linear infinite reverse;
}
.proc-text { font-family: var(--display); font-size: 13px; letter-spacing: 4px; color: var(--gold); font-weight: 700; text-transform: uppercase; margin-bottom: 8px; animation: procPulse 1.5s cubic-bezier(.16,1,.3,1) infinite; }
@keyframes procPulse { 0%,100%{opacity:1;} 50%{opacity:0.4;} }
.proc-log { font-family: var(--mono); font-size: 13px; color: #444; letter-spacing: 1px; height: 14px; text-transform: uppercase; }

/* ================================================================
   TOAST
   ================================================================ */
#toast {
  position: fixed; bottom: 24px; left: 50%;
  transform: translateX(-50%) translateY(80px);
  background: rgba(8,12,8,0.98); border: 1px solid var(--gold); border-left: 4px solid var(--gold);
  padding: 13px 22px; border-radius: 8px; display: flex; align-items: center; gap: 12px;
  font-size: 14px; font-weight: 600; z-index: 600000; min-width: 280px;
  box-shadow: 0 12px 40px rgba(0,0,0,0.5);
  transition: transform 0.45s cubic-bezier(.16,1,.3,1), opacity 0.45s;
  opacity: 0; -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
}
#toast.show { transform: translateX(-50%) translateY(0); opacity: 1; }
#toast.error { border-color: var(--red); border-left-color: var(--red); }
#toast i { flex-shrink: 0; font-size: 14px; }
#toast:not(.error) i { color: var(--gold); }
#toast.error i { color: var(--red); }

/* ================================================================
   GLASS INPUT
   ================================================================ */
.g-input {
  width: 100%; background: rgba(0,0,0,0.35); border: 1px solid var(--border2);
  border-radius: 10px; color: var(--text); padding: 12px 14px; font-size: 13px;
  outline: none; font-family: var(--body);
  transition: border-color 0.25s, box-shadow 0.25s; margin-bottom: 12px;
  text-align: center; letter-spacing: 3px;
}
.g-input:focus { border-color: rgba(212,175,55,0.5); box-shadow: 0 0 0 3px rgba(212,175,55,0.08); }
.g-input::placeholder { letter-spacing: 1px; color: var(--t3); }

/* ================================================================
   MOBILE RESPONSIVE
   ================================================================ */

/* Fluid modals on ALL screen sizes */
.picker-box  { width: min(380px, 95vw); }
.confirm-box { width: min(420px, 95vw); }
.auth-box    { width: min(380px, 95vw); }

/* Sidebar overlay — global (drawer pattern on all screen sizes) */
#sb-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.65); z-index: 999; display: none; -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
#sb-overlay.show { display: block; }

/* Sidebar open state */
#sidebar.mobile-open { transform: translateX(0) !important; }

/* ---- TABLET / MOBILE ≤ 820px -------- */
@media (max-width: 820px) {
  :root { --hd: 52px; }
}

/* ---- TABLET / MOBILE ≤ 768px ---------------------------------- */
@media (max-width: 768px) {
  :root { --hd: 52px; }

  /* Header — compact */
  #hdr { padding: 0 16px; }
  .hdr-week-pill { display: none; }
  .hdr-clock { display: none; }
  .hdr-brand-sub { display: none; }
  .hdr-brand-logo { font-size: 18px; letter-spacing: 5px; }
  .hdr-brand-img { height: 28px; }
  .hdr-admin-chip { max-width: 110px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; padding: 4px 8px; }

  /* Toolbar — wrap into rows */
  .alloc-toolbar { padding: 8px 12px; gap: 8px; flex-wrap: wrap; }
  .tab-btn { padding: 7px 14px; font-size: 13px; letter-spacing: 0.5px; }
  .week-nav { margin-left: 0 !important; width: 100%; justify-content: center; }
  .week-display { font-size: 13px; min-width: 100px; }

  /* Action bar */
  .action-bar { padding: 10px 12px; gap: 8px; flex-wrap: wrap; }

  /* Network view */
  #view-network { padding: 14px; }
  .network-grid { grid-template-columns: 1fr; }
  .net-dist-grid { grid-template-columns: 1fr !important; }
  .network-header h2 { font-size: 16px; }

  /* Overlays */
  .success-stats { grid-template-columns: 1fr 1fr; }
  .success-box { padding: 32px 20px; }

  /* Toast */
  #toast { left: 10px; right: 10px; transform: translateY(80px); min-width: unset; width: auto; max-width: none; }
  #toast.show { transform: translateY(0); }
}

/* ---- SMALL PHONES ≤ 480px ------------------------------------ */
@media (max-width: 480px) {
  :root { --hd: 48px; }

  /* Header */
  #hdr { padding: 0 12px; }
  .hdr-brand-logo { font-size: 16px; letter-spacing: 4px; }
  .hdr-admin-chip { display: none; }

  /* Toolbar */
  .alloc-toolbar { padding: 6px 10px; gap: 6px; }
  .tab-btn { font-size: 13px; padding: 6px 10px; flex: 1; text-align: center; }
  .week-nav { gap: 6px; }
  .week-display { font-size: 13px; min-width: 80px; }
  .week-nav-btn { width: 30px; height: 30px; font-size: 13px; }

  /* Grid */
  /* no height here either: see the note on .grid-scroll above */
  .rota-tbl { min-width: 680px; }
  .rota-tbl thead th { padding: 8px 5px; font-size: 13px; letter-spacing: 1px; }
  .col-member { min-width: 110px !important; padding: 8px 8px !important; }
  .alloc-cell { min-width: 80px; padding: 5px 4px; }
  .shift-sel { font-size: 13px; margin-bottom: 4px; }
  .time-chip { padding: 3px 2px; }
  .time-val { font-size: 13px; }
  .time-lbl { font-size: 13px; }
  .member-name-cell { font-size: 13px; }
  .member-role-cell { font-size: 13px; }
  .member-balance { font-size: 13px; padding: 2px 6px; }
  .hours-debt { font-size: 13px; padding: 2px 5px; }
  .ph-warning-strip, .ph-clear-strip { font-size: 13px; }

  /* Action bar */
  .action-bar { padding: 8px 10px; gap: 6px; }
  .action-bar .btn { font-size: 13px; padding: 7px 10px; }
  #workflow-actions { width: 100%; margin-left: 0 !important; }
  #workflow-actions .btn { flex: 1; justify-content: center; }

  /* Overlays */
  .success-stats { grid-template-columns: 1fr; }
  .success-box { padding: 28px 16px; }
  .confirm-footer { flex-direction: column; }
  .confirm-box { padding: 24px 16px; }

  .pick-num { padding: 10px 4px; font-size: 14px; }
  .picker-grid { gap: 6px; }

  /* Network */
  .audit-entry { padding: 10px 14px; gap: 10px; }
  .net-metric { font-size: 22px; }
}

#hamburger { display: flex; width: 36px; height: 36px; flex-direction: column; justify-content: center; align-items: center; gap: 5px; background: var(--panel2); border: 1px solid var(--border); border-radius: 8px; cursor: pointer; }
#hamburger span { width: 18px; height: 2px; background: var(--t2); border-radius: 2px; transition: all 0.3s; }

/* ================================================================
   TEST MODE BANNER + BODY SHIFT (Super Admin only)
   ================================================================ */
/* The design's test-mode strip: blue, calm, and it explains itself. It was a
   red alarm gradient with "All rota writes go to shadow collections", which
   names our implementation at somebody who wants to know whether it is safe
   to press things. Height is no longer fixed at 40px, because the sentence
   wraps on a narrow screen and a fixed strip would sit on top of the header;
   js/rota.js measures it into --test-banner-h. */
#test-mode-banner {
  display: none; position: fixed; top: 0; left: 0; right: 0; z-index: 999999;
  align-items: center; gap: 11px; flex-wrap: wrap;
  padding: 10px 20px;
  border-bottom: 1px solid rgba(74,158,255,.40);
  background: rgba(74,158,255,.16);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
#test-mode-banner > i { font-size: 13px; color: #4a9eff; }
#test-mode-banner .tmb-label {
  font-family: var(--mono); font-size: 13px; letter-spacing: 1.4px;
  text-transform: uppercase; color: #4a9eff;
}
#test-mode-banner .tmb-text {
  flex: 1 1 300px; min-width: 0;
  font-size: 13px; line-height: 1.5; color: var(--t2); text-wrap: pretty;
}
#test-mode-banner .test-toggle-btn {
  min-height: 44px; padding: 0 14px; border-radius: 11px;
  border: 1px solid rgba(74,158,255,.40); background: rgba(74,158,255,.16);
  color: var(--text); font-size: 13px; cursor: pointer;
}
#test-mode-banner .test-toggle-btn:hover { background: rgba(74,158,255,.26); }
#test-mode-banner.show { display: flex; animation: testBannerIn 0.45s cubic-bezier(0.16,1,0.3,1) both; }
@keyframes testBannerIn { from{transform:translateY(-100%);opacity:0;} to{transform:translateY(0);opacity:1;} }
.test-toggle-btn {
  background: rgba(255,255,255,0.18); border: 1px solid rgba(255,255,255,0.45); color: #fff;
  padding: 5px 16px; border-radius: 20px; cursor: pointer;
  font-size: 13px; font-weight: 900; letter-spacing: 1.5px; white-space: nowrap;
  transition: background 0.2s, transform 0.2s;
}
.test-toggle-btn:hover { background: rgba(255,255,255,0.32); transform: scale(1.05); }

/* Push sticky header + sidebar down when test banner is visible */
body.test-mode #hdr { top: var(--test-banner-h, 40px) !important; }
body.test-mode #sidebar { top: calc(var(--hd) + var(--test-banner-h, 40px)) !important; height: calc(100dvh - var(--hd) - var(--test-banner-h, 40px)) !important; }

/* SA sidebar test-mode item colour when active */
.nav-item.test-active { background: rgba(220,40,40,0.12) !important; border-color: rgba(220,40,40,0.3) !important; color: #ff6b6b !important; }
.nav-item.test-active i { color: #ff6b6b !important; }
/* ── LIGHT THEME ── */
[data-theme="light"]{--void:#ffffff;--deep:#f4f6f4;--base:#e8ede8;--lift:#dce4dc;--panel:rgba(4,80,30,0.05);--panel2:rgba(4,80,30,0.09);--border:rgba(4,80,30,0.16);--bord2:rgba(4,80,30,0.26);--gold:#04501e;--gold2:#065a23;--gdim:rgba(4,80,30,0.10);--gglow:rgba(4,80,30,0.22);--gsoft:rgba(4,80,30,0.04);--green:#43b14b;--gndim:rgba(67,177,75,0.12);--gnsoft:rgba(67,177,75,0.05);--red:#c42020;--rdim:rgba(196,32,32,0.10);--text:#000000;--t2:rgba(0,0,0,0.80);--t3:rgba(0,0,0,0.52);}
[data-theme="light"] body{background:#ffffff;}[data-theme="light"] body::before{display:none;}
[data-theme="light"] header{background:rgba(255,255,255,0.96)!important;border-color:rgba(4,80,30,0.14)!important;}
[data-theme="light"] aside,[data-theme="light"] #sidebar{background:rgba(244,246,244,0.98)!important;border-color:rgba(4,80,30,0.12)!important;}
[data-theme="light"] .glass,[data-theme="light"] .rota-card,[data-theme="light"] .shift-card{background:rgba(255,255,255,0.88)!important;border-color:rgba(4,80,30,0.13)!important;}
[data-theme="light"] input.gi,[data-theme="light"] textarea.gi,[data-theme="light"] select.gi{background:rgba(255,255,255,0.85)!important;border-color:rgba(4,80,30,0.20)!important;color:#000!important;}
[data-theme="light"] .btn-green{background:#43b14b;}[data-theme="light"] .btn-gold{background:#04501e;color:#fff;}

/* ── ROTA — extra standard breakpoints ── */
@media(max-width:640px){
  #hdr{padding:0 14px;}
  .hdr-brand span{display:none;}
  .view-panel.active{padding:12px;}
  /* .picker-box dropped from this list: the om-card frame owns its
     max-width, padding and radius now, and the !important here was the
     one thing still holding the picker off the design's sheet padding.
     .modal-box and .cf-modal appear nowhere in rota.html, so this rule
     is now inert on this page; kept in case that markup returns. */
  .modal-box,.cf-modal{max-width:calc(100vw - 20px)!important;padding:20px 14px!important;border-radius:14px;}
  .picker-grid{grid-template-columns:repeat(2,1fr)!important;}
  .balance-row,.stat-row{flex-wrap:wrap;gap:8px;}
  .rota-tabs{gap:4px;}
  .rota-tab{padding:6px 10px;font-size:13px;}
  .fs-modal-inner{max-width:calc(100vw - 20px);padding:20px 14px;}
}
@media(max-width:540px){
  #hdr{padding:0 10px;gap:8px;}
  .rota-tab span{display:none;}
  .rota-tab{padding:8px 10px;}
  .net-card{min-width:0;flex:1 1 calc(50% - 6px);}
  .filter-row{flex-wrap:wrap;gap:6px;}
  .filter-row select,.filter-row input{flex:1 1 calc(50% - 6px);}
}
@media(max-width:400px){
  #hdr{padding:0 8px;gap:5px;}
  .hdr-brand{display:none;}
  .net-card{flex:1 1 100%;}
  .rota-tbl th,.rota-tbl td{padding:4px 5px;font-size:13px;}
  .filter-row select,.filter-row input{flex:1 1 100%;}
}
/* ── Touch targets + table scroll ──
   Button min-heights are owned by css/responsive.css (centralised, 38px
   default — clears HIG 44pt once padding is added). Per CLAUDE.md
   centralised-shared-CSS rule we don't override here. Just keep the
   header back-button + scroll containers tuned for the rota grid. */
@media(max-width:640px){
  .page-pill{display:none;}
  .rota-scroll,.table-scroll,.dtbl-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;}
}

/* ── Weekly reconcile-to-credit row (Phase D, policy 2026-05-16) ── */
.rec-row{display:none;align-items:center;gap:8px;margin-top:6px;flex-wrap:wrap;}
.rec-row .rec-preview{font-size:13px;color:var(--t3);line-height:1.4;letter-spacing:.2px;}
.rec-row .rec-btn{font-size:13px;padding:5px 10px;border-color:rgba(240,200,50,.35);color:var(--gold);background:rgba(240,200,50,.06);transition:all .25s;}
.rec-row .rec-btn:hover:not(:disabled){background:rgba(240,200,50,.16);border-color:var(--gold);}
.rec-row .rec-btn:disabled{opacity:.45;cursor:not-allowed;}
.rec-row .rec-btn i{margin-right:5px;font-size:11px;}

/* ════════════════════════════════════════════════════════════════
   Rota sidebar header — restored brand logo block
   ════════════════════════════════════════════════════════════════ */
.rota-sb-hdr{
  display:flex;flex-direction:column;align-items:center;gap:8px;
  text-align:center;
}
.rota-sb-logo{
  height:48px;width:auto;max-width:120px;
  object-fit:contain;
  display:block;
  filter:drop-shadow(0 4px 16px rgba(212,175,55,.25));
  animation:rotaLogoIn .6s cubic-bezier(.16,1,.3,1) both;
}
@keyframes rotaLogoIn{
  from{opacity:0;transform:translateY(-6px) scale(.94);}
  to{opacity:1;transform:none;}
}
.rota-sb-brand-text .s-gmw93hf{
  font-family:'Cinzel',serif;font-size:18px;font-weight:700;
  letter-spacing:3px;color:var(--gold);
}

/* ════════════════════════════════════════════════════════════════════
   GRID LEGEND  (added 2026-08-03, from the Claude Design redesign)

   The grid carries ten distinct cell treatments and the portal had no
   legend for any of them, on any page. The colours here are the SAME
   tokens the cells themselves use, so the legend cannot drift away from
   what it explains: if a cell colour changes, change it in one place and
   both move together.
   ════════════════════════════════════════════════════════════════════ */
.rt-legend{
  margin:0 0 12px;border:1px solid var(--border);border-radius:14px;
  background:rgba(255,255,255,0.05);overflow:hidden;
}
.rt-legend-head{
  display:flex;align-items:center;gap:11px;width:100%;min-height:44px;padding:12px 16px;
  background:transparent;border:none;color:var(--t2);font-family:inherit;font-size:13px;
  font-weight:500;cursor:pointer;text-align:left;
}
.rt-legend-head:hover{background:rgba(255,255,255,0.04);color:var(--text);}
.rt-legend-q{color:var(--gold);font-size:14px;flex-shrink:0;}
.rt-legend-head > span{flex:1;min-width:0;}
.rt-legend-count{
  font-family:var(--mono);font-style:normal;font-size:13px;padding:3px 9px;border-radius:11px;
  border:1px solid var(--border);background:rgba(255,255,255,0.06);color:var(--t3);flex-shrink:0;
}
.rt-legend-chev{color:var(--t3);transition:transform .3s cubic-bezier(.16,1,.3,1);flex-shrink:0;}
.rt-legend.open .rt-legend-chev{transform:rotate(180deg);}
.rt-legend-body{display:none;padding:0 16px 16px;}
.rt-legend.open .rt-legend-body{display:block;animation:panelIn .3s cubic-bezier(.16,1,.3,1) both;}
/* panelIn, not cvIn: cvIn is the shared name on other pages but is NOT
   defined in any stylesheet this page loads, so it would have animated
   nothing at all and failed silently. LESSONS.md #5. */

/* auto-fit, never auto-fill: auto-fill keeps empty tracks, which would
   strand a single entry at its minimum width. LESSONS.md. */
.rt-legend-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(270px,1fr));gap:11px;}
.rt-leg{
  display:flex;gap:11px;padding:12px 13px;border-radius:11px;
  border:1px solid var(--border);background:rgba(255,255,255,0.03);
  width:100%;max-width:520px;margin-inline:auto;
}
.rt-leg strong{display:block;font-size:13px;font-weight:600;color:var(--text);margin-bottom:3px;}
.rt-leg p{margin:0;font-size:13px;line-height:1.55;color:var(--t3);}
.rt-leg-sw{
  width:38px;height:38px;border-radius:9px;flex-shrink:0;
  display:flex;align-items:center;justify-content:center;font-size:13px;
  border:1px solid var(--border);background:rgba(255,255,255,0.06);color:var(--t3);
}
.leg-normal{border-color:var(--border2);background:rgba(255,255,255,0.10);color:var(--t2);}
.leg-off{border-style:dashed;color:var(--t3);}
.leg-active{border-color:rgba(76,214,87,0.40);background:rgba(67,177,75,0.12);color:var(--green);}
.leg-missed{border-color:rgba(255,72,72,0.45);background:rgba(232,64,64,0.12);color:var(--red);
  box-shadow:inset 3px 0 0 var(--red);}
.leg-debt{border-color:rgba(255,72,72,0.45);background:rgba(232,64,64,0.12);color:var(--red);}
.leg-balanced{border-color:rgba(76,214,87,0.40);background:rgba(67,177,75,0.12);color:var(--green);
  box-shadow:inset 3px 0 0 var(--green);}
.leg-unsub{border-color:rgba(245,158,11,0.45);background:rgba(245,158,11,0.10);color:#f0a92b;}
.leg-perm{
  border-color:rgba(240,200,50,0.34);color:var(--gold);
  background-image:repeating-linear-gradient(45deg,rgba(240,200,50,0.20) 0 5px,transparent 5px 10px);
  box-shadow:inset 0 3px 0 rgba(240,200,50,0.5);
}
.leg-leave{border-color:rgba(74,158,255,0.40);background:rgba(74,158,255,0.10);color:var(--blue);}
.leg-pub{border-color:rgba(240,200,50,0.34);background:rgba(212,175,55,0.12);color:var(--gold);}
.rt-legend-foot{
  margin:12px 0 0;padding:11px 14px;border-radius:11px;font-size:13px;line-height:1.6;
  border:1px dashed rgba(240,200,50,0.34);background:rgba(212,175,55,0.08);color:var(--t2);
}
@media(max-width:540px){
  .rt-legend-grid{grid-template-columns:1fr;}
  .rt-leg{max-width:none;}
}

/* ════════════════════════════════════════════════════════════════════
   ROTA ALLOCATION REDESIGN  (2026-08-03)
   Ported from the Claude Design board "Rota Allocation.dc.html".

   RESTYLE, NOT REBUILD. Every rule below targets markup that already
   exists. Not one data-action, id, select or handler is touched, because
   the workflow is unchanged and the grid's <select> is how a shift is
   actually set. The design's cell is a 64px card with a state-toned
   border, a bold shift label, one time line and a status line; the
   current markup already carries all four, they were simply styled as a
   dense 8px box.

   This block sits at the END of rota.css deliberately: same file, same
   specificity, so later wins and the diff stays readable. It is safe to
   append here in a way it would NOT be in a shared sheet (LESSONS.md #3)
   because css/rota.css is this page's own stylesheet.
   ════════════════════════════════════════════════════════════════════ */

/* ── the grid cell becomes a card ── */
.rota-tbl tbody td { padding: 5px; }
.alloc-cell{
  background:rgba(255,255,255,0.05);
  border:1px solid var(--border);
  border-top:1px solid var(--border);        /* the 3px top rule is replaced by a full border */
  border-radius:11px;
  padding:9px 10px;
  min-height:64px;
  min-width:132px;
  display:flex;flex-direction:column;gap:3px;
  box-shadow:inset 3px 0 0 transparent;      /* the state strip lives here, one place */
}
.alloc-cell:hover:not(.locked){
  background:rgba(255,255,255,0.09);
  transform:none;                             /* the 1.02 scale jittered a dense grid */
  border-color:rgba(240,200,50,0.30);
  box-shadow:inset 3px 0 0 transparent,0 8px 22px -10px rgba(0,0,0,.55);
}

/* the shift label: the <select> reads as the design's bold title line */
.shift-sel{
  font-size:13px;font-weight:700;letter-spacing:.4px;margin-bottom:2px;
  text-transform:uppercase;color:var(--text);
  -webkit-appearance:none;appearance:none;
}
.shift-sel:disabled{opacity:1;color:var(--t2);}

/* the time chips read as one line, "08:00 to 12:00", and both stay clickable
   because each one opens the picker for its own end of the shift */
.time-row{gap:0 !important;align-items:baseline;flex-wrap:wrap;}
.time-chip{
  background:transparent;border:none;padding:0;border-radius:6px;
  font-family:var(--mono);font-size:13px;color:var(--t2);cursor:pointer;
}
.time-chip:hover{color:var(--gold);text-decoration:underline;}
.time-lbl{display:none;}                      /* the S / E letters are replaced by the word "to" */
.time-chip + .time-chip::before{content:'to';margin:0 5px;color:var(--t3);font-family:var(--body);}

/* ── state tones: one strip colour per state, matching the legend ── */
.missed-col   .alloc-cell{box-shadow:inset 3px 0 0 var(--red);border-color:rgba(255,72,72,0.45);background:rgba(232,64,64,0.10);}
/* The design's debt state is RED and DASHED, not gold: hours owed is a
   deficit, and gold is what the design uses for published and permanent. */
.debt-col     .alloc-cell{box-shadow:inset 3px 0 0 var(--red);border-color:rgba(255,72,72,.45);border-style:dashed;background:rgba(232,64,64,.12);}
.active-col   .alloc-cell{box-shadow:inset 3px 0 0 var(--green);border-color:rgba(76,214,87,0.40);background:rgba(67,177,75,0.10);}
.unsubmitted-col .alloc-cell{box-shadow:inset 3px 0 0 #f0a92b;border-color:rgba(245,158,11,0.45);background:rgba(245,158,11,0.09);}
.alloc-cell.leave-locked{border-color:rgba(74,158,255,0.40);background:rgba(74,158,255,0.10);}
/* Same reason: the top border belongs to the shift, not to the lock state. */
.alloc-cell.locked{
  border-right-color:rgba(240,200,50,0.34);
  border-bottom-color:rgba(240,200,50,0.34);
  border-left-color:rgba(240,200,50,0.34);
  background:rgba(212,175,55,0.10);opacity:1;
}

/* the status strips become quiet caption lines rather than shouting all-caps */
.missed-strip,.debt-strip,.unsubmitted-strip,.active-strip{
  font-size:13px;font-weight:600;letter-spacing:0;text-transform:none;margin-top:1px;
}
.missed-strip{animation:none;}                /* a pulsing strip per cell made the grid restless */
.active-strip{animation:pipBlink 2s cubic-bezier(.16,1,.3,1) infinite;}

/* ── the person column ── */
/* 8px, like every other cell. The design gives .whocell no padding of its
   own; it inherits `tbody td { padding:8px }`. Found by diffing our computed
   values against the design's declared ones rather than by being told. */
.rota-tbl tbody td.col-member{padding:8px;}
.member-name-cell{
  font-family:var(--display),serif;font-size:14px;font-weight:700;color:var(--text);
  white-space:normal;word-break:break-word;line-height:1.3;
}
.member-role-cell{font-family:var(--mono);font-size:13px;color:var(--t3);margin-top:2px;line-height:1.5;}
.member-balance{
  display:inline-flex;align-items:center;gap:5px;margin-top:6px;
  padding:4px 10px;border-radius:12px;font-family:var(--mono);font-size:13px;font-weight:600;
}
.balance-ok{border:1px solid var(--border);background:rgba(255,255,255,0.05);color:var(--t2);}
.balance-credit{border:1px solid rgba(76,214,87,0.40);background:rgba(67,177,75,0.12);color:#8ce694;}
.balance-over,.hours-debt{border:1px solid rgba(255,72,72,0.45);background:rgba(232,64,64,0.12);color:#ff8f8f;}

/* ── the action bar becomes the design's gold status card ── */
.action-bar{
  border:1px solid rgba(240,200,50,0.34);border-radius:14px;
  background:linear-gradient(135deg,rgba(212,175,55,0.12),rgba(255,255,255,0.03));
  padding:16px 18px;gap:11px;flex-wrap:wrap;align-items:center;
}
.action-bar .btn{min-height:44px;border-radius:11px;}

/* ── touch targets, everywhere the design put a control ── */
.week-nav-btn,.btn-fs-toggle,.tab-btn{min-height:44px;}
.cell-apply-credit-btn{min-width:32px;min-height:32px;}

@media(max-width:640px){
  .alloc-cell{min-width:118px;min-height:60px;}
  .member-name-cell{font-size:13px;}
}

/* The per-board button floor that used to sit here has been REMOVED.
   It was an interim override while css/responsive.css still shrank every
   button below the 13px floor and the 44px touch minimum on a phone. That
   shared rule is now correct for all 71 pages, so the local override is
   redundant and would only be a second place to keep in step. */


/* ── Live Network stat grid: auto-fit, and cap the card ───────────────
   .network-grid used repeat(auto-fill, ...), which keeps empty tracks: on
   a 1400px row a single stat card sat stranded at 280px against the full
   width. auto-fit collapses the empty tracks, and the cap stops the
   opposite failure of one card stretched edge to edge. Same defect and
   same fix as the EOM grids on 3 August. LESSONS.md. */
.net-card{ width:100%; max-width:460px; margin-inline:auto; }

/* ════════════════════════════════════════════════════════════════════
   ROTA ALLOCATION, THE DESIGN'S OWN LAYOUT  (2026-08-03)

   The earlier pass restyled the cells and stopped there, which is why the
   board did not look like the design. This is the layout the design
   actually specifies: a two-column shell with the grid in the main column
   and the leave rail beside it, a hero above the grid, and a card-per-
   person grid that replaces the table on a phone.

   Values are the design's own, read out of "Rota Allocation.dc.html"
   rather than approximated.
   ════════════════════════════════════════════════════════════════════ */

/* .shell{ grid-template-columns:minmax(0,1fr) 300px; gap:16px;
   max-width:1680px; padding:18px 20px 90px } and 1fr below 1220px. */
/* padding:18px 20px 90px is the design's own. Without the 20px sides the
   grid and the rail sit flush against both screen edges, which is what
   "it does not fit on desktop" was: at 1440 the main column measured 1124
   at x=0 instead of 1084 at x=20. Measured against the design, not
   guessed. */
.ra-shell{
  display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:16px;
  max-width:1680px;margin:0 auto;padding:18px 20px 90px;align-items:start;
}
.ra-main{min-width:0;display:flex;flex-direction:column;gap:13px;}
.ra-aside{
  min-width:0;display:flex;flex-direction:column;gap:13px;
  animation:wgIn .5s cubic-bezier(.16,1,.3,1) .12s both;
}
@keyframes wgIn{from{transform:translateY(14px);opacity:0}to{transform:none;opacity:1}}
@media(max-width:1220px){ .ra-shell{grid-template-columns:1fr;} }

/* ── the hero ── */
.ra-hero{
  border:1px solid rgba(240,200,50,.34);border-radius:16px;padding:19px 21px;
  background:linear-gradient(135deg,rgba(212,175,55,.12),rgba(255,255,255,.03));
}
.ra-hero-eyebrow{
  font-family:var(--mono);font-size:13px;letter-spacing:1.6px;text-transform:uppercase;color:var(--gold);
}
.ra-hero-title{
  font-family:var(--display),'Cinzel',serif;font-size:25px;font-weight:700;color:var(--text);
  margin:8px 0 9px;line-height:1.15;
}
.ra-hero-blurb{font-size:13px;line-height:1.65;color:var(--t2);margin:0;max-width:74ch;}

/* ── the grid frame: the design wraps the table in a bordered card ── */
.grid-scroll{
  overflow-x:auto;border:1px solid rgba(255,255,255,.21);border-radius:16px;
  background:rgba(255,255,255,.05);
}
.rota-tbl{min-width:1080px;border-collapse:separate;border-spacing:0;}
.rota-tbl thead th{
  position:sticky;top:0;z-index:3;background:#141d10;
  border-bottom:1px solid rgba(255,255,255,.21);
}
/* The person column stays put while the week scrolls sideways. This is
   what makes a seven-day grid usable on a laptop. */
.rota-tbl tbody td.col-member,
.rota-tbl thead th.col-member{
  position:sticky;left:0;z-index:2;min-width:230px;
  background:#141d10;border-right:1px solid rgba(255,255,255,.21);
}
.rota-tbl thead th.col-member{z-index:4;}

/* ── the mobile grid, one card per person ── */
.ra-mobgrid{display:none;flex-direction:column;gap:12px;}
.ra-mobgrid-note{
  padding:13px;border:1px dashed rgba(240,200,50,.34);border-radius:14px;
  background:rgba(212,175,55,.09);font-size:13px;line-height:1.6;color:var(--t2);
}
#ra-mobgrid-body{display:flex;flex-direction:column;gap:12px;}
.ramc{
  border:1px solid rgba(255,255,255,.21);border-radius:15px;
  background:rgba(255,255,255,.05);overflow:hidden;
  animation:scIn .42s cubic-bezier(.16,1,.3,1) both;
}
@keyframes scIn{from{transform:translateY(12px) scale(.96);opacity:0}to{transform:none;opacity:1}}
.ramc-head{
  padding:13px 14px;border-bottom:1px solid rgba(255,255,255,.12);
  background:rgba(255,255,255,.028);display:flex;align-items:center;gap:11px;flex-wrap:wrap;
}
.ramc-av{
  width:40px;height:40px;flex:0 0 auto;border-radius:50%;
  background:linear-gradient(135deg,var(--gold),#8b6914);color:#0c1109;
  border:1px solid rgba(255,255,255,.34);font-family:var(--mono);font-size:13px;font-weight:600;
  display:flex;align-items:center;justify-content:center;overflow:hidden;
}
.ramc-id{flex:1 1 150px;min-width:0;}
.ramc-name{font-size:13px;font-weight:600;color:var(--text);display:flex;align-items:center;gap:7px;}
.ramc-role{font-family:var(--mono);margin-top:3px;font-size:13px;color:var(--t3);}
.ramc-bal{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:6px;padding:4px 9px;border-radius:999px;
  font-family:var(--mono);font-size:13px;border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--t2);
}
.ramc-bal.credit{border-color:rgba(76,214,87,.40);background:rgba(67,177,75,.12);color:#8ce694;}
.ramc-bal.debt{border-color:rgba(255,72,72,.45);background:rgba(232,64,64,.12);color:#ff8f8f;}
.ramc-days{padding:11px;display:flex;flex-direction:column;gap:8px;}
.ramc-cell{
  position:relative;overflow:hidden;width:100%;min-height:60px;padding:9px 10px;border-radius:11px;
  display:flex;flex-direction:row;align-items:center;gap:11px;text-align:left;cursor:pointer;
  border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--text);
  font-family:var(--body,'DM Sans'),system-ui,sans-serif;
  transition:border-color .25s cubic-bezier(.16,1,.3,1),background .25s cubic-bezier(.16,1,.3,1);
}
.ramc-cell:hover:not(:disabled){border-color:rgba(240,200,50,.55);}
.ramc-cell:disabled{opacity:.75;cursor:not-allowed;}
.ramc-strip{position:absolute;left:0;top:0;bottom:0;width:3px;}
.ramc-day{flex:0 0 46px;font-family:var(--mono);font-size:13px;letter-spacing:1px;text-transform:uppercase;color:var(--t3);}
.ramc-ico{flex:0 0 auto;font-size:13px;}
.ramc-body{flex:1 1 auto;min-width:0;text-align:left;}
.ramc-val{display:block;font-family:var(--mono);font-size:13px;color:var(--text);}
.ramc-meta{display:block;margin-top:3px;font-family:var(--mono);font-size:13px;color:var(--t3);}
.ramc-pip{width:8px;height:8px;flex:0 0 auto;border-radius:50%;background:var(--green);}
.ramc-chev{flex:0 0 auto;font-size:13px;color:var(--t3);}

/* The design's own breakpoint: the table goes, the cards arrive. */
@media(max-width:900px){
  .grid-scroll{display:none !important;}
  .ra-mobgrid{display:flex !important;}
}
@media(min-width:901px){
  .ra-mobgrid{display:none !important;}
}

/* ════════════════════════════════════════════════════════════════════
   ROTA: THE REST OF THE DESIGN  (2026-08-03)

   The toolbar, the view tabs, the drawer and the overlays, all read out
   of "Rota Allocation.dc.html" rather than approximated. Same rule as the
   rest of this file: the markup is the board's own, only the presentation
   moves.
   ════════════════════════════════════════════════════════════════════ */

/* ── TOOLBAR: sticky under the header, pills in a tray ── */
/* The design's toolbar is a full-bleed sticky bar whose CONTENT is capped
   and inset by the same 20px as the shell, so the pills line up with the
   grid below them rather than starting at the screen edge. */
.alloc-toolbar{
  position:sticky;top:var(--hdh,70px);z-index:50;
  display:flex;align-items:center;gap:11px;flex-wrap:wrap;
  /* the SAME cap as the shell, so the pills sit at the same x as the
     grid on a wide screen; 1720 put them 20px out at 1920. */
  max-width:1680px;margin:0 auto;padding:12px 20px;
  background:rgba(20,29,16,.92);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border-bottom:1px solid rgba(255,255,255,.21);
}
/* the two population tabs share one tray, as the design has them */
.alloc-toolbar .tab-btn{
  display:flex;align-items:center;gap:8px;min-height:44px;padding:0 13px;
  border:1px solid transparent;border-radius:9px;background:transparent;
  color:var(--t2);font-size:13px;cursor:pointer;white-space:nowrap;letter-spacing:0;
  text-transform:none;font-weight:500;
}
.alloc-toolbar .tab-btn:hover{background:rgba(255,255,255,.07);}
.alloc-toolbar .tab-btn.active{
  background:rgba(212,175,55,.16);border-color:rgba(240,200,50,.34);color:var(--text);
}
/* the "fill permanent shifts" action is a gold-tinted pill, not a tab */
.alloc-toolbar .tab-btn.s-ytfzuds{
  border:1px solid rgba(240,200,50,.34);background:rgba(212,175,55,.12);
  border-radius:11px;padding:0 14px;
}
.alloc-toolbar .tab-btn.s-ytfzuds i{color:var(--gold);}

.week-nav{display:flex;align-items:center;gap:7px;margin-left:auto;}
.week-nav-btn,.btn-fs-toggle{
  width:44px;height:44px;min-height:44px;padding:0;border-radius:11px;
  border:1px solid rgba(255,255,255,.21);background:rgba(255,255,255,.05);
  color:var(--text);cursor:pointer;font-size:13px;
  display:inline-flex;align-items:center;justify-content:center;
}
.week-nav-btn:hover,.btn-fs-toggle:hover{background:rgba(255,255,255,.1);border-color:rgba(240,200,50,.34);}
.week-display{
  display:flex;align-items:center;min-height:44px;padding:0 15px;border-radius:11px;
  border:1px solid rgba(240,200,50,.34);background:rgba(212,175,55,.12);
  font-family:var(--mono);font-size:14px;white-space:nowrap;color:var(--text);
}
/* the staged pill */
.s-oulw6hh{
  display:flex;align-items:center;gap:8px;min-height:44px;padding:0 13px;border-radius:999px;
  border:1px solid rgba(240,200,50,.34);background:rgba(212,175,55,.12);
  font-family:var(--mono);font-size:13px;color:var(--gold);
}
.s-oulw6hh:empty{display:none;}

/* ── VIEW TABS: one tray, above the hero ── */
.ra-viewtabs{
  display:flex;gap:6px;padding:5px;border:1px solid rgba(255,255,255,.21);
  border-radius:13px;background:rgba(255,255,255,.05);overflow-x:auto;
  scrollbar-width:none;margin-bottom:13px;
}
.ra-viewtabs::-webkit-scrollbar{display:none;}
.ra-viewtab{
  display:flex;align-items:center;gap:9px;min-height:44px;padding:0 15px;flex-shrink:0;
  border:1px solid transparent;border-radius:10px;background:transparent;
  color:var(--t2);font-family:inherit;font-size:13px;cursor:pointer;white-space:nowrap;
  transition:background .25s cubic-bezier(.16,1,.3,1),border-color .25s cubic-bezier(.16,1,.3,1);
}
.ra-viewtab:hover{background:rgba(255,255,255,.07);}
.ra-viewtab.active{background:rgba(212,175,55,.16);border-color:rgba(240,200,50,.34);color:var(--text);}
.ra-viewtab-badge{
  font-family:var(--mono);padding:2px 7px;border-radius:999px;font-size:13px;
  border:1px solid rgba(240,200,50,.34);background:rgba(212,175,55,.14);color:var(--gold);
}
.ra-viewtab-badge:empty{display:none;}

/* ── NAV DRAWER: the design's own sheet ── */
#sidebar{
  width:min(320px,100vw);padding:18px 16px;
  border-right:1px solid rgba(240,200,50,.34);
  background:linear-gradient(165deg,#172213,#111a0e);
}
#sidebar .nav-item{
  display:flex;align-items:center;gap:11px;min-height:48px;padding:0 12px;
  border:1px solid transparent;border-radius:10px;background:transparent;
  color:var(--t2);font-size:13px;cursor:pointer;
  transition:background .25s cubic-bezier(.16,1,.3,1),border-color .25s cubic-bezier(.16,1,.3,1);
}
#sidebar .nav-item:hover{background:rgba(255,255,255,.07);}
#sidebar .nav-item.active{background:rgba(212,175,55,.16);border-color:rgba(240,200,50,.34);color:var(--text);}
#sidebar .nav-item.danger:hover{background:rgba(232,64,64,.16);border-color:rgba(255,72,72,.45);color:#ff8f8f;}
#sidebar .nav-section-label{
  padding:0 6px 8px;font-family:var(--mono);font-size:13px;letter-spacing:1.6px;
  text-transform:uppercase;color:var(--t3);margin-top:18px;
}

/* The frame that used to live here was a THIRD copy of the same values,
   written as ID-descendant selectors, so it outranked .om-card[data-w] and
   the width variants could never take effect: every overlay came out at the
   600px default whatever it asked for. A fourth copy sat on the hashed
   classes with !important. Both are gone; the single .om-card frame at the
   foot of this file is now the only one, and the ::before grab handles went
   with them because those elements now carry a real .om-grab child and were
   about to show two.

   What remains here is only what the frame does NOT own: the bespoke
   widths on the old boxes have to be released or they fight max-width. */
#picker-overlay .picker-box,
#confirm-modal .confirm-box,
#auth-modal .auth-box,
#publish-success .success-box{
  width:100%;
}

@media(max-width:820px){
  .alloc-toolbar{padding:10px 0;gap:9px;}
  .week-nav{margin-left:0;width:100%;justify-content:space-between;}
}

/* The two population tabs share one bordered tray, as the design has them,
   rather than floating loose in the toolbar. */
.ra-poptray{
  display:flex;gap:5px;padding:4px;border:1px solid rgba(255,255,255,.21);
  border-radius:12px;background:rgba(255,255,255,.05);flex-shrink:0;
}
/* the legend now sits inside the main column, so it stops spanning the
   full page width and lines up with the grid beneath it */
.ra-main > .rt-legend{margin:0;}
/* the design shows how many people each population holds, on the tab */
.ra-tabcount{
  font-family:var(--mono);padding:2px 7px;border-radius:999px;
  border:1px solid rgba(255,255,255,.21);font-size:13px;margin-left:2px;
}
.ra-tabcount:empty{display:none;}

/* ── THE CELL'S ONE DESCRIPTIVE LINE (design) ─────────────────────────
   The design gives a cell a shift name and one line saying what is true
   about it. That line now carries the times too, so the separate S/E time
   chips are redundant on the desktop grid and are hidden: two places
   showing the same times is how they start to disagree. The chips remain
   in the DOM and remain the click target for the picker. */
.ra-cellmeta{
  font-family:var(--mono);font-size:13px;line-height:1.45;color:var(--t3);
  margin-top:2px;white-space:normal;word-break:break-word;
}
.ra-cellmeta.meta-missed{color:#ff8f8f;}
.ra-cellmeta.meta-debt{color:var(--gold);}
.ra-cellmeta.meta-ok{color:#8ce694;}
.ra-cellmeta.meta-active{color:#8ce694;}
.ra-cellmeta.meta-unsub{color:#f0a92b;}
.ra-cellmeta.meta-pub{color:var(--t2);}
.ra-cellmeta.meta-lock{color:var(--blue);}

/* the times now live in the meta line, so the chip row is presentational
   only: kept clickable, taken out of the visual flow */
.alloc-cell .time-row{
  position:absolute;inset:auto 0 0 0;height:22px;opacity:0;pointer-events:auto;
}
.alloc-cell{position:relative;padding-bottom:9px;}
.alloc-cell .time-row:focus-within,
.alloc-cell:hover .time-row{opacity:.85;position:static;height:auto;}

/* the day header: full weekday over the date, at the floor */
.rota-tbl thead th .s-bif4k1h{
  font-size:13px !important;opacity:.7 !important;font-weight:400 !important;
  display:block;margin-top:2px;
}
.rota-tbl thead th{
  font-family:var(--mono);font-size:13px;letter-spacing:1.2px;
  text-transform:uppercase;color:var(--t3);padding:11px 12px;
}

/* ── the shift name as text, the way the design shows it ── */
.ra-cellname{
  font-size:13px;font-weight:700;letter-spacing:.4px;text-transform:uppercase;
  color:var(--text);line-height:1.3;
}
/* the select is the mechanism, not the surface: visually hidden but still
   focusable by script and still the thing onShiftChange listens to */
.alloc-cell .shift-sel{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}
.alloc-cell[role="button"]{cursor:pointer;}
.alloc-cell[role="button"]:focus-visible{outline:2px solid var(--gold);outline-offset:2px;}

/* ── SET THIS CELL overlay ── */
.rc-eyebrow{font-family:var(--mono);font-size:13px;letter-spacing:1.6px;text-transform:uppercase;color:var(--gold);}
.rc-title{font-family:var(--display),'Cinzel',serif;font-size:20px;font-weight:700;color:var(--text);margin:8px 0 8px;line-height:1.2;}
.rc-blurb{font-size:13px;line-height:1.65;color:var(--t2);margin:0 0 4px;}
.rc-body{margin-top:16px;}
.rc-group{
  font-family:var(--mono);font-size:13px;letter-spacing:1.4px;text-transform:uppercase;
  color:var(--t3);margin:16px 0 8px;
}
.rc-group:first-child{margin-top:0;}
.rc-items{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(240px,100%),1fr));gap:8px;}
.rc-item{
  position:relative;display:flex;flex-direction:column;gap:3px;align-items:flex-start;
  min-height:56px;padding:10px 12px;border-radius:11px;text-align:left;cursor:pointer;
  border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--text);
  font-family:var(--body,'DM Sans'),system-ui,sans-serif;
  transition:border-color .25s cubic-bezier(.16,1,.3,1),background .25s cubic-bezier(.16,1,.3,1);
}
.rc-item:hover{border-color:rgba(240,200,50,.55);background:rgba(255,255,255,.09);}
.rc-item.on{border-color:rgba(240,200,50,.34);background:rgba(212,175,55,.14);}
.rc-item-v{font-size:13px;font-weight:600;}
.rc-item-t{font-family:var(--mono);font-size:13px;color:var(--t3);}
.rc-item-on{position:absolute;top:10px;right:11px;font-size:13px;color:var(--gold);}
.rc-item.tone-gold{border-color:rgba(240,200,50,.34);}
.rc-item.tone-blue{border-color:rgba(74,158,255,.40);}
.rc-item.tone-lock{border-color:rgba(74,158,255,.28);background:rgba(74,158,255,.07);}
.rc-notice{
  display:flex;gap:10px;align-items:flex-start;margin-top:16px;padding:12px 14px;border-radius:12px;
  border:1px solid rgba(240,200,50,.34);background:rgba(212,175,55,.10);
  font-size:13px;line-height:1.6;color:var(--t2);
}
.rc-notice i{color:var(--gold);margin-top:2px;flex-shrink:0;}
.rc-acts{display:flex;gap:10px;justify-content:flex-end;margin-top:18px;flex-wrap:wrap;}
@media(max-width:640px){
  .rc-acts .btn{width:100%;}
}

/* ── PERSON CELL, the design's four lines ── */
.ra-person{display:flex;align-items:flex-start;gap:11px;}
.ra-person-av{
  width:40px;height:40px;flex:0 0 auto;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:linear-gradient(135deg,var(--gold),#8b6914);color:#0c1109;
  border:1px solid rgba(255,255,255,.34);
  font-family:var(--mono);font-size:13px;font-weight:600;
}
.ra-person-id{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1 1 auto;}
.ra-person-more{margin-top:8px;}
.ra-person-more > summary{
  font-family:var(--mono);font-size:13px;color:var(--t3);cursor:pointer;
  list-style:none;padding:4px 0;min-height:24px;
}
.ra-person-more > summary::-webkit-details-marker{display:none;}
.ra-person-more > summary::before{content:'▸ ';color:var(--gold);}
.ra-person-more[open] > summary::before{content:'▾ ';}
.ra-person-more > summary:hover{color:var(--text);}

/* ── BALANCE COLUMN: NET over the figure, and the action ── */
.col-net-owed{text-align:right;vertical-align:middle;}
.ra-net-lbl{
  display:block;font-family:var(--mono);font-size:13px;letter-spacing:1.4px;
  text-transform:uppercase;color:var(--t3);
}
.net-owed-val{display:block;font-family:var(--mono);font-size:14px;font-weight:600;margin-top:3px;}
.net-owed-owed{color:#ff8f8f;}
.net-owed-credit{color:#8ce694;}
.net-owed-ok{color:var(--t2);}
.ra-net-credit{
  display:inline-flex;align-items:center;justify-content:center;margin-top:7px;min-height:36px;
  padding:7px 12px;border-radius:10px;border:1px solid rgba(240,200,50,.34);
  background:rgba(212,175,55,.12);color:var(--gold);
  font-family:var(--body,'DM Sans'),system-ui,sans-serif;font-size:13px;cursor:pointer;white-space:nowrap;
  transition:background .25s cubic-bezier(.16,1,.3,1);
}
.ra-net-credit:hover{background:rgba(212,175,55,.24);}

/* ════════════════════════════════════════════════════════════════════
   THE ACTION BAR MUST NOT SIT ON TOP OF THE GRID  (2026-08-03)

   REPORTED: the rota card and the action-bar card interfere.

   position:sticky with bottom:0 keeps the bar in the viewport, which is
   the design's behaviour, but a sticky element still occupies the flow it
   was in: it floats OVER whatever is beneath it as you scroll, so the
   last rows of the grid slid under the bar.

   The fix is to shift it, not to touch the grid. The bar keeps its own
   clear band: a gap above it, and enough room reserved below the grid
   card that the final row always clears it.

   NOTE FOR THE NEXT READER: an earlier version of this block released the
   grid's height as well. That was wrong and is reverted. The grid keeps
   its own scroll box; only the bar moved.
   ════════════════════════════════════════════════════════════════════ */
body.rota-board .action-bar{
  position:sticky;bottom:0;z-index:40;
  border:1px solid rgba(240,200,50,.34);border-radius:16px;
  background:rgba(20,29,16,.94);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  box-shadow:0 -12px 40px -18px rgba(0,0,0,.8);
  margin-top:14px;
}
/* the room the sticky bar needs, so nothing is ever hidden under it */
body.rota-board .ra-main{padding-bottom:8px;}

.ra-actionbar-note{
  flex:1 1 320px;min-width:0;
}
.ra-actionbar-note strong{
  display:block;font-family:var(--mono);font-size:13px;letter-spacing:1.3px;
  text-transform:uppercase;color:var(--gold);
}
.ra-actionbar-note span{
  display:block;margin-top:5px;font-size:13px;line-height:1.6;color:var(--t2);
}
/* the rail's count line, under its heading */
.ra-rail-sub{
  font-family:var(--mono);font-size:13px;color:var(--t3);
  margin-top:6px;padding:0 15px 12px;
}
.ra-rail-sub:empty{display:none;}

/* ── DRAWER, the design's own head and badges ── */
.ra-drawer-head{display:flex;align-items:center;gap:11px;}
.ra-drawer-id{flex:1 1 auto;min-width:0;}
.ra-drawer-title{font-family:var(--display),'Cinzel',serif;font-size:18px;font-weight:600;color:var(--text);}
.ra-drawer-role{font-family:var(--mono);margin-top:3px;font-size:13px;color:var(--t3);}
.ra-nav-badge{
  margin-left:auto;font-family:var(--mono);font-size:13px;padding:2px 8px;border-radius:999px;
  border:1px solid rgba(240,200,50,.34);background:rgba(212,175,55,.14);color:var(--gold);flex-shrink:0;
}
.ra-nav-badge:empty{display:none;}
/* archive rows: a readable date range over when it was saved */
.ra-arch-range{font-size:13px;font-weight:600;}
.ra-arch-saved{font-family:var(--mono);font-size:13px;color:var(--t3);margin-top:2px;}
/* the design's fourth line on the person cell: the net position */
.ra-person-net{
  display:inline-flex;align-items:center;gap:6px;margin-top:7px;
  padding:4px 10px;border-radius:999px;font-family:var(--mono);font-size:13px;
  border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--t2);
}
.ra-person-net:empty{display:none;}
.ra-person-net.credit{border-color:rgba(76,214,87,.40);background:rgba(67,177,75,.12);color:#8ce694;}
.ra-person-net.debt{border-color:rgba(255,72,72,.45);background:rgba(232,64,64,.12);color:#ff8f8f;}
/* the design's table cell padding, so the grid breathes as it does there */
.rota-tbl tbody td{padding:8px;}



/* ── THE ROLE BANNER (design: padding 15px 17px, radius 15px, gap 13px) ── */
.ra-rolebanner{
  display:flex;align-items:flex-start;gap:13px;
  padding:15px 17px;border:1px solid var(--border);border-radius:15px;
  background:rgba(255,255,255,.05);
  animation:wgIn .5s cubic-bezier(.16,1,.3,1) both;
}
.ra-rolebanner[hidden]{display:none;}
.ra-rolebanner > i{margin-top:3px;font-size:13px;flex-shrink:0;}
.ra-rb-body{flex:1 1 300px;min-width:0;}
.ra-rb-eyebrow{
  font-family:var(--mono);font-size:13px;letter-spacing:1.4px;text-transform:uppercase;
}
.ra-rb-text{margin:6px 0 0;font-size:13px;line-height:1.6;color:var(--t2);text-wrap:pretty;}
/* Blue for viewing only, amber for a lead: the same two colours the rest of
   the board uses for "this is information" and "this is yours to finish". */
.ra-rolebanner[data-tone="ro"]{border-color:rgba(74,158,255,.40);background:rgba(74,158,255,.10);}
.ra-rolebanner[data-tone="ro"] > i,
.ra-rolebanner[data-tone="ro"] .ra-rb-eyebrow{color:#4a9eff;}
.ra-rolebanner[data-tone="lead"]{border-color:rgba(245,158,11,.45);background:rgba(245,158,11,.09);}
.ra-rolebanner[data-tone="lead"] > i,
.ra-rolebanner[data-tone="lead"] .ra-rb-eyebrow{color:#f59e0b;}

/* The column gap is now the ONLY thing that spaces these three, so their own
   margins have to go or they double up. The action bar in particular was
   measured and approved at a 14px gap from the grid card; the gap alone
   reproduces that exactly, whereas gap + its old margin-top made it 28. */
#view-alloc > #rt-legend{margin-bottom:0;}
#view-alloc > .action-bar{margin-top:0;}

/* ════════════════════════════════════════════════════════════════
   THE HEADER  (design, 2026-08-04)

   Every rule here is scoped to body.rota-board. css/header-command.css
   loads LAST on all 33 pages and carries !important on the shared
   chrome, so this file cannot quietly win: where the shared file sets a
   property with !important, the scoped rule below has to as well, and
   only for this board.

   Values are the design's own, read off its inline styles: pills
   padding 8px 13px / radius 999px / 13px / letter-spacing 1.2px, guide
   button min-height 44px / padding 0 12px / radius 11px, officer chip
   padding 6px 12px 6px 6px / radius 999px with a 32px disc, left group
   gap 11px, right group gap 9px.
   ════════════════════════════════════════════════════════════════ */
body.rota-board #hdr .hdr-left{
  display:flex;align-items:center;gap:11px;min-width:0;flex:1 1 auto;
}
body.rota-board #hdr .hdr-right{display:flex;align-items:center;gap:9px;flex-shrink:0;}

/* The way in. 44px, because it is a touch target and the portal floors
   them there; the design has the same number. */
body.rota-board #hamburger{
  width:44px;height:44px;flex:0 0 auto;
  display:flex;flex-direction:column;justify-content:center;align-items:center;gap:5px;
  border:1px solid var(--border);border-radius:10px;background:rgba(255,255,255,.05);
  cursor:pointer;padding:0;
}
body.rota-board #hamburger span{width:18px;height:2px;background:var(--t2);border-radius:2px;}

/* The crest sits in a white disc with a gold ring, as the design has it:
   the mark is dark and needs the light ground to read at 42px. */
body.rota-board #hdr .hdr-logo-disc{
  width:42px;height:42px;flex:0 0 auto;border-radius:50%;
  background:#fff;border:1.5px solid var(--gold);overflow:hidden;
  display:flex;align-items:center;justify-content:center;
}
body.rota-board #hdr .hdr-brand-img{
  width:100%;height:100%;object-fit:contain;padding:3px;
  opacity:1;animation:none;
}
/* The full association name, per the naming rule: DTTASA is the brand,
   not the first reference to the organisation. */
body.rota-board #hdr .hdr-brand-logo{
  font-family:var(--body,'DM Sans'),system-ui,sans-serif;
  font-size:13px;font-weight:600;letter-spacing:.2px;line-height:1.25;
  max-width:260px;
  background:none;-webkit-background-clip:initial;-webkit-text-fill-color:initial;
  color:var(--text);
}
body.rota-board #hdr .hdr-brand-sub{
  font-family:var(--mono);font-size:13px;letter-spacing:1.2px;line-height:1.3;
  text-transform:uppercase;color:var(--gold);opacity:.85;
}

/* The two pills. Same geometry, different colour: green is a statement of
   fact about the system, gold is which week you are looking at. */
body.rota-board #hdr .hdr-status,
body.rota-board #hdr .hdr-week-pill{
  display:flex;align-items:center;gap:8px;
  padding:8px 13px;border-radius:999px;
  font-family:var(--mono);font-size:13px;letter-spacing:1.2px;font-weight:400;
  white-space:nowrap;flex-shrink:0;
}
body.rota-board #hdr .hdr-status{
  border:1px solid rgba(76,214,87,.40);background:rgba(67,177,75,.12);
  color:var(--green);text-transform:uppercase;
}
body.rota-board #hdr .hdr-week-pill{
  border:1px solid rgba(240,200,50,.34);background:rgba(212,175,55,.12);color:var(--gold);
}
body.rota-board #hdr .hdr-week-pill > i{font-size:13px;color:var(--gold);}

/* Clock. The zone is named because the portal runs on WAT and most of the
   people reading this are not in it. */
body.rota-board #hdr .hdr-clock{
  display:flex;align-items:center;gap:7px;
  font-family:var(--mono);font-size:13px;color:var(--t2);white-space:nowrap;
}
body.rota-board #hdr .hdr-tz{color:var(--t3);}
body.rota-board #hdr #hdr-date{color:var(--t3);}

body.rota-board #hdr #rota-guide-btn{
  display:flex;align-items:center;gap:7px;min-height:44px;padding:0 12px;
  border:1px solid var(--border);border-radius:11px;background:rgba(255,255,255,.05);
  font-size:13px;color:var(--text);text-decoration:none;flex-shrink:0;
}
body.rota-board #hdr #rota-guide-btn:hover{background:rgba(255,255,255,.09);}
body.rota-board #hdr #rota-guide-btn > i{font-size:12px;color:var(--gold);}

/* Who is holding the board, and in what capacity. */
body.rota-board #hdr .hdr-officer{
  display:flex;align-items:center;gap:9px;
  padding:6px 12px 6px 6px;border:1px solid var(--border);border-radius:999px;
  flex-shrink:0;
}
body.rota-board #hdr #hdr-avatar{
  width:32px;height:32px;flex:0 0 auto;border-radius:50%;overflow:hidden;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--mono);font-size:13px;font-weight:600;
  background:linear-gradient(135deg,var(--gold),var(--gold2));color:var(--void);
}
body.rota-board #hdr #hdr-avatar img{width:100%;height:100%;object-fit:cover;}
body.rota-board #hdr .hdr-officer-id{min-width:0;}
body.rota-board #hdr .hdr-admin-chip{
  font-size:13px;line-height:1.2;font-weight:400;letter-spacing:0;
  color:var(--text);background:none;border:0;padding:0;border-radius:0;
  max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  text-transform:none;
}
body.rota-board #hdr .hdr-officer-role{
  font-family:var(--mono);font-size:13px;line-height:1.3;color:var(--t3);
  white-space:nowrap;
}
/* The same two colours the role banner uses, so the header and the banner
   never disagree about what the viewer is. */
body.rota-board #hdr .hdr-officer-role[data-role="full"]{color:var(--gold);}
body.rota-board #hdr .hdr-officer-role[data-role="lead"]{color:#f59e0b;}
body.rota-board #hdr .hdr-officer-role[data-role="ro"]{color:#4a9eff;}

/* Shedding order as the header narrows: the things you can get elsewhere
   go first, the things only the header carries go last. The week is on the
   grid, the date is on the grid, the role is on the banner. */
@media(max-width:1400px){
  body.rota-board #hdr .hdr-brand-logo{max-width:190px;}
}
@media(max-width:1240px){
  body.rota-board #hdr #hdr-date{display:none;}
}
@media(max-width:1100px){
  body.rota-board #hdr .hdr-status{display:none;}
  body.rota-board #hdr .hdr-brand-text{display:none;}
}
@media(max-width:900px){
  /* Icon only below 900. Measured at 39.8px wide with padding alone, under
     the portal's 44px touch target, so the width is set rather than implied. */
  body.rota-board #hdr #rota-guide-btn span{display:none;}
  body.rota-board #hdr #rota-guide-btn{
    min-width:44px !important;padding:0 !important;justify-content:center;
  }
}
@media(max-width:760px){
  body.rota-board #hdr .hdr-week-pill{display:none;}
  body.rota-board #hdr .hdr-officer-id{display:none;}
  body.rota-board #hdr .hdr-officer{padding:6px;}
}
@media(max-width:420px){
  body.rota-board #hdr .hdr-clock{display:none;}
}

/* ── BEATING THE SHARED COMMAND BAR, ON THIS BOARD ONLY ──────────────
   css/header-command.css loads after this file and sets these exact
   properties with !important, so specificity alone loses. Measured, not
   assumed: before this block the pills came out at 8px radius and 10px
   text, the guide button at 8px radius, the avatar at 30px.

   Only the properties that file marks !important are marked here, and
   every selector carries body.rota-board, so the other 32 pages that
   link header-command.css are untouched. */
body.rota-board #hdr .hdr-status,
body.rota-board #hdr .hdr-week-pill{
  border-radius:999px !important;
  font-size:13px !important;
  font-weight:400 !important;
  letter-spacing:1.2px !important;
  padding:8px 13px !important;
}
body.rota-board #hdr .hdr-status{
  background:rgba(67,177,75,.12) !important;
  border:1px solid rgba(76,214,87,.40) !important;
  color:var(--green) !important;
}
body.rota-board #hdr .hdr-week-pill{
  background:rgba(212,175,55,.12) !important;
  border:1px solid rgba(240,200,50,.34) !important;
  color:var(--gold) !important;
  text-transform:none !important;
}
body.rota-board #hdr .hdr-clock{
  font-size:13px !important;
  font-weight:400 !important;
  letter-spacing:normal !important;
  color:var(--t2) !important;
  background:none !important;
  border:0 !important;
  border-radius:0 !important;
  padding:0 !important;
}
/* 13px, not the shared file's 9px. The floor is 13px portal-wide. */
body.rota-board #hdr #hdr-date{
  font-size:13px !important;
  letter-spacing:normal !important;
  color:var(--t3) !important;
}
body.rota-board #hdr .hdr-admin-chip{
  background:none !important;
  border:0 !important;
  border-radius:0 !important;
  padding:0 !important;
  font-size:13px !important;
  font-weight:400 !important;
  letter-spacing:0 !important;
  text-transform:none !important;
  color:var(--text) !important;
}
body.rota-board #hdr #hdr-avatar{
  width:32px !important;height:32px !important;
  border:0 !important;
  font-size:13px !important;
}
body.rota-board #hdr #rota-guide-btn{
  height:auto !important;min-height:44px !important;
  border-radius:11px !important;
  background:rgba(255,255,255,.05) !important;
  border:1px solid var(--border) !important;
  color:var(--text) !important;
  padding:0 12px !important;
  font-size:13px !important;
}
body.rota-board #hdr #rota-guide-btn:hover{
  background:rgba(255,255,255,.09) !important;
  border-color:var(--border) !important;
  color:var(--text) !important;
}

/* At 400px the whole .hdr-brand was hidden, crest included, so a phone got
   a header with no mark on it at all. The design carries the crest at every
   width: it is what identifies the board. Only the words go. */
@media(max-width:400px){
  body.rota-board #hdr .hdr-brand{display:flex;}
  body.rota-board #hdr .hdr-brand-text{display:none;}
}

/* ════════════════════════════════════════════════════════════════
   LIVE NETWORK  (design, 2026-08-04)

   The design's own values: kdeck auto-fit minmax(210px,1fr) gap 12,
   card padding 16 radius 15 with a 30px Cinzel figure, panels padding
   18 radius 16, distribution track 10px tall radius 999, overview rows
   padding 12 radius 12 gap 11, activity dot 34px with a 1px rail.
   ════════════════════════════════════════════════════════════════ */
#view-network{flex-direction:column;gap:14px;}
#view-network.active{display:flex;}

.network-grid{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(210px,100%),1fr));gap:12px;
}
.net-card{
  padding:16px;border:1px solid var(--border);border-radius:15px;background:rgba(255,255,255,.05);
  animation:scIn .42s cubic-bezier(.16,1,.3,1) both;
}
.net-card-header{display:flex;align-items:center;justify-content:space-between;gap:10px;}
.net-card-header > div{
  font-family:var(--mono);font-size:13px;letter-spacing:1.2px;text-transform:uppercase;color:var(--t3);
}
.net-card-header > i{font-size:13px;}
.net-metric{
  margin-top:11px;font-family:var(--disp),Cinzel,serif;font-size:30px;line-height:1;font-weight:700;
}
.net-sub{margin-top:9px;font-size:13px;line-height:1.5;color:var(--t3);text-wrap:pretty;}
/* One tone per card, the same four the grid legend uses. */
.net-card[data-tone="green"]{border-color:rgba(76,214,87,.40);background:rgba(67,177,75,.12);}
.net-card[data-tone="green"] .net-metric,.net-card[data-tone="green"] .net-card-header > i{color:#8ce694;}
.net-card[data-tone="gold"]{border-color:rgba(240,200,50,.34);background:rgba(212,175,55,.12);}
.net-card[data-tone="gold"] .net-metric,.net-card[data-tone="gold"] .net-card-header > i{color:var(--gold);}
.net-card[data-tone="blue"]{border-color:rgba(74,158,255,.40);background:rgba(74,158,255,.10);}
.net-card[data-tone="blue"] .net-metric,.net-card[data-tone="blue"] .net-card-header > i{color:#4a9eff;}
.net-card[data-tone="red"]{border-color:rgba(255,72,72,.45);background:rgba(232,64,64,.12);}
.net-card[data-tone="red"] .net-metric,.net-card[data-tone="red"] .net-card-header > i{color:#ff8f8f;}

/* ── distribution, horizontal bars as the design has them ── */
.shift-dist{display:flex;flex-direction:column;gap:12px;}
.sd-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;font-size:13px;}
.sd-count{font-family:var(--mono);font-size:13px;color:var(--t2);}
.sd-count[data-tone="gold"]{color:var(--gold);}
.sd-count[data-tone="green"]{color:#8ce694;}
.sd-count[data-tone="blue"]{color:#4a9eff;}
.sd-track{
  margin-top:6px;height:10px;border-radius:999px;overflow:hidden;
  background:rgba(255,255,255,.05);border:1px solid var(--border);
}
.sd-fill{
  display:block;height:100%;border-radius:999px;background:rgba(255,255,255,.34);
  transform-origin:left center;animation:barGrow .5s cubic-bezier(.16,1,.3,1) both;
}
.sd-fill[data-tone="gold"]{background:linear-gradient(90deg,var(--gold),var(--gold2));}
.sd-fill[data-tone="green"]{background:rgba(76,214,87,.65);}
.sd-fill[data-tone="blue"]{background:rgba(74,158,255,.65);}
@keyframes barGrow{from{transform:scaleX(0);}to{transform:scaleX(1);}}

/* ── week overview rows ── */
.net-list{display:flex;flex-direction:column;gap:10px;}
.net-ov-row{
  display:flex;align-items:center;gap:11px;
  padding:12px;border:1px solid var(--border);border-radius:12px;background:rgba(255,255,255,.05);
}
.net-ov-row > i{flex:0 0 auto;font-size:13px;color:var(--t3);}
.net-ov-text{flex:1 1 auto;min-width:0;font-size:13px;line-height:1.5;text-wrap:pretty;}
.net-ov-val{flex:0 0 auto;font-family:var(--mono);font-size:14px;font-weight:600;color:var(--t2);}
.net-ov-row[data-tone="green"]{border-color:rgba(76,214,87,.40);background:rgba(67,177,75,.12);}
.net-ov-row[data-tone="green"] > i,.net-ov-row[data-tone="green"] .net-ov-val{color:#8ce694;}
.net-ov-row[data-tone="amber"]{border-color:rgba(245,158,11,.45);background:rgba(245,158,11,.09);}
.net-ov-row[data-tone="amber"] > i,.net-ov-row[data-tone="amber"] .net-ov-val{color:#f59e0b;}
.net-ov-row[data-tone="blue"]{border-color:rgba(74,158,255,.40);background:rgba(74,158,255,.10);}
.net-ov-row[data-tone="blue"] > i,.net-ov-row[data-tone="blue"] .net-ov-val{color:#4a9eff;}
.net-ov-row[data-tone="gold"]{border-color:rgba(240,200,50,.34);background:rgba(212,175,55,.12);}
.net-ov-row[data-tone="gold"] > i,.net-ov-row[data-tone="gold"] .net-ov-val{color:var(--gold);}
.net-ov-row[data-tone="red"]{border-color:rgba(255,72,72,.45);background:rgba(232,64,64,.12);}
.net-ov-row[data-tone="red"] > i,.net-ov-row[data-tone="red"] .net-ov-val{color:#ff8f8f;}

/* ── governance activity, the design's rail ── */
.net-act{display:flex;gap:13px;}
.net-act-rail{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;width:34px;}
.net-act-dot{
  width:34px;height:34px;border-radius:50%;flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;
  border:1px solid var(--border);background:rgba(255,255,255,.05);
}
.net-act-dot > i{font-size:12px;color:var(--t2);}
.net-act-line{flex:1 1 auto;width:1px;min-height:12px;background:var(--border);}
.net-act:last-child .net-act-line{display:none;}
.net-act-body{flex:1 1 auto;min-width:0;padding-bottom:15px;}
.net-act-what{font-size:13px;line-height:1.5;text-wrap:pretty;}
.net-act-when{margin-top:5px;font-family:var(--mono);font-size:13px;color:var(--t3);}
.net-act-dot[data-tone="gold"]{border-color:rgba(240,200,50,.34);background:rgba(212,175,55,.12);}
.net-act-dot[data-tone="gold"] > i{color:var(--gold);}
.net-act-dot[data-tone="green"]{border-color:rgba(76,214,87,.40);background:rgba(67,177,75,.12);}
.net-act-dot[data-tone="green"] > i{color:#8ce694;}
.net-act-dot[data-tone="red"]{border-color:rgba(255,72,72,.45);background:rgba(232,64,64,.12);}
.net-act-dot[data-tone="red"] > i{color:#ff8f8f;}

.net-empty{padding:16px;font-size:13px;line-height:1.6;color:var(--t3);text-wrap:pretty;}

/* ════════════════════════════════════════════════════════════════
   THE ONE OVERLAY FRAME  (design, 2026-08-04)

   The design has a SINGLE overlay frame, om-scrim / om-card / om-grab,
   and every overlay wears it. We had two: this frame under the name
   rc-*, used by the cell overlay alone, and seven other overlays each
   with a hand-rolled box of its own width, radius and padding.

   THE ENTRANCE IS AN ANIMATION, NOT A TRANSITION, and that is not a
   style choice. The first version defaulted the scrim to opacity:0 and
   raised it on .show. Six of these overlays do use .show; reconcile-modal
   sets style.display directly and never gets the class, so it would have
   opened fully transparent, a modal you cannot see and cannot dismiss.
   An animation runs whenever the element becomes displayed, whichever way
   it was shown, which is why the design uses one.

   Design values: scrim rgba(0,0,0,.72) blur 4 padding 20; card max-width
   min(600px, 100vw - 24px), padding 26px 24px, radius 16; at 640 a bottom
   sheet with a grab handle and safe-area padding.
   ════════════════════════════════════════════════════════════════ */
.om-scrim{
  /* z-index was lost when this frame was consolidated: the seven overlays
     declared in the markup each carry their own on an #id rule, so they were
     fine, and the ones BUILT IN JS (the cell overlay, the standard card, the
     republish list) had none and painted UNDER the page. elementFromPoint at
     the centre of the card returned the grid behind it. */
  position:fixed;inset:0;z-index:900;
  /* display:flex, or align-items and justify-content do NOTHING. The seven
     overlays declared in the markup each get flex from their own
     `#id.show{display:flex}`, so they centred and hid this; the ones built in
     JS fell back to display:block and their card sat hard left. The id rules
     that hide them outrank this, so nothing is revealed by adding it. */
  display:flex;
  align-items:center;justify-content:center;padding:20px;
  background:rgba(0,0,0,.72);
  -webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);
  animation:fadeIn .25s cubic-bezier(.16,1,.3,1) both;
}
.om-card{
  width:100%;max-width:min(600px,calc(100vw - 24px));max-height:calc(100vh - 40px);overflow-y:auto;
  /* the design's card is position:relative, and two of these overlays carry
     an inset:0 decorative pseudo that would otherwise anchor to the viewport */
  position:relative;
  padding:26px 24px;border-radius:16px;border:1px solid rgba(255,255,255,.21);
  background:linear-gradient(165deg,#172213,#111a0e);
  box-shadow:0 30px 70px -24px rgba(0,0,0,.75);
  animation:mIn .32s cubic-bezier(.16,1,.3,1) both;
  -webkit-backdrop-filter:none;backdrop-filter:none;
  transform:none;
}
/* The design's three width variants, so an overlay is as wide as its
   content needs and no wider. */
.om-card[data-w="760"]{max-width:min(760px,calc(100vw - 24px));}
.om-card[data-w="480"]{max-width:min(480px,calc(100vw - 24px));}
.om-card[data-w="420"]{max-width:min(420px,calc(100vw - 24px));}
/* And its two tones: a red edge when the action destroys something, a
   blue one when it is about a lock. */
.om-card[data-tone="destructive"]{border-left:3px solid var(--red);}
.om-card[data-tone="lock"]{border-left:3px solid #4a9eff;}
.om-grab{display:none;}

@media(max-width:640px){
  /* A bottom sheet on a phone, which is where a thumb can reach it. */
  .om-scrim{align-items:flex-end;padding:0;}
  .om-card{
    max-width:100% !important;border-radius:18px 18px 0 0;max-height:92vh;
    padding:22px 18px calc(22px + env(safe-area-inset-bottom));
    animation:shIn .34s cubic-bezier(.16,1,.3,1) both;
  }
  .om-grab{display:block;width:44px;height:4px;margin:0 auto 16px;border-radius:999px;background:rgba(255,255,255,.28);}
}

/* The ID rules below set the same scrim properties and outrank a class,
   so the frame could never take effect through them. Their appearance
   moves here; they keep display and z-index, which is behaviour. */
#processing.om-scrim, #picker-overlay.om-scrim, #confirm-modal.om-scrim,
#auth-modal.om-scrim, #publish-success.om-scrim,
#perm-picker-overlay.om-scrim, #reconcile-modal.om-scrim{
  background:rgba(0,0,0,.72);
  -webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);
  align-items:center;justify-content:center;padding:20px;
}
@media(max-width:640px){
  #processing.om-scrim, #picker-overlay.om-scrim, #confirm-modal.om-scrim,
  #auth-modal.om-scrim, #publish-success.om-scrim,
  #perm-picker-overlay.om-scrim, #reconcile-modal.om-scrim{
    align-items:flex-end;padding:0;
  }
}

/* These two carried their scrim on a hashed class in css/style-shim.css,
   with !important on background, padding and align-items, so the frame
   could not reach them: one stayed at a 0.6 black, the other never became
   a bottom sheet. The class is retired; what it provided beyond the frame,
   the stacking and the hidden default, is here. */
#perm-picker-overlay{display:none;z-index:800;}
#perm-picker-overlay.show{display:flex;}
#reconcile-modal{display:none;z-index:99999;}
/* built by _showRepublishDiffModal and appended straight to the body, so it
   opens as soon as it exists: no hidden default, and its own stacking. */
#republish-diff-modal{z-index:99999;}

/* The three entrances the overlay frame uses. They were NOT defined in any
   of the six stylesheets this page loads: other pages define fadeIn and mIn
   in their own sheets, which does nothing for this one. An undefined
   animation name throws no error and animates nothing, so every overlay
   would simply have appeared. Same class of fault as cvIn. Definitions are
   the design's own. */
@keyframes fadeIn{from{opacity:0;}to{opacity:1;}}
@keyframes mIn{from{transform:translateY(18px) scale(.985);opacity:0;}to{transform:none;opacity:1;}}
@keyframes shIn{from{transform:translateY(100%);}to{transform:none;}}

/* The clear-week button is icon only, and .btn-sm padding brought it out at
   42px wide: two short of the portal's 44px touch target. Measured, not
   assumed, on a 390px screen. */
#view-alloc .action-bar #btn-clear{
  min-width:44px;justify-content:center;
}

/* top:0, as the design has it. This was `top: var(--rota-sticky-top)`, an
   offset measured from the page header and toolbar, on the assumption that
   sticky here resolves against the VIEWPORT. It does not: `overflow-y:hidden`
   on .grid-scroll makes it a scroll container, so sticky resolves against
   THAT, and a 149px offset pushed the whole header row down into the rows.
   The VP saw the day names sitting inside the first cells.

   The design's header sits at the top of the grid and scrolls with the page,
   which is what top:0 gives. */
.rota-tbl thead th,
.rota-tbl thead th.col-member{ top: 0; }
/* Above the cells, below the toolbar. */
.rota-tbl thead th{ z-index: 20; }
.rota-tbl thead th.col-member{ z-index: 21; }
.rota-tbl tbody td.col-member{ z-index: 10; }

/* ── WHY THE PAGE STOPPED SCROLLING OVER THE GRID ────────────────────
   css/responsive.css lists .grid-scroll among the "nested scroll regions"
   that get `overscroll-behavior: contain`. For a drawer or a modal that is
   right: the scroll should not chain out to the page behind it. For this
   grid it is not, because the grid has no vertical scroll of its own, so
   `contain` does not stop chaining AT THE END, it stops it entirely, and a
   cursor over the grid froze the page.

   Proven rather than reasoned: a wheel over the grid moved the page 0px
   with the design's own `overflow-x:auto` declaration, and 500px the moment
   overscroll-behavior-y was released. The height was only half of it.

   responsive.css loads after this file, so an id is used to win on
   specificity rather than !important. .grid-scroll is used on no other
   page, so nothing else is affected. */
#view-alloc .grid-scroll{ overscroll-behavior-y: auto; }

/* Full screen is the one state where the grid DOES scroll itself: it is
   fixed to the viewport, so it needs its own vertical scroll back, and
   `contain` is correct again there. */
#view-alloc.grid-fullscreen .grid-scroll{
  /* Horizontal only, exactly as outside full screen. This was overflow-y:auto
     with `contain`, which is what turned the grid into its own scroll box. */
  overflow-y: hidden !important;
  overscroll-behavior-y: auto;
}

/* A shared rule sets `padding-top: max(env(safe-area-inset-top), 0px)
   !important` on #test-mode-banner so it clears a notch. On any screen
   without one that resolves to 0 and wipes the design's 10px. This keeps the
   notch clearance and puts the floor back. */
body.rota-board #test-mode-banner{
  padding-top: max(env(safe-area-inset-top), 10px) !important;
}

/* ════════════════════════════════════════════════════════════════
   THE STANDARD OVERLAY CARD  (design, 2026-08-04)

   The design does not carry a list of overlays for the rail; it carries
   a SPEC for each one, and one card that renders them. Values below are
   the design's own inline styles: accent disc 40px, eyebrow mono 13px
   1.4px uppercase, title 18px Cinzel, blurb 13px/1.62, meta grid
   auto-fit minmax(140px,1fr) gap 10 padding 12 radius 12, fields gap 13,
   inputs radius 12 min-height 46 (48 for the lock), actions gap 10
   min-height 48 right aligned.
   ════════════════════════════════════════════════════════════════ */
.ovc-head{display:flex;align-items:flex-start;gap:13px;}
.ovc-disc{
  width:40px;height:40px;flex:0 0 auto;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  border:1px solid var(--border);background:rgba(255,255,255,.05);
}
.ovc-disc > i{font-size:14px;}
.ovc-headtxt{flex:1 1 auto;min-width:0;}
.ovc-eyebrow{font-family:var(--mono);font-size:13px;letter-spacing:1.4px;text-transform:uppercase;}
.ovc-title{
  font-family:var(--disp),Cinzel,serif;margin:7px 0 0;font-size:18px;line-height:1.25;
  font-weight:700;text-wrap:pretty;color:var(--text);
}
.ovc-x{
  width:44px;height:44px;flex:0 0 auto;border:1px solid var(--border);border-radius:10px;
  background:rgba(255,255,255,.05);color:var(--text);cursor:pointer;font-size:13px;
}
.ovc-x:hover{background:rgba(255,255,255,.10);}
.ovc-blurb{margin:13px 0 0;font-size:13px;line-height:1.62;color:var(--t2);text-wrap:pretty;}
.ovc-notice{
  margin-top:15px;display:flex;align-items:flex-start;gap:11px;padding:14px;
  border:1px solid var(--border);border-radius:13px;background:rgba(255,255,255,.05);
}
.ovc-notice > i{margin-top:3px;font-size:13px;}
.ovc-notice > div{flex:1 1 auto;min-width:0;font-size:13px;line-height:1.6;color:var(--t2);text-wrap:pretty;}
.ovc-meta{margin-top:15px;display:grid;grid-template-columns:repeat(auto-fit,minmax(min(140px,100%),1fr));gap:10px;}
.ovc-meta-cell{padding:12px;border:1px solid var(--border);border-radius:12px;background:rgba(255,255,255,.05);}
.ovc-meta-k{font-family:var(--mono);font-size:13px;letter-spacing:1.2px;text-transform:uppercase;color:var(--t3);}
.ovc-meta-v{font-family:var(--mono);margin-top:6px;font-size:14px;font-weight:600;color:var(--t2);}
.ovc-fields{margin-top:15px;display:flex;flex-direction:column;gap:13px;}
.ovc-label{display:flex;align-items:baseline;gap:8px;font-size:13px;color:var(--text);}
.ovc-req{font-family:var(--mono);font-size:13px;color:var(--gold);}
.ovc-fields textarea,
.ovc-fields input,
.ovc-fields select{
  width:100%;margin-top:7px;border-radius:12px;
  border:1px solid rgba(255,255,255,.34);background:rgba(255,255,255,.10);
  color:var(--text);font-size:14px;font-family:inherit;
}
.ovc-fields textarea{padding:11px 12px;line-height:1.55;resize:vertical;}
.ovc-fields input,
.ovc-fields select{min-height:46px;padding:0 12px;}
.ovc-read{
  margin-top:7px;padding:11px 12px;border-radius:12px;border:1px dashed var(--border);
  font-size:13px;line-height:1.55;color:var(--t2);
}
.ovc-warn{
  margin-top:15px;display:flex;align-items:flex-start;gap:11px;padding:14px;
  border:1px solid rgba(255,72,72,.45);border-radius:13px;background:rgba(232,64,64,.12);
}
.ovc-warn > i{margin-top:3px;font-size:13px;color:#ff8f8f;}
.ovc-warn > div{flex:1 1 auto;min-width:0;font-size:13px;line-height:1.6;color:var(--t2);text-wrap:pretty;}
.ovc-err{margin-top:12px;font-size:13px;line-height:1.5;color:#ff8f8f;}
.ovc-err:empty{display:none;}
.ovc-actions{margin-top:20px;display:flex;gap:10px;justify-content:flex-end;flex-wrap:wrap;}
.ovc-btn{
  min-height:48px;padding:0 18px;border-radius:12px;cursor:pointer;
  font-size:14px;font-family:inherit;border:1px solid var(--border);
  background:rgba(255,255,255,.05);color:var(--text);font-weight:500;
}
.ovc-btn:hover{background:rgba(255,255,255,.10);}
.ovc-btn[data-kind="primary"]{
  font-weight:700;border-color:rgba(240,200,50,.34);
  background:linear-gradient(135deg,var(--gold),var(--gold2));color:var(--void);
}
.ovc-btn[data-kind="danger"]{
  font-weight:700;border-color:rgba(255,72,72,.45);
  background:rgba(232,64,64,.22);color:#ff8f8f;
}
.ovc-btn[data-kind="approve"]{
  font-weight:700;border-color:rgba(76,214,87,.40);
  background:rgba(67,177,75,.22);color:#8ce694;
}
.ovc-btn[disabled]{opacity:.55;cursor:not-allowed;}
/* Tone drives the accent disc, the eyebrow and the card's left edge. */
.om-card[data-tone="destructive"] .ovc-disc{border-color:rgba(255,72,72,.45);background:rgba(232,64,64,.12);}
.om-card[data-tone="destructive"] .ovc-disc > i,
.om-card[data-tone="destructive"] .ovc-eyebrow{color:#ff8f8f;}
.om-card[data-tone="lock"] .ovc-disc{border-color:rgba(74,158,255,.40);background:rgba(74,158,255,.10);}
.om-card[data-tone="lock"] .ovc-disc > i,
.om-card[data-tone="lock"] .ovc-eyebrow{color:#4a9eff;}
.om-card:not([data-tone]) .ovc-disc{border-color:rgba(240,200,50,.34);background:rgba(212,175,55,.12);}
.om-card:not([data-tone]) .ovc-disc > i,
.om-card:not([data-tone]) .ovc-eyebrow{color:var(--gold);}

/* ── THE PERSON CELL'S CHIPS (design) ────────────────────────────────
   The design puts the probation state and the balance side by side as
   two pills under the role, each mono 13px in a 999px capsule with
   padding 2px 8px, the balance one carrying a 10px icon. Ours had a
   one-letter "P" badge and a bare line of text, so the row read
   "AN / Adizha Nyako / Head of Volunteer Management / P / -68.80 h owed"
   where the design reads "...Officer, Operations / Probation /
   -18.25 h owed". */
.ra-person-chips{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px;}
.ra-chip{
  display:inline-flex;align-items:center;gap:6px;
  padding:2px 8px;border-radius:999px;
  font-family:var(--mono);font-size:13px;white-space:nowrap;
  border:1px solid var(--border);background:rgba(255,255,255,.05);color:var(--t2);
}
.ra-chip > i{font-size:10px;}
.ra-chip:empty{display:none;}
.ra-chip-prob{border-color:rgba(245,158,11,.45);background:rgba(245,158,11,.09);color:#f59e0b;}
.ra-chip-bal.debt{border-color:rgba(255,72,72,.45);background:rgba(232,64,64,.12);color:#ff8f8f;}
.ra-chip-bal.credit{border-color:rgba(76,214,87,.40);background:rgba(67,177,75,.12);color:#8ce694;}
.ra-chip-bal.flat{border-color:var(--border);background:rgba(255,255,255,.05);color:var(--t2);}
/* The design's disc is 38px, and the name row carries the crown inline. */
.ra-person-av{width:38px;height:38px;font-size:13px;font-weight:600;}
.ra-person-net{display:none;}

/* The disc holds a photo when there is one, so it has to clip and the image
   has to fill it. The design draws initials because its people are
   placeholders; ours are real and all of them have a photo. */
.ra-person-av, .ramc-av{overflow:hidden;padding:0;}
.ra-person-av img, .ramc-av img{width:100%;height:100%;object-fit:cover;display:block;border-radius:50%;}

/* ── FULL SCREEN KEEPS THE CONTROLS ──────────────────────────────────
   First pass hid the toolbar along with the hero and the legend, on the
   design's `showChrome: !fullscreen`. Wrong for us: the VP needs to move
   between GLOBAL and NEW STARTERS, run Fill Permanent Shifts, walk the
   weeks and leave full screen, all without coming out of it. Full screen
   is the same board with more room, not a stripped one.

   What goes is only what repeats something already on screen: the hero
   (a title), the legend (a reference panel) and the role banner. The
   toolbar, the week nav, the exit button, the grid and the action bar
   stay, and the leave summary follows underneath the grid. */
#view-alloc.grid-fullscreen .ra-hero,
#view-alloc.grid-fullscreen #rt-legend,
#view-alloc.grid-fullscreen #ra-rolebanner{ display: none !important; }
#view-alloc.grid-fullscreen{ padding: 0 !important; gap: 10px !important; }

/* The toolbar is OUTSIDE #view-alloc, so full screen has to bring it in.
   It sits at the top of the fixed panel and stays put. */
body.grid-fs .alloc-toolbar{
  display: flex !important;
  position: fixed !important; top: 0; left: 0; right: 0;
  z-index: 620;
  padding: 10px 16px;
  background: rgba(12,17,9,.94);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--border);
  max-width: none;
}
#view-alloc.grid-fullscreen{ padding-top: var(--fs-bar-h, 76px) !important; }

/* The shell stays two-column so the leave rail is still reachable, but it
   drops under the grid rather than squeezing it. */
/* js/rota.js moves .ra-aside INTO this panel on the way in, because it is a
   sibling of the column that holds the panel and no selector here can reach
   it otherwise. */
#view-alloc.grid-fullscreen > .ra-aside{
  display: block !important;
  position: static !important; top: auto !important;
  width: auto; margin: 12px 14px 92px;
}
#view-alloc.grid-fullscreen .grid-scroll{ margin: 0 14px; }
#view-alloc.grid-fullscreen .action-bar{ margin: 0 14px; }

/* The live pip, the design's own: 8px, --green, breathing on 2.4s. */
.ra-cellmeta{display:flex;align-items:center;gap:6px;}
.ra-cellpip{
  width:8px;height:8px;flex:0 0 auto;border-radius:50%;background:var(--green);
  animation:pulseRing 2.4s ease-out infinite;
}
@keyframes pulseRing{
  0%{box-shadow:0 0 0 0 rgba(76,214,87,.55);}
  70%{box-shadow:0 0 0 6px rgba(76,214,87,0);}
  100%{box-shadow:0 0 0 0 rgba(76,214,87,0);}
}

/* The exit control sits bottom right in full screen, where the design puts
   it ("Leave fullscreen", fixed right:20 bottom:20). It was top:14 right:18,
   which is now underneath the fixed toolbar and its week arrows. */
body.grid-fs #fs-exit-btn{
  top: auto !important; bottom: 20px !important; right: 20px !important;
  z-index: 880 !important;
  min-height: 48px; padding: 0 17px; border-radius: 12px;
  background: rgba(12,17,9,.92); color: var(--text); text-transform: none;
  font-weight: 500; letter-spacing: 0;
  box-shadow: 0 18px 44px -16px rgba(0,0,0,.8);
}

/* The rail is sticky in the two-column layout; in full screen it flows under
   the grid, so the stickiness has to come off or it pins itself under the
   toolbar instead of sitting where it belongs. */
/* And the exit control clears the action bar rather than landing on its
   buttons: measured, the bar occupies the bottom 62px. */
body.grid-fs #fs-exit-btn{ bottom: 92px !important; }

/* THE LIVE CELL, laid out as the VP specified: the on-shift icon first, then
   the breathing dot, then the shift name, all on one row; "On shift since"
   under it; and the time on its own line under that. */
.ra-cellname.is-live{display:flex;align-items:center;gap:6px;flex-wrap:nowrap;min-width:0;}
.ra-cellicon{font-size:11px;color:var(--green);flex:0 0 auto;}
.ra-cellname.is-live .ra-cellpip{margin:0;}
.ra-cellmeta.meta-active{flex-direction:column;align-items:flex-start;gap:1px;}
.ra-cellsince{font-family:var(--mono);font-size:13px;color:#8ce694;}

/* ── THE LEAVE CELL (design) ─────────────────────────────────────────
   Two lines, like every other cell: the padlock leading the leave name,
   and one line saying it is locked. The name WRAPS, because
   "Emergency Leave (Owed)" does not fit a day column on one line and was
   being squeezed into an unreadable strip. The padlock and an umbrella
   were both absolutely positioned over the text, and the Override button
   sat on top of it at bottom-right; the action is in the overlay now. */
.ra-cellname.is-leave{
  display:flex;align-items:flex-start;gap:6px;
  white-space:normal;overflow-wrap:anywhere;line-height:1.3;
}
.ra-cellname.is-leave .ra-cellicon{margin-top:2px;}
.alloc-cell.leave-locked{height:auto;}
/* Where the viewer may write over it, the cell is a control and says so. */
.alloc-cell.leave-locked.can-override{cursor:pointer;}
.alloc-cell.leave-locked.can-override:hover{
  border-color:rgba(74,158,255,.55);background:rgba(74,158,255,.16);
}

/* ── THE ACTION BAR'S BOTTOM EDGE ────────────────────────────────────
   A shared rule sets `padding-bottom: max(env(safe-area-inset-bottom),
   0px) !important` on sticky bottom bars so they clear a home indicator.
   On any screen without one that resolves to 0 and wipes the bar's own
   16px, so SAVE DRAFT and PUBLISH & DEPLOY sat 1px off the card edge once
   they wrapped to a second row. Measured at 760, 390 and 320: gap below
   the publish button, 1px. Same fault, same fix, as the test-mode strip:
   keep the safe-area clearance and put the floor back. */
body.rota-board .action-bar{
  padding-bottom: max(env(safe-area-inset-bottom), 16px) !important;
}
/* And the buttons never squeeze below a readable size when they wrap. */
body.rota-board .action-bar .btn{ flex: 0 0 auto; white-space: nowrap; }

/* ── THE BOARD'S EMPTY AND ERROR STATES (design) ─────────────────────
   Ours were a bare table row: "No staff in this view." and "Error
   loading grid: <exception message>". The design gives each a proper
   notice with a disc, a title, a sentence saying what to do next, and a
   retry where one makes sense. Values are the design's: disc 40px,
   radius 15, padding 18, title 18px Cinzel, text 13px/1.6. */
.ra-notice-cell{padding:18px 8px !important;}
.ra-notice{
  display:flex;align-items:flex-start;gap:14px;
  padding:18px;border-radius:15px;
  border:1px solid var(--border);background:rgba(255,255,255,.05);
}
.ra-notice[data-stroke="dashed"]{border-style:dashed;}
.ra-notice-disc{
  width:40px;height:40px;flex:0 0 auto;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  border:1px solid var(--border);background:rgba(255,255,255,.05);
}
.ra-notice-disc > i{font-size:14px;}
.ra-notice-body{flex:1 1 auto;min-width:0;}
.ra-notice-title{
  font-family:var(--disp),Cinzel,serif;font-size:18px;line-height:1.25;
  font-weight:700;color:var(--text);text-wrap:pretty;
}
.ra-notice-text{margin:7px 0 0;font-size:13px;line-height:1.6;color:var(--t2);text-wrap:pretty;}
.ra-notice-detail{margin:6px 0 0;font-size:13px;line-height:1.6;color:var(--t3);text-wrap:pretty;}
.ra-notice-act{
  flex:0 0 auto;min-height:44px;padding:0 16px;border-radius:11px;cursor:pointer;
  border:1px solid rgba(255,72,72,.45);background:rgba(232,64,64,.16);
  color:#ff8f8f;font-size:13px;font-family:inherit;
}
.ra-notice-act:hover{background:rgba(232,64,64,.26);}
.ra-notice[data-tone="gold"]{border-color:rgba(240,200,50,.34);background:rgba(212,175,55,.12);}
.ra-notice[data-tone="gold"] .ra-notice-disc{border-color:rgba(240,200,50,.34);background:rgba(212,175,55,.16);}
.ra-notice[data-tone="gold"] .ra-notice-disc > i{color:var(--gold);}
.ra-notice[data-tone="red"]{border-color:rgba(255,72,72,.45);background:rgba(232,64,64,.07);}
.ra-notice[data-tone="red"] .ra-notice-disc{border-color:rgba(255,72,72,.45);background:rgba(232,64,64,.12);}
.ra-notice[data-tone="red"] .ra-notice-disc > i{color:#ff8f8f;}
@media(max-width:640px){ .ra-notice{flex-wrap:wrap;} .ra-notice-act{width:100%;} }

/* ── LIVE NETWORK: the design's section chrome ───────────────────────
   Header 15px 16px with a bottom rule, a gold shield, the title in
   Cinzel 18px, and a green "Live" pill on the right whose dot breathes.
   Ours was an h3 with a bare pip floating beside it. */
.audit-stream{
  border:1px solid var(--border);border-radius:16px;
  background:rgba(255,255,255,.05);overflow:hidden;
}
.audit-stream-header{
  display:flex;align-items:center;gap:11px;flex-wrap:wrap;
  padding:15px 16px;border-bottom:1px solid rgba(255,255,255,.12);
}
.audit-stream-header > i{font-size:13px;color:var(--gold);}
.audit-stream-header h3{
  flex:1 1 auto;min-width:0;margin:0;
  font-family:var(--disp),Cinzel,serif;font-size:18px;font-weight:600;color:var(--text);
}
.ra-live-pill{
  display:flex;align-items:center;gap:7px;flex:0 0 auto;
  padding:5px 11px;border-radius:999px;
  border:1px solid rgba(76,214,87,.40);background:rgba(67,177,75,.12);
  font-family:var(--mono);font-size:13px;color:var(--green);
}
.ra-live-pill > i{font-size:6px;animation:blinkPip 2.4s cubic-bezier(.16,1,.3,1) infinite;}
@keyframes blinkPip{0%,100%{opacity:1;}50%{opacity:.25;}}
.audit-stream-body{padding:14px;display:flex;flex-direction:column;gap:0;max-height:none;}

/* Every section fills the width it is given, and stacks cleanly on a phone. */
#view-network > *{width:100%;}
.net-dist-grid{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(320px,100%),1fr));gap:14px;
}
@media(max-width:820px){ .net-dist-grid{grid-template-columns:1fr;} }

/* ── THE POPULATION TRAY ON A PHONE ──────────────────────────────────
   `flex-shrink:0` on a tray holding two long labels made it 430px wide in
   a 390px viewport, so the whole page scrolled sideways. It is the
   toolbar, so it did that in BOTH views. The tray now shares the row and
   its tabs share the tray. */
@media(max-width:640px){
  .ra-poptray{ flex-shrink:1; min-width:0; width:100%; }
  .ra-poptray .tab-btn{
    flex:1 1 0; min-width:0; justify-content:center; padding:0 9px;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }
  /* The counts stay: they are the reason to look at the tray at all. */
  .ra-poptray .tab-btn .ra-nav-badge{flex:0 0 auto;}
}

/* The toolbar acts on a week of cells. On the Live network deck there is no
   week to populate, no permanent shift to fill and no staged count to read,
   so the whole strip goes rather than sitting there inert. */
body.rota-view-network .alloc-toolbar{display:none !important;}

/* Use permanent, back on the row and easy to hit. */
.ra-person-perm{margin-top:8px;}
.ra-person-perm .tab-btn{
  display:inline-flex;align-items:center;gap:7px;
  min-height:36px;padding:0 12px;border-radius:10px;
  border:1px solid rgba(240,200,50,.34);background:rgba(212,175,55,.12);
  color:var(--gold);font-size:13px;letter-spacing:0;font-weight:400;cursor:pointer;
  white-space:nowrap;
}
.ra-person-perm .tab-btn:hover{background:rgba(212,175,55,.22);}
.ra-person-perm .tab-btn i{font-size:11px;}

/* ── THE LOADING STATE (design) ──────────────────────────────────────
   A skeleton of the grid, so the shape of what is coming is on screen at
   once. It was a single spinning circle in an empty table, which reads as
   a hang. Design measurements: disc 38, text lines 13, cell blocks 56,
   name column 150, gap 12 in a row and 14 between rows. */
.ra-skel-cell{padding:16px 8px !important;}
.ra-skel{
  display:flex;flex-direction:column;gap:14px;
  padding:16px;border:1px solid var(--border);border-radius:16px;
  background:rgba(255,255,255,.05);
}
.ra-skel-row{display:flex;align-items:center;gap:12px;}
.ra-skel-av{width:38px;height:38px;border-radius:50%;flex:0 0 auto;}
.ra-skel-id{flex:0 0 150px;display:flex;flex-direction:column;gap:8px;}
.ra-skel-id .skel{height:13px;display:block;}
.ra-skel-cellblock{flex:1 1 auto;height:56px;}
/* The skeleton shimmer. `shim` is used by the portal's skeletons everywhere
   but is defined in each page's OWN sheet, and rota.css had only
   `shimmerLine`, which is a different animation. A grep for "@keyframes shim"
   matched shimmerLine as a prefix and told me it was there; the test that
   checks used-against-defined caught the truth. */
@keyframes shim{from{background-position:200% 0;}to{background-position:-200% 0;}}
.ra-skel .skel{
  border-radius:8px;
  background:linear-gradient(90deg,rgba(255,255,255,.05),rgba(255,255,255,.11),rgba(255,255,255,.05));
  background-size:200% 100%;
  animation:shim 1.25s linear infinite;
}
@media(max-width:820px){ .ra-skel .hide-sm{display:none;} }

/* ── PUBLISHED IS VISIBLE TO EVERYONE ────────────────────────────────
   The design's published cell is a gold border over a gold tint with a
   padlock, and that is a fact about the WEEK, not about the reader. Ours
   applied it through `.locked`, which is `isLive && !canOverridePublished()`,
   so the people who publish saw no tint at all: a published cell and a draft
   cell differed by one small padlock and one word. Now every reader sees the
   state, and the padlock still says whether they may write over it. */
.alloc-cell.is-published{
  /* NEVER `border-color` here. The shift colour is carried as an INLINE
     border-top-color (MORNING gold, AFTERNOON sky, FULL_DAY green, OVERTIME
     orange, TRAINING purple, SHADOWING teal) and the shorthand with
     !important overrides an inline style, so every published cell went
     uniformly gold and the whole colour system disappeared from a live week.
     The three sides that carry no meaning are tinted; the TOP is left to the
     shift. */
  border-right-color:rgba(240,200,50,.34);
  border-bottom-color:rgba(240,200,50,.34);
  border-left-color:rgba(240,200,50,.34);
  background:rgba(212,175,55,.10);
}
/* A draft cell stays neutral, which is what makes the gold mean something. */
.alloc-cell.is-published .ra-cellmeta{color:var(--gold);}

/* The published padlock is GOLD, as the design has it. Ours was red, which is
   the colour this board uses for a MISSED shift everywhere else, so a
   published cell was wearing the alarm colour. The open variant is gone with
   it: a published shift is locked, whoever is looking. */
.cell-lock-icon.pub-lock{color:var(--gold);opacity:.85;}

/* ── THE DESIGN'S TEN CELL STATES, exact values ──────────────────────
   Diffed head to head against the design's CELL map by COMPUTED style.
   Seven of ten did not match: off, balanced and permanent had no rule at
   all, debt was gold where the design is red, unsubmitted was solid where
   the design is dashed, and the neutral border was .23 against .21. */
.alloc-cell{border-color:rgba(255,255,255,.21);}
.alloc-cell.is-off{
  border-color:rgba(255,255,255,.34);border-style:dashed;background:transparent;
}
.balanced-col .alloc-cell{
  box-shadow:inset 3px 0 0 var(--green);
  border-color:rgba(76,214,87,.40);background:rgba(67,177,75,.12);
}
.unsubmitted-col .alloc-cell{border-style:dashed;}
.alloc-cell.is-permanent{
  border-color:rgba(240,200,50,.34);
  background:repeating-linear-gradient(135deg, rgba(212,175,55,.14) 0 7px, rgba(212,175,55,.05) 7px 14px);
}
/* The design's active and missed backgrounds are .12; ours were .10. */
.active-col .alloc-cell{background:rgba(67,177,75,.12);}
.missed-col .alloc-cell{background:rgba(232,64,64,.12);}

/* ── THE LEAVE RAIL ROW (design) ─────────────────────────────────────
   Design values: row flex, align centre, gap 11, padding 12, radius 12,
   1px border in the leave tone over a tint of it; a 34px initials disc,
   mono 13px, on rgba(255,255,255,.10) with a rgba(255,255,255,.34)
   border; the name 13px/600; the type line mono 13px in the tone,
   3px under the name; and a padlock, 11px, rgba(242,247,238,.68),
   which ours did not draw at all. */
#leave-sidebar-body{display:flex;flex-direction:column;gap:9px;padding:12px;}
.ra-leaverow{
  display:flex;align-items:center;gap:11px;
  padding:12px;border:1px solid var(--border);border-radius:12px;
  animation:cvIn .38s cubic-bezier(.16,1,.3,1) both;
}
.ra-leaverow-av{
  width:34px;height:34px;flex:0 0 auto;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.34);
  font-family:var(--mono);font-size:13px;color:var(--text);
}
.ra-leaverow-id{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;}
.ra-leaverow-name{font-size:13px;font-weight:600;color:var(--text);}
.ra-leaverow-type{font-family:var(--mono);margin-top:3px;font-size:13px;}
.ra-leaverow-lock{flex:0 0 auto;font-size:11px;color:var(--t3);}
/* The design's own cvIn. LESSONS.md records that this exact name was once
   used on this board and defined in none of its six sheets, so it animated
   nothing. Defined here, where it is used. */
@keyframes cvIn{from{transform:translateY(10px);opacity:0;}to{transform:none;opacity:1;}}

/* ════════════════════════════════════════════════════════════════
   THE NAV DRAWER  (design, 2026-08-04)

   Same items as ours had, styled as plain rows where the design uses
   cards. Values are the design's own inline styles: panel min(320px,
   100vw) with 18px 16px padding, a gold right edge and the 165deg
   gradient; head disc 40px white with a 1.5px gold ring, title Cinzel
   18/600, role mono 13; section labels mono 13 at 1.6px tracking; every
   nav item a 48px card with a 1px border, 11px radius and a .028 fill;
   archive rows DASHED with a 44px delete; footer separated by a rule,
   test mode blue, exit red.
   ════════════════════════════════════════════════════════════════ */
#sidebar{
  width:min(320px,100vw);padding:18px 16px;overflow-y:auto;
  border-right:1px solid rgba(240,200,50,.34);
  background:linear-gradient(165deg,#172213,#111a0e);
}
.ra-drawer-head{display:flex;align-items:center;gap:11px;}
.ra-drawer-disc{
  width:40px;height:40px;flex:0 0 auto;border-radius:50%;overflow:hidden;
  background:#fff;border:1.5px solid var(--gold);
  display:flex;align-items:center;justify-content:center;
}
.ra-drawer-disc img{width:100%;height:100%;object-fit:contain;padding:3px;}
.ra-drawer-id{flex:1 1 auto;min-width:0;}
.ra-drawer-title{font-family:var(--disp),Cinzel,serif;font-size:18px;font-weight:600;color:var(--text);}
.ra-drawer-role{font-family:var(--mono);margin-top:3px;font-size:13px;color:var(--t3);}
.ra-drawer-x{
  width:44px;height:44px;flex:0 0 auto;cursor:pointer;
  border:1px solid var(--border);border-radius:10px;
  background:rgba(255,255,255,.05);color:var(--text);font-size:13px;
}
.ra-drawer-x:hover{background:rgba(255,255,255,.10);}

#sidebar .nav-section-label{
  padding:0 6px 8px;margin-top:18px;
  font-family:var(--mono);font-size:13px;letter-spacing:1.6px;
  text-transform:uppercase;color:var(--t3);
}
#sidebar .nav-item{
  display:flex;align-items:center;gap:11px;min-height:48px;padding:0 12px;
  border:1px solid var(--border);border-radius:11px;
  background:rgba(255,255,255,.028);color:var(--text);
  font-size:13px;text-align:left;cursor:pointer;margin-bottom:5px;
  animation:cvIn .38s cubic-bezier(.16,1,.3,1) both;
}
#sidebar .nav-item > i:first-child{width:15px;font-size:12px;color:var(--gold);flex:0 0 auto;}
#sidebar .nav-item > span:first-of-type{flex:1 1 auto;min-width:0;}
#sidebar .nav-item:hover{background:rgba(255,255,255,.07);}
#sidebar .nav-item.active{background:rgba(212,175,55,.16);border-color:rgba(240,200,50,.34);}
#sidebar #nav-network > i:first-child{color:var(--green);}
#sidebar .nav-item.danger{border-color:rgba(255,72,72,.45);background:rgba(232,64,64,.12);color:#ff8f8f;}
#sidebar .nav-item.danger > i:first-child{color:#ff8f8f;}
#sidebar #sa-test-nav{border-color:rgba(74,158,255,.40);background:rgba(74,158,255,.10);}
#sidebar #sa-test-nav > i:first-child{color:#4a9eff;}
#sidebar .ra-nav-badge{
  flex:0 0 auto;padding:2px 8px;border-radius:999px;
  border:1px solid rgba(240,200,50,.34);background:rgba(212,175,55,.14);
  font-family:var(--mono);font-size:13px;color:var(--gold);
}
#sidebar .ra-nav-badge:empty{display:none;}
#sidebar #archive-count{border-color:var(--border2,rgba(255,255,255,.34));background:transparent;color:var(--t2);}
#sidebar .nav-divider{height:1px;background:rgba(255,255,255,.12);margin:18px 0 16px;}

#archive-sub{display:flex;flex-direction:column;gap:7px;margin-top:8px;}

/* The design's cell name row: icon, value, pip; mono 13 with .4px tracking
   and the value truncating rather than wrapping. */
.ra-cellname.is-stated{display:flex;align-items:center;gap:7px;width:100%;min-width:0;}
.ra-cellname-txt{
  flex:1 1 auto;min-width:0;font-family:var(--mono);font-size:13px;letter-spacing:.4px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.ra-cellmeta:empty{display:none;}

/* ── THE STRIPS, diffed against the design's CELL map ─────────────────
   Left strip: missed, debt and balanced only. Top strip: permanent only,
   and DASHED, which is the warning that changing it changes a pattern and
   not just a week. Ours also striped active and unsubmitted, which the
   design does not: active is signalled by the breathing pip and
   unsubmitted by its dashed edge, so the extra strips were noise. */
.active-col .alloc-cell,
.unsubmitted-col .alloc-cell{box-shadow:none;}
.alloc-cell.is-permanent{position:relative;}
.alloc-cell.is-permanent::before{
  content:'';position:absolute;top:0;height:3px;pointer-events:none;
  /* INSET and clipped to the rounded box. The strip was left:0;right:0 on a
     cell with an 11px radius and overflow:visible, so its square corners
     jutted past the cell's rounded ones: the VP saw the yellow ribbon
     overflowing. Inset by the radius and given the same rounding, it stops
     inside the corner instead of cutting across it. */
  left:11px;right:11px;
  border-radius:0 0 2px 2px;
  background:repeating-linear-gradient(90deg,var(--gold) 0 5px,transparent 5px 10px);
}

/* Two tabs, so on a phone they share the row rather than sitting in a
   horizontal scroller: "Live network" ended 32px past a 320px viewport with
   nothing on screen to say it was there. The tray still scrolls if a third
   tab is ever added. */
@media(max-width:420px){
  .ra-viewtabs{overflow-x:visible;}
  .ra-viewtab{flex:1 1 0;min-width:0;padding:0 10px;justify-content:center;flex-shrink:1;}
  .ra-viewtab > span:not(.ra-viewtab-badge){overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
}

/* ── ONE SCROLLER IN THE DRAWER ──────────────────────────────────────
   #sidebar and .sidebar-inner BOTH had overflow-y:auto, so the inner one
   scrolled inside a panel that had room to spare: a scrollbar appeared
   over the nav with the outer panel not full. The design has a single
   <nav> that scrolls. The inner element also added its own 16/14/20
   padding on top of the panel's 18/16, which is why the items sat inset.
   The panel owns the padding and the scroll; the inner is a plain column. */
#sidebar .sidebar-inner{
  overflow:visible;
  padding:0;
  gap:0;
  flex:0 0 auto;
}
/* The footer group is pushed down only when there IS room, so it never
   forces a scrollbar of its own on a short window. */
#sidebar .nav-spacer{flex:1 1 auto;min-height:0;}

/* ── DRAFT ARCHIVES (design) ─────────────────────────────────────────
   Two faults, found by reading what _rtRenderDrafts actually emits rather
   than what I had styled:

   1. `.archive-sub.open` was `max-height:260px; overflow-y:auto` with a
      3px scrollbar. The design has no scroller: the drawer itself scrolls
      and the archive list is simply part of it. Four rows at 66px each
      never fitted 260px, so it always scrolled, on a bar almost nobody
      could see or grab.
   2. I had styled .ra-archive-row and friends. NOTHING renders those. The
      real classes are .archive-entry, .ra-arch-range, .ra-arch-saved and
      .archive-entry-del. Styling a class the code does not emit is the
      same as writing nothing.

   Design values: rows DASHED at 11px radius over a .028 fill, padding
   11px 12px, gap 7 between, and a 44px red delete button. */
.archive-sub{margin:8px 0 0;max-height:0;overflow:hidden;
  transition:max-height .4s cubic-bezier(.16,1,.3,1);}
.archive-sub.open{
  max-height:none;          /* no cap: the drawer is the scroller */
  overflow:visible;
  display:flex;flex-direction:column;gap:7px;
}
#sidebar .archive-entry{
  display:flex;align-items:center;gap:10px;justify-content:flex-start;
  padding:11px 12px;border:1px dashed rgba(255,255,255,.34);border-radius:11px;
  background:rgba(255,255,255,.028);
  font-size:13px;font-weight:400;letter-spacing:0;color:var(--text);cursor:pointer;
}
#sidebar .archive-entry:hover{background:rgba(255,255,255,.07);border-color:rgba(240,200,50,.34);color:var(--text);}
#sidebar .archive-entry > .u-flex-1{flex:1 1 auto;min-width:0;}
#sidebar .ra-arch-range{font-family:var(--mono);font-size:13px;font-weight:400;}
#sidebar .ra-arch-saved{font-family:var(--mono);font-size:13px;color:var(--t3);margin-top:3px;}
/* A 44px target, as the design draws it, not a 4px text link. */
#sidebar .archive-entry-del{
  width:44px;height:44px;flex:0 0 auto;padding:0;
  display:flex;align-items:center;justify-content:center;
  border:1px solid rgba(255,72,72,.45);border-radius:10px;
  background:rgba(232,64,64,.12);color:#ff8f8f;font-size:11px;
}
#sidebar .archive-entry-del:hover{background:rgba(232,64,64,.22);color:#ff8f8f;}
