/* ==========================================================================
   BARCOM — application layer.

   ds.css is the design system and the source of truth for every colour,
   font, space and radius. Nothing here hard-codes a hex, a font name or a
   value the tokens already carry. This file only adds the app shell and the
   page patterns the three design files show.

   Modernist rules that hold everywhere:
     · zero corner radius   — --radius-md is 0 on purpose
     · 2px dividers         — never softened to hairlines
     · flush-left labels    — including inside a wide button
     · accent used sparingly, for the primary action and small emphasis
   ========================================================================== */

/* --------------------------------------------------------------------------
   Theme — dark green accent.

   ds.css ships a red accent (#ec3013). Rather than edit that file, the two
   accent ramps are re-pointed here: barcom.css loads after ds.css, so this
   :root block wins, and your design system file stays exactly as exported —
   re-export it any time and the green survives.

   Nothing else in the codebase names a colour. Every button, link, status
   pill, panel and focus ring reads these tokens, so changing the nine steps
   below is the whole colour change. To try a different green, edit
   --color-accent and the 100–900 ramp together, keeping 100 lightest and
   900 darkest; 600 and 700 are the hover and active states, so they must
   stay darker than the base.
   -------------------------------------------------------------------------- */

:root {
  /* One height for every form control.
     Heights used to be set inline, field by field, and drifted: search boxes
     were 48px while the dropdowns beside them were 46px, so the filter row on
     the Cases Board, Citizens and Track sat two pixels out of line. */
  --control-h: 46px;

  --color-accent: #15653f;      /* primary buttons, links, accent panels */
  --color-accent-2: #3d8168;    /* secondary accent, used sparingly */

  --color-accent-100: #eef6f1;  /* tinted row background, unread rows */
  --color-accent-200: #d5e9de;  /* light status pill background */
  --color-accent-300: #aed3c0;
  --color-accent-400: #74b394;  /* dark-mode primary hover */
  --color-accent-500: #3a9068;
  --color-accent-600: #125736;  /* primary button hover */
  --color-accent-700: #0e442a;  /* primary button active, link hover */
  --color-accent-800: #0a3220;  /* text on accent-200 */
  --color-accent-900: #0a2418;  /* text on accent-300 */


  /* ------------------------------------------------------------------------
     Stage tones.

     Colour encodes urgency rather than category, so the board is readable at
     a glance without learning eleven separate hues:

       teal   moving normally, nobody blocked
       amber  somebody must act before this can move
       red    the resident has pulled out
       slate  concluded, still reopenable
       grey   filed away

     Every card also carries its sub-state breakdown as text, so none of this
     is load-bearing on its own — the board still reads photocopied in black
     and white, which matters for a printed appendix.

     The three board washes are deliberately weak. A saturated band would
     fight both the cards sitting on it and the dark green the rest of the
     system is built from.
     --------------------------------------------------------------------- */
  --tone-teal:      #15653f;
  --tone-teal-bg:   #eef6f1;
  --tone-teal-fg:   #0e442a;

  /* Yellow-green: a proceeding is in hand. Distinct from the Validation
     teal, so the two kinds of "nothing is wrong" read apart at a glance. */
  --tone-green:     #5c7a1e;
  --tone-green-bg:  #f3f7e9;
  --tone-green-fg:  #3f5514;

  --tone-amber:     #b26a00;
  --tone-amber-bg:  #fdf3e3;
  --tone-amber-fg:  #7a4800;

  --tone-red:       #a32c28;
  --tone-red-bg:    #fbeeed;
  --tone-red-fg:    #7d201d;

  --tone-slate:     #3f4b57;
  --tone-slate-bg:  #eef1f4;
  --tone-slate-fg:  #2a333c;

  --tone-grey:      #6b6b6b;
  --tone-grey-bg:   #f1f1f1;
  --tone-grey-fg:   #4a4a4a;

  --board-sand:     #fdfaf3;
  --board-slate:    #f4f7fa;
  --board-sage:     #f2f7f4;

  --color-accent-2-100: #f0f6f3;
  --color-accent-2-200: #dbe9e2;
  --color-accent-2-300: #bcd6c9;
  --color-accent-2-400: #8fb9a5;
  --color-accent-2-500: #5f9a80;
  --color-accent-2-600: #487d66;
  --color-accent-2-700: #366050;
  --color-accent-2-800: #27453a;
  --color-accent-2-900: #1d3129;
}

html, body { margin: 0; padding: 0; background: var(--color-bg); color: var(--color-text); }
body { font-family: var(--font-body); -webkit-font-smoothing: antialiased; }
a { color: var(--color-accent); }
a:hover { color: var(--color-accent-700); }
select.input { appearance: none; background-image: none; }
input[type="checkbox"] { accent-color: var(--color-accent); width: 20px; height: 20px; }

/* --------------------------------------------------------------------------
   Shell — two header rows, then sidebar + content, as in the design.

   Row 1  brand · user initials
   Row 2  top nav: burger (mobile only) + Home / Alerts / Bulletin
   Below  sticky sidebar on desktop, drawer on mobile

   There is no bottom bar. An earlier version had one; it used
   position:sticky with bottom:0, which pins to the viewport only while the
   container overflows. On a short page it simply sat after the content and
   appeared to float mid-screen. The design never had one.
   -------------------------------------------------------------------------- */

.app-shell { min-height: 100vh; display: flex; flex-direction: column; }

/* Both header rows travel together when the page scrolls. */
.app-top { position: sticky; top: 0; z-index: 40; background: var(--color-bg); }

.app-header {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 10px var(--space-4);
  border-bottom: 2px solid var(--color-divider);
}

.brand { display: flex; align-items: center; gap: 10px; margin-right: auto; text-decoration: none; color: inherit; min-width: 0; }
.brand-mark {
  width: 32px; height: 32px; flex: none;
  background: var(--color-accent); color: var(--color-bg);
  display: grid; place-items: center;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 14px;
}
.brand-text { display: flex; flex-direction: column; line-height: 1.1; min-width: 0; }
.brand-name { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 17px; letter-spacing: -0.02em; }
.brand-tagline {
  font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.header-user {
  display: flex; align-items: center; gap: 9px; min-height: 44px;
  padding: 4px 6px; text-decoration: none; color: inherit;
  background: transparent; border: 0; cursor: pointer; font-family: inherit;
}
.header-user:hover { background: color-mix(in srgb, var(--color-text) 6%, transparent); }
.header-user-text { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.15; }
.header-user-name { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 13px; }
.header-user-role { font-size: 10.5px; color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.avatar {
  width: 32px; height: 32px; flex: none;
  background: var(--color-neutral-300); color: var(--color-neutral-900);
  display: grid; place-items: center;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 12px;
}

/* Profile menu — the only Log Out in the app. */
.profile-menu { position: relative; }

.caret {
  width: 0; height: 0; flex: none;
  border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  opacity: 0.6; transition: transform 0.15s ease;
}
.header-user[aria-expanded="true"] .caret { transform: rotate(180deg); }

.profile-dropdown {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 60;
  min-width: 248px; max-width: 88vw;
  background: var(--color-bg);
  border: 2px solid var(--color-divider);
  display: flex; flex-direction: column;
}
.profile-dropdown[hidden] { display: none; }

.profile-item {
  display: flex; flex-direction: column; gap: 2px; align-items: flex-start;
  width: 100%; text-align: left; text-decoration: none; color: var(--color-text);
  background: transparent; border: 0; cursor: pointer; font-family: inherit;
  padding: 13px 16px; min-height: 48px; justify-content: center;
}
.profile-item:hover { background: color-mix(in srgb, var(--color-text) 6%, transparent); }

/* The address can be long; wrap rather than overflow the panel. */
.profile-item-email {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 13px; overflow-wrap: anywhere;
}
.profile-item-sub { font-size: 11px; color: color-mix(in srgb, var(--color-text) 55%, transparent); }

.profile-item-logout {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 13.5px; color: var(--color-accent-700);
}
.profile-item-logout:hover { background: color-mix(in srgb, var(--color-accent) 10%, transparent); }

/* Row 2 — equal columns; the burger takes a fixed 56px when present. */
.top-nav {
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  border-bottom: 2px solid var(--color-divider);
}
.top-nav.has-burger { grid-template-columns: 56px repeat(3, 1fr); }

.top-nav-link {
  min-height: 52px; display: flex; align-items: center; justify-content: center;
  gap: 5px; padding: 0 6px; text-decoration: none; color: var(--color-text);
  border-bottom: 3px solid transparent;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
}
.top-nav-link:hover { background: color-mix(in srgb, var(--color-text) 6%, transparent); }
.top-nav-link.is-active {
  border-bottom-color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 9%, transparent);
  color: var(--color-accent-700);
}

.burger {
  min-height: 52px; cursor: pointer; border: 0;
  border-bottom: 3px solid transparent; background: transparent;
  color: var(--color-text); display: grid; place-items: center;
}
.burger:hover { background: color-mix(in srgb, var(--color-text) 6%, transparent); }
.burger-bars { display: flex; flex-direction: column; gap: 4px; width: 20px; }
.burger-bars span { height: 2px; background: currentColor; }

/* --------------------------------------------------------------------------
   Body: sidebar + main
   -------------------------------------------------------------------------- */

.app-body { display: flex; align-items: flex-start; flex: 1; min-height: 0; }
.app-main { flex: 1; min-width: 0; }

.side-nav {
  position: sticky; top: 100px; width: 232px; flex: none; align-self: flex-start;
  border-right: 2px solid var(--color-divider);
  padding: 16px 0; display: flex; flex-direction: column; gap: 2px;
}
.side-nav-kicker {
  font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 50%, transparent);
  padding: 0 16px 10px;
}
.side-nav-link {
  text-align: left; text-decoration: none; color: var(--color-text);
  border-left: 3px solid transparent;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 13.5px; padding: 13px 16px; min-height: 46px;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
.side-nav-link:hover { background: color-mix(in srgb, var(--color-text) 5%, transparent); }
.side-nav-link.is-active {
  border-left-color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 9%, transparent);
  color: var(--color-accent-700);
}

/* --------------------------------------------------------------------------
   Mobile drawer
   -------------------------------------------------------------------------- */

.drawer-backdrop {
  position: fixed; inset: 0; z-index: 90;
  background: color-mix(in srgb, #201e1d 55%, transparent);
  display: flex;
}
.drawer-backdrop[hidden] { display: none; }

.drawer {
  width: 280px; max-width: 84vw; height: 100%;
  background: var(--color-bg);
  display: flex; flex-direction: column;
  padding: 16px 0; overflow-y: auto;
  animation: barcomSlide 0.18s ease-out;
}
@keyframes barcomSlide {
  from { transform: translateX(-100%); }
  to   { transform: translateX(0); }
}
@media (prefers-reduced-motion: reduce) {
  .drawer { animation: none; }
}

.drawer-head {
  display: flex; align-items: center; gap: 10px;
  padding: 0 16px 14px; border-bottom: 2px solid var(--color-divider);
}
.drawer-name { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 15px; }
.drawer-role { font-size: 11px; color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.drawer-list { display: flex; flex-direction: column; gap: 2px; padding-top: 10px; }
.drawer .side-nav-link { font-size: 14px; padding: 14px 16px; min-height: 50px; }

/* Below the sidebar breakpoint the drawer takes over. */
@media (max-width: 860px) {
  .side-nav { display: none; }
  .header-user-text { display: none; }
}
@media (min-width: 861px) {
  .burger { display: none; }
  .top-nav.has-burger { grid-template-columns: repeat(3, 1fr); }
  .drawer-backdrop { display: none !important; }
}

/* --------------------------------------------------------------------------
   Footer (public pages only)
   -------------------------------------------------------------------------- */

.app-footer {
  margin-top: auto; display: flex; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-4); border-top: 2px solid var(--color-divider);
  font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

/* --------------------------------------------------------------------------
   Page frame
   -------------------------------------------------------------------------- */

.page {
  width: 100%; max-width: 1080px; margin: 0 auto;
  padding: 20px var(--space-4) var(--space-8);
  display: flex; flex-direction: column; gap: 22px;
}
.page-narrow { max-width: 760px; }
.page-wide   { max-width: 1280px; }

.page-kicker {
  font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.page-title { margin: 6px 0 4px; font-size: clamp(26px, 6vw, 36px); letter-spacing: -0.02em; }
.page-sub   { margin: 0; font-size: 14px; color: color-mix(in srgb, var(--color-text) 68%, transparent); }

.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-3); margin-bottom: 10px;
}

/* --------------------------------------------------------------------------
   Flash messages
   -------------------------------------------------------------------------- */

.flash {
  padding: var(--space-3) var(--space-4);
  font-size: 13.5px; border-bottom: 2px solid var(--color-divider);
}
.flash-success { background: var(--color-neutral-800); color: var(--color-bg); }
.flash-error   { background: var(--color-accent);      color: var(--color-bg); }

/* --------------------------------------------------------------------------
   The action panel — Client Home's red "you are next to act" block
   -------------------------------------------------------------------------- */

.action-panel { border: 2px solid var(--color-accent); display: flex; flex-direction: column; }
.action-panel-head {
  background: var(--color-accent); color: var(--color-bg);
  padding: 11px var(--space-4);
  display: flex; flex-wrap: wrap; gap: var(--space-2);
  align-items: baseline; justify-content: space-between;
}
.action-panel-title { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 14px; }
.action-panel-note  { font-size: 11.5px; opacity: 0.9; }

/* --------------------------------------------------------------------------
   Quick actions — the two big tiles
   -------------------------------------------------------------------------- */

.quick-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 2px; background: var(--color-divider);
}
.quick-tile {
  text-align: left; cursor: pointer; border: 0; font-family: inherit;
  padding: 22px 18px; display: flex; flex-direction: column; gap: 6px; min-height: 118px;
  text-decoration: none;
}
.quick-tile-accent  { background: var(--color-accent);  color: var(--color-bg); }
.quick-tile-accent:hover { background: var(--color-accent-600); }
.quick-tile-surface { background: var(--color-surface); color: var(--color-text); }
.quick-tile-surface:hover { background: var(--color-neutral-200); }
.quick-kicker { font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; opacity: 0.85; }
.quick-tile-surface .quick-kicker { color: var(--color-accent-700); opacity: 1; }
.quick-label { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 21px; line-height: 1.1; }
.quick-note  { font-size: 12.5px; opacity: 0.9; }
.quick-tile-surface .quick-note { color: color-mix(in srgb, var(--color-text) 68%, transparent); opacity: 1; }

