/* ============================================================
   AssemblySite — Unified Stylesheet
   Merged from: site.css + dc.css + Blazor defaults
   Dark theme native | Mobile-first
   ============================================================ */

/* ── CSS Custom Properties (VDC theme — SP Red+Green) ── */
:root {
    /*  Corporate light. Same variable NAMES as the dark campaign palette this
        replaced, so the ~2,900 var() call sites did not have to change.  */
    --bg: #ffffff; --bg2: #161920; --bg3: #1f232c; --bg4: #232833;
    --border: #232833; --border2: #333b49;
    --text: #f5f7fa; --muted: #7c8494; --muted2: #aeb6c2;

    /*  Semantic hues are darkened against the dark-theme originals: #4caf50 on
        white is 2.8:1 and fails AA, #15803d is 4.6:1 and passes. Every value
        below clears 4.5:1 on --bg.  */
    --green: #15803d; --green-dim: rgba(21,128,61,0.10);
    --red: #b91c1c; --red-dim: rgba(185,28,28,0.10);
    --amber: #b45309; --amber-dim: rgba(180,83,9,0.10);
    --blue: #1d4ed8; --blue-dim: rgba(29,78,216,0.10);
    --cyan: #0e7490;
    --purple: #6d28d9; --purple-dim: rgba(109,40,217,0.10);

    /*  One accent across all seven sites: the product reads as one system, and
        users move between assembly/teams/booth on the same credentials.  */
    --primary: #1e40af;
    --accent: #2563eb; --accent-dim: rgba(37,99,235,0.10);
    --on-accent: #ffffff;

    --shadow-sm: 0 1px 2px rgba(15,23,42,0.06);
    --shadow: 0 1px 3px rgba(15,23,42,0.10), 0 1px 2px rgba(15,23,42,0.06);
    --shadow-lg: 0 10px 24px rgba(15,23,42,0.10);

    --mono: 'JetBrains Mono', ui-monospace, monospace;
    --sans: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --radius: 8px}

