/* ==========================================================================
   Canadian Response Network — Member Portal
   Design system mirroring the approved UI mockup
   ========================================================================== */

:root {
  --red: #e4002b;
  --red-600: #c80024;
  --red-50: #fdecef;

  --navy-900: #0b1622;
  --navy-850: #0f1d2a;
  --navy-800: #16232f;
  --navy-700: #223141;
  --navy-600: #33465a;

  --bg: #f1f4f7;
  --surface: #ffffff;
  --surface-alt: #f8fafc;
  --border: #e3e8ee;
  --border-strong: #cfd8e2;

  --text: #17263a;
  --text-soft: #45566a;
  --muted: #7c8b9c;
  --on-dark: #ffffff;
  --on-dark-soft: #a9b8c9;

  --success: #12833c;
  --success-bg: #e6f6ec;
  --warning: #b45309;
  --warning-bg: #fdf3d8;
  --danger: #c02626;
  --danger-bg: #fdeaea;
  --info: #1d4ed8;
  --info-bg: #e6ecfd;

  --radius-sm: 6px;
  --radius: 10px;
  --radius-lg: 14px;

  --shadow-sm: 0 1px 2px rgba(16, 30, 46, .06);
  --shadow: 0 2px 8px rgba(16, 30, 46, .07);
  --shadow-lg: 0 12px 32px rgba(11, 22, 34, .16);

  --sidebar-w: 250px;
  --topbar-h: 60px;

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

html { overflow-x: clip; }

body {
  margin: 0;
  overflow-x: clip;
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { margin: 0; font-weight: 700; letter-spacing: -.01em; }
h1 { font-size: 22px; }
h2 { font-size: 18px; }
h3 { font-size: 15px; }
p { margin: 0 0 10px; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
ul { margin: 0; padding: 0; list-style: none; }
svg { flex: none; }

.text-muted { color: var(--muted); }
.text-soft { color: var(--text-soft); }
.text-sm { font-size: 13px; }
.text-xs { font-size: 12px; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.mt-0 { margin-top: 0; }
.mt-1 { margin-top: 8px; }
.mt-2 { margin-top: 16px; }
.mt-3 { margin-top: 24px; }
.mb-2 { margin-bottom: 16px; }
.w-full { width: 100%; }
.nowrap { white-space: nowrap; }
.flex { display: flex; }
.flex-between { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.flex-center { display: flex; align-items: center; gap: 8px; }
.flex-wrap { flex-wrap: wrap; }
.gap-1 { gap: 6px; }
.gap-2 { gap: 12px; }
.gap-3 { gap: 20px; }
.flex-1 { flex: 1 1 auto; min-width: 0; }
.hidden { display: none !important; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ============================================================ app shell == */

.app { min-height: 100vh; }

.sidebar {
  position: fixed;
  inset: 0 auto 0 0;
  width: var(--sidebar-w);
  background: var(--navy-900);
  color: var(--on-dark);
  display: flex;
  flex-direction: column;
  z-index: 40;
  transition: transform .22s ease;
}

.sidebar__header {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 68px;
  padding: 14px 12px 14px 18px;
  border-bottom: 1px solid rgba(255, 255, 255, .07);
}
.sidebar__brand {
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  min-width: 0;
}
.sidebar__brand img { width: 132px; height: auto; }
.sidebar__brand--sm img { width: 118px; }


/* ------------------------------------------- collapsed rail (desktop) --- */







/* the group holding the current page keeps its marker brighter */


/* tooltip for the collapsed rail — only rendered on hover so it never adds
   phantom horizontal overflow to the page */

.sidebar__nav {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 12px 10px 20px;
}
.sidebar__label {
  padding: 14px 12px 6px;
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--on-dark-soft);
  opacity: .7;
}

/* ------------------------------------------------- collapsible nav groups */

.nav-group + .nav-group { margin-top: 2px; }

.nav-group__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  margin: 0;
  padding: 14px 12px 6px;
  position: relative;
  border: 0;
  background: none;
  color: var(--on-dark-soft);
  font: inherit;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  cursor: pointer;
  border-radius: var(--radius-sm);
}
.nav-group__toggle:hover { color: #fff; opacity: .9; }
.nav-group__toggle:focus-visible { outline: 2px solid var(--red); outline-offset: -2px; }

.nav-group__icon { display: none; }

.nav-group__chevron {
  display: inline-flex;
  transition: transform .18s ease;
  opacity: .8;
}
.nav-group__toggle[aria-expanded="false"] .nav-group__chevron { transform: rotate(-90deg); }

.nav-group__items { display: block; }
.nav-group__items[hidden] { display: none; }

.nav-group.has-active > .nav-group__toggle { color: #fff; opacity: 1; }

.nav-link {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  color: #d3dde8;
  font-size: 13.5px;
  font-weight: 500;
  margin-bottom: 2px;
  transition: background .15s ease, color .15s ease;
}
.nav-link svg { opacity: .85; }
.nav-link:hover { background: rgba(255, 255, 255, .07); color: #fff; }
.nav-link.is-active {
  background: var(--red);
  color: #fff;
  font-weight: 600;
  box-shadow: 0 4px 12px rgba(228, 0, 43, .35);
}
.nav-link.is-active svg { opacity: 1; }
.nav-link__count {
  margin-left: auto;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--red);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.nav-link.is-active .nav-link__count { background: #fff; color: var(--red); }

.sidebar__footer {
  padding: 14px 18px;
  border-top: 1px solid rgba(255, 255, 255, .07);
  font-size: 12px;
  color: var(--on-dark-soft);
}
.sidebar__footer a { color: #fff; font-weight: 600; }

.main {
  margin-left: var(--sidebar-w);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  height: var(--topbar-h);
  background: var(--navy-800);
  color: #fff;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 22px;
  box-shadow: 0 1px 0 rgba(255, 255, 255, .06);
}
.topbar__toggle {
  display: none;
  background: rgba(255, 255, 255, .08);
  border: 0;
  color: #fff;
  border-radius: var(--radius-sm);
  padding: 7px;
  cursor: pointer;
}
.topbar__spacer { flex: 1 1 auto; }
.topbar__icon-btn {
  position: relative;
  background: transparent;
  border: 0;
  color: #dbe4ee;
  padding: 8px;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.topbar__icon-btn:hover { background: rgba(255, 255, 255, .1); color: #fff; }
.topbar__dot {
  position: absolute;
  top: 4px;
  right: 4px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--red);
  border: 2px solid var(--navy-800);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

.user-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 8px 5px 5px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .08);
  color: #fff;
  cursor: pointer;
  border: 0;
}
.user-chip:hover { background: rgba(255, 255, 255, .15); }
.user-chip__name { font-size: 13px; font-weight: 600; line-height: 1.15; }
.user-chip__role { font-size: 11px; color: var(--on-dark-soft); line-height: 1.15; }

.avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--navy-600);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12.5px;
  font-weight: 700;
  flex: none;
  overflow: hidden;
  border: 2px solid rgba(255, 255, 255, .18);
}
.avatar img { width: 100%; height: 100%; object-fit: cover; }
/* Size ladder: --sm 28px · base 34px · --md 56px · --lg 104px. The old scale jumped
   straight from 34 to 104, which left no step for a table cell that wanted a face
   slightly more prominent than the sidebar's without becoming a profile picture. */
.avatar--md { width: 56px; height: 56px; font-size: 18px; }
.avatar--lg { width: 104px; height: 104px; font-size: 30px; border: 0; }
.avatar--sm { width: 28px; height: 28px; font-size: 11px; }

.dropdown { position: relative; }
.dropdown__menu {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  min-width: 220px;
  background: #fff;
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: 6px;
  display: none;
  z-index: 60;
}
.dropdown.is-open .dropdown__menu { display: block; }
.dropdown__header { padding: 10px 12px; border-bottom: 1px solid var(--border); margin-bottom: 6px; }
.check-list { display: grid; gap: 6px; }
.check-list .check { margin: 0; }

.dropdown__footer { padding: 10px 12px; border-top: 1px solid var(--border); }
.dropdown__item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 12px;
  border: 0;
  background: none;
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 13.5px;
  color: var(--text);
  cursor: pointer;
  text-align: left;
}
.dropdown__item:hover { background: var(--surface-alt); color: var(--red); }

.page {
  flex: 1 1 auto;
  padding: 24px 28px 40px;
  width: 100%;
  /* Wide enough that a 27" monitor is not mostly empty, capped so prose does not
     turn into unreadable lines on an ultrawide. Centred in whatever the sidebar leaves. */
  max-width: 1760px;
  margin-inline: auto;
}

.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}
.page-head__title { display: flex; flex-direction: column; gap: 2px; }
.page-head__sub { color: var(--muted); font-size: 13px; }
/* Membership number and badges under a page title. Wraps, so a long tier name and
   three badges still settle onto a second line rather than overflowing. */
.page-head__tags {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 4px;
}
.page-head h1 { font-size: 21px; }

.breadcrumb {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--muted);
  margin-bottom: 14px;
}
.breadcrumb a:hover { color: var(--red); }

/* ================================================================ cards == */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 16px 18px;
  border-bottom: 1px solid var(--border);
}
.card__title { font-size: 15px; font-weight: 700; }
.card__body { padding: 18px; }
.card__body--flush { padding: 0; }
.card__foot {
  padding: 14px 18px;
  border-top: 1px solid var(--border);
  background: var(--surface-alt);
  border-radius: 0 0 var(--radius) var(--radius);
}

.grid { display: grid; gap: 18px; }

/* A vertical run of cards.
   A grid's `gap` only separates its own items, so cards nested inside a plain
   wrapper div end up touching. Making the wrapper itself a grid restores the
   spacing without changing the markup structure. */
.stack {
  display: grid;
  gap: 18px;
  align-content: start;
  /* An explicit minmax(0) column, plus min-width:0 on the children, is what lets a
     wide table inside a card shrink and hand off to .table-wrap's overflow-x.
     Grid items default to min-width:auto, so without this the track is forced
     open by its content and the page scrolls sideways. */
  grid-template-columns: minmax(0, 1fr);
}
.stack > * { min-width: 0; }

/* Weather: let the conditions cell wrap its label instead of forcing the table wide. */
.weather-table .weather-cond { white-space: normal; min-width: 150px; }
.weather-table .weather-cond span { vertical-align: middle; }
.weather-table .weather-cond svg { vertical-align: middle; margin-right: 2px; }

/* A card or stack directly after a grid would otherwise butt straight up
   against the last row of that grid. */
.grid + .card,
.grid + .stack,
.grid + section.card { margin-top: 18px; }
.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid--5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.grid--6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.grid--sidebar { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); align-items: start; }
/* Above ~1500px of content, stop splitting evenly and cap the aside. */
@media (min-width: 1500px) {
  .grid--sidebar { grid-template-columns: minmax(0, 1fr) minmax(300px, 460px); }
}

/* Dashboard: once there is real width, the side column stops being a single
   stack and its cards sit side by side, so the page fills instead of trailing
   off into one narrow column. */
@media (min-width: 1500px) {
  .dash { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); }
  .dash__side { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.grid--profile { grid-template-columns: 320px minmax(0, 1fr); align-items: start; }

.section-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 12px;
  font-size: 14.5px;
  font-weight: 700;
}
.section-title a { color: var(--red); font-size: 12.5px; font-weight: 600; }
.section-title a:hover { text-decoration: underline; }

/* ============================================================ stat cards = */

.stat {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
  box-shadow: var(--shadow-sm);
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 132px;
}
.stat__icon {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--info-bg);
  color: var(--info);
}
.stat__icon--success { background: var(--success-bg); color: var(--success); }
.stat__icon--warning { background: var(--warning-bg); color: var(--warning); }
.stat__icon--danger { background: var(--danger-bg); color: var(--danger); }
.stat__icon--red { background: var(--red-50); color: var(--red); }
.stat__label { font-size: 12.5px; color: var(--muted); font-weight: 600; }
.stat__value { font-size: 26px; font-weight: 800; line-height: 1; }
.stat__foot { margin-top: auto; font-size: 12px; color: var(--muted); }
.stat__flag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--warning-bg);
  color: var(--warning);
  font-size: 11.5px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 999px;
}