/* --------------------------------------------------------------------------
   Row list — the shared list pattern across every screen
   -------------------------------------------------------------------------- */

.row-list { display: flex; flex-direction: column; }
.row {
  text-align: left; cursor: pointer; font-family: inherit; color: inherit;
  border: 0; border-bottom: 1px solid var(--color-divider); background: transparent;
  padding: 14px 2px; display: grid; grid-template-columns: 1fr auto;
  gap: var(--space-3); align-items: flex-start; min-height: 62px;
  text-decoration: none; width: 100%;
}
.row:hover { background: color-mix(in srgb, var(--color-text) 4%, transparent); }
.row-main { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.row-trk  { font-family: ui-monospace, monospace; font-size: 11.5px; color: color-mix(in srgb, var(--color-text) 60%, transparent); }
.row-title { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 15px; line-height: 1.2; }
.row-meta {
  display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center;
  font-size: 12px; color: color-mix(in srgb, var(--color-text) 62%, transparent);
}
.row-note { font-size: 12.5px; color: color-mix(in srgb, var(--color-text) 70%, transparent); text-wrap: pretty; }

/* Inside the red action panel the rows sit on the accent border. */
.action-panel .row { padding: 13px var(--space-4); min-height: 66px; }

/* --------------------------------------------------------------------------
   Status board tiles
   -------------------------------------------------------------------------- */

.status-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 2px; background: var(--color-divider);
}
.status-tile {
  background: var(--color-surface); color: inherit; text-decoration: none;
  padding: 18px var(--space-4); display: flex; flex-direction: column; gap: 4px;
  min-height: 104px; border: 0; font-family: inherit; text-align: left; cursor: pointer;
}
.status-tile:hover { background: var(--color-neutral-200); }
.status-count { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 34px; line-height: 1; }
.status-name  { font-size: 12.5px; letter-spacing: 0.06em; text-transform: uppercase; color: color-mix(in srgb, var(--color-text) 62%, transparent); }

/* --------------------------------------------------------------------------
   Boxes, tables, timeline
   -------------------------------------------------------------------------- */

.box { border: 2px solid var(--color-divider); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-3); }
.box-accent { border-color: var(--color-accent); }

.data-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.data-table th {
  text-align: left; font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  padding: 10px var(--space-2); border-bottom: 2px solid var(--color-divider);
}
.data-table td { padding: 12px var(--space-2); border-bottom: 1px solid var(--color-divider); vertical-align: top; }
.data-table tbody tr:hover { background: color-mix(in srgb, var(--color-text) 4%, transparent); }

.timeline { display: flex; flex-direction: column; border-left: 2px solid var(--color-divider); padding-left: var(--space-4); }
.timeline-item { padding: var(--space-3) 0; position: relative; }
.timeline-item::before {
  content: ""; position: absolute; left: calc(var(--space-4) * -1 - 5px); top: 20px;
  width: 8px; height: 8px; background: var(--color-accent);
}
.timeline-when { font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.timeline-what { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 14.5px; margin: 3px 0; }
.timeline-note { font-size: 13px; color: color-mix(in srgb, var(--color-text) 72%, transparent); margin: 0; }
.timeline-internal {
  font-size: 12.5px; margin-top: 6px; padding: var(--space-2);
  background: var(--color-neutral-200); border-left: 2px solid var(--color-accent);
}

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */

.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--space-3); }
.form-grid .field-wide { grid-column: 1 / -1; }
.field + .field { margin-top: var(--space-3); }
.form-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; padding-top: var(--space-3); border-top: 2px solid var(--color-divider); }
.input { min-height: 46px; font-size: 15px; }
textarea.input { min-height: 120px; }

/* Wizard steps on the complaint form */
.steps { display: flex; gap: 2px; background: var(--color-divider); }
.step {
  flex: 1; padding: var(--space-2) var(--space-3); background: var(--color-surface);
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.step.is-current { background: var(--color-accent); color: var(--color-bg); }
.step.is-done    { background: var(--color-neutral-800); color: var(--color-bg); }

/* --------------------------------------------------------------------------
   Empty states
   -------------------------------------------------------------------------- */

.empty { padding: 40px 0; }
.empty-title { margin: 0 0 4px; font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 17px; }
.empty-note  { margin: 0; font-size: 13.5px; color: color-mix(in srgb, var(--color-text) 62%, transparent); }

/* --------------------------------------------------------------------------
   Landing
   -------------------------------------------------------------------------- */

.hero {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  border-bottom: 2px solid var(--color-divider);
}
.hero-copy { padding: 40px 20px 44px; display: flex; flex-direction: column; gap: 18px; justify-content: center; max-width: 620px; }
.hero-title { margin: 0; font-size: clamp(34px, 8vw, 58px); letter-spacing: -0.03em; }
.hero-lead  { margin: 0; font-size: 16px; max-width: 52ch; color: color-mix(in srgb, var(--color-text) 72%, transparent); }
.hero-panel { background: var(--color-accent); color: var(--color-bg); padding: 40px 20px; display: flex; flex-direction: column; justify-content: center; gap: var(--space-3); }

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 2px; background: var(--color-divider); }
.stat { background: var(--color-bg); padding: 22px 18px; display: flex; flex-direction: column; gap: 4px; }
.stat-num { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 38px; line-height: 1; }
.stat-label { font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: color-mix(in srgb, var(--color-text) 55%, transparent); }

.section { padding: 40px 20px; border-bottom: 2px solid var(--color-divider); }

/* --------------------------------------------------------------------------
   Auth
   -------------------------------------------------------------------------- */

/* Log In and Registration: a full-height two-column split. Each column has a
   340px floor, so the accent panel drops below the form on a phone rather
   than squeezing. */
/* ── Log in and sign up ───────────────────────────────────────────────────
   One centred column at every width.
   The green panel beside it is gone. It carried a seal and a sentence, and
   on a phone it pushed the form below the fold — so somebody arriving to log
   in met a slogan and had to scroll to find the thing they came for. Both
   seals now sit at the top of the form, which says whose service this is in
   a fraction of the height and reads the same on any screen. */
.auth-centre {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 24px 16px;
}

.auth-pane {
  display: flex; flex-direction: column;
  width: 100%; max-width: 440px;
  gap: 20px;
}

/* The two marks, centred above the form. */
.auth-centre .auth-seals { justify-content: center; margin-bottom: 2px; }

.auth-panel {
  background: var(--color-accent); color: var(--color-bg);
  padding: 40px 24px;
  display: flex; flex-direction: column; justify-content: flex-end;
  gap: 12px; min-height: 220px;
}
.auth-panel-kicker {
  font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-bg) 80%, transparent);
}
.auth-panel-title {
  margin: 0; font-size: clamp(24px, 4vw, 38px); line-height: 1.06;
  letter-spacing: -0.02em; max-width: 22ch;
}