/* ── Reset & Base ── */
* { box-sizing: border-box}
html, body { margin:0; padding:0; background:#161920; color:var(--text); font-family:var(--sans); font-size:16px; line-height:1.4}
h1, h2, h3 { margin:0 0 8px}
h2 { font-size:20px}
h3 { font-size:16px}
a { color:var(--cyan); text-decoration:none !important}
a:hover { text-decoration:none !important}

/* ── Blazor framework styles ── */
.content { padding-top:1.1rem}
h1:focus { outline:none}
.valid.modified:not([type=checkbox]) { outline:1px solid #15803d}
.invalid { outline:1px solid #b91c1c}
.validation-message { color:#ff5c77}
.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem; color: white}
.blazor-error-boundary::after { content: "An error has occurred."}
.darker-border-checkbox.form-check-input { border-color: #333b49}
.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder { color: var(--bs-secondary-color, var(--muted)); text-align: end}
.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder { text-align: start}

/* ── Topbar ── */
.topbar { display:flex; justify-content:space-between; align-items:center; padding:10px 16px; color:var(--text); background:linear-gradient(90deg,#161920,#161920); border-bottom:1px solid rgba(185,28,28,.25); position:sticky; top:0; z-index:50; box-shadow:0 2px 12px rgba(0,0,0,.35)}
.topbar .brand { font-family:var(--mono); font-size:13px; font-weight:800; letter-spacing:.18em; color:var(--red); text-transform:uppercase; text-shadow:0 0 14px rgba(185,28,28,.4)}
.topbar a, .topbar span { color:var(--muted2); font-size:13px}
.topbar a { text-decoration:none}
.topbar .logout-btn { display:inline-block; padding:7px 16px; background:rgba(255,255,255,0.072); color:#f5f7fa; border:1px solid rgba(255,255,255,0.216); border-radius:8px; font-size:13px; font-weight:600; text-decoration:none; transition:all .15s; cursor:pointer}
.topbar .logout-btn:hover { background:rgba(185,28,28,.85); border-color:rgba(185,28,28,.95); transform:translateY(-1px)}

/* Layer-specific brand colors */
.topbar.layer-state         .brand { color:#fbbf24; text-shadow:0 0 16px rgba(161,98,7,.35)}
.topbar.layer-district      .brand { color:#c4b5fd; text-shadow:0 0 16px rgba(109,40,217,.35)}
.topbar.layer-parliamentary .brand { color:#60a5fa; text-shadow:0 0 16px rgba(29,78,216,.35)}
.topbar.layer-assembly      .brand { color:#ff5c77; text-shadow:0 0 16px rgba(185,28,28,.35)}
.topbar.layer-sector        .brand { color:#3fd37e; text-shadow:0 0 16px rgba(21,128,61,.35)}
.topbar.layer-booth         .brand { color:#fbbf24; text-shadow:0 0 16px rgba(180,83,9,.35)}

@media (max-width: 480px) {
    .topbar { padding:10px 12px}
    .topbar .brand { font-size:12px; letter-spacing:.10em}
    .topbar .logout-btn { padding:5px 12px; font-size:12px}
}

/* ── Main content ── */
.main { padding:16px; padding-bottom:60px; max-width:700px; margin:0 auto; flex:1; min-width:0}

/* ── Bottom navigation ── */
.bottombar { position:fixed; bottom:0; left:0; right:0; background:#161920; border-top:1px solid rgba(185,28,28,.18); display:flex; z-index:10}
.bottombar a { flex:1; text-align:center; text-decoration:none; color:var(--muted); font-family:var(--mono); font-size:11px; font-weight:700; letter-spacing:.1em; text-transform:uppercase; padding:12px 0}
/*  The bar is the only navigation below 1000px, and its links were about 39px
    tall (11px x 1.4 + 24px padding) -- under the 44px floor the rest of the app
    keeps. It is also driven by WarRoomDestinations now, so a statewide account
    can carry nine labels: the bar scrolls sideways instead of crushing them. */
.bottombar { overflow-x:auto; -webkit-overflow-scrolling:touch; scrollbar-width:none}
.bottombar::-webkit-scrollbar { display:none}
.bottombar a { flex:1 0 auto; min-height:44px; display:flex; align-items:center; justify-content:center; padding:0 12px; white-space:nowrap}
.bottombar a.active { color:var(--on-accent); background:var(--red); border-radius:6px}
.bottombar a:active { color:var(--red)}

/* ── Page header ── */
.page-header { display:flex; align-items:flex-start; justify-content:space-between; margin-bottom:24px; gap:16px}
.page-title { font-family:var(--mono); font-size:17px; font-weight:700; color:var(--text)}
.page-subtitle { font-size:13px; color:var(--muted); margin-top:3px}
.page-actions { display:flex; gap:8px; align-items:center; flex-shrink:0; flex-wrap:wrap}

/* ── Section header ── */
.section-hdr { font-family:var(--mono); font-size:11px; letter-spacing:.18em; color:var(--muted); text-transform:uppercase; border-bottom:1px solid var(--border); padding-bottom:7px; margin-bottom:14px}

/* ── Stat cards ── */
.cards-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(155px,1fr)); gap:10px; margin-bottom:24px}
.col-span-2 { grid-column:span 2}
.cards-grid-8 { display:grid; grid-template-columns:repeat(8,minmax(0,1fr)); gap:10px; margin-bottom:24px}
.cards-grid-7 { display:grid; grid-template-columns:repeat(7,minmax(0,1fr)); gap:10px; margin-bottom:24px}
@media(max-width:700px){ .cards-grid-8,.cards-grid-7{grid-template-columns:repeat(2,minmax(0,1fr))} }

.stat-card { background:var(--bg2); border:1px solid var(--border); border-radius:var(--radius); padding:14px 16px; position:relative; overflow:hidden}
.stat-card.c-green  { border-top:2px solid var(--green)}
.stat-card.c-red    { border-top:2px solid var(--red)}
.stat-card.c-amber  { border-top:2px solid var(--amber)}
.stat-card.c-blue   { border-top:2px solid var(--blue)}
.stat-card.c-cyan   { border-top:2px solid var(--cyan)}
.stat-card.c-purple { border-top:2px solid var(--purple)}
.stat-card.c-gray   { border-top:2px solid #333b49}

.card-label { font-family:var(--mono); font-size:11px; letter-spacing:.12em; color:var(--muted); text-transform:uppercase; margin-bottom:8px}
.card-value { font-family:var(--mono); font-size:24px; font-weight:700; line-height:1; margin-bottom:5px}
.c-green  .card-value { color:var(--green)}
.c-red    .card-value { color:var(--red)}
.c-amber  .card-value { color:var(--amber)}
.c-blue   .card-value { color:var(--blue)}
.c-cyan   .card-value { color:var(--cyan)}
.c-purple .card-value { color:var(--purple)}
.c-gray   .card-value { color:#aeb6c2}
.card-sub { font-family:var(--mono); font-size:10px; color:var(--muted)}

/* ── Progress bar ── */
.progress-box { background:var(--bg2); border:1px solid var(--border); border-radius:var(--radius); padding:18px 22px; margin-bottom:24px}
.progress-top { display:flex; justify-content:space-between; align-items:baseline; margin-bottom:10px}
.progress-pct { font-family:var(--mono); font-size:18px; font-weight:700; color:var(--green)}
.progress-meta { font-family:var(--mono); font-size:10px; color:var(--muted)}
.prog-track { height:8px; background:var(--bg4); border-radius:4px; overflow:hidden; display:flex; gap:1px}
.prog-seg { height:100%; border-radius:3px; transition:width .5s ease}
.seg-done { background:var(--green)} .seg-fail { background:var(--red)} .seg-nf { background:var(--border2)} .seg-ip { background:var(--amber)}
.prog-legend { display:flex; flex-wrap:wrap; gap:14px; margin-top:8px}
.leg { display:flex; align-items:center; gap:5px; font-family:var(--mono); font-size:10px; color:var(--muted)}
.leg-dot { width:7px; height:7px; border-radius:2px; flex-shrink:0}

/* ── Two-column layout ── */
.two-col { display:grid; grid-template-columns:1fr 1fr; gap:18px; margin-bottom:24px}
@media(max-width:1050px){ .two-col{grid-template-columns:1fr} }

/* ── Tables ── */
.table-wrap { background:var(--bg2); border:1px solid var(--border); border-radius:var(--radius); margin-bottom:24px}
.data-table { width:100%; border-collapse:collapse; font-size:12px}
.data-table th { background:var(--bg3); color:var(--muted); font-family:var(--mono); font-size:11px; letter-spacing:.1em; text-transform:uppercase; padding:8px 12px; text-align:left; border-bottom:1px solid var(--border); white-space:nowrap}
.data-table td { padding:8px 12px; border-bottom:1px solid var(--border); color:var(--muted2); font-family:var(--mono); font-size:11px}
.data-table tr:last-child td { border-bottom:none}
.data-table tr:hover td { background:var(--bg3)}
.data-table a { color:var(--cyan); text-decoration:none}
.data-table a:hover { text-decoration:underline}
.data-table th.sortable { cursor:pointer}
.data-table th.sortable:hover { color:var(--text)}

/* ── Bar chart (CSS only) ── */
.bar-chart { display:flex; flex-direction:column; gap:6px}
.bar-row { display:flex; align-items:center; gap:10px; font-family:var(--mono); font-size:10px}
.bar-label { width:80px; color:var(--muted); text-align:right; flex-shrink:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.bar-track { flex:1; height:18px; background:var(--bg4); border-radius:3px; overflow:hidden; position:relative}
.bar-fill { height:100%; border-radius:3px; transition:width .4s ease; display:flex; align-items:center; justify-content:flex-end; padding-right:6px; font-size:9px; font-weight:700}
.bar-value { width:60px; text-align:right; flex-shrink:0; color:var(--muted2)}
.bar { background:var(--green)}

/* ── PDA-G palette ── */
.pdag-p { color:var(--amber)} .pdag-d { color:var(--blue)} .pdag-a { color:var(--green)} .pdag-g { color:var(--purple)}
.bg-pdag-p { background:var(--amber)} .bg-pdag-d { background:var(--blue)} .bg-pdag-a { background:var(--green)} .bg-pdag-g { background:var(--purple)}
.pdag-tile { display:flex; flex-direction:column; align-items:center; justify-content:center}
.pdag-letter { font-size:40px; font-weight:800; font-family:var(--sans); line-height:1; margin-bottom:4px}
.pdag-p .pdag-letter { color:var(--amber)}
.pdag-d .pdag-letter { color:var(--blue)}
.pdag-a .pdag-letter { color:var(--green)}
.pdag-g .pdag-letter { color:var(--purple)}

/* ── Badges ── */
.badge { display:inline-block; font-family:var(--mono); font-size:11px; font-weight:700; letter-spacing:.06em; padding:2px 5px; border-radius:3px}
.badge-done    { background:var(--green-dim); color:var(--green)}
.badge-failed  { background:var(--red-dim); color:var(--red)}
.badge-ip      { background:var(--amber-dim); color:var(--amber)}
.badge-pending { background:var(--bg4); color:var(--muted2)}

/* ── Buttons ── */
.btn { display:inline-block; padding:10px 20px; background:var(--bg3); border:1px solid var(--border2); color:var(--text); font-family:var(--mono); font-size:11px; border-radius:var(--radius); text-decoration:none; cursor:pointer}
.btn:active, .btn:hover { background:var(--bg4)}
.page-actions .btn { font-size:10px; padding:5px 12px; white-space:nowrap}
.page-actions .btn-green { background:var(--green-dim); color:var(--green); border-color:var(--green)}
.pill { background:var(--green-dim); color:var(--green)}

/* Bootstrap overrides for dark theme */
.btn-primary { background-color:var(--green); border-color:var(--green); color:var(--on-accent)}
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus { box-shadow:0 0 0 0.1rem rgba(15,23,42,.1), 0 0 0 0.25rem rgba(21,128,61,.4)}

/* ── Cards ── */
.card { background:var(--bg2); border:1px solid var(--border); color:var(--text); border-radius:8px; padding:16px; margin-bottom:12px; box-shadow:0 1px 4px rgba(0,0,0,.18)}

/* ── Forms ── */
input[type=text], input[type=password], input[type=email], input[type=number], textarea, select {
    width:100%; box-sizing:border-box; padding:10px 12px; font-size:14px; font-family:var(--sans);
    background:var(--bg3); color:var(--text); border:1px solid var(--border2); border-radius:var(--radius); outline:none; transition:border-color .15s, box-shadow .15s}
input:focus, textarea:focus, select:focus { border-color:var(--cyan); box-shadow:0 0 0 2px rgba(14,116,144,.15)}
textarea { min-height:60px; resize:vertical}
select { cursor:pointer; appearance:none; -webkit-appearance:none;
    background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14'><path d='M3 5 L7 9 L11 5' stroke='%2394a3b8' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-repeat:no-repeat; background-position:right 12px center; padding-right:34px}
.form-row { margin-bottom:14px}
.form-row label { display:block; font-family:var(--mono); font-size:11px; font-weight:600; color:var(--muted2); letter-spacing:.06em; text-transform:uppercase; margin-bottom:5px}

.edit-actions { display:flex; align-items:center; gap:10px; flex-wrap:wrap}
.btn-save { background:var(--green)!important; color:var(--on-accent)!important; border-color:var(--green)!important; font-weight:700; padding:10px 28px!important; font-size:13px!important}
.btn-save:hover { opacity:.9}
.btn-cancel { background:var(--bg3)!important; color:var(--muted2)!important; border:1px solid var(--border2)!important; padding:10px 22px!important; font-size:13px!important}
.btn-cancel:hover { background:var(--bg4)!important; color:var(--text)!important}

/* ── Status messages ── */
.err { color:var(--red); font-weight:600}
.ok  { color:var(--green); font-weight:600}
.err-text { color:var(--red)!important; font-size:10px}

/* ── Voter cards ── */
.voter-card { background:linear-gradient(135deg,#161920,#161920); border:1px solid rgba(21,128,61,0.10); border-radius:10px; margin-bottom:8px; overflow:hidden; border-left:3px solid var(--green); box-shadow:0 2px 12px rgba(0,0,0,.35); transition:transform .15s,box-shadow .15s}
.voter-card:hover { transform:translateY(-1px); box-shadow:0 4px 20px rgba(0,0,0,.45)}
.voter-card a { color:var(--cyan); text-decoration:none}
.voter-card a:active { text-decoration:underline}
.voter-card.vc-m { border-left-color:var(--blue); box-shadow:0 2px 12px rgba(0,0,0,.35),inset 0 0 0 1px rgba(29,78,216,.06)}
.voter-card.vc-f { border-left-color:#be185d; box-shadow:0 2px 12px rgba(0,0,0,.35),inset 0 0 0 1px rgba(190,24,93,.06)}

.vc-layout { display:flex; align-items:stretch}
.vc-srno { display:flex; align-items:center; justify-content:center; min-width:46px; padding:0 4px; font-family:var(--mono); font-size:15px; font-weight:800; color:var(--muted2); background:rgba(255,255,255,0.036); border-right:1px solid rgba(148,163,184,0.08); flex-shrink:0}
.vc-content { flex:1; min-width:0; padding:12px 14px}

.vc-row1 { display:flex; align-items:flex-start; gap:8px; margin-bottom:4px}
.vc-name { flex:1; min-width:0; font-size:15px; font-weight:700; color:#f5f7fa; line-height:1.35}
.vc-en { font-size:12px; font-weight:400; color:var(--muted2)}
.vc-edit { flex-shrink:0; padding:4px 12px; border-radius:6px; background:rgba(185,28,28,.10); border:1px solid rgba(185,28,28,.25); color:var(--red); text-decoration:none; font-family:var(--mono); font-size:10px; font-weight:700; white-space:nowrap; transition:all .15s; letter-spacing:.03em}
.vc-edit:hover { background:rgba(185,28,28,.20); border-color:var(--red); box-shadow:0 0 8px rgba(185,28,28,.2)}

.vc-row2 { display:flex; align-items:center; gap:8px; margin-bottom:5px; font-size:12px}
.vc-sur { color:var(--muted2); font-weight:500}
.vc-vid { font-family:var(--mono); font-size:10px; color:var(--green); letter-spacing:.03em; padding:2px 7px; background:rgba(21,128,61,.10); border:1px solid rgba(21,128,61,.15); border-radius:4px; font-weight:600}

.vc-row3 { display:flex; flex-wrap:wrap; gap:0; font-family:var(--mono); font-size:11px; color:var(--muted2); line-height:1.3}
.vc-row3 span { white-space:nowrap}
.vc-row3 span::after { content:"\00b7"; margin:0 5px; color:var(--muted); opacity:.4}
.vc-row3 span:last-child::after { display:none}
.vc-row3 .vc-ph { color:var(--green)}
.vc-row3 .vc-pty { color:var(--blue); font-weight:700}

/* ── Tile grid ── */
.tile-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:14px; padding:16px}
.tile { background:var(--bg2); border:1px solid var(--border); border-radius:12px; padding:16px; text-align:center; text-decoration:none; color:var(--text); box-shadow:0 2px 8px rgba(0,0,0,.25); transition:transform .15s,box-shadow .15s,border-color .15s}
.tile:active { transform:scale(0.97)}
.tile:hover { box-shadow:0 4px 20px rgba(0,0,0,.35); border-color:var(--border2)}
.tile img { width:80px; height:80px; object-fit:contain}
.tile h5 { margin:8px 0 0; font-size:14px; font-weight:600; color:var(--muted2)}

/* ── Picker bar ── */
.pdc-picker { display:grid; grid-template-columns:auto 1fr; gap:10px; align-items:center; width:100%; margin:14px 0 22px}
@media(max-width:600px){ .pdc-picker{grid-template-columns:1fr} }
.pdc-picker-lbl { font-family:var(--mono); font-size:11px; color:var(--muted2); text-transform:uppercase; letter-spacing:.14em; font-weight:700}
.pdc-picker-sel {
    appearance:none; -webkit-appearance:none; cursor:pointer; width:100%; max-width:420px;
    background-color:var(--bg3);
    background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14'><path d='M3 5 L7 9 L11 5' stroke='%2394a3b8' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-repeat:no-repeat; background-position:right 12px center;
    color:var(--text); border:1px solid var(--border2); border-radius:8px;
    padding:9px 34px 9px 12px; font-family:var(--mono); font-size:13px; font-weight:500}
.pdc-picker-sel:focus { outline:none; border-color:#0e7490; box-shadow:0 0 0 2px rgba(14,116,144,.18)}
.pdc-picker-sel option { background:var(--bg2); color:var(--text)}

/* ── Geo bar ── */
.geo-bar { display:flex; flex-wrap:wrap; gap:10px; align-items:center; margin:14px 0 22px}
.geo-bar select { appearance:none; -webkit-appearance:none; background:var(--bg3); color:var(--text); border:1px solid var(--border2); border-radius:8px; padding:9px 12px; font-family:var(--mono); font-size:13px; font-weight:500}

/* ── Booth Picker ── */
.bp-bar { display:flex; align-items:center; gap:10px; padding:10px 14px; margin:0 0 12px; background:linear-gradient(135deg,#161920,#161920); border:1px solid rgba(21,128,61,0.10); border-radius:var(--radius); flex-wrap:wrap}
.bp-lbl { font-family:var(--mono); font-size:10px; font-weight:600; color:var(--muted); text-transform:uppercase; letter-spacing:.08em; white-space:nowrap}
.bp-sel { flex:1; min-width:140px; padding:8px 30px 8px 10px; font-family:var(--mono); font-size:12px; background:var(--bg3); color:var(--text); border:1px solid var(--border2); border-radius:var(--radius); outline:none; appearance:none; -webkit-appearance:none; cursor:pointer; background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14'><path d='M3 5 L7 9 L11 5' stroke='%2394a3b8' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>"); background-repeat:no-repeat; background-position:right 10px center}
.bp-sel:focus { border-color:var(--cyan); box-shadow:0 0 0 2px rgba(14,116,144,.15)}

/* ── Search box ── */
.search-box { background:var(--bg3); border:1px solid var(--border2); color:var(--text); font-family:var(--mono); font-size:12px; padding:7px 12px; border-radius:var(--radius); outline:none; width:260px}
.search-box:focus { border-color:var(--cyan)}

/* ── Filter bar ── */
.filter-header { font-family:var(--mono); font-size:15px; font-weight:700; color:var(--text); padding:14px 0 4px; letter-spacing:.02em}
.filter-bar { display:flex; align-items:center; gap:10px; padding:10px 14px; margin:6px 0 10px; background:linear-gradient(135deg,#161920,#161920); border:1px solid rgba(21,128,61,0.10); border-radius:var(--radius); flex-wrap:wrap; box-shadow:0 2px 10px rgba(0,0,0,.3)}
.filter-bar label { font-family:var(--mono); font-size:10px; font-weight:600; color:var(--muted); text-transform:uppercase; letter-spacing:.08em; white-space:nowrap}
.filter-bar select, .filter-bar input[type=text] { flex:1; min-width:120px; padding:9px 12px; font-family:var(--mono); font-size:13px; background:var(--bg3); color:var(--text); border:1px solid var(--border2); border-radius:var(--radius); outline:none; transition:border-color .15s,box-shadow .15s; appearance:none; -webkit-appearance:none}
.filter-bar select { background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14'><path d='M3 5 L7 9 L11 5' stroke='%2394a3b8' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>"); background-repeat:no-repeat; background-position:right 10px center; padding-right:30px; cursor:pointer}
.filter-bar select:focus, .filter-bar input[type=text]:focus { border-color:var(--cyan); box-shadow:0 0 0 2px rgba(14,116,144,.15)}
.filter-bar .btn { background:var(--green); color:var(--on-accent); border:none; padding:9px 18px; font-family:var(--mono); font-size:11px; font-weight:700; border-radius:var(--radius); cursor:pointer; letter-spacing:.04em; text-transform:uppercase; transition:opacity .15s}
.filter-bar .btn:hover { opacity:.85}
.filter-results-count { font-family:var(--mono); font-size:12px; color:var(--muted2); padding:4px 0 8px; letter-spacing:.02em}

/* ── Letter picker ── */
.letter-picker { display:flex; flex-wrap:wrap; gap:4px; padding:8px 16px}
.letter-picker a { padding:4px 8px; background:var(--bg3); color:var(--muted2); border:1px solid var(--border); text-decoration:none; border-radius:4px; font-size:12px}
.letter-picker a.active { background:var(--red); color:var(--on-accent); border-color:var(--red); font-weight:700}

/* ── Surname Cloud ── */
.surname-cloud { display:flex; flex-wrap:wrap; gap:6px 10px; align-items:baseline; padding:14px; margin:8px 0 12px; background:linear-gradient(135deg,#161920,#161920); border:1px solid rgba(21,128,61,0.10); border-radius:var(--radius); line-height:1.6; box-shadow:0 2px 10px rgba(0,0,0,.3)}
.sc-tag { text-decoration:none; color:var(--muted2); font-family:var(--sans); transition:color .15s; white-space:nowrap}
.sc-tag:hover { color:var(--accent)}
.sc-tag.sc-active { color:var(--accent); font-weight:700}
.sc-tag .sc-cnt { font-size:inherit; color:var(--muted); font-family:var(--mono); font-weight:400}

/* ── Pager ── */
.pager { display:flex; flex-wrap:wrap; gap:4px; justify-content:center; padding:16px 0; margin:12px 0}
.pager-btn { display:inline-flex; align-items:center; justify-content:center; min-width:36px; height:36px; padding:0 10px; border-radius:var(--radius); font-size:13px; font-weight:600; color:var(--text); background:var(--bg2); border:1px solid var(--border); text-decoration:none; cursor:pointer; transition:background .15s,border-color .15s}
.pager-btn:hover { background:var(--bg3); border-color:var(--border2)}
.pager-btn.active { background:var(--accent); color:var(--on-accent); border-color:var(--accent)}
.pager-btn.disabled { opacity:.35; cursor:default; pointer-events:none}
.pager-dots { display:inline-flex; align-items:center; padding:0 4px; color:var(--muted)}

/* ── Back link ── */
.back-link { display:inline-block; margin-top:16px; font-family:var(--mono); font-size:12px; color:var(--cyan); text-decoration:none; padding:6px 0}
.back-link:hover { text-decoration:underline}

/* ── Text helpers ── */
.text-muted  { color:var(--muted)}
.text-muted2 { color:var(--muted2)}
.text-green  { color:var(--green)}
.text-red    { color:var(--red)}
.text-amber  { color:var(--amber)}
.text-blue   { color:var(--blue)}
.text-cyan   { color:var(--cyan)}
.text-purple { color:var(--purple)}
.mono { font-family:var(--mono)}
.mb24 { margin-bottom:24px}

/* ── Stat grid ── */
.stat-grid > div { color:var(--muted2)}

/* ── Login page ── */

/* Assembly layer theme */
body.layer-assembly { --layer-primary: #1d4ed8; --layer-secondary: #1d4ed8}

/* Voter Card */
.voter-card{background:var(--bg2,#161920);border:1px solid rgba(255,255,255,0.096);border-radius:10px;padding:12px;margin-bottom:8px}
.voter-card.vc-m{border-left:3px solid #1d4ed8}
.voter-card.vc-f{border-left:3px solid #be185d}
.vc-head{display:flex;justify-content:space-between;font-size:12px;color:#aeb6c2;margin-bottom:4px}
.vc-name{font-size:15px;font-weight:700;color:#f5f7fa}
.vc-hname{font-size:13px;color:#aeb6c2;margin-top:2px}
.vc-detail{font-size:12px;color:#60a5fa;margin-top:6px;display:flex;gap:12px}
.vc-tag{display:inline-block;font-size:11px;background:rgba(255,255,255,0.072);border-radius:4px;padding:2px 8px;margin-top:6px;color:#aeb6c2}
/* Pager */
.pager{display:flex;align-items:center;justify-content:center;gap:12px;padding:12px}
.pager button{background:var(--bg2,#161920);border:1px solid rgba(255,255,255,0.12);color:#f5f7fa;padding:6px 16px;border-radius:6px;cursor:pointer}
.pager button:disabled{opacity:.4;cursor:default}
.pager .pager-info{font-size:13px;color:#aeb6c2}
/* Booth Picker */
.booth-picker select{width:100%;padding:8px 12px;background:var(--bg2,#161920);border:1px solid rgba(255,255,255,0.12);border-radius:8px;color:#f5f7fa;font-size:14px}

/* ── Ported-page primitives (carried over from the DistrictWeb stylesheet so the
      pages ported out of PDAProject/WarRoomWeb keep the house classes) ── */
.btn-sm { padding:4px 10px; font-size:10px}
.btn-danger { background:var(--red-dim); color:var(--red); border-color:var(--red)}
.form-card { background:var(--bg2); border:1px solid var(--border); border-radius:var(--radius); padding:18px; margin-bottom:24px}
.msg-err { font-family:var(--mono); font-size:12px; color:var(--red); background:var(--red-dim);
           border:1px solid var(--red); border-radius:var(--radius); padding:12px 14px; margin-bottom:16px}
.count-badge { flex:0 0 auto; font-family:var(--mono); font-size:11px; color:var(--cyan);
               background:var(--bg3); border:1px solid var(--border2); border-radius:var(--radius); padding:5px 10px}
/*  A neutral note: something the reader should know that is not a fault. Before
    this existed, explanatory boxes borrowed .msg-err and every visit to a board
    opened on a red panel that reported no error. */
.msg-note { font-family:var(--mono); font-size:12px; line-height:1.55; color:var(--muted2); background:var(--bg2);
            border:1px solid var(--border2); border-left:3px solid var(--border2); border-radius:var(--radius);
            padding:12px 14px; margin-bottom:16px}
.empty-row { text-align:center; padding:28px 12px !important; color:var(--muted); font-style:italic}


/* ── Account login card (/Account/Login) ──
   Phone-first: these apps render inside a MAUI WebView, so the card stays
   narrow, tap targets stay >= 44px and the inputs stay at 16px so iOS does
   not zoom the viewport on focus. Accent is set per app on .login-card. */
/*  Centred both ways. This was align-items:flex-start, which pinned the card
    to the top of a full-height flex container - horizontally centred, but
    sitting under the topbar with the rest of the viewport empty below it.
    The six projects that style .login-wrap inline in Login.razor already
    centre it this way; these six were the odd ones out.

    min-height uses svh where supported so the card does not jump when a
    mobile browser's address bar collapses; vh is the fallback.            */
.login-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 80vh;
    min-height: 80svh;
    padding: 24px 16px}
.login-card { --login-accent:var(--accent); --login-ink:var(--on-accent); width:100%; max-width:360px; background:var(--bg2); border:1px solid var(--border2); border-radius:14px; padding:24px 20px; box-shadow:0 12px 32px rgba(0,0,0,.45)}
.login-header { text-align:center; margin-bottom:20px}
.login-logo { font-size:40px; line-height:1; margin-bottom:8px}
.login-title { font-family:var(--mono); font-size:20px; font-weight:800; letter-spacing:.10em; text-transform:uppercase; color:var(--login-accent, var(--accent)); margin:0 0 4px}
.login-sub { color:var(--muted); font-size:12px; margin:0}
.login-field { margin-bottom:14px}
.login-label { display:block; font-size:11px; font-weight:700; letter-spacing:.14em; text-transform:uppercase; color:var(--muted); margin-bottom:6px}
.login-input { width:100%; min-height:46px; padding:12px 14px; background:var(--bg); border:1px solid var(--border2); border-radius:10px; color:var(--text); font-size:16px; outline:none; transition:border-color .15s, box-shadow .15s}
.login-input:focus { border-color:var(--login-accent, var(--accent)); box-shadow:0 0 0 3px rgba(15,23,42,.07)}
/*  No opacity: #8e96a6 at .7 over #0e1014 was about 3.7:1; at full strength it is
    about 6:1. The fields carry visible labels, but a hint should still be legible. */
.login-input::placeholder { color:var(--muted); opacity:1}
.login-remember { margin-bottom:18px; color:var(--muted2); font-size:13px}
.login-remember label { display:flex; align-items:center; gap:10px; min-height:44px; margin:0; cursor:pointer}
.login-btn { width:100%; min-height:48px; padding:13px 20px; background:var(--login-accent, var(--accent)); border:none; border-radius:10px; color:var(--login-ink, var(--on-accent)); font-family:var(--mono); font-size:15px; font-weight:800; letter-spacing:.08em; text-transform:uppercase; cursor:pointer; transition:filter .15s, transform .1s}
.login-btn:hover { filter:brightness(1.08)}
.login-btn:active { transform:translateY(1px)}

/* ── Voter record (/voters/edit) ──────────────────────────────────────────
   Ported from AssemblyWeb's redesigned voter record. The old layout stacked
   .form-card/.form-row blocks with labels at 11px --muted2, which gave every
   section the same weight — nothing told you where the identity ended and the
   survey began. The hero + accented .vr-sec blocks restore that hierarchy.

   Accents are taken from WarRoomWeb's own tokens, not AssemblyWeb's greens:
   this app is red-accented, so --vr-accent falls back to --accent (#ef4444)
   and the identity chrome (hero rule, avatar, EPIC) is red rather than green.
   --green/--amber survive only where they carry status meaning, not identity. */

.vr-hero {
    background: linear-gradient(150deg, var(--bg3) 0%, var(--bg2) 60%);
    border: 1px solid var(--border2); border-left: 3px solid var(--accent);
    border-radius: 12px; padding: 16px; margin-bottom: 14px}
.vr-hero-top { display: flex; gap: 13px; align-items: center}
.vr-avatar {
    flex: 0 0 46px; width: 46px; height: 46px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(150deg, var(--accent), #b91c1c);
    color: #f5f7fa; font-family: var(--mono); font-size: 16px; font-weight: 800}
.vr-name { font-size: 18px; font-weight: 700; color: #f5f7fa; line-height: 1.25}
.vr-name-hi { font-size: 14px; color: var(--muted2); margin-top: 1px}
.vr-epic { font-size: 11px; color: var(--accent); margin-top: 4px; letter-spacing: .06em}

.vr-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 13px}
.vr-chip {
    font-family: var(--mono); font-size: 10.5px; color: var(--muted2);
    background: rgba(255,255,255,0.048); border: 1px solid var(--border2);
    border-radius: 999px; padding: 4px 10px; white-space: nowrap}
.vr-chip b { color: var(--text); font-weight: 700}
.vr-ok   { color: var(--green); border-color: var(--green)}
.vr-warn { color: var(--amber); border-color: var(--amber)}
/* P/D/A/G take WarRoomWeb's own bucket colours (.pdag-* above), not
   AssemblyWeb's — a voter's badge here must read the same hue as the same
   bucket on /voters/pdag and the PDA-G overview tiles. */
.vr-pdag { font-weight: 700}
.vr-pdag.pd-p { color: var(--amber);  border-color: var(--amber)}
.vr-pdag.pd-d { color: var(--blue);   border-color: var(--blue)}
.vr-pdag.pd-a { color: var(--green);  border-color: var(--green)}
.vr-pdag.pd-g { color: var(--purple); border-color: var(--purple)}

.vr-sec {
    background: var(--bg2); border: 1px solid var(--border);
    border-left: 3px solid var(--vr-accent, var(--accent));
    border-radius: 10px; margin-bottom: 12px; overflow: hidden}
.vr-sec-hdr {
    font-family: var(--mono); font-size: 10px; font-weight: 700;
    letter-spacing: .16em; text-transform: uppercase;
    color: var(--vr-accent, var(--accent));
    padding: 11px 14px 9px; border-bottom: 1px solid var(--border)}
.vr-list {
    padding: 2px 0;
    /* Two pairs across. One field per full-width line left most of the row empty,
       which pushed the later sections below the fold for no gain. */
    display: grid;
    grid-template-columns: 1fr 1fr}
/* Vertical rule between the columns, matching the horizontal one in weight. */
.vr-list > .vr-row:nth-child(odd) { border-right: 1px solid rgba(255,255,255,0.048)}
/* Both columns end at the last two children, not just the final one. */
.vr-list > .vr-row:nth-last-child(-n+2) { border-bottom: 0}
@media (max-width: 560px) {
    .vr-list { grid-template-columns: 1fr}
    .vr-list > .vr-row:nth-child(odd) { border-right: 0}
    .vr-list > .vr-row:nth-last-child(-n+2) { border-bottom: 1px solid rgba(255,255,255,0.048)}
    .vr-list > .vr-row:last-child { border-bottom: 0}
}
.vr-row {
    display: flex; align-items: baseline; gap: 12px;
    padding: 9px 14px; border-bottom: 1px solid rgba(255,255,255,0.048);
    min-width: 0;   /* let a long value shrink rather than widen its grid column */
}
.vr-row:last-child { border-bottom: 0}
.vr-k {
    flex: 0 0 42%; font-family: var(--mono); font-size: 10px;
    letter-spacing: .1em; text-transform: uppercase; color: var(--muted2)}
.vr-v { flex: 1 1 auto; min-width: 0; font-size: 13.5px; color: var(--text); word-break: break-word}
.vr-empty { color: var(--muted); opacity: .55}

/* survey form */
.vr-form { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 14px}
.vr-f { display: flex; flex-direction: column; gap: 4px; min-width: 0}
.vr-f.vr-wide { grid-column: 1 / -1}
.vr-f label {
    font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em;
    text-transform: uppercase; color: var(--muted2);
    /* .form-row label is display:block with a bottom margin; the flex column
       here owns the spacing, so neither is inherited. */
    display: block; margin: 0}
/* background-COLOR, never the `background` shorthand: the global `select` rule
   is appearance:none and draws its chevron as a background-image, which the
   shorthand would silently erase and leave the control looking like a text box. */
.vr-f select, .vr-f input, .vr-f textarea {
    width: 100%; background-color: var(--bg); color: var(--text);
    border: 1px solid var(--border2); border-radius: 7px;
    padding: 8px 10px; font-size: 13px; font-family: var(--sans)}
/* Same reason: keep room on the right for that chevron. */
.vr-f select { padding-right: 30px; background-position: right 10px center}
.vr-f select:focus, .vr-f input:focus, .vr-f textarea:focus {
    outline: none; border-color: var(--accent);
    box-shadow: 0 0 0 2px var(--accent-dim)}
/* sub-label under an input: the roll's age beside the date-of-birth box, and the
   "leave blank to keep it" note under a masked Aadhaar. */
.vr-hint {
    display: block; margin-top: 4px;
    font-size: 11px; line-height: 1.35; color: var(--muted, #7c8494)}
.vr-f.vr-check { flex-direction: row; align-items: center; gap: 8px}
.vr-f.vr-check input { width: auto}
.vr-f.vr-check label { text-transform: none; font-size: 12px; letter-spacing: 0}

.vr-actions {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 0 14px 14px}
/* Scoped to the record rather than redefining the global .btn-primary, which
   several other WarRoomWeb pages rely on being green. */
.vr-actions .btn-primary { background-color: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: 700}
.vr-actions .btn-primary[disabled] { opacity: .6; cursor: default}

@media (max-width: 560px) {
    .vr-form { grid-template-columns: 1fr}
    .vr-k { flex-basis: 46%}
}

/* ── Dropdown affordance ──
   Every <select> gets a visible chevron. Without it a select styled to match the
   surrounding inputs is indistinguishable from a text box, so nothing tells the
   user it opens a list -- which is exactly how the Category and Occupation
   fields on the voter form read.

   appearance:none removes the platform arrow (which is drawn light-on-light and
   effectively invisible in a dark WebView on Android), and the chevron is a data
   URI so it still renders with no network in the field. Padding on the right
   keeps a long option from running underneath it. */
select,
.vr-f select,
select.inp,
select.form-select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' stroke='%23cbd5e1' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 12px;
    padding-right: 30px}

/* The native popup inherits the page, not the control, so option colours are set
   explicitly or they come out unreadable on a dark theme. */
select option { background: #161920; color: #f5f7fa}

/* A multi-select or a sized list is not a dropdown and must not claim to be. */
select[multiple],
select[size]:not([size="1"]) {
    background-image: none;
    padding-right: 10px}

/*  Was an orphan: the rule sat indented with a closing brace and no opener,
    so the brace closed nothing and everything after it parsed one level out.
    Restored to the small screen query it was clearly written for. */
@media (max-width: 560px) {
    .hero-card .hero-title { font-size: 20px}
}

/* ════════════════════════════════════════════════════════════════════════
   HERO HEADERS  (each card declares a plain background before the color-mix
   one: a color-mix fallback, since an unsupported value voids the whole
   declaration and would leave the card transparent)
   ────────────────────────────────────────────────────────────────────────
   Every page title becomes a card, and it is done HERE rather than in the
   227 .razor files that render one. They all already share .page-header,
   so restyling the class reaches every page at once -- including the sixty
   that go through <VotersHeader> -- with no markup to get wrong and one
   place to tune afterwards.

   The existing per-family accent is kept, not replaced: --ph-accent is
   already green for /voters, cyan for /booth and purple for AI, and it now
   drives the rail, the wash and the glow together so a page still announces
   which family it belongs to.
   ════════════════════════════════════════════════════════════════════════ */

.page-header {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;

    padding: 15px 17px 15px 19px;
    margin-bottom: 20px;
    border-radius: 0 12px 12px 0;

    border: 1px solid rgba(255,255,255,0.09);
    border-left: 0;

    /*  A wash angled off the family accent, at low enough alpha that the card
        reads as lit from the rail rather than tinted a colour. The second
        layer is the flat panel underneath it. */
    background:
        linear-gradient(105deg,
            color-mix(in srgb, var(--ph-accent, var(--green)) 13%, transparent) 0%,
            color-mix(in srgb, var(--ph-accent, var(--green)) 4%, transparent) 40%,
            transparent 74%),
        var(--bg2, #161920);

    box-shadow:
        inset 0 1px 0 rgba(15,23,42,.035),
        0 6px 18px rgba(0, 0, 0, .28)}

/*  The rail was a 3px bar floated inside the old flat header; as a card edge it
    runs the full height and carries a soft bloom so it looks lit rather than
    drawn on. */
.page-header::before {
    content: "";
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 3px;
    border-radius: 0;
    background: var(--ph-accent, var(--green));
    box-shadow: 0 0 12px -1px var(--ph-accent, var(--green))}

.page-title {
    font-family: inherit;
    font-size: 21px;
    font-weight: 800;
    letter-spacing: -.012em;
    line-height: 1.16;
    color: var(--text);
    text-wrap: balance}

/*  Subtitle as an uppercase mono eyebrow: it is almost always a location or a
    count -- "Booth 101 · AC 100" -- which is reference data, not prose, and
    reads faster spaced out than set as a sentence. */
.page-subtitle,
.page-header .page-sub {
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--muted2, var(--muted));
    margin-top: 5px}

.page-hd { align-items: center; gap: 13px}

.page-icon,
.page-icon-svg {
    opacity: 1;
    margin-top: 0;
    filter: drop-shadow(0 2px 5px rgba(0, 0, 0, .45))}

.page-actions { align-self: center}

@media (max-width: 560px) {
    .page-header { padding: 13px 13px 13px 15px; border-radius: 0 10px 10px 0}
    .page-title  { font-size: 18px}
    .page-subtitle, .page-header .page-sub { font-size: 10px; letter-spacing: .09em}
}

/* ── Dashboard hero (Home) ────────────────────────────────────────────────
   Home names a place rather than a page, so it keeps its centred layout and
   gets the same card treatment around it. */
.bv-hero {
    position: relative;
    text-align: center;
    padding: 26px 18px 22px;
    margin: 0 0 22px;
    border-radius: 14px;
    border: 1px solid rgba(255,255,255,0.09);
    background: var(--bg2, #161920);
    background:
        radial-gradient(120% 130% at 50% -25%,
            color-mix(in srgb, var(--accent, #b45309) 15%, transparent) 0%,
            transparent 62%),
        var(--bg2, #161920);
    box-shadow:
        inset 0 1px 0 rgba(15,23,42,.04),
        0 8px 26px rgba(0, 0, 0, .32);
    overflow: hidden}

/*  A hairline across the top, brightest at the centre, so the card has a lip
    to catch the eye without a heavy border. */
.bv-hero::before {
    content: "";
    position: absolute;
    left: 12%; right: 12%; top: 0;
    height: 1px;
    background: linear-gradient(90deg,
        transparent,
        var(--accent, #b45309) 50%,
        transparent);
    opacity: .55}

.bv-hero h1 {
    font-size: clamp(19px, 5.2vw, 25px);
    font-weight: 800;
    letter-spacing: -.015em;
    line-height: 1.2;
    margin: 0;
    text-wrap: balance}

.bv-hero-sub {
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--muted2, var(--muted));
    margin: 9px 0 0}

/* ── Section headers ──
   The same rail idea one level down, so a section reads as belonging to the
   page above it rather than as another unrelated band. */
.section-hdr {
    position: relative;
    padding-left: 11px;
    margin-top: 22px}

.section-hdr::before {
    content: "";
    position: absolute;
    left: 0; top: 50%;
    width: 3px; height: 13px;
    transform: translateY(-50%);
    border-radius: 2px;
    background: var(--accent, #b45309);
    opacity: .8}

/* ── Splitters ────────────────────────────────────────────────────────────
   One divider treatment, reached three ways so no page needs new markup to
   get it: the .split utility, any bare <hr> (there are eleven across the
   apps and none of them were styled -- they rendered as the browser's grey
   default inset line on a dark page), and the footer back-link, which is the
   same "end of content" moment on 65 pages.

   A rule that fades at both ends reads as a divider; one that runs edge to
   edge reads as a border and implies the thing below is a different region.
   The diamond marks the centre so the line has a reason to be there. */

.split,
hr {
    position: relative;
    height: 1px;
    border: 0;
    margin: 20px 0 22px;
    background: linear-gradient(90deg,
        transparent,
        rgba(255,255,255,0.156) 18%,
        rgba(255,255,255,0.156) 82%,
        transparent);
    overflow: visible}

.split::after,
hr::after {
    content: "";
    position: absolute;
    left: 50%; top: 50%;
    width: 7px; height: 7px;
    transform: translate(-50%, -50%) rotate(45deg);
    background: var(--accent, #b45309);
    box-shadow: 0 0 0 4px var(--bg, #161920), 0 0 10px rgba(180,83,9,.45)}

/*  A plain rule, for places where the diamond would be one mark too many. */
.split-plain::after, hr.plain::after { display: none}

/*  End-of-page back link. The divider is drawn above the link rather than
    added as an element, so all 65 pages that already render one pick it up
    without being touched. Width is capped so it stays a divider and does not
    become a full-bleed border on a wide screen. */
.back-link {
    position: relative;
    display: inline-block;
    margin-top: 30px}

.back-link::before {
    content: "";
    position: absolute;
    left: 50%; top: -17px;
    transform: translateX(-50%);
    width: min(340px, 66vw);
    height: 1px;
    background: linear-gradient(90deg,
        transparent,
        rgba(255,255,255,0.144) 22%,
        rgba(255,255,255,0.144) 78%,
        transparent)}

/* ── Analysis hero (compact variant) ──
   Home and Analysis were the same centred card carrying the same @GeoName and
   subtitles two words apart, so switching tabs looked like nothing had
   happened. Home names a PLACE and is the front door, so it keeps the tall
   centred treatment. Analysis is a working screen, so it gets a shorter
   left-aligned band with an eyebrow: different silhouette, and it gives back
   the vertical space to the charts that are the actual content. */
.bv-hero.hero-work {
    text-align: left;
    padding: 14px 16px 14px 18px;
    border-radius: 0 12px 12px 0;
    background: var(--bg2, #161920);
    background:
        linear-gradient(100deg,
            color-mix(in srgb, var(--purple, #6d28d9) 13%, transparent) 0%,
            color-mix(in srgb, var(--purple, #6d28d9) 4%, transparent) 42%,
            transparent 76%),
        var(--bg2, #161920)}

/*  Rail instead of the top hairline, so the two heroes do not even share an
    edge treatment. */
.bv-hero.hero-work::before {
    left: 0; right: auto; top: 0; bottom: 0;
    width: 3px; height: auto;
    background: var(--purple, #6d28d9);
    box-shadow: 0 0 12px -1px var(--purple, #6d28d9);
    opacity: 1}

.bv-hero.hero-work .hero-eyebrow {
    display: block;
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--purple, #c4b5fd);
    margin: 0 0 5px}

.bv-hero.hero-work h1 {
    font-size: clamp(16px, 4.2vw, 19px);
    line-height: 1.25;
    text-wrap: balance}

.bv-hero.hero-work .bv-hero-sub {
    margin-top: 6px;
    letter-spacing: .09em}

/* ── Centred page header ──
   For a hub screen whose header names the place rather than labelling a list.
   Same card, same family rail, stacked and centred so it reads as an opening
   rather than a row of controls. */
.page-header.ph-center {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 10px;
    padding: 17px 16px 16px}

.page-header.ph-center > div { width: 100%}
.page-header.ph-center .page-actions { align-self: center}

/*  The rail would sit off to one side of centred text, so a centred header
    takes the hairline the dashboard hero uses instead. */
.page-header.ph-center::before {
    left: 12%; right: 12%; top: 0; bottom: auto;
    width: auto; height: 1px;
    background: linear-gradient(90deg, transparent,
        var(--ph-accent, var(--green)) 50%, transparent);
    box-shadow: none;
    opacity: .6}

.page-header.ph-center { border-left: 1px solid rgba(255,255,255,0.09); border-radius: 12px}

/* ── Centred hero background ──
   A plain panel under centred text looked empty, so the card gets three
   layers, all pure CSS so nothing has to load in the field:

     1. a soft dome of the family accent rising from the top edge,
     2. a fine diagonal weave at very low alpha for texture,
     3. the flat panel underneath.

   The weave is 1px lines on a 7px repeat -- close enough to read as a surface
   rather than as stripes, and it sits under the text at 2.5% so it never
   competes with it. */
.page-header.ph-center {
    background: var(--bg2, #161920);
    background:
        radial-gradient(125% 150% at 50% -30%,
            color-mix(in srgb, var(--ph-accent, var(--green)) 20%, transparent) 0%,
            color-mix(in srgb, var(--ph-accent, var(--green)) 5%, transparent) 38%,
            transparent 66%),
        repeating-linear-gradient(135deg,
            rgba(255,255,255,0.03) 0px,
            rgba(255,255,255,0.03) 1px,
            transparent 1px,
            transparent 7px),
        var(--bg2, #161920);
    overflow: hidden}

/*  A faint bloom behind the title, so the centre of the card is the brightest
    point and the eye lands on the name first. */
.page-header.ph-center .page-title {
    position: relative;
    text-shadow: 0 0 26px color-mix(in srgb, var(--ph-accent, var(--green)) 32%, transparent)}

/*  Corner ticks: two short rules at the lower corners that stop the textured
    panel from ending abruptly. */
.page-header.ph-center::after {
    content: "";
    position: absolute;
    left: 18%; right: 18%; bottom: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent,
        color-mix(in srgb, var(--ph-accent, var(--green)) 45%, transparent) 50%,
        transparent);
    opacity: .5}

/*  first-thing tightening: <main> pads 16px all round, which suits a page that
    opens with text but leaves a visible band above a card meant to sit just
    under the top bar. */
main.main > .comms-row:first-child,
main.main > .page-header:first-child,
main.main > .bv-hero:first-child { margin-top: -6px}
/* ── Booth combobox ──
   A text input bound to a <datalist>: type a number or part of the name and the
   browser narrows the suggestions. Replaces a <select> that listed ~440 booths
   with no way in but scrolling.

   Sized and coloured to match the selects beside it so the filter bar still
   reads as one row of controls, and given the same chevron so it is obviously
   a list and not a free-text field. */
.bc-input {
    min-width: 210px;
    flex: 1 1 210px;
    padding: 7px 28px 7px 11px;
    border-radius: 8px;
    border: 1px solid rgba(255,255,255,0.168);
    background-color: rgba(255,255,255,0.06);
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' stroke='%23cbd5e1' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 9px center;
    background-size: 12px;
    color: var(--text);
    font-family: inherit;
    font-size: 13px}

.bc-input::placeholder { color: var(--muted2, var(--muted)); opacity: .75}
.bc-input:focus { outline: none; border-color: var(--accent)}

/*  Typed text that does not resolve to a booth yet. Not an error -- it is what
    a half-finished word looks like -- so it warns rather than shouts, and the
    previously chosen booth is still what would submit. */
.bc-input.bc-bad { border-color: var(--amber, #b45309)}

/*  Chromium draws its own dropdown arrow inside a datalist input on some
    builds; ours is already in the background. */
.bc-input::-webkit-calendar-picker-indicator { opacity: 0}

@media (max-width: 480px) {
    .bc-input { min-width: 0; width: 100%; flex-basis: 100%}
}

/* ── Booth combobox dropdown ──
   Drawn here rather than by a native <datalist>. On Android the WebView renders
   datalist suggestions as an unstyled list that floats over the page, ignores
   the theme and clips every booth name mid-word -- the number and the name
   arrive as one truncated string. This list is ordinary markup, so it is
   themed, scrollable, and can show the number and the name as two things. */
.bc-host { position: relative; display: inline-flex; flex: 1 1 240px; min-width: 0}

.bc-list {
    position: absolute; left: 0; right: 0; top: calc(100% + 4px);
    z-index: 60;
    max-height: min(52vh, 340px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    background: var(--bg2, #161920);
    border: 1px solid rgba(255,255,255,0.168);
    border-radius: 10px;
    box-shadow: 0 12px 34px rgba(0, 0, 0, .55);
    padding: 4px}

.bc-item {
    display: flex; align-items: baseline; gap: 9px;
    padding: 9px 10px;
    border-radius: 7px;
    cursor: pointer;
    line-height: 1.25}

.bc-item + .bc-item { border-top: 1px solid rgba(255,255,255,0.06)}
.bc-item:hover, .bc-item.bc-on { background: rgba(255,255,255,0.084)}

/*  The number is the thing being submitted, so it is fixed-width and leads;
    the name wraps to a second line rather than being cut, which is the whole
    complaint about the native list. */
.bc-n {
    font-family: var(--mono); font-size: 12.5px; font-weight: 700;
    color: var(--accent); flex: 0 0 auto; min-width: 30px}
.bc-t { font-size: 13px; color: var(--text); overflow-wrap: anywhere}

.bc-none { padding: 12px 10px; font-size: 13px; color: var(--muted2, var(--muted))}

@media (max-width: 480px) {
    .bc-list { max-height: 46vh}
    .bc-item { padding: 11px 10px}   /* a comfortable touch target */
}

/* ── password reveal ── */
.pw-wrap { position:relative; display:block}
/*  Room for the eye so a long password does not run under it. */
.pw-input { padding-right:46px}
.pw-eye { position:absolute; top:50%; right:6px; transform:translateY(-50%); width:36px; height:36px; display:flex; align-items:center; justify-content:center; padding:0; background:transparent; border:none; border-radius:8px; color:var(--muted); cursor:pointer; transition:color .15s, background .15s}
.pw-eye:hover { color:var(--text); background:rgba(255,255,255,0.072)}
.pw-eye:focus-visible { outline:2px solid var(--login-accent, var(--accent)); outline-offset:-2px}
.pw-eye svg { width:19px; height:19px; fill:currentColor}
/*  Only one glyph shows at a time: open eye while hidden, struck-through while
    visible, so the icon reports the current state rather than the action. */
.pw-eye .pw-off { display:none}
.pw-eye.on { color:var(--login-accent, var(--accent))}
.pw-eye.on .pw-on { display:none}
.pw-eye.on .pw-off { display:block}

/* ── Desktop shell ────────────────────────────────────────────────────────
   Sidebar above 1000px, the original phone bottombar below it. Both are
   rendered by MainLayout; only CSS decides which is visible.

   WHY BOTH. Apps/WarRoomApp is a live Android + iOS shell pointing at this
   same site, with no screen-size gate anywhere in Lib.Maui. Desktop-only
   markup would ship a broken phone app to everyone already running it.

   The rail itself is lifted from DatacenterWeb, which uses it for a 52-page
   analytics site. What is NOT copied is its collapse behaviour: below 900px
   it stacks all 21 sections above the content, which on a phone is a wall of
   links before you reach the page. Here the rail simply goes away.          */
.layout { display: flex; min-height: calc(100vh - 52px)}
.sidebar { width:225px; min-width:225px; background:var(--bg2); border-right:1px solid var(--border); padding:14px 0 40px; position:sticky; top:52px; height:calc(100vh - 52px); overflow-y:auto}
.sidebar::-webkit-scrollbar { width:8px}
.sidebar::-webkit-scrollbar-thumb { background:var(--bg4); border-radius:4px}
.nav-section { padding:0 10px; margin-bottom:6px}
.nav-label { font-family:var(--mono); font-size:9px; letter-spacing:.2em; color:var(--muted); text-transform:uppercase; padding:6px 8px; margin-bottom:2px; cursor:pointer; list-style:none; display:flex; align-items:center; gap:6px; border-radius:var(--radius); user-select:none}
.nav-label::-webkit-details-marker { display:none}
.nav-label::before { content:"\25B8"; font-size:9px; opacity:.6; transition:transform .15s}
.nav-section[open] > .nav-label::before { transform:rotate(90deg)}
.nav-label:hover { background:var(--bg3)}
.nav-section + .nav-section { border-top:1px solid var(--border); padding-top:4px}
.nav-link { display:flex; align-items:center; gap:9px; padding:6px 10px; border-radius:var(--radius); color:var(--muted2); text-decoration:none; font-size:12.5px; font-weight:500; transition:all .15s}
.nav-link:hover { background:var(--bg3); color:var(--text); text-decoration:none}
.nav-link.active { background:var(--green-dim); color:var(--green)}
.nav-link .icon { width:15px; text-align:center; font-size:12px; flex-shrink:0}

/*  Below the breakpoint the rail is gone and the bottombar returns, so .main
    keeps its phone shape: a 700px reading column and clearance for the bar. */
@media (min-width: 1000px) {
    .main { max-width: none; padding: 20px 26px 40px}
    .bottombar { display: none}
}

@media (max-width: 999.98px) {
    .layout { display: block}
    .sidebar { display: none}
}

/*  The login page has no rail; keep its narrow card centred. */
.main--plain { max-width: 700px; margin: 0 auto}

/*  Wide tables must scroll inside their own box. This was `overflow:hidden`,
    which CLIPPED them - a column past the edge was simply unreachable, on the
    26 pages that use .data-table. It mattered less at 700px because the tables
    were built for it; at full width it is the difference between a usable
    report and a truncated one. */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch}

/*  Type sized for a 375px viewport is absurd on a monitor: 9px headers, 11px
    cells. Restored to something readable once there is room for it. */
@media (min-width: 1000px) {
    .data-table { font-size: 13px}
    .data-table th { font-size: 11.5px}
    .data-table td { font-size: 12.5px}
}

/*  auto-fill at 155px gives four tidy columns inside a 700px box and about ten
    cramped ones at 1600px. A wider floor keeps the cards card-shaped.         */
@media (min-width: 1000px) {
    .cards-grid { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr))}
}

/* ══ ELEVATION ══
   Approved direction, applied at the token layer.

   This is a light to dark flip, so it redefines the palette the whole product
   already reads rather than overriding rules one at a time. Roughly 2,900
   var() call sites pick it up at once, which is why every site turns over
   together instead of drifting apart.

   Depth comes from two shadows on every surface: a tight contact shadow and a
   wide soft one. Colour is spent only where it carries meaning, green for
   gain and red for loss, so the accent never competes with the data.

   Contrast, measured on both grounds rather than assumed. Card value 16.4:1,
   headings 15.8:1, body 12.9:1, muted 4.8:1 at worst, positive 9.1:1, negative 5.9:1,
   link 6.9:1. The direction's own muted grey was 4.07:1 and has been nudged
   from #727A88 to #8e96a6, the smallest change that clears AA. */

:root {
    --bg:      #0e1014;
    --bg2:     #161920;
    --bg3:     #1f232c;
    --bg4:     #2a303c;

    --border:  #232833;
    --border2: #333b49;

    --text:    #f5f7fa;
    --muted:   #8e96a6;
    --muted2:  #aeb6c2;

    --green:   #3fd37e;  --green-dim:  rgba(63,211,126,0.14);
    --red:     #ff5c77;  --red-dim:    rgba(255,92,119,0.14);
    --amber:   #fbbf24;  --amber-dim:  rgba(251,191,36,0.14);
    --blue:    #60a5fa;  --blue-dim:   rgba(96,165,250,0.14);
    --cyan:    #4dd0e1;
    --purple:  #c4b5fd;  --purple-dim: rgba(196,181,253,0.14);

    --primary:   #60a5fa;
    --accent:    #60a5fa;
    --accent-dim: rgba(96,165,250,0.14);
    --on-accent: #0e1014;

    --shadow-sm: 0 1px 2px rgba(0,0,0,.40);
    --shadow:    0 1px 2px rgba(0,0,0,.40), 0 6px 16px -8px rgba(0,0,0,.55);
    --shadow-lg: 0 2px 4px rgba(0,0,0,.45), 0 18px 40px -16px rgba(0,0,0,.65);

    --radius: 11px}

html, body { background: #0e1014; color: #f5f7fa}

/*  Surfaces lift off the ground. The pair of shadows is the whole direction:
    a tight contact edge plus a wide soft one. */
.card, .stat-card, .acard, .tile, .pdag-tile, .progress-box, .table-wrap,
.voter-card, .filter-bar, .surname-cloud, .form-card, .login-card,
.hero-card, .vr-sec, .bv-sec, .panel {
    background: #161920;
    /*  Longhands, not the `border` shorthand. The shorthand also sets
        border-left-width, which flattened the 4px gender rail on every voter
        card and the accent rails on .vr-sec and .bv-sec. */
    border-color: #232833;
    border-style: solid;
    border-width: 1px;
    border-radius: 11px;
    box-shadow: 0 1px 2px rgba(0,0,0,.40), 0 6px 16px -8px rgba(0,0,0,.55)}

/*  A card inside a card was the same #161920 as its parent, so the inner one
    had no visible edge at all. Nested surfaces take the next step up the ramp
    and a lighter rule, which is what makes the boundary read. */
:is(.card, .stat-card, .panel, .vr-sec, .bv-sec, .table-wrap, .form-card,
    .progress-box, .hero-card)
:is(.card, .stat-card, .tile, .acard, .progress-box, .pdag-tile, .voter-card) {
    background: #1f232c;
    border-color: #333b49;
    box-shadow: 0 1px 2px rgba(0,0,0,.35)}

/*  Three deep is rare but happens in the war room panels. */
:is(.card, .stat-card, .panel) :is(.card, .stat-card)
:is(.card, .stat-card, .tile) {
    background: #262b36;
    border-color: #3c4553}

/*  The band is a surface too, one step up from the page. */
.topbar {
    background: #161920;
    border-bottom: 1px solid #232833;
    box-shadow: none;
    color: #f5f7fa}
/*  Six layer scoped rules set the brand to a per tier hue at 0,3,0 -- amber for
    booth, red for assembly and so on -- and outrank a plain .topbar .brand.
    The attribute selector matches whichever one this site emits and ties their
    specificity, and coming later it wins. Colour here would be decoration; in
    this direction colour is reserved for gain and loss. */
.topbar .brand,
.topbar[class*="layer-"] .brand,
.topbar a, .topbar span { color: #f5f7fa; text-shadow: none}
.topbar .brand .brand-sep { color: #8e96a6}

.bottombar {
    background: #161920;
    border-top: 1px solid #232833;
    -webkit-backdrop-filter: none;
    backdrop-filter: none}

/*  ── Dividers, carried over to dark and extended ──
    The stylesheet already had a good splitter: a rule that fades at both ends
    with a diamond marking the centre. Its gradient was rgba(15,23,42,.13),
    dark ink meant for a light page, which on #0e1014 is invisible. Same rule,
    inverted, plus the diamond glow moved off the retired amber.

    It is then extended to the seams that had no markup to hang a splitter on:
    the head of a big card, the top of a nested group, and repeating rows. A
    hairline at those joins is what stops a card reading as one undivided
    block. Deliberately faint at 1.19:1 on the card -- a divider is not content
    and the 3:1 minimum governs controls and meaningful graphics, not rules. */

.split, hr {
    background: linear-gradient(90deg,
        transparent,
        rgba(255,255,255,.14) 18%,
        rgba(255,255,255,.14) 82%,
        transparent)}
.split::after, hr::after {
    background: var(--accent, #60a5fa);
    box-shadow: 0 0 0 4px var(--bg, #0e1014), 0 0 10px rgba(96,165,250,.45)}

/*  Seam under a big card's own heading. Small tiles are excluded below. */
.stat-card > .card-label:first-child,
.card > .card-label:first-child,
.vr-sec > h3:first-child,
.bv-sec > h3:first-child {
    border-bottom: 1px solid #232833;
    padding-bottom: 9px;
    margin-bottom: 11px}

/*  A nested group is a new region, so it opens with a seam. */
.card > .cards-grid,
.stat-card > .cards-grid,
.vr-sec > .cards-grid,
.bv-sec > .cards-grid,
.panel > .cards-grid {
    border-top: 1px solid #232833;
    padding-top: 13px;
    margin-top: 13px}

/*  Repeating rows read as a list once ruled. The last carries none so the
    group does not end on a dangling line. */
.bc-item, .vr-row, .list-row, .feed-item { border-bottom: 1px solid #1b1f27}
.bc-item:last-child, .vr-row:last-child,
.list-row:last-child, .feed-item:last-child { border-bottom: 0}

/*  A tile has one region and needs no seam inside it. */
.pdag-tile > .card-label:first-child,
.tile > .card-label:first-child {
    border-bottom: 0; padding-bottom: 0; margin-bottom: 4px}

/*  Figures lead. A value outranks its own label. */
.card-value, .kpi-val, .pdag-n {
    color: #f5f7fa;
    font-weight: 800;
    letter-spacing: -.025em;
    font-variant-numeric: tabular-nums}
.card-label, .kpi-lbl { color: #8e96a6}
.card-sub { color: #8e96a6}

/*  Deltas carry direction, so a glance gives sign as well as size. */
.c-green .card-sub, .up   { color: #3fd37e}
.c-red   .card-sub, .down { color: #ff5c77}

table th { color: #8e96a6; border-bottom: 1px solid #232833}
table td { color: #d8dde5; border-bottom: 1px solid #1b1f27}

/*  Focus stays visible and never borrows the action colour. */
.btn:focus, .btn:active:focus, .btn:focus-visible,
button:focus-visible, a:focus-visible,
select:focus-visible, input:focus-visible {
    outline: 2px solid #60a5fa;
    outline-offset: 2px;
    box-shadow: none}

/*  Tap targets. A finger needs about 44px; these sat at 31-34px, and a
    @media (max-width:380px) rule made the circles SMALLER on exactly the
    screens that are touch-only. The narrow screen is the touch screen. */
.btn, .pager-btn, .vc-edit,
.filter-bar select, .filter-bar input, .search-box,
.sc-tag, .letter-picker a { min-height: 44px}

.vc-act, .voter-card .vc-act { width: 44px; height: 44px}

/*  The phone bar's links sat at about 39px, on the only navigation a phone has.
    Listed here with the other targets so the floor is read in one place; the
    flex centring that keeps the label mid-height is on .bottombar a above.
    (.cx-btn carries its own floor in css/comms.css, beside its padding.) */
.bottombar a { min-height: 44px}

/* ── Collapsible navigation (js/navcollapse.js) ─────────────────────────────── */
.topbar-left { display:inline-flex; align-items:center; gap:10px; margin-right:auto } /* keeps user name + Logout in the right corner */
.nav-toggle { min-width:44px; min-height:44px; display:inline-flex; align-items:center; justify-content:center;
  background:transparent; color:inherit; border:1px solid rgba(255,255,255,.18); border-radius:8px;
  font-size:18px; line-height:1; cursor:pointer }
.nav-toggle:hover { background:rgba(255,255,255,.08) }
.nav-toggle:focus-visible { outline:2px solid currentColor; outline-offset:2px }
html.nav-collapsed .sidebar,
html.nav-collapsed .support-sidebar { display:none !important }
.nav-section-label { cursor:pointer; user-select:none; display:flex; align-items:center; gap:6px }
.nav-section-label::before { content:"BE"; font-size:10px; opacity:.6; transition:transform .15s }
.nav-section-label.collapsed::before { transform:rotate(-90deg) }
.nav-section-label.collapsed + .nav-section { display:none }
/* The toggle only matters where the sidebar exists (>= 1000px). */
@media (max-width: 999px) { .nav-toggle { display:none } }