/* =============================================================== buttons = */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 9px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background .15s ease, box-shadow .15s ease, border-color .15s ease, color .15s ease;
}
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn--primary { background: var(--red); color: #fff; box-shadow: 0 2px 6px rgba(228, 0, 43, .28); }
.btn--primary:hover { background: var(--red-600); }
.btn--dark { background: var(--navy-800); color: #fff; }
.btn--dark:hover { background: var(--navy-700); }
.btn--outline { background: #fff; border-color: var(--border-strong); color: var(--text); }
.btn--outline:hover { border-color: var(--red); color: var(--red); }
.btn--ghost { background: transparent; color: var(--text-soft); }
.btn--ghost:hover { background: var(--surface-alt); color: var(--red); }
.btn--success { background: var(--success); color: #fff; }
.btn--success:hover { filter: brightness(.93); }
.btn--danger { background: var(--danger-bg); color: var(--danger); }
.btn--danger:hover { background: var(--danger); color: #fff; }
.btn--sm { padding: 6px 11px; font-size: 12.5px; }
.btn--lg { padding: 12px 22px; font-size: 15px; }
.btn--block { width: 100%; }
.btn--icon { padding: 8px; }

.icon-btn {
  background: transparent;
  border: 0;
  color: var(--muted);
  padding: 6px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  display: inline-flex;
}
.icon-btn:hover { background: var(--surface-alt); color: var(--red); }

/* ================================================================ badges = */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.6;
  white-space: nowrap;
  background: #eef2f6;
  color: var(--text-soft);
}
.badge__dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.badge--success { background: var(--success-bg); color: var(--success); }
.badge--warning { background: var(--warning-bg); color: var(--warning); }
.badge--danger { background: var(--danger-bg); color: var(--danger); }
.badge--info { background: var(--info-bg); color: var(--info); }
.badge--muted { background: #eef2f6; color: var(--muted); }
.badge--red { background: var(--red-50); color: var(--red); }
.badge--outline { background: transparent; border: 1px solid var(--border-strong); color: var(--text-soft); }

/* ================================================================ tables = */

.table-wrap { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.table th {
  text-align: left;
  font-size: 11.5px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 700;
  padding: 11px 16px;
  background: var(--surface-alt);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.table td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: #fafcfe; }
.table__actions { display: flex; align-items: center; justify-content: flex-end; gap: 4px; }
/* The whole incident row opens the detail modal. */
.incident-row { cursor: pointer; }
.incident-row:hover > td { background: var(--surface-alt); }
.incident-row:focus { outline: none; }
.incident-row:focus-visible > td { background: var(--info-bg); }
.incident-row:focus-visible > td:first-child { box-shadow: inset 3px 0 0 var(--info); }

.table__id {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  color: var(--muted);
}
.table--compact td, .table--compact th { padding: 9px 12px; }

/* ================================================================== tabs = */

.tabs {
  display: flex;
  align-items: center;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 18px;
  overflow-x: auto;
}
.tab {
  position: relative;
  padding: 11px 16px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-soft);
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
.tab:hover { color: var(--red); }
.tab.is-active { color: var(--red); border-bottom-color: var(--red); }
.tab__count {
  margin-left: 6px;
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
  background: #eef2f6;
  border-radius: 999px;
  padding: 1px 7px;
}
.tab.is-active .tab__count { background: var(--red-50); color: var(--red); }

/* Section tabs that carry an icon, as on the admin member page. The plain filter tabs
   above are text only, so the icon variant opts into flex alignment; the count badge
   drops its own margin because the gap now supplies the spacing. */
.tabs--icons .tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.tabs--icons .tab svg { opacity: .75; }
.tabs--icons .tab.is-active svg { opacity: 1; }
.tabs--icons .tab__count { margin-left: 0; }

/* Top-level view switcher (List | Calendar) reads as a heavier bar than the
   secondary filter tabs below it. */
.tabs--primary {
  margin-bottom: 20px;
  border-bottom-color: var(--border-strong, #cbd5e1);
}
.tabs--primary .tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 13px 20px;
  font-size: 14.5px;
}
.tabs--primary .tab svg { opacity: .8; }
.tabs--primary .tab.is-active svg { opacity: 1; }

/* Result-count strip above the paged list. */
.result-count {
  font-size: 12.5px;
  color: var(--muted);
  margin-bottom: 10px;
}

.pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}
.pager__link {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-soft);
  padding: 8px 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
  white-space: nowrap;
}
.pager__link:hover { color: var(--red); border-color: var(--red); }
.pager__link.is-disabled { opacity: .4; pointer-events: none; }
.pager__status { font-size: 12.5px; color: var(--muted); }
@media (max-width: 560px) {
  .pager__status { display: none; }
  .pager { justify-content: space-between; }
}

.segmented {
  display: inline-flex;
  padding: 3px;
  background: #eef2f6;
  border-radius: 999px;
  gap: 2px;
}
.segmented a {
  padding: 6px 14px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-soft);
}
.segmented a.is-active { background: #fff; color: var(--text); box-shadow: var(--shadow-sm); }

/* ================================================================= forms = */

.field { margin-bottom: 16px; }
.field__label {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-soft);
  margin-bottom: 6px;
}
.field__hint { font-size: 12px; color: var(--muted); margin-top: 5px; }
.field__error { font-size: 12px; color: var(--danger); margin-top: 5px; font-weight: 600; }

.input, .select, .textarea {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: #fff;
  font: inherit;
  font-size: 13.5px;
  color: var(--text);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.input:focus, .select:focus, .textarea:focus {
  outline: 0;
  border-color: var(--red);
  box-shadow: 0 0 0 3px rgba(228, 0, 43, .12);
}
.input.has-error, .select.has-error { border-color: var(--danger); }
/* Canada Post writes a postal code A1A 1A1, so the field shows it that way as it is
   typed. Display only: the value that reaches the database is whatever
   normalize_postal_code() produced, not this. */
.input--postal { text-transform: uppercase; letter-spacing: .06em; }
/* A value the server owns and an admin must not change -- currently the membership ID.
   Styled as a field so it lines up with its neighbours, but dimmed and flattened so it
   does not read as something you can type into. */
.input--readonly {
  background: var(--surface-alt);
  color: var(--text-soft);
  cursor: default;
  box-shadow: none;
}
.textarea { min-height: 96px; resize: vertical; }
.select {
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%237c8b9c' stroke-width='2'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 32px;
}
.input-group { position: relative; }
.input-group .input { padding-left: 38px; }
.input-group__icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  pointer-events: none;
}

.checkbox { display: flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; }
.checkbox input { width: 15px; height: 15px; accent-color: var(--red); }

.form-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 16px; }
.form-row--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

/* A group heading inside a single long form.
   Elsewhere in the project a grouped form is several cards, one per group — but the
   admin member form is one POST to one endpoint, so its groups are labelled in place
   rather than split into separate cards. First one needs no top margin, since the card
   body already provides one. */
.form-section {
  margin: 26px 0 15px;
  padding-bottom: 7px;
  border-bottom: 1px solid var(--border);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--muted);
}
.form-section:first-child { margin-top: 0; }

.file-drop {
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius);
  padding: 22px;
  text-align: center;
  background: var(--surface-alt);
  cursor: pointer;
}
.file-drop:hover { border-color: var(--red); }
.file-drop input { display: none; }

/* =========================================================== event cards = */

.event-card {
  display: flex;
  gap: 16px;
  padding: 16px 0;
  border-bottom: 1px solid var(--border);
}
.event-card:last-child { border-bottom: 0; }
.event-card__thumb {
  position: relative;
  width: 148px;
  height: 92px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  flex: none;
  background: var(--surface-alt);
}
.event-card__thumb img { width: 100%; height: 100%; object-fit: cover; }
.event-card__body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.event-card__title { font-size: 15px; font-weight: 700; }
.event-card__meta { display: flex; flex-wrap: wrap; gap: 6px 18px; font-size: 12.5px; color: var(--text-soft); }
.event-card__meta span { display: inline-flex; align-items: center; gap: 6px; }
.event-card__actions { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; justify-content: center; }
.event-card--sm .event-card__thumb { width: 96px; height: 62px; }
.event-card--sm .event-card__title { font-size: 13.5px; }

.date-chip {
  width: 58px;
  height: 58px;
  border-radius: var(--radius-sm);
  background: var(--red);
  color: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: none;
  box-shadow: 0 4px 10px rgba(228, 0, 43, .3);
}
.date-chip__month { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.date-chip__day { font-size: 22px; font-weight: 800; line-height: 1; }
.date-chip--muted { background: var(--navy-800); box-shadow: none; }
.date-chip--sm { width: 46px; height: 46px; }
.date-chip--sm .date-chip__day { font-size: 17px; }

/* ============================================================ dashboard === */

.hero {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}
.hero__greet { font-size: 21px; font-weight: 800; }
.hero__sub { color: var(--muted); font-size: 13px; }
.member-id { font-size: 11.5px; color: var(--muted); text-align: right; line-height: 1.7; }
.member-id strong { color: var(--text-soft); font-weight: 600; }

.pill-status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--success-bg);
  color: var(--success);
  font-size: 12.5px;
  font-weight: 700;
  padding: 7px 13px;
  border-radius: 999px;
}
.pill-status__dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; }