/* Inline hint under a field, e.g. the contact-number rule. */
.field-hint {
  display: block; margin-top: 5px; font-size: 11.5px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.field-hint.is-ok  { color: var(--color-accent-700); }
.field-hint.is-bad { color: var(--color-accent); }

/* The six-digit code box: wide-spaced monospace so digits are easy to check. */
.otp-input {
  font-family: ui-monospace, monospace;
  font-size: 26px; letter-spacing: 0.4em;
  text-align: center; min-height: 58px;
}

/* The auth layout has no header, so a flash has to float over the split. */
.flash-float {
  position: fixed; top: 0; left: 0; right: 0; z-index: 60;
  border-bottom: 0;
}

/* --------------------------------------------------------------------------
   Utilities
   -------------------------------------------------------------------------- */

.stack   { display: flex; flex-direction: column; gap: var(--space-3); }
.cluster { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.push    { margin-left: auto; }
.mono    { font-family: ui-monospace, monospace; }
.rule    { height: 2px; background: var(--color-divider); border: 0; margin: 0; }

/* Severity and confidentiality are staff-only markers. */
.badge-confidential {
  font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase;
  border: 1px solid var(--color-accent); color: var(--color-accent-700);
  padding: 2px 7px;
}

/* --------------------------------------------------------------------------
   Dark mode — the same tokens, re-pointed. Radius stays 0.
   -------------------------------------------------------------------------- */

body.dark {
  --color-bg: #1a1918;
  --color-surface: #262423;
  --color-text: #f3f2f2;
  --color-divider: color-mix(in srgb, #f3f2f2 32%, transparent);

  /* The accent has to be re-pointed for dark mode, not just inherited.
     .btn-primary paints --color-bg as its TEXT colour, which is near-black
     here — and near-black on #15653f is a 2.5:1 contrast, unreadable. This
     lighter green reads at 5.6:1 as a button and as a link on the dark
     ground, so both directions stay legible. */
  --color-accent: #4fa07c;

  /* Tones re-pointed for dark mode. The light washes above are near-white and
     would blow out the board; these are dark grounds with light text, keeping
     the same five meanings at readable contrast. */
  --tone-teal-bg:   #12301f;  --tone-teal-fg:   #9fd7ba;
  --tone-green-bg:  #1f2810;  --tone-green-fg:  #bcd68a;
  --tone-amber-bg:  #33240c;  --tone-amber-fg:  #f0c078;
  --tone-red-bg:    #331615;  --tone-red-fg:    #eba6a3;
  --tone-slate-bg:  #1e242b;  --tone-slate-fg:  #b6c3d0;
  --tone-grey-bg:   #242424;  --tone-grey-fg:   #b8b8b8;

  --board-sand:     #221f19;
  --board-slate:    #191d22;
  --board-sage:     #17211b;
}
body.dark .btn-primary:hover  { background: var(--color-accent-300); }
body.dark .btn-primary:active { background: var(--color-accent-200); }

/* --------------------------------------------------------------------------
   Password field with a Show/Hide button
   -------------------------------------------------------------------------- */

.pw-row { display: flex; gap: 8px; align-items: stretch; }
.pw-row .input { flex: 1; min-width: 0; min-height: 46px; }

/* Fixed width so the button does not jump as the label flips Show/Hide. */
.pw-toggle { flex: none; min-height: 46px; width: 76px; justify-content: center; }

/* --------------------------------------------------------------------------
   Filter bar — search above a responsive row of dropdowns.

   Matches the design: full-width search, then the selects wrapping into as
   many columns as fit at a 190px minimum, so three filters sit side by side
   on a laptop and stack on a phone.
   -------------------------------------------------------------------------- */

.filter-bar { display: flex; flex-direction: column; gap: 10px; }

.filter-search { display: flex; gap: 8px; align-items: stretch; }
.filter-search .input { flex: 1; min-width: 0; min-height: var(--control-h); font-size: 15px; }
.filter-search-btn { flex: none; min-height: var(--control-h); }

.filter-selects {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px;
}
.filter-selects .input { min-height: 46px; }

.filter-count {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; padding-top: 10px; border-top: 2px solid var(--color-divider);
}

/* --------------------------------------------------------------------------
   Reports
   -------------------------------------------------------------------------- */

.report-kinds {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 3px;
}
.report-kind {
  outline: 1px solid var(--color-divider);
  background: var(--color-bg); color: var(--color-text);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 14px; line-height: 1.25;
  padding: 15px; min-height: 74px;
  display: flex; align-items: center; text-decoration: none;
}
.report-kind:hover { background: var(--color-neutral-200); color: var(--color-text); }
.report-kind.is-active { background: var(--color-accent); color: var(--color-bg); }

.report-totals td {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  border-top: 2px solid var(--color-divider);
}

/* --------------------------------------------------------------------------
   Print — a printed report is the sheet alone, no interface around it
   -------------------------------------------------------------------------- */

@media print {
  .barcom-noprint,
  .app-top, .side-nav, .drawer-backdrop, .app-footer, .flash { display: none !important; }

  body { background: #fff; color: #000; }
  .app-body, .app-main, .page { display: block; max-width: none; padding: 0; margin: 0; }
  .box { border: 1px solid #000; }

  /* Keep a long table readable across pages. */
  table { page-break-inside: auto; }
  tr    { page-break-inside: avoid; page-break-after: auto; }
  thead { display: table-header-group; }

  a[href]::after { content: ""; }
}

/* --------------------------------------------------------------------------
   Case dialog — the confirm stage echoes back what was entered
   -------------------------------------------------------------------------- */

@keyframes barcomRise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .dialog { animation: none !important; }
}

.dialog-backdrop[hidden] { display: none !important; }

.echo-label {
  font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.echo-value {
  font-size: 14px;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
}

/* The active sub-tab on Citizens — a ghost button that reads as selected. */
.btn.is-active-filter {
  border-bottom: 2px solid var(--color-accent);
  color: var(--color-accent-700);
}

/* --------------------------------------------------------------------------
   The hidden attribute must win.

   [hidden] gets display:none from the browser's own stylesheet, which any
   inline "display:flex" or "display:grid" silently overrides — an element
   marked hidden then stays fully visible. That is what put all five wizard
   steps on one page.

   This one rule makes hidden authoritative everywhere: wizard steps, dialog
   stages, the evidence list, the anonymous notice, the profile menu.
   -------------------------------------------------------------------------- */

[hidden] { display: none !important; }

/* --------------------------------------------------------------------------
   Complaint wizard
   -------------------------------------------------------------------------- */

/* Layout lives here rather than inline, so the hidden attribute alone is
   enough to take a step off the page. */
.wizard-step-stack { display: flex; flex-direction: column; gap: 14px; }
.wizard-step-grid  { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; }
.wizard-step-rows  { display: flex; flex-direction: column; gap: 2px; background: var(--color-divider); }

.evidence-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }

.anon-note {
  border: 2px solid var(--color-accent); padding: 14px;
  display: flex; flex-direction: column; gap: 6px;
}

/* A status card with nothing in it is muted, so a busy board reads at a
   glance. It stays clickable: an empty list is still a useful answer. */
.status-tile.is-empty .status-count { color: color-mix(in srgb, var(--color-text) 45%, transparent); }
.status-tile.is-empty .status-name  { color: color-mix(in srgb, var(--color-text) 40%, transparent); }

/* --------------------------------------------------------------------------
   Attachments: attach, photograph, rename, remove
   -------------------------------------------------------------------------- */

.attach { display: flex; flex-direction: column; gap: 10px; }

.attach-list {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px;
}

.attach-card {
  position: relative; border: 1px solid var(--color-divider);
  background: var(--color-surface);
  display: flex; flex-direction: column; overflow: hidden;
}
.attach-thumb { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; filter: grayscale(1); }
.attach-kind {
  aspect-ratio: 4 / 3; display: grid; place-items: center;
  font-family: ui-monospace, monospace; font-size: 11px;
}
.attach-name {
  font-family: ui-monospace, monospace; font-size: 10.5px; padding: 5px 6px;
  background: var(--color-bg);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.attach-tools { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; }
.attach-btn {
  border: 0; border-top: 1px solid var(--color-divider); cursor: pointer;
  background: var(--color-bg); color: var(--color-text);
  font-family: inherit; font-size: 11px; padding: 8px 4px; min-height: 36px;
}
.attach-btn:hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
.attach-btn-remove { color: var(--color-accent-700); border-left: 1px solid var(--color-divider); }

.attach-error { margin: 0; font-size: 12.5px; color: var(--color-accent-700); }

/* --------------------------------------------------------------------------
   Unread alert count
   -------------------------------------------------------------------------- */

/* A count beside the Alerts link, the way a messaging app shows one. Square
   rather than round, to stay with the Modernist rules. */
.alert-badge {
  display: inline-grid; place-items: center;
  min-width: 20px; height: 20px; padding: 0 5px; margin-left: 6px;
  background: var(--color-accent); color: var(--color-bg);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 11px; line-height: 1; vertical-align: middle;
}
.top-nav-link.is-active .alert-badge { background: var(--color-accent-700); }

/* --------------------------------------------------------------------------
   Collapsible case sections
   -------------------------------------------------------------------------- */

/* <details> rather than JavaScript: it collapses before the script loads and
   still works with JavaScript off. */
.case-section { border: 2px solid var(--color-divider); background: var(--color-bg); }

.case-section-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 16px; cursor: pointer; list-style: none;
  min-height: 56px;
}
.case-section-head::-webkit-details-marker { display: none; }

/* A caret that turns, drawn in CSS so no icon file is needed. */
.case-section-head::after {
  content: ''; flex: none; width: 9px; height: 9px; margin-left: 4px;
  border-right: 2px solid var(--color-text); border-bottom: 2px solid var(--color-text);
  transform: rotate(45deg); transition: transform 0.15s ease;
}
.case-section[open] > .case-section-head::after { transform: rotate(-135deg); }
.case-section-head:hover { background: var(--color-surface); }

.case-section-body {
  max-height: 420px; overflow-y: auto;
  border-top: 2px solid var(--color-divider);
  padding: 0 16px 14px;
}

@media (prefers-reduced-motion: reduce) {
  .case-section-head::after { transition: none; }
}

/* --------------------------------------------------------------------------
   Checkbox
   -------------------------------------------------------------------------- */

/* ds.css's .radio hides the input and draws a round dot in its place, which
   is right for a radio and wrong for a checkbox: a checkbox marked up that
   way disappears entirely. This is the square equivalent, and it styles the
   real input rather than hiding it, so it stays keyboard-reachable. */
.checkbox {
  display: inline-flex; align-items: center; gap: 8px;
  cursor: pointer; font-size: 14px; min-height: 32px;
}
.checkbox input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 18px; height: 18px; flex: none; margin: 0;
  border: 1.5px solid var(--color-divider);
  background: var(--color-bg);
  cursor: pointer;
  display: grid; place-content: center;
}
.checkbox:hover input[type="checkbox"] { border-color: var(--color-accent); }
.checkbox input[type="checkbox"]:checked {
  background: var(--color-accent); border-color: var(--color-accent);
}
/* The tick, drawn rather than loaded — no icon file to go missing. */
.checkbox input[type="checkbox"]:checked::after {
  content: ''; width: 5px; height: 9px; margin-top: -2px;
  border: solid var(--color-bg); border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.checkbox input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--color-accent); outline-offset: 2px;
}
.checkbox input[type="checkbox"]:disabled {
  opacity: 0.5; cursor: not-allowed;
}

/* A grid of them, for picking several categories at once. */
.checkbox-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px 16px;
}

/* --------------------------------------------------------------------------
   Modal scrolling
   -------------------------------------------------------------------------- */

/* ds.css centres a dialog with `place-items: center` and gives it no height
   limit. A short dialog is fine; the Proceed dialog with its schedule fields,
   or the IIR with several attendees, grows taller than the viewport and the
   overflow lands off-screen in both directions — unreachable, because the
   backdrop itself does not scroll and the page behind it is covered.

   Fixed by making the backdrop the scrolling surface and capping the dialog
   at the viewport height. `align-items: start` matters: with `center`, a
   dialog taller than the screen has its top pushed above the scroll origin,
   so the first fields stay unreachable however far you scroll. */
.dialog-backdrop {
  place-items: start center;
  overflow-y: auto;
  overscroll-behavior: contain;          /* don't scroll the page behind it */
  -webkit-overflow-scrolling: touch;
}

.dialog {
  /* Never taller than the space it has, minus the backdrop's own padding. */
  max-height: calc(100dvh - var(--space-4) * 2);
  margin-block: auto;                    /* still centred when it does fit */
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* The heading stays put while the body scrolls, so it is always clear which
   action is being confirmed. */
.dialog-title {
  position: sticky; top: 0; z-index: 1;
  background: var(--color-surface);
  padding-block: 2px;
}

/* Likewise the buttons: a long dialog whose Confirm sits below the fold
   reads as having no way to submit. */
.dialog-actions {
  position: sticky; bottom: 0;
  background: var(--color-surface);
  padding-top: var(--space-2);
}

/* Older browsers without dvh fall back to vh, which is close enough. */
@supports not (height: 100dvh) {
  .dialog { max-height: calc(100vh - var(--space-4) * 2); }
}

/* On a phone the padding is wasted space; the dialog takes the width. */
@media (max-width: 560px) {
  .dialog-backdrop { padding: var(--space-2); }
  .dialog { max-height: calc(100dvh - var(--space-2) * 2); }
}

/* --------------------------------------------------------------------------
   Cases board — three stacked boards of stage cards
   -------------------------------------------------------------------------- */

.board {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  background: var(--board-sand);
  border: 1px solid var(--color-divider);
}
.board-sand  { background: var(--board-sand); }
.board-slate { background: var(--board-slate); }
.board-sage  { background: var(--board-sage); }

.board-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  flex-wrap: wrap;
}

/* auto-fit rather than a fixed count: four across on a desktop, three on a
   tablet, two on a phone. Two-up is deliberate — eleven cards stacked one per
   row is a very long scroll, and these numbers are short enough to sit
   side by side. */
.board-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
}

.stage-card {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 14px 14px 14px 16px;
  min-height: 96px;              /* comfortably past the 48px tap target */
  background: var(--color-bg);
  border: 1px solid var(--color-divider);
  border-left: 4px solid var(--tone-teal);
  text-decoration: none;
  color: var(--color-text);
  transition: background 0.12s ease;
}
.stage-card:hover { background: var(--color-surface); }

.stage-card.tone-teal  { border-left-color: var(--tone-teal); }
.stage-card.tone-green { border-left-color: var(--tone-green); }
.stage-card.tone-amber { border-left-color: var(--tone-amber); }
.stage-card.tone-red   { border-left-color: var(--tone-red); }
.stage-card.tone-slate { border-left-color: var(--tone-slate); }
.stage-card.tone-grey  { border-left-color: var(--tone-grey); }

.stage-count {
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 28px;
  line-height: 1;
}
.stage-name {
  font-size: 11px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 62%, transparent);
}
.stage-subs {
  font-size: 11.5px;
  line-height: 1.35;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
  text-wrap: pretty;
}
/* Only shown past a week, so it reads as a warning rather than decoration. */
.stage-age {
  font-size: 11px;
  font-weight: 700;
  color: var(--tone-amber-fg);
}

/* An empty stage stays on the board — a card that disappears at zero makes
   the board's shape change as cases move, which is disorienting. */
.stage-card.is-empty { opacity: 0.55; }
.stage-card.is-empty .stage-count { color: color-mix(in srgb, var(--color-text) 45%, transparent); }

@media (max-width: 380px) {
  .board { padding: 12px; }
  .stage-card { padding: 12px; min-height: 88px; }
  .stage-count { font-size: 24px; }
}

/* --------------------------------------------------------------------------
   Case detail — collapsible sections and the gallery
   -------------------------------------------------------------------------- */

/* A case with thirty updates and twenty photographs is unusable as one
   scroll, and the action buttons end up below all of it. <details> rather
   than a scripted toggle: it opens without JavaScript, and the browser
   handles the keyboard and screen-reader behaviour already. */
.see-more { margin-top: 4px; }
.see-more > summary {
  cursor: pointer;
  list-style: none;
  padding: 10px 0;
  min-height: 44px;                 /* a real tap target, not just a link */
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12.5px;
  color: var(--color-accent-700);
}
.see-more > summary::-webkit-details-marker { display: none; }
.see-more > summary::after {
  content: '▾';
  font-size: 11px;
  transition: transform 0.12s ease;
}
.see-more[open] > summary::after { transform: rotate(180deg); }
.see-more[open] > summary::before { content: ''; }
.see-more > summary:hover { text-decoration: underline; }

.see-more-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-top: 4px;
}

/* Simple key/value rows for the details that do not need a paragraph. */
.kv-list { display: flex; flex-direction: column; gap: 8px; }
.kv {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  font-size: 13.5px;
}
.kv-k {
  flex: 0 0 160px;
  color: color-mix(in srgb, var(--color-text) 58%, transparent);
}
.kv-v { flex: 1 1 200px; }

/* auto-fill rather than auto-fit: with two photographs the tiles stay tile
   sized instead of stretching to half the screen each. */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: 10px;
}

.gallery-item {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-divider);
  background: var(--color-bg);
  text-decoration: none;
  color: var(--color-text);
  overflow: hidden;
}
.gallery-item:hover { background: var(--color-surface); }

.gallery-item img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
  background: var(--color-surface);
}

.gallery-doc {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 3;
  background: var(--color-surface);
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 15px;
  letter-spacing: 0.06em;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

.gallery-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 9px 10px;
}
.gallery-name {
  font-size: 12px;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.gallery-by {
  font-size: 11px;
  line-height: 1.35;
  color: color-mix(in srgb, var(--color-text) 58%, transparent);
}

@media (max-width: 380px) {
  .gallery-grid { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); }
  .kv-k { flex-basis: 100%; }
}

/* --------------------------------------------------------------------------
   Profile menu — replaces Sign Up / Log In once somebody is signed in
   -------------------------------------------------------------------------- */

.profile-menu { position: relative; }

.profile-menu > summary {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 6px 10px 6px 6px;
  min-height: 48px;                  /* the same tap target as the buttons it replaces */
  cursor: pointer;
  list-style: none;
  border: 1px solid var(--color-divider);
  background: var(--color-bg);
  user-select: none;
}
.profile-menu > summary::-webkit-details-marker { display: none; }
.profile-menu > summary:hover { background: var(--color-surface); }

/* The one round thing in a system built entirely from square corners, and
   deliberately so: a circle of initials reads as "a person" at a glance, and
   nothing else on the page reads that way. */
.profile-avatar {
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--color-accent);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 13px;
  letter-spacing: 0.02em;
}

.profile-name {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 13.5px;
  max-width: 190px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.profile-caret {
  font-size: 10px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
  transition: transform 0.12s ease;
}
.profile-menu[open] .profile-caret { transform: rotate(180deg); }

.profile-panel {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 60;
  min-width: 230px;
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  border: 1px solid var(--color-divider);
  box-shadow: 0 8px 24px rgb(0 0 0 / 12%);
}

.profile-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--color-divider);
  background: var(--color-surface);
}
.profile-head-name { font-family: var(--font-heading); font-weight: 800; font-size: 13.5px; }
.profile-head-role {
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 58%, transparent);
}