.banner {
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--surface);
  margin-bottom: 16px;
}
.banner__img { height: 128px; background-size: cover; background-position: center; }
.banner__body { padding: 16px 18px; }

/* On-shift / incident callout: tinted strip rather than a full card. */
.banner--alert {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 14px 18px;
  margin-bottom: 16px;
  border: 1px solid var(--red);
  border-left-width: 4px;
  border-radius: var(--radius);
  background: #fff5f6;
  color: var(--navy-900);
}
.banner--alert svg { color: var(--red); flex: 0 0 auto; }

.timeline { display: flex; flex-direction: column; }
.timeline__item { display: flex; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--border); }
.timeline__item:last-child { border-bottom: 0; }
/* The membership ID currently in force. Tinted and pulled in from the left rather
   than relying on a badge alone, so which of several IDs is live is obvious at a
   glance instead of something you have to read to find out. */
.timeline__item.is-current {
  margin: 0 -10px;
  padding: 12px 10px;
  border-radius: var(--radius-sm);
  background: var(--success-bg, #ecfdf3);
}
.id-history__badge {
  display: inline-block;
  margin-right: 8px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--success-bg, #ecfdf3);
  color: var(--success, #0a7d4b);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  vertical-align: 2px;
}

/* ------------------------------------------------------------------ notes */
/* A stored admin note is rendered HTML, not text, so it needs the same typographic
   treatment the public .prose block gets in site.css — which the admin layout does not
   load. Kept deliberately short: an admin note is a paragraph or two, not an article, and
   the heading sizes here are a step down from the public ones. */
.note-body {
  margin-top: 6px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-soft);
}
.note-body > *:first-child { margin-top: 0; }
.note-body > *:last-child { margin-bottom: 0; }
.note-body p { margin: 0 0 .6em; }
.note-body h3 { margin: 1em 0 .35em; font-size: 1.02rem; color: var(--text); }
.note-body h4 { margin: 1em 0 .3em; font-size: .95rem; color: var(--text); }
.note-body ul, .note-body ol { margin: 0 0 .6em; padding-left: 1.3em; }
.note-body li { margin-bottom: .25em; }
.note-body a { color: var(--red); text-decoration: underline; text-underline-offset: 2px; }
.note-body blockquote {
  margin: .5em 0;
  padding: 4px 0 4px 12px;
  border-left: 3px solid var(--border-strong, #cbd5e1);
  color: var(--muted);
  font-style: italic;
}
.note-body hr { margin: .8em 0; border: 0; border-top: 1px solid var(--border); }
.note-body code {
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--surface-alt, #f1f5f9);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .92em;
}

/* A note carried over from the old single-cell notes field. It has no human author, so
   it is set apart from real observations rather than dressed up to look like one. */
.timeline__item.is-imported .avatar { opacity: .55; }
.timeline__item.is-imported .note-body { color: var(--muted); }
.timeline__item.is-imported .id-history__badge {
  background: #eef2f6;
  color: var(--muted);
}
.timeline__icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  background: var(--info-bg);
  color: var(--info);
}
.timeline__icon--success { background: var(--success-bg); color: var(--success); }
.timeline__icon--warning { background: var(--warning-bg); color: var(--warning); }
.timeline__title { font-size: 13px; font-weight: 600; }
.timeline__meta { font-size: 11.5px; color: var(--muted); }

.service-strip {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  margin-top: 18px;
}
.service-strip__item {
  background: var(--surface);
  padding: 18px 12px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-soft);
}
.service-strip__item svg { color: var(--red); }

/* ============================================================== profile === */

.avatar-card { text-align: center; }
.avatar-card .avatar { margin: 0 auto 12px; }

/* ------------------------------------------------- member portrait control --- */
/* The portrait on the admin member page is the control for changing it, so it has to
   read as something you can press: a button reset to nothing, with a hover ring and a
   focus ring that are both visible against the white card. The overlay only appears on
   hover or keyboard focus, so the resting state is still just a portrait. */
.avatar-btn {
  position: relative;
  display: inline-block;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
  line-height: 0;
}
.avatar-btn .avatar { margin: 0; }
.avatar-btn::after {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 2px solid transparent;
  transition: border-color .15s ease, background-color .15s ease;
}
.avatar-btn:hover::after { border-color: var(--red); }
.avatar-btn:focus-visible { outline: none; }
.avatar-btn:focus-visible::after { border-color: var(--red); background: rgba(228, 0, 43, .08); }

.avatar-btn__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(11, 22, 34, .55);
  color: #fff;
  opacity: 0;
  transition: opacity .15s ease;
}
.avatar-btn:hover .avatar-btn__overlay,
.avatar-btn:focus-visible .avatar-btn__overlay { opacity: 1; }

/* The portrait in the photo dialog, at a size worth looking at before committing. */
.photo-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 22px;
  border-radius: var(--radius);
  background: var(--surface-alt, #f1f5f9);
}
.photo-preview .avatar { margin: 0; width: 132px; height: 132px; font-size: 38px; border: 0; }

/* A styled stand-in for the native file input. */
.file-picker {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 13px;
  border: 1px dashed var(--border-strong, #cbd5e1);
  border-radius: var(--radius-sm);
  background: #fff;
  font-size: 13.5px;
  color: var(--text-soft);
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease, background-color .15s ease;
}
.file-picker:hover {
  border-color: var(--red);
  border-style: solid;
  color: var(--red);
  background: var(--red-50, #fef2f2);
}
/* The input is sr-only, so it never receives focus itself — the label carries it. */
.file-picker:focus-within,
label.file-picker:has(input:focus-visible) {
  border-color: var(--red);
  border-style: solid;
  box-shadow: 0 0 0 2px rgba(228, 0, 43, .18);
}
.detail-list { display: grid; grid-template-columns: 190px minmax(0, 1fr); }
.detail-list dt {
  padding: 11px 0;
  font-size: 12.5px;
  color: var(--muted);
  border-bottom: 1px solid var(--border);
}
.detail-list dd {
  margin: 0;
  padding: 11px 0;
  font-size: 13.5px;
  font-weight: 500;
  border-bottom: 1px solid var(--border);
}
.detail-list dt:last-of-type, .detail-list dd:last-of-type { border-bottom: 0; }

/* ================================================================ login === */

.auth {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  /* `safe` matters: a plain `center` clips the top of the card once the column is
     taller than the viewport (short screens, long validation errors), and the
     logo is the first thing that goes missing. */
  align-items: center;
  align-items: safe center;
  background: var(--navy-900);
  position: relative;
  overflow-y: auto;
}
.auth__bg {
  position: fixed;
  inset: 0;
  background: var(--navy-800) url('/assets/img/login-bg.svg') center / cover no-repeat;
}
.auth__overlay {
  position: fixed;
  inset: 0;
  background:
    radial-gradient(90% 70% at 50% 40%, rgba(11, 22, 34, .45), rgba(11, 22, 34, .88));
}
/* Single centered column: logo + tagline, the card, then the footer note. */
.auth__center {
  position: relative;
  width: 100%;
  max-width: 460px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
  padding: 40px 20px;
  margin: auto;
  color: #fff;
}
.auth__brand { display: flex; flex-direction: column; align-items: center; gap: 12px; text-align: center; }
/*
 * The wordmark is a 10000x4122 canvas whose artwork is 9161x3410 (~4% padding each
 * side). At width 150px the visible mark was only ~56px tall next to a 400px card,
 * which read as an undersized afterthought. 260px puts it at roughly the optical
 * weight you want for a lockup sitting above a form, and max-width keeps it from
 * overflowing the column on narrow phones.
 */
.auth__logo { width: 260px; max-width: 100%; height: auto; }
.auth__tagline {
  margin: 0;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--on-dark-soft);
  text-shadow: 0 2px 14px rgba(0, 0, 0, .6);
}
.auth__tagline span { color: #ff5a76; }
.auth__meta { font-size: 12.5px; color: var(--on-dark-soft); text-align: center; text-shadow: 0 1px 10px rgba(0, 0, 0, .6); }
.auth__meta strong { color: #fff; }

.auth-card {
  width: 100%;
  max-width: 400px;
  background: rgba(13, 25, 37, .88);
  backdrop-filter: blur(6px);
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: var(--radius-lg);
  padding: 30px 30px 26px;
  color: #fff;
  box-shadow: var(--shadow-lg);
}
.auth-card h1 { font-size: 21px; text-align: center; }
.auth-card__sub { text-align: center; color: var(--on-dark-soft); font-size: 13px; margin: 6px 0 22px; }
.auth-card .field__label { color: #c8d4e0; }
.auth-card .input {
  background: rgba(255, 255, 255, .06);
  border-color: rgba(255, 255, 255, .18);
  color: #fff;
}
.auth-card .input::placeholder { color: rgba(255, 255, 255, .45); }
.auth-card .input:focus {
  background: rgba(255, 255, 255, .1);
  border-color: var(--red);
}
.auth-card__row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 4px 0 20px; }
.auth-card__link { color: #ff8098; font-size: 12.5px; font-weight: 600; }
.auth-card__link:hover { text-decoration: underline; }
.auth-card .checkbox { color: #c8d4e0; font-size: 12.5px; }
.auth-card .checkbox input { accent-color: var(--red); }
.auth-card__foot { margin-top: 18px; padding-top: 16px; border-top: 1px solid rgba(255, 255, 255, .1); text-align: center; font-size: 12.5px; color: var(--on-dark-soft); }
.auth-card .btn--primary { width: 100%; padding: 12px; font-size: 15px; }
.auth-card .field__error { color: #ff9aae; }

/* =============================================================== flash === */

.flash {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  font-size: 13.5px;
  font-weight: 500;
  margin-bottom: 16px;
  border: 1px solid transparent;
}

/* ------------------------------------------------------------------ toasts --- */
/*
 * Flashes are toasts: they float, they stack, they dismiss. Errors and warnings stay
 * until dismissed (see the .toast--sticky rule in the partial), because losing "your
 * message was not sent" to a timer is how a message gets sent twice.
 */
.toast {
  position: fixed;
  top: 74px;              /* clear of the topbar */
  right: 20px;
  z-index: 900;
  width: min(400px, calc(100vw - 40px));
  margin-bottom: 0;
  box-shadow: var(--shadow-lg);
  animation: toast-in .18s ease-out;
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none; }
}

.toast.is-leaving {
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity .18s ease, transform .18s ease;
}

.toast__close {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin: -2px -4px 0 auto;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  opacity: .55;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}
.toast__close:hover { opacity: 1; background: rgba(0, 0, 0, .06); }
.toast__close:focus-visible { outline: 2px solid currentColor; outline-offset: 1px; opacity: 1; }

/* A toast that is dismissed should not be announced again, and vice versa. */
.toast[hidden] { display: none; }

@media (max-width: 640px) {
  .toast { top: auto; bottom: 16px; right: 12px; left: 12px; width: auto; }
}
.flash--success { background: var(--success-bg); color: var(--success); border-color: #bfe6cd; }
.flash--error { background: var(--danger-bg); color: var(--danger); border-color: #f3c9c9; }
.flash--warning { background: var(--warning-bg); color: var(--warning); border-color: #f0dcae; }
.flash--info { background: var(--info-bg); color: var(--info); border-color: #c8d6f8; }

/* =========================================================== pagination === */

.pagination { display: flex; align-items: center; gap: 6px; }
.pagination a, .pagination span {
  min-width: 30px;
  height: 30px;
  padding: 0 8px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-soft);
  background: #fff;
}
.pagination a:hover { border-color: var(--red); color: var(--red); }
.pagination .is-active { background: var(--red); border-color: var(--red); color: #fff; }
.pagination .is-disabled { opacity: .45; pointer-events: none; }

.toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}
.search {
  position: relative;
  flex: 0 1 300px;
}
.search .input { padding-left: 36px; }
.search__icon { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--muted); }
.toolbar .select { width: auto; min-width: 150px; }

.empty {
  text-align: center;
  padding: 46px 20px;
  color: var(--muted);
}
.empty__icon {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--surface-alt);
  color: var(--border-strong);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 12px;
}

.callout {
  display: flex;
  gap: 12px;
  padding: 14px 16px;
  border-radius: var(--radius);
  background: var(--info-bg);
  color: #1e3a8a;
  font-size: 13px;
  border: 1px solid #c8d6f8;
}
.callout--warning { background: var(--warning-bg); color: var(--warning); border-color: #f0dcae; }
.callout--danger { background: var(--danger-bg); color: var(--danger); border-color: #f3c9c9; }

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(11, 22, 34, .6);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 80;
}
.modal-backdrop.is-open { display: flex; }
.modal {
  background: #fff;
  border-radius: var(--radius-lg);
  width: 100%;
  max-width: 520px;
  max-height: 90vh;
  overflow: auto;
  box-shadow: var(--shadow-lg);
}
/* Upload modals carry a preview row per photo, so they need more room than a form. */
.modal--wide { max-width: 720px; }
.modal__head { display: flex; align-items: center; justify-content: space-between; padding: 18px 20px; border-bottom: 1px solid var(--border); }
.modal__body { padding: 20px; }
.modal__foot { display: flex; justify-content: flex-end; gap: 10px; padding: 16px 20px; border-top: 1px solid var(--border); background: var(--surface-alt); }

.scrim { display: none; }

/* ========================================================== responsive === */

/* ~1560px viewport leaves ~1250px of content: six stat cards need ~215px each. */
@media (max-width: 1560px) {
  .grid--5, .grid--6 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 1180px) {
  .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--5, .grid--6 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--sidebar, .grid--profile { grid-template-columns: minmax(0, 1fr); }
  .service-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
  .sidebar { transform: translateX(-100%); box-shadow: var(--shadow-lg); }
    body.nav-open .sidebar { transform: translateX(0); }
  body.nav-open .scrim {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(11, 22, 34, .5);
    z-index: 35;
  }
  .main { margin-left: 0; }
  .topbar__toggle { display: inline-flex; }
  .grid--3, .grid--2 { grid-template-columns: minmax(0, 1fr); }
  .page { padding: 18px 16px 32px; }
  .detail-list { grid-template-columns: minmax(0, 1fr); }
  .detail-list dt { border-bottom: 0; padding-bottom: 0; }
  .event-card { flex-wrap: wrap; }
  .event-card__actions { flex-direction: row; width: 100%; justify-content: flex-start; }
  .auth__center { gap: 18px; padding: 32px 16px; }
}

@media (max-width: 560px) {
  .grid--4, .grid--5, .grid--6 { grid-template-columns: minmax(0, 1fr); }
  .form-row, .form-row--3 { grid-template-columns: minmax(0, 1fr); }
  .user-chip__meta { display: none; }
}

@media print {
  .sidebar, .topbar, .btn, .toolbar { display: none !important; }
  .main { margin: 0; }
  .card { box-shadow: none; }
}

/* --------------------------------------------------------- member picker */
.member-picker {
  max-height: 240px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 4px 10px;
  background: var(--surface-alt);
}
.member-picker .member-option + .member-option { border-top: 1px solid var(--border); }

/* Count pill inside a button — used for "3 awaiting review" style affordances. */
.btn__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  margin-left: 6px;
  border-radius: 999px;
  background: var(--red);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
  line-height: 1;
}

/* ============================================================== gallery === */

.gallery-head { margin-bottom: 18px; }

/* Tag chips double as filters and as static labels. */
.tag-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 14px 0 4px;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: #fff;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-soft);
  text-decoration: none;
  white-space: nowrap;
}
.chip:hover { border-color: var(--red); color: var(--red); }
.chip.is-active { background: var(--red); border-color: var(--red); color: #fff; }
.chip.is-active .chip__n { background: rgba(255, 255, 255, .22); color: #fff; }
.chip.is-static { cursor: default; background: #eef2f6; border-color: transparent; }
.chip__n {
  font-size: 10.5px;
  font-weight: 700;
  padding: 0 6px;
  border-radius: 999px;
  background: #eef2f6;
  color: var(--muted, #7a8896);
}

/* Album cards */
.album-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(248px, 1fr));
  gap: 18px;
  margin-top: 18px;
}
.album-card {
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius, 12px);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: box-shadow .16s ease, transform .16s ease;
}
.album-card:hover { box-shadow: 0 10px 26px rgba(11, 22, 34, .1); transform: translateY(-2px); }
.album-card__cover {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  background: #eef2f6;
  overflow: hidden;
}
.album-card__cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.album-card__placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted, #7a8896);
}
.album-card__body { padding: 13px 15px 15px; display: flex; flex-direction: column; gap: 6px; }
.album-card__flags { display: flex; flex-wrap: wrap; gap: 6px; }
.album-card__flags:empty { display: none; }
.album-card__title { margin: 0; font-size: 15px; font-weight: 700; line-height: 1.3; }
.album-card__title a { color: inherit; text-decoration: none; }
.album-card__meta { margin-top: auto; }

/* Photo grid */
.photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 12px;
  margin-top: 18px;
}
.photo-tile {
  position: relative;
  margin: 0;
  aspect-ratio: 1 / 1;
  border-radius: 10px;
  overflow: hidden;
  background: #eef2f6;
  cursor: zoom-in;
}
.photo-tile img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .2s ease; }
.photo-tile:hover img { transform: scale(1.04); }
.photo-tile__caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 18px 10px 8px;
  font-size: 11.5px;
  font-weight: 600;
  color: #fff;
  background: linear-gradient(transparent, rgba(11, 22, 34, .78));
  opacity: 0;
  transition: opacity .16s ease;
}
.photo-tile:hover .photo-tile__caption,
.photo-tile:focus-within .photo-tile__caption { opacity: 1; }
.photo-tile__status { position: absolute; top: 8px; left: 8px; }
.photo-tile__delete { position: absolute; top: 8px; right: 8px; opacity: 0; transition: opacity .16s ease; }
.photo-tile:hover .photo-tile__delete,
.photo-tile:focus-within .photo-tile__delete { opacity: 1; }

/* Moderation queue */
.review-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding: 13px 16px;
  margin-bottom: 16px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
}
.review-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 14px;
}
.review-card {
  margin: 0;
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
.review-card.is-hidden-public { border-style: dashed; }
.review-card > a { display: block; aspect-ratio: 4 / 3; background: #eef2f6; }
.review-card > a img { width: 100%; height: 100%; object-fit: cover; display: block; }
.review-card__check {
  position: absolute;
  z-index: 2;
  margin: 8px;
  padding: 5px;
  background: rgba(255, 255, 255, .94);
  border-radius: 7px;
  box-shadow: 0 1px 4px rgba(11, 22, 34, .2);
}
.review-card { position: relative; }
.review-card figcaption { padding: 11px 12px 13px; display: flex; flex-direction: column; gap: 8px; }
.review-card__meta { display: flex; flex-direction: column; gap: 2px; font-size: 13px; }
.review-card__actions { display: flex; flex-wrap: wrap; gap: 6px; }
.review-card__actions form { display: contents; }

/* Lightbox */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 30px 64px;
  background: rgba(11, 22, 34, .93);
}
.lightbox[hidden] { display: none; }
.lightbox__figure {
  margin: 0;
  max-width: 100%;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.lightbox__figure img { max-width: 100%; max-height: 82vh; object-fit: contain; border-radius: 8px; }
.lightbox__figure figcaption { color: #fff; font-size: 13.5px; text-align: center; opacity: .9; }
.lightbox__close,
.lightbox__nav {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .14);
  color: #fff;
  cursor: pointer;
}
.lightbox__close { top: 18px; right: 18px; }
.lightbox__nav--prev { left: 14px; top: 50%; transform: translateY(-50%); }
.lightbox__nav--next { right: 14px; top: 50%; transform: translateY(-50%); }
.lightbox__close:hover,
.lightbox__nav:hover { background: rgba(255, 255, 255, .3); }

/* Photo details: camera, exposure, date and place, behind a button rather than printed
   on the page. Two aligned columns, muted labels — the aim is a spec sheet, not a dump,
   so only the fields a photo actually has are rendered (server side, PhotoMeta::rows()). */
.lightbox__toggle {
  padding: 6px 14px;
  border: 1px solid rgba(255, 255, 255, .25);
  border-radius: 999px;
  background: rgba(255, 255, 255, .1);
  color: #fff;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background .16s ease, border-color .16s ease;
}
.lightbox__toggle:hover { background: rgba(255, 255, 255, .22); }
.lightbox__toggle[hidden] { display: none; }
.lightbox__details {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 6px 18px;
  width: 100%;
  max-width: 460px;
  max-height: 34vh;
  margin: 0;
  padding: 14px 18px;
  overflow-y: auto;
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 10px;
  background: rgba(255, 255, 255, .07);
  color: #fff;
  font-size: 13px;
  text-align: left;
}
.lightbox__details[hidden] { display: none; }
.lightbox__details dt {
  color: rgba(255, 255, 255, .58);
  font-weight: 600;
  white-space: nowrap;
}
.lightbox__details dd {
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Making room for the panel: the photo gives up height so the two fit one screen, and
   the figure scrolls if a small window still cannot hold them. */
.lightbox.is-detailed .lightbox__figure { overflow-y: auto; }
.lightbox.is-detailed .lightbox__figure img { max-height: 56vh; }
@media (max-width: 640px) {
  .lightbox { padding: 16px; }
  .lightbox__nav { width: 38px; height: 38px; }
  .lightbox__nav--prev { left: 6px; }
  .lightbox__nav--next { right: 6px; }
}

/* Inline info banner (also used for the "awaiting review" notice). */
.notice {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 13px 16px;
  margin: 16px 0;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: #fff;
  font-size: 13.5px;
  color: var(--text-soft);
}
.notice--info { background: #f2f7fd; border-color: #cfe2f7; color: #1b4b7d; }
.notice svg { flex: 0 0 auto; margin-top: 2px; }

/* ------------------------------------------------------- drag to file --- */

/* The Unsorted tray while a photo is being dragged. */
.photo-grid.is-dragging .photo-tile { opacity: .4; }
.photo-grid.is-dragging .photo-tile[draggable="true"] { cursor: grabbing; }

/* An album card is a drop target only while something is being dragged. */
.album-card.is-drop-target {
  border-color: var(--red);
  box-shadow: 0 0 0 3px var(--red-50), 0 12px 28px rgba(11, 22, 34, .14);
  transform: translateY(-3px);
}
.album-card.is-drop-target .album-card__cover::after {
  content: "Drop to file here";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(228, 0, 43, .82);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
}
.photo-tile[draggable="true"] { cursor: grab; }

/* Photo credit — the photographer's name for that photo, under the caption on the tile
   and in the lightbox, so who took a picture is visible on the public pages. */
.photo-tile__credit {
  display: block;
  margin-top: 2px;
  font-weight: 500;
  opacity: .85;
}
.lightbox__credit {
  display: block;
  margin-top: 4px;
  font-size: 12.5px;
  opacity: .75;
}
.lightbox__credit[hidden] { display: none; }

/* Arrange mode: reorder an album by dragging a tile or with its earlier/later arrows.
   The arrows are the primary control, so the caption (which holds them) is always shown
   here rather than fading in on hover. */
.photo-grid--arrange .photo-tile { cursor: grab; }
.photo-grid--arrange .photo-tile.is-dragging { opacity: .35; }
.photo-grid--arrange .photo-tile__caption { opacity: 1; }
.photo-tile__pos {
  position: absolute;
  top: 8px;
  right: 8px;
  min-width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  background: rgba(11, 22, 34, .72);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
}
.arrange__moves { display: inline-flex; gap: 4px; margin-top: 6px; }
.arrange__moves .icon-btn {
  width: 26px;
  height: 26px;
  background: rgba(255, 255, 255, .9);
  color: #0b1622;
}
.arrange__moves .icon-btn:hover { background: #fff; }
.arrange__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding: 11px 14px;
  margin-top: 18px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
}
.arrange__bar[hidden] { display: none; }
.arrange__foot { display: flex; align-items: center; gap: 10px; margin-top: 18px; }

/* Describe-your-photos screen shown straight after a batch upload. */
.review-list { display: grid; gap: 12px; margin-top: 18px; }
.review-item {
  display: grid;
  grid-template-columns: 132px minmax(0, 1fr) 160px;
  gap: 16px;
  align-items: start;
  padding: 14px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
}
.review-item__thumb {
  aspect-ratio: 1 / 1;
  border-radius: 8px;
  overflow: hidden;
  background: #eef2f6;
}
.review-item__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.review-item__fields { display: grid; gap: 12px; }
.review-item__fields .field { margin: 0; }
.review-item__meta { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.review-foot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 18px; }

@media (max-width: 760px) {
  .review-item { grid-template-columns: 92px minmax(0, 1fr); }
  .review-item__meta { grid-column: 1 / -1; flex-direction: row; flex-wrap: wrap; }
}

/* --------------------------------------------------------- photo uploader --- */

/* Drop zone + live previews + a caption and credit per photo. The file input itself is
   sr-only; the dashed panel above is its <label>, so clicking anywhere in the panel opens
   the picker while the real control stays reachable by keyboard and screen reader. */
.uploader { margin-bottom: 4px; }
.uploader__drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 26px 20px;
  text-align: center;
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface-alt);
  cursor: pointer;
  transition: border-color .16s ease, background .16s ease, box-shadow .16s ease;
}
.uploader__drop:hover,
.uploader:focus-within .uploader__drop { border-color: var(--red); background: var(--red-50); }
.uploader__drop.is-over {
  border-color: var(--red);
  background: var(--red-50);
  box-shadow: 0 0 0 3px rgba(228, 0, 43, .12);
}
.uploader__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  margin-bottom: 4px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  color: var(--red);
}
.uploader__title { font-weight: 700; color: var(--text); }
.uploader__sub { font-size: 13px; color: var(--text-soft); }
.uploader__browse { color: var(--red); font-weight: 600; text-decoration: underline; }
.uploader__hint { max-width: 48ch; margin-top: 6px; font-size: 11.5px; color: var(--muted); }

.uploader__note {
  margin: 10px 0 0;
  padding: 9px 12px;
  border: 1px solid #f3c9c9;
  border-radius: var(--radius-sm);
  background: var(--danger-bg);
  color: var(--danger);
  font-size: 12.5px;
  font-weight: 600;
}
.uploader__note[hidden] { display: none; }

.uploader__list {
  display: grid;
  gap: 10px;
  max-height: 420px;
  margin-top: 14px;
  padding-right: 2px;
  overflow-y: auto;
}
.uploader__list[hidden] { display: none; }
.uploader__item {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr) auto;
  gap: 14px;
  align-items: start;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}