.profile-link {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 46px;
  padding: 0 14px;
  border: 0;
  background: none;
  font: inherit;
  font-size: 13.5px;
  text-align: left;
  text-decoration: none;
  color: var(--color-text);
  cursor: pointer;
}
.profile-link:hover { background: var(--color-surface); }
.profile-link-danger { color: #a32c28; }

/* On a phone the name is the first thing to go; the circle still identifies
   the account, and the panel widens to stay reachable. */
@media (max-width: 560px) {
  .profile-name { display: none; }
  .profile-menu > summary { padding: 6px; }
  .profile-panel { min-width: 200px; }
}

/* --------------------------------------------------------------------------
   Reports — one document, in sections, printable as it stands
   -------------------------------------------------------------------------- */

.report-h {
  margin: 0 0 4px;
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 14px;
}

.report-section { display: flex; flex-direction: column; gap: 12px; }

.report-cover { border-left: 4px solid var(--color-accent); }

/* auto-fill, not auto-fit: with three figures the tiles stay tile-sized
   instead of stretching to a third of the page each. */
.report-figures {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));
  gap: 10px;
}
.report-figure {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  background: var(--color-surface);
  border-left: 3px solid var(--color-accent);
}
.report-figure-n { font-family: var(--font-heading); font-weight: 800; font-size: 20px; line-height: 1; }
.report-figure-l {
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 58%, transparent);
}

.report-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
}

.report-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.report-table th,
.report-table td {
  padding: 7px 8px;
  border-bottom: 1px solid var(--color-divider);
  text-align: left;
  vertical-align: top;
}
.report-table th {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 11.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 60%, transparent);
}
.report-table td.num,
.report-table th.num { text-align: right; white-space: nowrap; }

/* --------------------------------------------------------------------------
   Print: the report alone, on A4
   -------------------------------------------------------------------------- */