.uploader__thumb {
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border-radius: 8px;
  background: #eef2f6;
}
.uploader__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.uploader__fields { display: grid; gap: 10px; min-width: 0; }
.uploader__field { display: block; }
.uploader__field .field__label { margin-bottom: 3px; }
.uploader__file {
  overflow: hidden;
  color: var(--text-soft);
  font-size: 12px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.uploader__remove { color: var(--muted); }
.uploader__remove:hover { color: var(--danger); background: var(--red-50); }

@media (max-width: 620px) {
  .uploader__item { grid-template-columns: 64px minmax(0, 1fr) auto; gap: 10px; }
}

/* ------------------------------------------------------ photo detail --- */

.photo-detail {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: 24px;
  align-items: start;
  margin-top: 18px;
}
.photo-detail__stage {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px;
}
.photo-detail__stage img {
  width: 100%;
  height: auto;
  max-height: 72vh;
  object-fit: contain;
  display: block;
  border-radius: 8px;
  background: #eef2f6;
}
.photo-detail__side {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 18px;
}
.photo-detail__flags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.photo-detail__flags:empty { display: none; }

.divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 18px 0 12px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted, #7a8896);
}
.divider::after { content: ""; flex: 1; height: 1px; background: var(--border); }

@media (max-width: 980px) {
  .photo-detail { grid-template-columns: minmax(0, 1fr); }
}