@media print {
  @page { size: A4; margin: 14mm 12mm; }

  /* The shell is navigation, not content. */
  .barcom-noprint,
  .app-header,
  .app-nav,
  .app-footer,
  .profile-menu { display: none !important; }

  body { background: #fff; color: #000; font-size: 11pt; }
  .page, .page-wide { max-width: none; padding: 0; gap: 10mm; }

  /* A section split across a page break is unreadable, and a table whose
     heading is on the previous page is worse. */
  .report-section, .report-cover { break-inside: avoid; border: 0; padding: 0; background: none; }
  .report-table { break-inside: auto; }
  .report-table tr { break-inside: avoid; break-after: auto; }
  thead { display: table-header-group; }
  tfoot { display: table-footer-group; }

  .box { border: 0; padding: 0; background: none; }
  .report-figure { border-left: 2px solid #000; background: none; }
  a[href]::after { content: ""; }   /* no printed URLs cluttering the sheet */
}

/* Referred-to-city-office panel, above the timeline on escalated cases. */
.case-agency {
  border-left: 4px solid var(--tone-amber, #b26a00);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.tag-amber {
  background: color-mix(in srgb, var(--tone-amber, #b26a00) 14%, transparent);
  color: var(--tone-amber, #b26a00);
}
.tag-accent {
  background: color-mix(in srgb, var(--color-accent) 14%, transparent);
  color: var(--color-accent-700, var(--color-accent));
}

/* --------------------------------------------------------------------------
   Analytics — exploration board
   -------------------------------------------------------------------------- */

/* auto-fill, not auto-fit: with three KPIs the tiles stay tile-sized rather
   than stretching to a third of the screen each. */
.an-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
}
.an-kpi {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 12px 14px;
  background: var(--color-surface);
  border-left: 3px solid var(--color-accent);
}
.an-kpi-l {
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 58%, transparent);
}
.an-kpi-n { font-family: var(--font-heading); font-weight: 800; font-size: 24px; line-height: 1.05; }
.an-kpi-d { font-size: 11.5px; display: flex; gap: 6px; align-items: baseline; }
.an-kpi-prev { color: color-mix(in srgb, var(--color-text) 50%, transparent); }

/* Direction is never carried by colour alone — the arrow says it too, which
   matters for anyone who cannot tell the two greens apart. */
.tone-up   { color: #1f7a3d; }
.tone-down { color: #a32c28; }
.tone-flat { color: color-mix(in srgb, var(--color-text) 52%, transparent); }

.an-rates { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px; }
.an-rate { display: flex; flex-direction: column; gap: 6px; }
.an-rate-head { display: flex; justify-content: space-between; font-size: 12.5px; }
.an-rate-n { font-family: var(--font-heading); font-weight: 800; }
.an-bar { height: 8px; background: var(--color-surface); }
.an-bar > span { display: block; height: 100%; background: var(--color-accent); }

.an-flow { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.an-stage {
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px 12px; background: var(--color-surface);
  border-top: 3px solid var(--color-accent);
}
.an-stage-name { font-family: var(--font-heading); font-weight: 700; font-size: 12.5px; }
.an-stage-n { font-family: var(--font-heading); font-weight: 800; font-size: 20px; line-height: 1.1; }
.an-stage-sub { font-size: 11px; color: color-mix(in srgb, var(--color-text) 58%, transparent); }

.an-bars { display: flex; flex-direction: column; gap: 7px; }
.an-barrow { display: grid; grid-template-columns: minmax(120px, 1fr) 3fr auto; gap: 10px; align-items: center; }
.an-barrow-l { font-size: 12.5px; }
.an-barrow-bar { height: 14px; background: var(--color-surface); }
.an-barrow-bar > span { display: block; height: 100%; background: var(--color-accent); }
.an-barrow-n { font-family: var(--font-heading); font-weight: 700; font-size: 12.5px; text-align: right; }

/* A plain column chart. Scrolls sideways inside its own box rather than
   forcing the page to, which is what makes it usable on a phone. */
.an-spark { display: flex; align-items: flex-end; gap: 3px; height: 150px; overflow-x: auto; padding-bottom: 2px; }
.an-spark-col { display: flex; flex-direction: column; justify-content: flex-end; align-items: center;
                gap: 4px; min-width: 26px; height: 100%; flex: 1 0 auto; }
.an-spark-bar { width: 100%; background: var(--color-accent); min-height: 3px; }
.an-spark-x { font-size: 9.5px; color: color-mix(in srgb, var(--color-text) 52%, transparent); white-space: nowrap; }

.an-legend { display: flex; flex-wrap: wrap; gap: 14px; font-size: 11.5px;
             color: color-mix(in srgb, var(--color-text) 60%, transparent); }
.an-sw { display: inline-block; width: 14px; height: 10px; margin-right: 5px; vertical-align: middle; }
.an-sw-1 { background: color-mix(in srgb, var(--color-accent) 25%, transparent); }
.an-sw-2 { background: color-mix(in srgb, var(--color-accent) 55%, transparent); }
.an-sw-3 { background: var(--color-accent); }

@media (max-width: 480px) {
  .an-barrow { grid-template-columns: 1fr auto; }
  .an-barrow-bar { display: none; }
}

/* Inline field guidance — used by the mobile-number and password checks. */
.field-hint { font-size: 11.5px; margin-top: 5px; display: block;
              color: color-mix(in srgb, var(--color-text) 58%, transparent); }
.field-hint-ok  { color: #1f7a3d; }
.field-hint-bad { color: #a32c28; }

.pw-rules { list-style: none; margin: 8px 0 0; padding: 0;
            display: flex; flex-wrap: wrap; gap: 6px 14px; }
.pw-rule { font-size: 11.5px; color: color-mix(in srgb, var(--color-text) 55%, transparent); }
/* The tick and cross carry the meaning as well as the colour, so the list
   still reads for anyone who cannot tell the two apart. */
.pw-rule::before { content: '○ '; }
.pw-rule-ok  { color: #1f7a3d; }
.pw-rule-ok::before { content: '✓ '; }
.pw-rule-no  { color: #a32c28; }
.pw-rule-no::before { content: '✗ '; }

/* ==========================================================================
   Landing page, public header and footer
   --------------------------------------------------------------------------
   One ordered block: tokens, header, sections top to bottom, then EVERY
   responsive rule at the end. The order is the point. Rules appended after a
   media query override it at equal specificity, and an earlier version of
   this block did exactly that — each late correction silently undid the
   phone layout, leaving the hero in two squeezed columns at 320px.

   Every landing class is prefixed ld-: .step, .steps, .stat and .hero already
   belong to the complaint wizard and would have been restyled otherwise.
   Header and nav rules are scoped to .public-layout because the dashboards
   use .app-header and .nav-link too.
   ========================================================================== */

:root { --ld-measure: 1180px; }

/* ── Public header ────────────────────────────────────────────────────── */
body.public-layout .app-header {
  padding-left:  max(20px, calc((100% - var(--ld-measure)) / 2));
  padding-right: max(20px, calc((100% - var(--ld-measure)) / 2));

  /* Travels with the page, as the dashboards' header already did via
     .app-top. On a page this long, navigation that only exists at the very
     top means scrolling back up to go anywhere. */
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--color-bg);
}
.brand-logo { width: 40px; height: 40px; object-fit: contain; flex: none; }

.public-layout .app-nav { display: flex; align-items: center; gap: 4px; }
.public-layout .nav-link {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 12px;
  font-size: 14px; font-weight: 600; text-decoration: none;
  color: color-mix(in srgb, var(--color-text) 80%, transparent);
  border-bottom: 2px solid transparent;
}
.public-layout .nav-link:hover { color: var(--color-accent); border-bottom-color: var(--color-accent); }
.public-layout .nav-link:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }

.public-layout .header-actions { display: flex; align-items: center; gap: 8px; }

.nav-toggle { position: absolute; opacity: 0; pointer-events: none; }
.nav-burger { display: none; }

/* ── Shared type ──────────────────────────────────────────────────────── */
.ld-landing { display: flex; flex-direction: column; }
.ld-landing [id] { scroll-margin-top: 80px; }

.ld-eyebrow { font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
              font-weight: 700; color: var(--color-accent); }
.ld-eyebrow-sub { font-weight: 500; letter-spacing: 0.06em;
                  color: color-mix(in srgb, var(--color-text) 60%, transparent); }
.ld-btn-lg { min-height: 50px; padding: 0 22px; font-size: 15px; }

/* ── Sections: one measure and one rhythm, used everywhere ────────────── */
.ld-lsec, .ld-closing, .site-footer-grid, .site-footer-bottom {
  padding-left:  max(24px, calc((100% - var(--ld-measure)) / 2));
  padding-right: max(24px, calc((100% - var(--ld-measure)) / 2));
}
.ld-lsec { padding-top: 80px; padding-bottom: 80px; border-bottom: 1px solid var(--color-divider);
           display: flex; flex-direction: column; gap: 36px; }
.ld-lsec-alt { background: var(--color-surface); }
.ld-lsec-head { display: flex; flex-direction: column; gap: 8px; max-width: 760px; }
.ld-lsec-head-split { max-width: none; flex-direction: row; justify-content: space-between;
                      align-items: flex-end; gap: 20px; flex-wrap: wrap; }
.ld-lsec-head-split > div { display: flex; flex-direction: column; gap: 8px; max-width: 720px; }
.ld-lsec-title { margin: 0; font-family: var(--font-heading); font-weight: 800;
                 font-size: clamp(24px, 2.4vw, 32px); letter-spacing: -0.02em; line-height: 1.15;
                 text-wrap: balance; }
.ld-lsec-lead { margin: 0; font-size: 16px; line-height: 1.6;
                color: color-mix(in srgb, var(--color-text) 72%, transparent); }

/* ── Hero ─────────────────────────────────────────────────────────────── */
.ld-hero { display: grid; grid-template-columns: minmax(0, 1.18fr) minmax(0, 1fr);
           border-bottom: 1px solid var(--color-divider); }
.ld-hero-main { display: flex; flex-direction: column; justify-content: center; gap: 20px;
                padding: 72px 48px 72px max(24px, calc((100vw - var(--ld-measure)) / 2)); }
/* Two sentences, two lines: sized so each fits the text column. */
.ld-hero-title { margin: 0; font-family: var(--font-heading); font-weight: 800;
                 font-size: clamp(28px, 2.5vw, 36px); line-height: 1.12; letter-spacing: -0.025em;
                 text-wrap: balance; }
.ld-hero-lead { margin: 0; font-size: 16.5px; line-height: 1.6; max-width: 54ch;
                color: color-mix(in srgb, var(--color-text) 78%, transparent); }
.ld-hero-sub  { margin: 0; font-size: 14.5px; max-width: 56ch;
                color: color-mix(in srgb, var(--color-text) 62%, transparent); }
.ld-hero-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 6px; }

.ld-hero-side { position: relative; min-height: 480px; background: var(--color-surface); }
.ld-hero-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* In the corner and compact: the building is the point of the photo. */
.ld-hero-card { position: absolute; right: 28px; bottom: 28px; max-width: 470px;
                background: var(--color-bg); padding: 18px 20px; display: flex; flex-direction: column; gap: 8px;
                border-top: 4px solid var(--color-accent); box-shadow: 0 10px 30px rgb(0 0 0 / 12%); }
.ld-hero-card-title { margin: 0; font-family: var(--font-heading); font-weight: 800;
                      font-size: 17px; line-height: 1.25; text-wrap: balance; }
.ld-hero-card p { margin: 0; font-size: 13px; line-height: 1.5;
                  color: color-mix(in srgb, var(--color-text) 72%, transparent); }

/* Six steps, numbered in a grid. No arrows: a wrapped row would leave one
   dangling at the start of a line. */
.ld-mini-flow { list-style: none; margin: 4px 0 0; padding: 0;
                display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.ld-mini-flow li { display: flex; align-items: center; gap: 7px; min-width: 0;
                   padding: 6px 8px; font-size: 11.5px; font-weight: 700; line-height: 1.25;
                   overflow-wrap: anywhere; background: var(--color-accent-100); color: var(--color-accent-700); }
.ld-mini-n { flex: none; display: inline-flex; align-items: center; justify-content: center;
             width: 18px; height: 18px; background: var(--color-accent); color: #fff;
             font-size: 10.5px; font-weight: 800; }

/* ── Statistics ───────────────────────────────────────────────────────── */
.ld-stat-strip { display: grid; grid-template-columns: repeat(4, 1fr); background: var(--color-bg);
                 border-bottom: 1px solid var(--color-divider);
                 padding-left:  max(0px, calc((100% - var(--ld-measure)) / 2));
                 padding-right: max(0px, calc((100% - var(--ld-measure)) / 2)); }
.ld-stat { padding: 30px 24px; display: flex; flex-direction: column; gap: 4px; }
.ld-stat:first-child { padding-left: 0; }
.ld-stat + .ld-stat { border-left: 1px solid var(--color-divider); }
.ld-stat-n { font-family: var(--font-heading); font-weight: 800; font-size: 38px;
             line-height: 1; color: var(--color-accent); }
.ld-stat-l { font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
             color: color-mix(in srgb, var(--color-text) 58%, transparent); }

/* ── About ────────────────────────────────────────────────────────────── */
.ld-about-grid { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
                 gap: 64px; align-items: start; }
.ld-prose p { margin: 0 0 14px; font-size: 15px; line-height: 1.65; max-width: 62ch; }
.ld-pillars { display: flex; flex-direction: column; border-top: 1px solid var(--color-divider); }
.ld-pillar { padding: 18px 0; border-bottom: 1px solid var(--color-divider); }
.ld-pillar-h { font-family: var(--font-heading); font-weight: 800; font-size: 13px;
               letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-accent); }
.ld-pillar p { margin: 6px 0 0; font-size: 14px; }

/* ── Process ──────────────────────────────────────────────────────────── */
.ld-steps { list-style: none; margin: 0; padding: 0; border-top: 3px solid var(--color-accent);
            display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); }
.ld-step { padding: 20px 16px 4px; display: flex; flex-direction: column; gap: 6px; }
.ld-step + .ld-step { border-left: 1px solid var(--color-divider); }
.ld-step-n { font-family: var(--font-heading); font-weight: 800; font-size: 13px; color: var(--color-accent); }
.ld-step-t { font-family: var(--font-heading); font-weight: 800; font-size: 17px; }
.ld-step p { margin: 0; font-size: 13.5px; line-height: 1.5;
             color: color-mix(in srgb, var(--color-text) 72%, transparent); }

/* ── Mission & vision ─────────────────────────────────────────────────── */
.ld-mv-grid { display: grid; grid-template-columns: 1fr 1fr; border: 1px solid var(--color-divider); }
.ld-mv-panel { padding: 30px 28px; display: flex; flex-direction: column; gap: 12px; }
.ld-mv-panel + .ld-mv-panel { border-left: 1px solid var(--color-divider); }
.ld-mv-label { font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
               font-weight: 700; color: var(--color-accent); }
.ld-mv-quote { margin: 0; font-family: var(--font-heading); font-weight: 700; font-size: 18px; line-height: 1.4; }
.ld-mv-panel p:not(.ld-mv-quote) { margin: 0; font-size: 14px;
                                   color: color-mix(in srgb, var(--color-text) 70%, transparent); }

/* ── Analytics preview ────────────────────────────────────────────────── */
.ld-preview-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.ld-preview-card { background: var(--color-bg); border: 1px solid var(--color-divider);
                   padding: 20px; display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.ld-preview-h { font-family: var(--font-heading); font-weight: 800; font-size: 14px; }
.ld-preview-note, .ld-preview-empty { margin: 0; font-size: 12px;
                                      color: color-mix(in srgb, var(--color-text) 56%, transparent); }
.ld-pbar { display: grid; grid-template-columns: minmax(110px, 1.2fr) 2fr auto; gap: 10px; align-items: center; }
.ld-pbar-l { font-size: 13px; }
.ld-pbar-track { height: 10px; background: var(--color-surface); }
.ld-pbar-track > span { display: block; height: 100%; background: var(--color-accent); }
.ld-pbar-n { font-family: var(--font-heading); font-weight: 700; font-size: 13px; text-align: right; }

/* Trend: one column per month, the month beneath, a hairline for an empty
   month so the gap is visible. Child selectors only — a descendant rule here
   once painted the month labels green along with the bars. */
.ld-pspark { display: flex; align-items: stretch; gap: 6px; height: 150px; }
.ld-pspark > .ld-pcol { flex: 1; min-width: 0; display: flex; flex-direction: column;
                        justify-content: flex-end; gap: 6px; }
.ld-pcol > .ld-pbar-v { display: block; background: var(--color-accent); min-height: 1px; }
.ld-pcol > .ld-px { font-size: 10.5px; text-align: center; white-space: nowrap; overflow: hidden;
                    color: color-mix(in srgb, var(--color-text) 55%, transparent); }

.ld-privacy-line { margin: 0; font-size: 13px; padding: 14px 16px; background: var(--color-bg);
                   border-left: 3px solid var(--color-accent); max-width: 860px; }

/* ── Geography ────────────────────────────────────────────────────────── */
.ld-geo-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; }
.ld-geo-tile { padding: 26px 24px; display: flex; flex-direction: column; gap: 6px;
               border: 1px solid var(--color-divider); }
.ld-geo-name { font-family: var(--font-heading); font-weight: 800; font-size: 16px; }
.ld-geo-n { font-family: var(--font-heading); font-weight: 800; font-size: 36px; line-height: 1.05; }
.ld-geo-sub { font-size: 12.5px; }
/* Three tints of one green, never red: concentration of reports is not
   danger, and colour is the first thing a reader interprets. */
.ld-heat-1 { background: color-mix(in srgb, var(--color-accent) 10%, var(--color-bg)); }
.ld-heat-2 { background: color-mix(in srgb, var(--color-accent) 30%, var(--color-bg)); }
.ld-heat-3 { background: color-mix(in srgb, var(--color-accent) 58%, var(--color-bg)); }
.ld-geo-legend { display: flex; flex-wrap: wrap; gap: 16px; font-size: 12px; }
.ld-geo-legend i { display: inline-block; width: 16px; height: 11px; margin-right: 6px;
                   vertical-align: middle; border: 1px solid var(--color-divider); }

/* ── Guides: the resident's leads, staff guides follow ───────────────── */
.ld-guide-primary { background: var(--color-bg); border: 1px solid var(--color-divider);
                    border-top: 4px solid var(--color-accent); padding: 28px;
                    display: flex; flex-direction: column; gap: 18px; }
.ld-guide-primary-head { display: flex; justify-content: space-between; align-items: center;
                         gap: 16px; flex-wrap: wrap; }
.ld-guide-cards { list-style: none; margin: 0; padding: 0;
                  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.ld-guide-card { display: flex; flex-direction: column; gap: 6px; padding: 16px; background: var(--color-surface); }
.ld-guide-card strong { font-family: var(--font-heading); font-size: 14.5px; }
.ld-guide-card > span:not(.ld-guide-n) { font-size: 13px; line-height: 1.5;
                                         color: color-mix(in srgb, var(--color-text) 70%, transparent); }
.ld-guide-n { display: inline-flex; align-items: center; justify-content: center;
              width: 26px; height: 26px; background: var(--color-accent); color: #fff;
              font-family: var(--font-heading); font-weight: 800; font-size: 13px; }

.ld-guide-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.ld-guide { background: var(--color-bg); border: 1px solid var(--color-divider);
            padding: 20px; display: flex; flex-direction: column; gap: 10px; }
.ld-guide-h { font-family: var(--font-heading); font-weight: 800; font-size: 14px;
              padding-bottom: 8px; border-bottom: 2px solid var(--color-accent); }
.ld-guide-primary-head .ld-guide-h { border: 0; padding: 0; font-size: 19px; }
.ld-guide-list { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 5px; font-size: 13px; }

/* ── Help ─────────────────────────────────────────────────────────────── */
.ld-help-band { background: var(--color-accent-100); }
.ld-help-inner { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 32px; align-items: center; }
.ld-help-inner > div:first-child { display: flex; flex-direction: column; gap: 12px; }
.ld-help-inner p { margin: 0; font-size: 14.5px; }
.ld-help-card { background: var(--color-bg); padding: 24px; display: flex; flex-direction: column;
                gap: 10px; border-top: 3px solid var(--color-accent); }
.ld-help-card p { font-size: 14px; line-height: 1.55; }
.ld-help-h { font-family: var(--font-heading); font-weight: 800; font-size: 13px;
             letter-spacing: 0.08em; text-transform: uppercase; }
.ld-help-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 4px; }

/* ── Team ─────────────────────────────────────────────────────────────── */
.ld-about-us { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: 48px; align-items: center; }
.ld-about-us .ld-lsec-head { gap: 12px; }
.ld-about-us .ld-lsec-head p:not(.ld-lsec-lead) { margin: 0; font-size: 14.5px; line-height: 1.6; }
/* height:auto matters: the image's height attribute otherwise overrides
   aspect-ratio and stretches the photo into a tall strip. */
.ld-about-photo { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; }
.ld-team-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.ld-member { border: 1px solid var(--color-divider); display: flex; flex-direction: column; background: var(--color-bg); }
.ld-member-photo { display: block; width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover;
                   object-position: top; background: #fff; border-bottom: 3px solid var(--color-accent); }
.ld-member-body { padding: 20px; display: flex; flex-direction: column; gap: 8px; }
.ld-member-name { margin: 0; font-family: var(--font-heading); font-weight: 800; font-size: 16px; }
.ld-member-role { font-size: 12px; font-weight: 700; color: var(--color-accent); }
.ld-member-body p { margin: 0; font-size: 13px; line-height: 1.55;
                    color: color-mix(in srgb, var(--color-text) 72%, transparent); }
.ld-member-tags { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 5px; }
.ld-member-tags li { font-size: 11px; padding: 3px 7px; background: var(--color-surface); }

/* ── Research ─────────────────────────────────────────────────────────── */
.ld-focus-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
                 border-top: 1px solid var(--color-divider); border-left: 1px solid var(--color-divider); }
.ld-focus { padding: 20px; background: var(--color-bg);
            border-right: 1px solid var(--color-divider); border-bottom: 1px solid var(--color-divider); }
.ld-focus-h { font-family: var(--font-heading); font-weight: 800; font-size: 14.5px; }
.ld-focus p { margin: 6px 0 0; font-size: 13.5px; color: color-mix(in srgb, var(--color-text) 70%, transparent); }
.ld-commitment { margin: 0; padding: 28px 30px; max-width: 880px; background: var(--color-bg);
                 border-left: 4px solid var(--color-accent); }
.ld-commitment p { margin: 0 0 10px; font-family: var(--font-heading); font-weight: 800; font-size: 20px; line-height: 1.35; }
.ld-commitment footer { font-size: 14px; color: color-mix(in srgb, var(--color-text) 70%, transparent); }

/* ── Closing and legal ────────────────────────────────────────────────── */
.ld-closing { padding-top: 88px; padding-bottom: 88px; text-align: center; border-bottom: 1px solid var(--color-divider);
              display: flex; flex-direction: column; gap: 16px; align-items: center; }
.ld-closing-title { margin: 0; font-family: var(--font-heading); font-weight: 800; max-width: 22ch;
                    font-size: clamp(24px, 3.2vw, 36px); letter-spacing: -0.02em; text-wrap: balance; }
.ld-closing > p { margin: 0; max-width: 64ch; font-size: 15px; color: color-mix(in srgb, var(--color-text) 72%, transparent); }
.ld-closing .ld-closing-final { font-family: var(--font-heading); font-weight: 700; color: var(--color-accent); }

.ld-legal { background: var(--color-surface); padding-top: 40px; padding-bottom: 40px; }
.ld-legal-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px; }
.ld-legal-h { font-family: var(--font-heading); font-weight: 800; font-size: 13px; letter-spacing: 0.06em; text-transform: uppercase; }
.ld-legal-grid p { margin: 6px 0 0; font-size: 13px; color: color-mix(in srgb, var(--color-text) 70%, transparent); }

/* ── Footer ───────────────────────────────────────────────────────────── */
.site-footer { border-top: 3px solid var(--color-accent); background: var(--color-bg); }
.site-footer-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.3fr; gap: 28px;
                    padding-top: 40px; padding-bottom: 40px; }
.site-footer-col { display: flex; flex-direction: column; gap: 6px; font-size: 13px; }
.site-footer-col a { color: var(--color-text); text-decoration: none; }
.site-footer-col a:hover { color: var(--color-accent); text-decoration: underline; }
.site-footer-col p { margin: 6px 0 0; color: color-mix(in srgb, var(--color-text) 65%, transparent); }
.site-footer-brand { display: flex; gap: 10px; align-items: center; }
.site-footer-brand div { display: flex; flex-direction: column; }
.site-footer-brand strong { font-family: var(--font-heading); font-size: 16px; }
.site-footer-brand span { font-size: 12px; color: color-mix(in srgb, var(--color-text) 62%, transparent); }
.site-footer-h { font-family: var(--font-heading); font-weight: 800; font-size: 12px;
                 letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 4px; }
.site-footer-bottom { display: flex; flex-wrap: wrap; gap: 8px 22px; justify-content: space-between;
                      padding-top: 18px; padding-bottom: 18px; border-top: 1px solid var(--color-divider);
                      font-size: 12px; color: color-mix(in srgb, var(--color-text) 60%, transparent); }
.site-footer-legal { display: flex; gap: 14px; }
.site-footer-legal a { color: inherit; }

/* ── The two marks on the log-in and sign-up panels ───────────────────── */
.auth-seals { display: flex; align-items: center; gap: 14px; margin-bottom: 20px; }
.auth-seal {
  width: 76px; height: 76px; object-fit: contain;
  /* White disc behind each: the panel is deep green, and both marks carry
     green of their own that would otherwise disappear into it. */
  background: #fff; border-radius: 50%; padding: 8px; flex: none;
}
/* The city seal is a circle and is shown as one. The BARCOM mark is a square
   wordmark, and forcing it into a disc clipped the lettering at the edges —
   so it gets a rounded square instead. Each mark keeps its own shape. */
.auth-seal-barcom { border-radius: 14px; padding: 8px; }

@media (max-width: 640px) {
  .auth-centre { padding: 20px 14px; align-items: flex-start; }
  .auth-seals { gap: 10px; margin-bottom: 10px; }
  .auth-seal { width: 60px; height: 60px; padding: 5px; }
}

/* ==========================================================================
   Responsive — every breakpoint rule lives here, after all base rules
   ========================================================================== */

@media (max-width: 1100px) {
  .ld-steps { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ld-steps .ld-step:nth-child(4) { border-left: 0; }
  .ld-steps .ld-step:nth-child(n+4) { border-top: 1px solid var(--color-divider); }
  .ld-team-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ld-guide-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ld-guide-row { grid-template-columns: 1fr; }
  .site-footer-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 860px) {
  /* Header: a menu button replaces the inline links. */
  .public-layout .app-header { flex-wrap: wrap; position: relative; }
  .public-layout .nav-burger { display: flex; flex-direction: column; justify-content: center; gap: 5px;
                               width: 44px; height: 44px; margin-left: auto; cursor: pointer;
                               border: 1px solid var(--color-divider); }
  .public-layout .nav-burger span { display: block; height: 2px; margin: 0 11px; background: var(--color-text); }
  .public-layout .app-nav { display: none; order: 10; width: 100%; flex-direction: column; gap: 0;
                            border-top: 1px solid var(--color-divider); }
  .public-layout .app-nav .nav-link { padding: 14px 4px; border-bottom: 1px solid var(--color-divider); }
  .public-layout .nav-toggle:checked ~ .app-nav { display: flex; }
  .public-layout .nav-toggle:focus-visible + .nav-burger { outline: 2px solid var(--color-accent); outline-offset: 2px; }

  /* Every two-column section becomes one. */
  .ld-hero, .ld-about-grid, .ld-mv-grid, .ld-preview-grid, .ld-help-inner,
  .ld-about-us, .ld-legal-grid { grid-template-columns: 1fr; }

  /* Hero: text first, then the photo, then the card beneath it rather than
     laid over it, where it would hide most of the picture. */
  .ld-hero-main { padding: 40px 20px; }
  .ld-hero-title { font-size: 28px; }
  .ld-hero-side { min-height: 0; }
  .ld-hero-photo { position: static; height: 220px; }
  .ld-hero-card { position: static; max-width: none; box-shadow: none; }

  .ld-stat-strip { grid-template-columns: 1fr 1fr; }
  .ld-stat, .ld-stat:first-child { padding: 22px 20px; }
  .ld-stat:nth-child(3) { border-left: 0; }
  .ld-stat:nth-child(n+3) { border-top: 1px solid var(--color-divider); }

  .ld-lsec { padding-top: 52px; padding-bottom: 52px; gap: 26px; }
  .ld-about-grid, .ld-about-us { gap: 28px; }
  .ld-mv-panel + .ld-mv-panel { border-left: 0; border-top: 1px solid var(--color-divider); }

  .ld-steps { grid-template-columns: 1fr; border-top: 0; border-left: 3px solid var(--color-accent); }
  .ld-steps .ld-step { border-left: 0; border-top: 1px solid var(--color-divider); padding: 16px; }
  .ld-steps .ld-step:first-child { border-top: 0; }

  .ld-focus-grid { grid-template-columns: 1fr; }
  .ld-guide-primary { padding: 20px; }
  .ld-closing { padding-top: 56px; padding-bottom: 56px; }
  .site-footer-grid { padding-top: 28px; padding-bottom: 28px; }
}

@media (max-width: 520px) {
  .ld-team-grid, .ld-guide-cards, .site-footer-grid { grid-template-columns: 1fr; }
  .ld-stat-n { font-size: 30px; }
  .ld-mini-flow { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ld-pbar { grid-template-columns: 1fr auto; }
  .ld-pbar-track { display: none; }
  .ld-preview-card { padding: 16px; }
  /* Twelve month labels cannot fit; every third is shown. Every column is
     still drawn, so no month disappears — only its caption. */
  .ld-pspark { gap: 3px; }
  .ld-pcol > .ld-px { visibility: hidden; }
  .ld-pcol:nth-child(3n+1) > .ld-px { visibility: visible; }
}

@media (max-width: 400px) {
  .ld-hero-main { padding-left: 18px; padding-right: 18px; }
  .ld-hero-title { font-size: 25px; }
  .ld-hero-actions { flex-direction: column; align-items: stretch; }
  .ld-hero-actions .btn { justify-content: center; }
}

/* ── Cases board: quick actions ───────────────────────────────────────────
   A short row under each board heading, pointing at the stages that are
   waiting on somebody. The board says how much there is; this says what to
   open first. Hidden entirely when a board is up to date. */
.board-quick { display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
               padding: 10px 0 2px; }
.board-quick-label { font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase;
                     font-weight: 700; color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.board-quick-link {
  display: inline-flex; align-items: center; gap: 7px; min-height: 34px;
  padding: 0 11px; font-size: 12.5px; font-weight: 600; text-decoration: none;
  color: var(--color-text); background: var(--color-bg);
  border: 1px solid var(--color-divider);
}
.board-quick-link:hover { border-color: var(--color-accent); color: var(--color-accent); }
.board-quick-n { font-family: var(--font-heading); font-weight: 800; font-size: 12px;
                 padding: 1px 6px; background: var(--tone-amber, var(--color-surface));
                 color: var(--tone-amber-fg, var(--color-text)); }
@media (max-width: 520px) { .board-quick { gap: 6px; } }


/* ── Form controls: one height, one baseline ──────────────────────────────
   Applied to the control itself rather than to each usage, so a field added
   later lines up without anyone remembering to say so. Inline heights still
   win where a control is deliberately bigger (the large hero buttons). */
.input,
select.input,
input.input,
.filter-bar .input,
.filter-bar select { min-height: var(--control-h); }

/* Textareas keep the height they already had (see textarea.input above).
   They are sized by the amount of writing expected, not by the row they sit
   in — an earlier version of this block set them all to 96px and quietly
   shrank the narrative box on the Incident Log Form. */

/* Buttons that sit in a row of fields match them. */
.filter-bar .btn,
.form-actions .btn { min-height: var(--control-h); }

/* Labels sit directly above their control with the same gap everywhere, so
   two fields side by side start their inputs on the same line even when one
   label wraps to two lines and the other does not. */
.field { display: flex; flex-direction: column; gap: 6px; }
.field > label { line-height: 1.3; }
.form-grid > .field { align-self: stretch; }
/* The control is pushed to the bottom of the field, which is what keeps a
   one-line label and a two-line label aligned on the input rather than on
   the label. */
.form-grid > .field > .input,
.form-grid > .field > select,
.form-grid > .field > textarea { margin-top: auto; }

/* A search input is not a plain text box to the browser: it carries a native
   search widget with sizing of its own, which made it render two pixels
   taller than the dropdowns beside it even with identical font, padding and
   min-height. Turning the appearance off makes it an ordinary field again,
   so the filter row on the Cases Board, Citizens and Track sits level. */
input[type="search"] {
  appearance: none;
  -webkit-appearance: none;
}
/* Chrome's clear button is part of that widget; without it the field would
   lose its "x". Kept, sized to the row. */
input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  width: 14px; height: 14px; cursor: pointer;
  background: currentColor;
  opacity: 0.45;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 4l8 8M12 4l-8 8' stroke='black' stroke-width='2' fill='none'/%3E%3C/svg%3E") center/contain no-repeat;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 4l8 8M12 4l-8 8' stroke='black' stroke-width='2' fill='none'/%3E%3C/svg%3E") center/contain no-repeat;
}
input[type="search"]::-webkit-search-cancel-button:hover { opacity: 0.8; }

/* A field and its button on one line. Both take the shared control height, so
   neither stretches the other: a flex row sizes itself to its tallest child,
   which is how a 48px button used to drag a 46px search box up with it. */
.field-row { display: flex; gap: 8px; align-items: stretch; }
.field-row > .input { flex: 1; min-width: 0; min-height: var(--control-h); }
.field-row > .btn   { flex: none; min-height: var(--control-h); }

/* ── Wide tables on a narrow screen ───────────────────────────────────────
   A table with six or seven columns cannot shrink to a phone without either
   becoming unreadable or pushing the whole page sideways — and a page that
   scrolls sideways hides content people never find, because nothing suggests
   it is there.

   So the TABLE scrolls inside its own box instead, and the page does not.
   Wrapping happens here rather than in markup so every table is covered,
   including ones added later. */
.data-table,
.report-table { display: block; max-width: 100%; overflow-x: auto; }
/* display:block on a table detaches its internal layout, so the inner table
   element is restored explicitly. */
.data-table > thead, .report-table > thead,
.data-table > tbody, .report-table > tbody,
.data-table > tfoot, .report-table > tfoot { display: table; width: 100%; min-width: max-content; }

@media (min-width: 861px) {
  /* Back to an ordinary table where there is room for one. */
  .data-table, .report-table { display: table; overflow-x: visible; }
  .data-table > thead, .report-table > thead,
  .data-table > tbody, .report-table > tbody,
  .data-table > tfoot, .report-table > tfoot { display: table-row-group; min-width: 0; }
  .data-table > thead, .report-table > thead { display: table-header-group; }
}

/* The resident's top navigation scrolls rather than pushing the page over:
   three links plus a long label ran three pixels past the edge on a 390px
   screen, which is enough to make the whole page shift when swiped. */
@media (max-width: 520px) {
  .top-nav { overflow-x: auto; }
  .top-nav-link { white-space: nowrap; }
}

/* ── The language toggle ──────────────────────────────────────────────────
   One button, both options visible, the current one filled in. A dropdown
   was the wrong control for a choice of two: it turned one tap into four and
   took the width of a real field in the header. */
.lang-toggle { display: flex; align-items: center; }
.lang-toggle-btn {
  display: inline-flex; align-items: stretch; cursor: pointer;
  padding: 0; background: none;
  border: 1px solid var(--color-divider);
  font-family: var(--font-heading); font-weight: 800; font-size: 11.5px;
  letter-spacing: 0.04em; line-height: 1;
}
.lang-toggle-btn:hover { border-color: var(--color-accent); }
.lang-toggle-btn:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.lang-toggle-half {
  display: flex; align-items: center; padding: 0 9px; min-height: 30px;
  color: color-mix(in srgb, var(--color-text) 52%, transparent);
}
/* The current language is the filled half, so which one is active is read
   from the shape rather than from remembering what the button does. */
.lang-toggle-half.is-on { background: var(--color-accent); color: #fff; }

/* ── The analytics map ────────────────────────────────────────────────── */
.an-map {
  /* Tall enough to read three barangays apart, short enough that the numbers
     below it stay on the same screen. Capped against the viewport so it can
     never fill a laptop display. */
  height: clamp(220px, 34vh, 340px);
  width: 100%;
  border: 1px solid var(--color-divider);
}
.an-map-dot {
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; color: #fff; cursor: pointer;
  font-family: var(--font-heading); font-weight: 800; font-size: 12px;
  border: 2px solid rgba(255,255,255,.85);
}
@media (max-width: 640px) { .an-map { height: clamp(200px, 30vh, 260px); } }

/* ── Cases board: entries first, counts after ─────────────────────────────
   .page is a flex column, so the order is set here rather than by moving the
   markup. The list is what people came to work through; the board's numbers
   summarise it, and a summary belongs after the thing it sums up. */
.case-section-first { order: 1; }
.board-after        { order: 2; }

/* Each board folds away. The summary carries the pointer and the marker, so
   the whole heading row is the control. */
details.board > summary { cursor: pointer; list-style: none; }
details.board > summary::-webkit-details-marker { display: none; }
details.board > summary::after {
  content: '▾'; margin-left: 10px; font-size: 12px; flex: none;
  transition: transform .15s ease;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
details.board[open] > summary::after { transform: rotate(180deg); }

/* ── The filter row ───────────────────────────────────────────────────────
   One grid for every control, so Search, Sort, Show and Category share a
   baseline instead of each sizing itself. On a phone they stack: four
   controls squeezed onto one line are four controls nobody can read. */
.filter-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  align-items: end;
}
.filter-grid > .field { min-width: 0; }
@media (max-width: 640px) {
  .filter-grid { grid-template-columns: 1fr; }
  .field-row { flex-direction: column; align-items: stretch; }
  .field-row > .btn { width: 100%; }
}

/* ── An update that brought no paperwork ──────────────────────────────────
   The marker on the line turns red and the entry says so in words. Not every
   update should carry a file, so this reads as a prompt to look rather than
   as a fault. */
.tl-noattach {
  align-self: flex-start;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 2px 7px;
  color: var(--tone-red-fg, #a3282d);
  border: 1px solid color-mix(in srgb, var(--tone-red-fg, #a3282d) 40%, transparent);
}

/* What a document IS, above what its file is called. */
.gallery-doc-label {
  font-family: var(--font-heading); font-weight: 800; font-size: 11px;
  line-height: 1.25; color: var(--color-accent);
}

/* The paperwork a case carries, on the entry lists. */
.doc-summary { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 4px; }
.doc-summary-tag {
  font-size: 10.5px; font-weight: 600; padding: 1px 6px;
  border: 1px solid var(--color-divider);
  color: color-mix(in srgb, var(--color-text) 72%, transparent);
}
.doc-summary-none {
  font-size: 10.5px; font-weight: 600; padding: 1px 6px;
  color: var(--tone-red-fg, #a3282d);
  border: 1px solid color-mix(in srgb, var(--tone-red-fg, #a3282d) 35%, transparent);
}

/* ── Location suggestions ─────────────────────────────────────────────── */
.geo-results {
  display: flex; flex-direction: column;
  border: 1px solid var(--color-divider); background: var(--color-bg);
  max-height: 210px; overflow-y: auto;
}
.geo-result {
  text-align: left; padding: 9px 11px; font-size: 13px; line-height: 1.35;
  background: none; border: 0; border-bottom: 1px solid var(--color-divider);
  cursor: pointer; color: var(--color-text);
}
.geo-result:last-child { border-bottom: 0; }
.geo-result:hover { background: var(--color-surface); color: var(--color-accent); }

/* ── Image viewer ─────────────────────────────────────────────────────────
   Opening a photograph used to take over a new browser tab, which loses the
   case you were reading and shows the image at whatever size the file
   happens to be — often far larger than the screen. This keeps it in the
   page and fits it to the window instead. */
.lightbox {
  position: fixed; inset: 0; z-index: 120;
  display: flex; align-items: center; justify-content: center;
  padding: 28px;
  background: rgba(12, 18, 14, .88);
}
.lightbox[hidden] { display: none; }

.lightbox-figure {
  display: flex; flex-direction: column; gap: 10px;
  max-width: 100%; max-height: 100%;
}
/* The image never exceeds the window, whatever its real size. */
.lightbox-img {
  max-width: 100%;
  max-height: calc(100vh - 128px);
  object-fit: contain;
  background: #fff;
  display: block; margin: 0 auto;
}
.lightbox-cap {
  color: #fff; font-size: 12.5px; text-align: center; text-wrap: pretty;
  display: flex; flex-direction: column; gap: 2px;
}
.lightbox-cap b { font-family: var(--font-heading); font-size: 13px; }

.lightbox-close {
  position: absolute; top: 14px; right: 16px;
  width: 42px; height: 42px; cursor: pointer;
  background: rgba(255,255,255,.12); color: #fff;
  border: 1px solid rgba(255,255,255,.35);
  font-size: 20px; line-height: 1;
}
.lightbox-close:hover { background: rgba(255,255,255,.22); }

.lightbox-open {
  position: absolute; bottom: 14px; right: 16px;
  color: #fff; font-size: 12px; text-decoration: underline;
  background: none; border: 0; cursor: pointer;
}
@media (max-width: 640px) {
  .lightbox { padding: 14px; }
  .lightbox-img { max-height: calc(100vh - 150px); }
}

/* ── On/off switch ────────────────────────────────────────────────────────
   Still a checkbox underneath, so it posts the same value, works from the
   keyboard and needs no JavaScript.

   Every colour here is a plain value with a variable only as an override.
   The first version built the track with color-mix() on a custom property;
   if that property is not resolvable the WHOLE declaration is dropped, which
   left a transparent track and a white knob floating over the caption. A
   switch that renders as a stray dot is worse than a plain checkbox. */
.switch {
  position: relative;               /* so the hidden input has an anchor */
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  padding: 2px 0;
}

/* Hidden from sight, not from the keyboard or a screen reader:
   display:none would take it out of the tab order entirely. */
.switch > input[type="checkbox"] {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  margin: 0;
  pointer-events: none;
}

.switch-track {
  position: relative;
  flex: 0 0 auto;
  box-sizing: border-box;
  display: block;
  width: 44px;
  height: 24px;
  background: #c8ccc9;              /* plain grey: always renders */
  border: 1px solid #b0b5b2;
  border-radius: 999px;
  transition: background .16s ease, border-color .16s ease;
}

.switch-knob {
  position: absolute;
  top: 2px; left: 2px;
  box-sizing: border-box;
  width: 18px; height: 18px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .3);
  transition: transform .16s ease;
}

.switch > input:checked + .switch-track {
  background: #15653f;
  background: var(--color-accent, #15653f);
  border-color: #114f31;
}
.switch > input:checked + .switch-track .switch-knob { transform: translateX(20px); }

.switch > input:focus-visible + .switch-track {
  outline: 2px solid var(--color-accent, #15653f);
  outline-offset: 2px;
}

.switch-label { font-size: 14px; line-height: 1.4; }

/* ── On / off, said in the corner ─────────────────────────────────────────
   A dot beside the words, so the state is readable at a glance from the top
   of the panel without hunting for the switch. Never colour alone: the word
   stays next to it, for anyone who cannot tell the two apart. */
.state-flag { display: inline-flex; align-items: center; gap: 6px; }
.state-dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: #b23b3b;
  flex: 0 0 auto;
}
.state-dot.is-on { background: #1c7c4a; }

/* The switch on its own line, set apart from the fields it governs: turning
   the feature on is a different kind of decision from filling in a key. */
.switch-row {
  display: flex; align-items: center;
  padding: 10px 0 14px;
  border-bottom: 1px solid var(--color-divider);
  margin-bottom: 14px;
}

/* ── Attachment tools ─────────────────────────────────────────────────────
   Download and print sit under the tile rather than on it: on the tile they
   would be pressed by accident by anyone reaching for the photograph. */
.gallery-cell { display: flex; flex-direction: column; }
.gallery-tools {
  display: flex; gap: 1px; margin-top: -1px;
}
.gallery-tool {
  flex: 1; text-align: center; cursor: pointer;
  padding: 5px 4px; font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.04em; text-transform: uppercase; text-decoration: none;
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
}
.gallery-tool:hover { color: var(--color-accent); border-color: var(--color-accent); }

/* The stage and the paperwork for it, read together at the end of a row. */
.row-side {
  display: flex; flex-direction: column; align-items: flex-end; gap: 5px;
  flex: 0 1 auto; min-width: 0; max-width: 46%;
}
.row-side .doc-summary { justify-content: flex-end; margin-top: 0; }
@media (max-width: 640px) {
  .row-side { align-items: flex-start; max-width: 100%; }
  .row-side .doc-summary { justify-content: flex-start; }
}

/* ── Map legend ───────────────────────────────────────────────────────────
   The colours mean nothing without it, and a legend the reader has to
   remember from another page is no legend at all. */
.map-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; padding: 2px 0; }
.map-legend-item { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; }
.map-legend-dot {
  width: 11px; height: 11px; flex: none;
  border: 1px solid color-mix(in srgb, #333 60%, transparent);
  border: 1px solid #555;            /* plain fallback, so white still shows */
}
/* Leaflet sets its own stacking; keep it under the dialogs and the viewer. */
.leaflet-pane, .leaflet-control { z-index: 5 !important; }

/* ── Category colour ──────────────────────────────────────────────────────
   The swatch sits beside the name so the colour and the category are learned
   together, rather than by cross-referencing a legend on another page. */
.cat-swatch {
  width: 14px; height: 14px; flex: none;
  border: 1px solid #555;              /* so white is still a visible chip */
  display: inline-block;
}
.cat-color-form { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.cat-color-input {
  width: 46px; height: 30px; padding: 2px; cursor: pointer;
  border: 1px solid var(--color-divider); background: var(--color-bg);
}

/* The category label in a chart row carries its swatch, so the chart and the
   map are read with one palette rather than two. */
.an-barrow-l { display: inline-flex; align-items: center; gap: 7px; }

/* ── What the categoriser has been doing ──────────────────────────────────
   Every failure path in the categoriser is quiet by design, so a complaint is
   never blocked by a third party being down. Quiet is not the same as
   invisible: this is where it says what happened. */
.ai-status { display: flex; flex-direction: column; gap: 6px; padding: 12px 0 4px; }
.ai-status-warn { color: var(--tone-amber-fg, #8a5a00); }
.ai-log { display: flex; flex-direction: column; gap: 3px; }
.ai-log-row { display: flex; flex-wrap: wrap; gap: 10px; font-size: 12px; align-items: baseline; }
.ai-log-when { min-width: 118px; color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.ai-log-out {
  font-weight: 700; text-transform: uppercase; font-size: 10.5px; letter-spacing: 0.05em;
  padding: 1px 6px; border: 1px solid var(--color-divider);
}
.ai-out-suggested { color: #14532d; border-color: #14532d; }
.ai-out-failed, .ai-out-disabled { color: #a3282d; border-color: #a3282d; }
.ai-log-err { color: color-mix(in srgb, var(--color-text) 70%, transparent); }

/* ── Log in / sign up: centred, whichever markup is in place ──────────────
   The rebuilt views use .auth-centre. These rules make the OLD markup
   (.auth-split with a green .auth-panel beside the form) render the same
   way, so a stale view file left behind by a partial copy still produces a
   centred form rather than the two-column layout.

   Written after the original .auth-split rules on purpose: later wins, and
   this must beat them. */
.auth-split {
  display: flex !important;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 24px 16px;
}

/* The side panel carried a seal and a slogan. On a phone it pushed the form
   below the fold, which is the whole reason it is going. The seals now live
   above the form; nothing is lost by hiding it. */
.auth-split > .auth-panel { display: none !important; }

.auth-split > .auth-pane {
  max-width: 440px;
  width: 100%;
  margin: 0;
  padding: 0;
}

/* A stale view has no seals above the form, so it falls back to the BARCOM
   wordmark in the header — which every auth page already carries. */
@media (max-width: 640px) {
  .auth-split { padding: 20px 14px; align-items: flex-start; }
}

/* ── Log in / sign up: a card on a dark green field ───────────────────────
   The form sits in a white container so it reads as one object with an edge,
   and the page behind it carries the barangay's green. Applied to both the
   new markup and the old, for the same reason as the rules above: whichever
   view file is on disk, the page should look right. */
.auth-centre,
.auth-split {
  background: #15653f;
  background: var(--color-accent, #15653f);
}

.auth-centre > .auth-pane,
.auth-split  > .auth-pane {
  background: var(--color-bg, #fff);
  border: 1px solid rgba(0, 0, 0, .10);
  /* Enough lift to sit off the green without looking like it floats. */
  box-shadow: 0 10px 30px rgba(0, 0, 0, .18);
  padding: 30px 28px 34px;
  max-width: 460px;
  width: 100%;
}

/* The seals sat on green before and carried their own white disc for
   contrast. On a white card that disc is invisible padding, so they shrink
   back to their own shape. */
.auth-centre .auth-seal,
.auth-split  .auth-seal { background: transparent; }

/* Room to breathe above and below on a tall screen, and the card still
   reaches the top on a short one rather than being cut off. */
.auth-centre, .auth-split { padding: 32px 16px; }

@media (max-width: 640px) {
  .auth-centre, .auth-split { padding: 16px 12px; align-items: flex-start; }
  .auth-centre > .auth-pane,
  .auth-split  > .auth-pane { padding: 22px 18px 26px; }
}

/* ── A desk, with a way to take it off ────────────────────────────────────
   The chip carries its own remove button rather than a separate edit mode:
   one click to grant, one to withdraw, and the current state always visible.
   The form inside is why the chip is inline-flex — a form is a block by
   default and would break the row. */
.desk-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 4px 3px 10px; font-size: 12.5px; font-weight: 600;
  border: 1px solid var(--color-divider); background: var(--color-bg);
}
.desk-chip.is-confidential {
  border-color: var(--color-accent);
  color: var(--color-accent);
}
.desk-chip form { display: inline-flex; margin: 0; }
.desk-chip-x {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; cursor: pointer; font-size: 15px; line-height: 1;
  background: none; border: 0; color: inherit; opacity: .55;
}
.desk-chip-x:hover { opacity: 1; color: #a3282d; }

/* ── AI case assessment (staff verification) ───────────────────────────── */
.asmt-form { display:flex; flex-direction:column; gap:12px; }
.asmt-grid { display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:12px; }
.asmt-grid .asmt-wide { grid-column:1 / -1; }
.asmt-grid .field { margin:0; display:flex; flex-direction:column; gap:4px; min-width:0; }
.asmt-grid .input { width:100%; }
.asmt-grid textarea.input { resize:vertical; }
.asmt-form .input:disabled { opacity:.85; cursor:not-allowed; }
.asmt-ai { border-left:3px solid #2563eb; padding:6px 10px; background:#eff6ff; display:flex; flex-direction:column; gap:4px; }
body.dark .asmt-ai { background:#172554; }
@media (max-width:640px) { .asmt-grid { grid-template-columns:1fr; } }

/* ── Result pop-ups (success / failed) and the resident prompt ─────────── */
.result-pop-backdrop {
  position: fixed; inset: 0; z-index: 130;
  display: flex; align-items: center; justify-content: center;
  padding: 16px; background: rgba(10, 20, 14, .55);
  animation: resultFade .15s ease-out;
}
.result-pop {
  width: 100%; max-width: 400px; background: var(--color-surface, #fff); color: var(--color-text, #111);
  border-radius: 14px; padding: 28px 22px 20px; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  box-shadow: 0 18px 50px rgba(0,0,0,.3); border-top: 6px solid #16a34a;
  animation: resultRise .18s ease-out;
}
.result-pop.is-failed { border-top-color: #dc2626; background: #fef2f2; color: #7f1d1d; }
.result-pop.is-ask    { border-top-color: var(--color-accent, #166534); }
.result-pop-icon {
  width: 72px; height: 72px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font: 700 40px/1 system-ui, sans-serif; color: #fff; background: #16a34a;
  box-shadow: 0 0 0 8px rgba(22, 163, 74, .15);
}
.result-pop.is-failed .result-pop-icon { background: #dc2626; box-shadow: 0 0 0 8px rgba(220, 38, 38, .18); }
.result-pop.is-ask .result-pop-icon    { background: var(--color-accent, #166534); box-shadow: 0 0 0 8px rgba(22, 101, 52, .15); }
.result-pop-title { font-weight: 800; font-size: 22px; letter-spacing: -.01em; }
.result-pop.is-failed .result-pop-title { color: #b91c1c; }
.result-pop-msg { margin: 0; font-size: 15px; line-height: 1.45; text-wrap: pretty; }
.result-pop-msg.is-secondary { opacity: .75; font-size: 13.5px; }
.result-pop-ok { min-height: 46px; min-width: 140px; justify-content: center; margin-top: 6px; }
.result-pop-btn-fail { background: #dc2626; border-color: #dc2626; color: #fff; }
.result-pop-btn-fail:hover { background: #b91c1c; }
.result-pop-row { display: flex; gap: 10px; width: 100%; margin-top: 6px; }
.result-pop-row .btn { flex: 1; min-height: 48px; justify-content: center; }
body.dark .result-pop.is-failed { background: #3b0d0d; color: #fecaca; }
body.dark .result-pop.is-failed .result-pop-title { color: #fca5a5; }
@keyframes resultFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes resultRise { from { transform: translateY(10px) scale(.97); opacity: 0; } to { transform: none; opacity: 1; } }

/* ── Timeline / Gallery pop-up panels ─────────────────────────────────── */
.case-history-buttons { display: flex; flex-wrap: wrap; gap: 10px; flex-direction: row; }
.case-history-buttons .btn { flex: 1 1 200px; min-height: 48px; justify-content: center; }
.popup-panel { z-index: 95; }
.popup-wide { width: 100%; max-width: 820px; display: flex; flex-direction: column; gap: 12px; }
.popup-head { display: flex; align-items: center; justify-content: space-between; gap: 10px;
              position: sticky; top: 0; z-index: 2; background: var(--color-surface); padding-bottom: 6px; }
.popup-head .btn { min-height: 40px; min-width: 40px; font-size: 22px; line-height: 1; }

/* ── Keyword tiers: HIGH / MEDIUM / LOW side by side ──────────────────── */
.kw-tiers { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; align-items: start; }
.kw-tiers > .kw-tier { min-width: 0; margin: 0; }
@media (max-width: 760px) { .kw-tiers { grid-template-columns: 1fr; } }

/* ── "What is Notes for?" under each action dialog's Note box ─────────── */
.note-help { display: block; font-size: 12.5px; line-height: 1.45; opacity: .8; margin-bottom: 4px; }
.note-help strong { display: block; margin-top: 2px; }
.action-success { border-top: 6px solid #16a34a; } .action-success .dialog-actions { width: 100%; }
.kw-drop > summary { cursor: pointer; } .kw-drop[open] > .kw-tiers { margin-top: 12px; }

/* ── Entry List: recent generated forms ───────────────────────────────── */
.entry-forms-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; }
.entry-form { display: flex; flex-direction: column; gap: 4px; padding: 10px 12px; border: 1px solid var(--color-border, #cbd5c0);
              border-left: 4px solid #d97706; text-decoration: none; color: inherit; background: var(--color-surface); }
.entry-form:hover { border-color: var(--color-accent); }
.entry-form-label { font-weight: 700; font-size: 14px; line-height: 1.3; }
.entry-form-status { align-self: flex-start; font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 999px; }
.entry-form-status.is-ok, .entry-row-form.is-ok { background: #dcfce7; color: #166534; }
.entry-form-status.is-draft, .entry-row-form.is-draft { background: #fef3c7; color: #92400e; }
.entry-forms-list .entry-form:has(.is-ok) { border-left-color: #16a34a; }
.entry-row-form { display: inline-block; margin-top: 4px; font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 999px; max-width: 100%; }

/* ── Forgot-password modal ─────────────────────────────────────────────── */
.fp-backdrop { z-index: 110; place-items: center; }
.fp-dialog { width: 100%; max-width: 440px; display: flex; flex-direction: column; gap: 14px; border-top: 6px solid var(--color-accent, #166534); }
.fp-head { display: flex; align-items: center; justify-content: space-between; }
.fp-x { min-height: 40px; min-width: 40px; font-size: 22px; line-height: 1; }
.fp-steps { list-style: none; margin: 0; padding: 0; display: flex; gap: 6px; }
.fp-steps li { flex: 1; display: flex; align-items: center; gap: 6px; font-size: 12px; opacity: .5; }
.fp-steps li span { width: 22px; height: 22px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
                    font-weight: 700; font-size: 12px; background: var(--color-neutral-200, #e5e7eb); }
.fp-steps li.is-on { opacity: 1; font-weight: 600; }
.fp-steps li.is-on span { background: var(--color-accent, #166534); color: #fff; }
.fp-steps li.is-done span { background: #16a34a; color: #fff; }
.fp-step { display: flex; flex-direction: column; gap: 12px; }
.fp-step[hidden] { display: none; }
.fp-step.is-busy { opacity: .6; pointer-events: none; }
.fp-text { margin: 0; font-size: 14px; line-height: 1.45; text-wrap: pretty; }
.fp-btn { min-height: 48px; justify-content: center; font-size: 15px; }
.fp-code { font: 700 26px/1 ui-monospace, monospace; letter-spacing: .45em; text-align: center; min-height: 56px; }
.fp-alert { margin: 0; padding: 10px 12px; border-radius: 8px; font-size: 14px; background: #fef2f2; color: #b91c1c; border: 1px solid #fca5a5; }
.fp-alert.is-ok { background: #f0fdf4; color: #166534; border-color: #86efac; }
.fp-ok { display: flex; gap: 12px; align-items: center; padding: 12px; border-radius: 10px; background: #f0fdf4; border: 2px solid #16a34a; color: #14532d; font-size: 13.5px; }
.fp-ok[hidden] { display: none; }
.fp-ok-icon { flex: none; width: 40px; height: 40px; border-radius: 50%; background: #16a34a; color: #fff;
              display: flex; align-items: center; justify-content: center; font: 700 22px/1 system-ui, sans-serif; }
.fp-links { display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.fp-links[hidden] { display: none; }
.fp-link { background: none; border: 0; padding: 6px 0; color: var(--color-accent-700, #166534); font: inherit; font-size: 13.5px; text-decoration: underline; cursor: pointer; }
.fp-pw { position: relative; }
.fp-pw .input { width: 100%; padding-right: 64px; min-height: 46px; }
.fp-eye { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); background: none; border: 0; font-size: 12.5px;
          font-weight: 600; color: var(--color-accent-700, #166534); cursor: pointer; padding: 6px; }
.fp-rules { list-style: none; margin: 6px 0 0; padding: 0; display: grid; gap: 3px; font-size: 12.5px; }
.fp-rules li::before { content: '\2715'; display: inline-block; width: 18px; color: #b91c1c; }
.fp-rules li.is-ok { color: #15803d; }
.fp-rules li.is-ok::before { content: '\2713'; color: #15803d; }
.fp-match { font-size: 12.5px; min-height: 16px; }
.fp-match.is-ok { color: #15803d; } .fp-match.is-bad { color: #b91c1c; }
.fp-done { align-items: center; text-align: center; }
body.dark .fp-ok { background: #052e16; color: #bbf7d0; }
body.dark .fp-alert { background: #3b0d0d; color: #fecaca; }
.fp-step .input.is-invalid { border-color: #dc2626; box-shadow: 0 0 0 3px rgba(220,38,38,.15); } a.fp-btn[hidden] { display: none; }

/* ── Resident: Pending / Validated complaint form box ─────────────────── */
.client-form-box { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; justify-content: space-between; border-left: 5px solid #d97706; }
.client-form-box.is-validated { border-left-color: #16a34a; }

/* ── Install-the-app bar (PWA) ─────────────────────────────────────────── */
.pwa-bar { position: fixed; left: 50%; bottom: 16px; transform: translateX(-50%); z-index: 100;
           width: calc(100% - 32px); max-width: 520px; display: flex; align-items: center; gap: 12px;
           padding: 10px 12px; background: var(--color-surface, #fff); color: var(--color-text, #111);
           border: 1px solid var(--color-accent, #15653f); border-left: 5px solid var(--color-accent, #15653f);
           border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,.25); font-size: 13.5px; line-height: 1.35; }
.pwa-bar img { width: 40px; height: 40px; border-radius: 8px; flex: none; }
.pwa-bar-text { flex: 1; min-width: 0; }
.pwa-bar-install { min-height: 40px; flex: none; }
.pwa-bar-x { flex: none; background: none; border: 0; font-size: 22px; line-height: 1; cursor: pointer; color: inherit; padding: 4px 6px; }
@media print { .pwa-bar { display: none; } }

/* ── AI Case Assessment: Validate / Invalidate pop-up ─────────────────── */
.asmt-decide { z-index: 105; place-items: center; }
.asmt-choices { display: grid; gap: 10px; }
.asmt-choice { display: flex; gap: 12px; align-items: center; padding: 12px; border: 2px solid var(--color-border, #cbd5c0);
               border-radius: 10px; cursor: pointer; font-size: 14px; }
.asmt-choice input { position: absolute; opacity: 0; pointer-events: none; }
.asmt-choice-icon { flex: none; width: 38px; height: 38px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
                    font: 700 20px/1 system-ui, sans-serif; color: #fff; background: #94a3b8; }
.asmt-choice.is-validate:has(input:checked)   { border-color: #16a34a; background: #f0fdf4; }
.asmt-choice.is-validate:has(input:checked) .asmt-choice-icon { background: #16a34a; }
.asmt-choice.is-invalidate:has(input:checked) { border-color: #dc2626; background: #fef2f2; }
.asmt-choice.is-invalidate:has(input:checked) .asmt-choice-icon { background: #dc2626; }
.asmt-choice:focus-within { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.asmt-btn-danger { background: #dc2626; border-color: #dc2626; color: #fff; }
.asmt-btn-danger:hover { background: #b91c1c; }
.asmt-invalid { padding: 10px 12px; border-left: 4px solid #dc2626; background: #fef2f2; color: #7f1d1d; font-size: 13.5px; }
.client-form-box.is-invalidated { border-left-color: #dc2626; }
body.dark .asmt-invalid { background: #3b0d0d; color: #fecaca; }

/* ── Case types per category (Analytics) ───────────────────────────────── */
.ct-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.ct-card { border: 1px solid var(--color-divider); padding: 12px 14px; display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.ct-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.ct-title { display: inline-flex; align-items: center; gap: 7px; font-weight: 700; font-size: 14px; }
.ct-total { font-family: var(--font-heading); font-weight: 700; font-size: 13px; white-space: nowrap; }
.ct-card .an-barrow { grid-template-columns: minmax(110px, 1.4fr) 2fr auto; }
.ct-card .an-barrow.is-zero { opacity: .55; }
.ct-unset .an-barrow-l, tr.ct-unset td { font-style: italic; color: color-mix(in srgb, var(--color-text) 65%, transparent); }
.ct-unset .an-barrow-bar > span { background: color-mix(in srgb, var(--color-text) 30%, transparent); }
tr.ct-cat td { border-top: 2px solid var(--color-divider); }
@media (max-width: 640px) { .ct-grid { grid-template-columns: 1fr; } .ct-card .an-barrow { grid-template-columns: 1fr auto; } .ct-card .an-barrow-bar { display: none; } }

/* AI Case Assessment: Department with its Case type directly below. */
.asmt-grid .asmt-stack { display:flex; flex-direction:column; gap:12px; min-width:0; }
.asmt-grid .input[hidden], .rc-type .input[hidden] { display:none; }

/* Settings foot: Help Center and Log Out, on every role's Settings. */
.settings-foot { border-top: 2px solid var(--color-divider); padding-top: 20px; display: flex; flex-wrap: wrap; gap: 10px; }
.settings-foot .settings-logout { color: var(--color-accent-700); border-color: var(--color-accent); }

/* ── Help Center ─────────────────────────────────────────────────────────── */
.help-tabs { display: flex; flex-wrap: wrap; gap: 8px; }
.help-tabs .btn { min-height: 44px; display: inline-flex; align-items: center; gap: 8px; }
.help-count { font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 999px; background: var(--color-surface); }
.help-section { scroll-margin-top: 90px; }
.help-list { display: flex; flex-direction: column; }
.help-item { border-top: 1px solid var(--color-divider); }
.help-item:first-child { border-top: 0; }
.help-item > summary { cursor: pointer; list-style: none; display: flex; justify-content: space-between; align-items: center; gap: 10px;
                       padding: 12px 2px; font-weight: 600; min-height: 44px; }
.help-item > summary::-webkit-details-marker { display: none; }
.help-item > summary::after { content: '+'; font-size: 18px; line-height: 1; color: var(--color-accent); flex: none; }
.help-item[open] > summary::after { content: '−'; }
.help-body { padding: 0 2px 14px; line-height: 1.55; text-wrap: pretty; }
.help-body p { margin: 0; }
.help-body ol { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 6px; }
.help-item[hidden], .help-section[hidden] { display: none; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Phone notifications (Settings) */
.push-status { margin: 0; font-weight: 600; display: flex; align-items: center; gap: 8px; }
.push-status::before { content: ''; width: 10px; height: 10px; border-radius: 50%; background: #9ca3af; flex: none; }
.push-status.is-on::before { background: #16a34a; }
.push-status.is-bad::before { background: #dc2626; }
[data-push-box] .btn[hidden], [data-push-box] [hidden] { display: none; }