/* ------------------------------------------------- "add existing" picker */

.picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 10px;
  max-height: 46vh;
  overflow: auto;
  padding: 2px;
}
.picker-item {
  position: relative;
  display: block;
  cursor: pointer;
  border: 2px solid transparent;
  border-radius: 9px;
  overflow: hidden;
  background: #eef2f6;
}
.picker-item input {
  position: absolute;
  z-index: 2;
  top: 6px;
  left: 6px;
  width: 17px;
  height: 17px;
}
.picker-item img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; display: block; }
.picker-item:has(input:checked) { border-color: var(--red); }
.picker-item__label {
  display: block;
  padding: 5px 7px;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.25;
  background: #fff;
}
.picker-item__label em {
  display: block;
  font-style: normal;
  font-weight: 500;
  color: var(--muted, #7a8896);
}

/* ------------------------------------------------------ album manager --- */

.manager {
  display: grid;
  grid-template-columns: 264px minmax(0, 1fr);
  gap: 18px;
  align-items: start;
  margin-top: 18px;
}

/* ---- filter sidebar ---- */
.manager__side {
  position: sticky;
  top: 16px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px;
  max-height: calc(100vh - 32px);
  overflow: auto;
}
.manager__filters { display: flex; flex-direction: column; gap: 12px; }

.seg-group {
  display: inline-flex;
  padding: 3px;
  gap: 2px;
  background: #eef2f6;
  border-radius: 999px;
}
.seg-group .seg {
  border: 0;
  background: transparent;
  padding: 5px 11px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-soft);
  cursor: pointer;
}
.seg-group .seg:hover { color: var(--red); }
.seg-group .seg.is-active { background: #fff; color: var(--text, #16232f); box-shadow: 0 1px 3px rgba(11, 22, 34, .12); }

.manager__facet { margin-top: 16px; }
.manager__facet-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--muted, #7a8896);
  margin-bottom: 7px;
}
.manager__facet-head a { font-size: 10.5px; text-transform: none; letter-spacing: 0; color: var(--red); }
.manager__chips { display: flex; flex-wrap: wrap; gap: 6px; }
.manager__chips .chip { font-size: 12px; padding: 4px 10px; }

/* ---- panes ---- */
.manager__main { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.manager__pane {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
}
.manager__pane-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 13px 16px;
  border-bottom: 1px solid var(--border);
  background: #fbfcfd;
}
.manager__pane-head h2 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 14px;
  font-weight: 700;
}
.manager__pane-body { padding: 14px; min-height: 120px; }
.manager__pane-body .photo-grid { margin-top: 0; }

.manager__remove {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border: 1px dashed var(--border-strong, #cbd5e1);
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--muted, #7a8896);
  transition: all .15s ease;
}
.manager__remove.is-drop-target {
  border-style: solid;
  border-color: var(--danger, #d92d20);
  background: #fef2f2;
  color: var(--danger, #d92d20);
}

/* The album pane is the drop target for library photos. */
.manager__pane.is-drop-target {
  border-color: var(--red);
  box-shadow: 0 0 0 3px var(--red-50, #fdecef);
}
.manager__pane.is-drop-target .manager__pane-body::after {
  content: "Drop to add to this album";
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 64px;
  margin-top: 10px;
  border: 2px dashed var(--red);
  border-radius: 10px;
  color: var(--red);
  font-size: 13px;
  font-weight: 700;
}

.photo-tile__drop-hint {
  display: block;
  font-weight: 500;
  opacity: .82;
  font-size: 10.5px;
}

@media (max-width: 1080px) {
  .manager { grid-template-columns: minmax(0, 1fr); }
  .manager__side { position: static; max-height: none; }
}

/* ============================================================ post editor === */

/* The settings column stays beside the editor for as long as there is room. It only
   stacks on a phone — an earlier 1100px breakpoint put it underneath the editor on an
   ordinary laptop, which is not what a two-column form is for. */
.editor-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 18px;
  align-items: start;
}
.editor-layout__main { min-width: 0; }
.editor-layout__side { position: sticky; top: 16px; display: flex; flex-direction: column; gap: 14px; }

/* toolbar */
/* Direct child of .card, so it supplies its own padding, top radius and divider
   rather than inheriting .card__head's flex row. */
.editor-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
  background: #fbfcfd;
  border-radius: var(--radius, 12px) var(--radius, 12px) 0 0;
}
.editor-toolbar__group {
  display: flex;
  align-items: center;
  gap: 3px;
  padding-right: 8px;
  margin-right: 2px;
  border-right: 1px solid var(--border);
}
.editor-toolbar__group:last-child { border-right: 0; }
.editor-toolbar__group--end { margin-left: auto; padding-right: 0; border-right: 0; }

.editor-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-width: 30px;
  height: 30px;
  padding: 0 8px;
  border: 1px solid transparent;
  border-radius: 7px;
  background: transparent;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-soft);
  cursor: pointer;
}
.editor-btn:hover { background: #eef2f6; color: var(--text, #16232f); }
.editor-btn.is-active {
  background: var(--red-50, #fdecef);
  border-color: var(--red);
  color: var(--red);
}
.select--sm { height: 30px; padding: 0 24px 0 9px; font-size: 12.5px; width: auto; }
.editor-count { margin-right: 6px; white-space: nowrap; }

/* the editable surface */
.editor-surface {
  min-height: 380px;
  max-height: 62vh;
  overflow: auto;
  padding: 22px 24px;
  font-size: 15px;
  line-height: 1.7;
  color: var(--text, #16232f);
}
.editor-surface:focus { outline: 2px solid var(--red); outline-offset: -2px; }
.editor-surface:empty::before {
  content: "Write here, or switch to Code to paste HTML.";
  color: var(--muted, #7a8896);
}
.editor-surface h2 { margin: 1.6em 0 .5em; font-size: 1.32rem; }
.editor-surface h3 { margin: 1.4em 0 .4em; font-size: 1.12rem; }
.editor-surface blockquote {
  margin: 1.2em 0;
  padding-left: 16px;
  border-left: 3px solid var(--red);
  color: var(--text-soft);
}
.editor-surface img { max-width: 100%; height: auto; border-radius: 8px; }
.editor-surface [data-album-card] {
  display: block;
  padding: 12px 14px;
  border: 1px dashed var(--border-strong, #cbd5e1);
  border-radius: 9px;
  background: #fbfcfd;
  color: var(--muted, #7a8896);
  font-size: 13px;
  font-weight: 600;
}
.editor-source {
  width: 100%;
  min-height: 380px;
  padding: 16px;
  border: 0;
  border-radius: 0 0 var(--radius, 12px) var(--radius, 12px);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px;
  line-height: 1.6;
  resize: vertical;
}
.input--title { font-size: 17px; font-weight: 600; }

/* preview pane, sharing the site's prose rules */
.editor-preview { border-top: 1px solid var(--border); background: #fff; }
.editor-preview__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
  padding: 10px 14px;
  background: #fbfcfd;
  border-bottom: 1px solid var(--border);
}
.editor-preview__body { padding: 24px; max-height: 62vh; overflow: auto; }

/* overlays: link dialog + insert picker */
.editor-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(11, 22, 34, .55);
}
.editor-overlay[hidden] { display: none; }
.editor-overlay__panel {
  width: 100%;
  max-width: 720px;
  max-height: 84vh;
  display: flex;
  flex-direction: column;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 24px 60px rgba(11, 22, 34, .3);
  overflow: hidden;
}
.editor-overlay__panel--sm { max-width: 480px; }
.editor-overlay__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 15px 18px;
  border-bottom: 1px solid var(--border);
}
.editor-overlay__head h2 { margin: 0; font-size: 15px; font-weight: 700; }
.editor-overlay__body { padding: 18px; overflow: auto; }

.editor-picker__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 10px;
  margin: 8px 0 20px;
}
.editor-picker__item {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: #fff;
  overflow: hidden;
  cursor: pointer;
  text-align: left;
  font: inherit;
}
.editor-picker__item:hover { border-color: var(--red); }
.editor-picker__item img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; }
.editor-picker__item strong,
.editor-picker__item em {
  display: block;
  padding: 6px 8px;
  font-size: 11.5px;
  font-style: normal;
  line-height: 1.3;
}
.editor-picker__item strong { font-weight: 700; }
.editor-picker__item em { color: var(--muted, #7a8896); padding-top: 0; }

/* Narrower sidebar before giving up on two columns. */
@media (max-width: 1240px) {
  .editor-layout { grid-template-columns: minmax(0, 1fr) 258px; gap: 14px; }
  .editor-layout__side { position: static; }
}

@media (max-width: 820px) {
  .editor-layout { grid-template-columns: minmax(0, 1fr); }
  .editor-layout__side { position: static; }
}

.hero-preview { margin-top: 12px; }
.hero-preview img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 9px;
  display: block;
  margin-bottom: 5px;
  background: #eef2f6;
}

/* ======================================================== chip tag input === */

.tag-input { position: relative; }

.tag-input__box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px;
  min-height: 40px;
  padding: 5px 7px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 9px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.tag-input__box:focus-within {
  border-color: var(--red);
  box-shadow: 0 0 0 3px var(--red-50, #fdecef);
}

.tag-input__chips { display: contents; }

/* The typed name becomes one of these. */
.tag-chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  max-width: 100%;
  padding: 3px 4px 3px 9px;
  background: #eef2f6;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text, #16232f);
}
.tag-chip__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tag-chip__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 17px;
  height: 17px;
  flex: 0 0 17px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--muted, #7a8896);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}
.tag-chip__remove:hover { background: #dbe2e8; color: var(--danger, #d92d20); }

/* The field the user actually types into, inside the chip row. */
.tag-input__entry {
  flex: 1 1 130px;
  min-width: 130px;
  height: 26px;
  border: 0;
  outline: 0;
  background: transparent;
  font-size: 13.5px;
  color: var(--text, #16232f);
}
.tag-input__entry::placeholder { color: var(--muted, #7a8896); }

/* Typeahead */
.tag-input__menu {
  position: absolute;
  z-index: 30;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 3px;
  max-height: 210px;
  overflow: auto;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 9px;
  box-shadow: 0 12px 28px rgba(11, 22, 34, .16);
}
.tag-input__menu[hidden] { display: none; }
.tag-menu__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  padding: 7px 11px;
  border: 0;
  background: transparent;
  text-align: left;
  font-size: 13px;
  color: var(--text, #16232f);
  cursor: pointer;
}
.tag-menu__item:hover { background: #f4f6f8; }
.tag-menu__item em {
  font-style: normal;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--red);
}

/* Suggested / most-used quick add */
.tag-input__suggest { margin-top: 9px; }
.tag-input__suggest > .text-xs { display: block; margin-bottom: 5px; }
.tag-suggest {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: #fff;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-soft);
  cursor: pointer;
}
.tag-suggest:hover { border-color: var(--red); color: var(--red); }
/* Contextual suggestions read as recommendations, not just popularity. */
.tag-suggest--relevant { background: var(--red-50, #fdecef); border-color: #f6c6d0; color: var(--red); }
.tag-suggest:disabled,
.tag-suggest.is-applied { opacity: .45; cursor: default; }
.tag-suggest:disabled:hover { border-color: var(--border); color: var(--text-soft); }
.tag-suggest__n { font-size: 10.5px; font-weight: 700; opacity: .7; }

/* ================================================== photo picker modal === */

.editor-overlay__panel--wide { max-width: 900px; }

.editor-picker__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--border);
  background: #fbfcfd;
}
.editor-picker__bar .input { flex: 1 1 260px; }
.editor-picker__filters { display: inline-flex; gap: 2px; padding: 3px; background: #eef2f6; border-radius: 999px; }
.editor-picker__filters .seg {
  border: 0;
  background: transparent;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-soft);
  cursor: pointer;
}
.editor-picker__filters .seg.is-active { background: #fff; color: var(--text, #16232f); box-shadow: 0 1px 3px rgba(11, 22, 34, .12); }

.editor-picker__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 18px;
  border-top: 1px solid var(--border);
  background: #fbfcfd;
}

.editor-picker__item em { color: var(--muted, #7a8896); }
.editor-picker__meta { padding-top: 0 !important; font-weight: 500; font-size: 10.5px; }

/* ==================================================== hero image picker === */

.hero-current {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: #fbfcfd;
}
.hero-current img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 7px;
  display: block;
  background: #eef2f6;
}
.hero-current__none { font-size: 12.5px; color: var(--muted, #7a8896); padding: 10px 2px; }

.editor-picker__tags {
  padding: 10px 18px;
  border-bottom: 1px solid var(--border);
}
.editor-picker__tags > .text-xs { display: block; margin-bottom: 6px; }
.editor-picker__tagchips { display: flex; flex-wrap: wrap; gap: 6px; }
.editor-picker__tagchips .tag-suggest.is-active {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
}
.editor-picker__tagchips .tag-suggest.is-active .tag-suggest__n { opacity: .85; }

.hero-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: 10px;
}
.hero-grid__item {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 9px;
  overflow: hidden;
  background: #fff;
  cursor: pointer;
  text-align: left;
  font: inherit;
}
.hero-grid__item img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; display: block; }
.hero-grid__item em {
  display: block;
  padding: 5px 7px;
  font-style: normal;
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.25;
}
.hero-grid__item:hover { border-color: var(--red); }
.hero-grid__item:hover img { opacity: .9; }

/* ------------------------------------------------- event page tab panels --- */

/* The bar sits flush under the hero image, so the card reads as one unit. */
.evt-tabs { border-bottom: 1px solid var(--border); background: #fbfcfd; }
.evt-tabs__bar {
  display: flex;
  align-items: stretch;
  gap: 2px;
  padding: 0 6px;
  overflow-x: auto;
}
.evt-tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 12px 15px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-soft);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.evt-tab:hover { color: var(--red); }
.evt-tab.is-active {
  color: var(--red);
  border-bottom-color: var(--red);
  background: #fff;
}
.evt-tab:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: -3px;
  border-radius: 6px 6px 0 0;
}
.evt-tab svg { opacity: .75; }
.evt-tab.is-active svg { opacity: 1; }

/* Panels are plain flow content; the last child never needs trailing padding. */
/* Every panel pads its own content, so switching tabs never shifts the text sideways.
   The Weather panel's partial emits no .card__body of its own, so the rule below covers
   it too rather than leaving that one tab flush against the card edge. */
.evt-panel > * { min-width: 0; }
.evt-panel > .card__body,
.evt-panel > [data-weather],
.evt-panel > .empty { padding: 18px; }
.evt-panel .table-wrap { margin: 0; }

/* Leaflet mount point inside the Map tab. Empty when the event has no coordinates. */
.evt-map {
  margin-top: 12px;
  height: 260px;
  border-radius: 10px;
  overflow: hidden;
  background: #eef2f6;
  border: 1px solid var(--border);
}
.evt-map:empty { display: none; }

/* ------------------------------------------- incident cards (event page) --- */

.incident-cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.incident-card {
  display: block;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--border);
  border-radius: 8px;
  background: #fff;
  cursor: pointer;
}
.incident-card:hover { background: #fbfcfd; border-color: var(--red); }
.incident-card:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 1px;
}

/* The left edge carries the status, so a wall of cards reads at a glance. */
.incident-card[data-status="Open"]        { border-left-color: var(--warning); }
.incident-card[data-status="Monitoring"]  { border-left-color: var(--info); }
.incident-card[data-status="Resolved"]    { border-left-color: var(--success); }
.incident-card[data-status="Closed"]      { border-left-color: var(--border); }
.incident-card[data-status="False Alarm"] { border-left-color: var(--border); opacity: .72; }

.incident-card__top {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.incident-card__top strong { font-size: 14px; }

.incident-card__desc {
  margin: 6px 0 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text-soft);
}

.incident-card__meta {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 8px;
  font-size: 12px;
  color: var(--muted);
}
.incident-card__meta span { display: inline-flex; align-items: center; gap: 4px; }

/* ------------------------------------------------------------ lost & found --- */

/* Tiles on the event page card: a photo is the whole identifier, so it leads. */
.lf-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
}

.lf-tile {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface);
  text-decoration: none;
  color: inherit;
  transition: border-color .12s ease, transform .12s ease;
}
.lf-tile:hover { border-color: var(--red); transform: translateY(-2px); }
.lf-tile:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

.lf-tile__photo {
  display: block;
  aspect-ratio: 4 / 3;
  background: var(--surface-alt);
  overflow: hidden;
}
.lf-tile__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.lf-tile__body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 9px 10px 11px;
}
.lf-tile__name {
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.3;
}
.lf-tile__meta { font-size: 11.5px; color: var(--muted); }

/* Once claimed or disposed the tile stays readable but stops competing for attention. */
.lf-tile.is-closed { opacity: .62; }
.lf-tile.is-closed .lf-tile__photo img { filter: grayscale(.5); }

/* Full list on the per-event page. */
.lf-list { display: flex; flex-direction: column; gap: 12px; }

.lf-item {
  display: flex;
  gap: 14px;
  padding: 12px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--warning);
  border-radius: var(--radius);
  background: var(--surface);
}
.lf-item[data-status="Claimed"]  { border-left-color: var(--success); }
.lf-item[data-status="Disposed"] { border-left-color: var(--border-strong); }
.lf-item.is-closed { background: var(--surface-alt); }
.lf-item.is-closed .lf-item__media img { filter: grayscale(.6); opacity: .8; }

.lf-item__media { flex: 0 0 132px; }
.lf-item__media a { display: block; }
.lf-item__media img {
  width: 132px;
  height: 100px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  display: block;
  background: var(--surface-alt);
}
.lf-item__media-hidden {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: 132px;
  height: 100px;
  border-radius: var(--radius-sm);
  background: var(--surface-alt);
  color: var(--muted);
  font-size: 11.5px;
}

.lf-item__body { flex: 1 1 auto; min-width: 0; }
.lf-item__top {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.lf-item__top strong { font-size: 14.5px; }

.lf-item__desc {
  margin: 6px 0 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text-soft);
}

.lf-item__meta {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 8px;
  font-size: 12px;
  color: var(--muted);
}
.lf-item__meta span { display: inline-flex; align-items: center; gap: 4px; }

.lf-item__notes {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 8px 0 0;
  padding: 7px 10px;
  border-radius: var(--radius-sm);
  background: var(--surface-alt);
  font-size: 12.5px;
  color: var(--text-soft);
}

.lf-item__actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 12px;
}
.lf-item__inline-form { display: inline-flex; margin: 0; }

/*
 * <details> does the disclosure, so these forms work with scripting off.
 *
 * Closed, a disclosure is just its summary and sits in the button row like any other
 * button. Opened, flex-basis:100% pushes it onto its own line so the form has the full
 * width of the card instead of being squeezed beside the summary.
 */
.lf-item__disclosure {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.lf-item__disclosure[open] { flex-basis: 100%; }

.lf-item__disclosure > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.lf-item__disclosure > summary::-webkit-details-marker { display: none; }
.lf-item__disclosure[open] > summary {
  border-color: var(--red);
  color: var(--red);
}

.lf-item__form {
  width: 100%;
  margin-top: 12px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-alt);
}
.lf-item__form-foot {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 4px;
}

/* --------------------------------------- map picker search results (admin) --- */

/*
 * The geocoder never picks a result on the admin's behalf: "Caledonia" exists in four
 * countries and a silent first-hit choice is how an event ends up pinned in Wisconsin.
 * So the hits are a list, and the ones in the right country are marked.
 */
.location-result__head {
  padding: 8px 12px;
  background: var(--surface-alt);
  border-bottom: 1px solid var(--border);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .05em;
}

.location-result {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
  padding: 9px 12px;
  border: 0;
  border-bottom: 1px solid var(--border);
  border-left: 3px solid transparent;
  background: transparent;
  text-align: left;
  cursor: pointer;
  font: inherit;
}
.location-result:last-child { border-bottom: 0; }
.location-result:hover { background: var(--surface-alt); border-left-color: var(--red); }
.location-result:focus-visible { outline: 2px solid var(--red); outline-offset: -2px; }

.location-result.is-likely { border-left-color: var(--success); }

.location-result__name { font-size: 13.5px; font-weight: 600; }
.location-result__meta { font-size: 11.5px; color: var(--muted); }

/* --------------------------------------------------------- upload progress --- */

/*
 * A native form POST reports nothing, so the only feedback is the tab's favicon
 * spinning — indistinguishable from a hang. This is the visible half of the XHR upload
 * handler in app.js: which file, how far, and how long it has been.
 */
.upload-overlay {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(11, 22, 34, .55);
  backdrop-filter: blur(2px);
}
.upload-overlay[hidden] { display: none; }

.upload-overlay__box {
  width: min(420px, 100%);
  padding: 20px;
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
}

.upload-overlay__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.upload-overlay__title { font-size: 15px; font-weight: 700; }
.upload-overlay__pct {
  font-size: 13px;
  font-weight: 700;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.upload-overlay__bar {
  height: 8px;
  margin-top: 12px;
  border-radius: 999px;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  overflow: hidden;
}
.upload-overlay__bar > span {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: var(--red);
  transition: width .18s ease-out;
}

.upload-overlay__file {
  margin-top: 10px;
  font-size: 12.5px;
  color: var(--text-soft);
  word-break: break-all;
}

.upload-overlay__note {
  margin-top: 6px;
  font-size: 12px;
  color: var(--muted);
}

.upload-overlay__foot {
  display: flex;
  justify-content: flex-end;
  margin-top: 14px;
}

/* Waiting on the network reads differently from actively progressing. */
.upload-overlay.is-sending .upload-overlay__bar > span {
  background: repeating-linear-gradient(
    90deg, var(--red) 0 12px, #ff6b86 12px 24px
  );
  background-size: 24px 100%;
  animation: upload-stripes 1.1s linear infinite;
}
@keyframes upload-stripes {
  from { background-position: 0 0; }
  to   { background-position: 24px 0; }
}

.upload-overlay.is-done .upload-overlay__bar > span { background: var(--success); }
.upload-overlay.is-error .upload-overlay__bar > span { background: var(--danger); }
.upload-overlay.is-error .upload-overlay__title { color: var(--danger); }

/*
 * The inline note under a file input. This is the only upload feedback before the upload
 * starts, and it is deliberately not a modal: nothing is in flight yet, so a dialog would
 * offer a Cancel with nothing to cancel.
 */
.upload-note {
  font-size: 11.5px;
  color: var(--muted);
}
.upload-note.is-error {
  color: var(--danger);
  font-weight: 600;
}
