/* ==========================================================================
   Ushersboard — House on the Rock, The Refuge Abuja
   Brand colours sampled from the church logo:
     forest #395231 · leaf #87c248 · sun #fbe83e
   Chart colours are NOT brand colours: they come from a colour-vision-safe
   palette (blue / orange / aqua). A brand-green series was tested and failed
   protanope separation against orange, so brand green stays UI chrome only.
   ========================================================================== */

:root {
  color-scheme: light;

  --brand-900:#1d2b19; --brand-800:#2b3f24; --brand-700:#395231; --brand-600:#47653c;
  --brand-500:#54693c; --brand-400:#87c248; --brand-300:#a5d472; --brand-100:#e6f2dc;
  --sun:#fbe83e; --sun-deep:#d9c313;
  /* Text/icon colour that sits on a --brand-700 fill. Flips with the theme,
     because brand-700 is dark green in light mode and leaf green in dark. */
  --on-brand:#ffffff;
  /* Warning and 'serious' are sub-3:1 on a light surface, so badge text uses a
     darkened ink there and the status hue itself on dark. */
  --ink-warning:#8a5f00; --ink-serious:#a8451c;

  --page:#f6f8f2; --surface:#ffffff; --surface-2:#f1f4ea; --surface-3:#e8ecdf;
  --ink:#14180f; --ink-2:#4d5346; --muted:#84897a;
  --line:#e0e4d6; --line-strong:#cdd3bf;
  --ring:rgba(57,82,49,.14); --shadow:0 1px 2px rgba(20,24,15,.05), 0 8px 24px -12px rgba(20,24,15,.18);
  --shadow-lg:0 2px 4px rgba(20,24,15,.06), 0 24px 56px -20px rgba(20,24,15,.28);

  --series-1:#2a78d6; --series-2:#eb6834; --series-3:#1baf7a;
  --seq-100:#cde2fb; --seq-250:#86b6ef; --seq-400:#3987e5; --seq-550:#1c5cab; --seq-700:#0d366b;
  --good:#0ca30c; --warning:#fab219; --serious:#ec835a; --critical:#d03b3b;
  --grid:#e1e0d9; --axis:#c3c2b7; --chart-surface:#ffffff;

  --radius:14px; --radius-sm:9px; --radius-lg:20px;
  --nav-w:262px; --top-h:64px;
  --sans:"Open Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --display:"Didact Gothic", "Open Sans", system-ui, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    color-scheme: dark;
    --page:#0c0f0b; --surface:#151a15; --surface-2:#1c221b; --surface-3:#242c23;
    --ink:#f1f4ec; --ink-2:#c0c7b6; --muted:#8b9182;
    --line:#283027; --line-strong:#3a4438;
    --ring:rgba(135,194,72,.18); --shadow:0 1px 2px rgba(0,0,0,.5), 0 10px 28px -14px rgba(0,0,0,.8);
    --shadow-lg:0 2px 6px rgba(0,0,0,.55), 0 28px 60px -22px rgba(0,0,0,.9);
    --brand-100:#22301c; --brand-700:#87c248; --brand-600:#9ed35f; --on-brand:#0c0f0b;
    --ink-warning:#fab219; --ink-serious:#ec835a;
    --series-1:#3987e5; --series-2:#d95926; --series-3:#199e70;
    --seq-100:#0d366b; --seq-250:#184f95; --seq-400:#2a78d6; --seq-550:#5598e7; --seq-700:#b7d3f6;
    --grid:#2c2c2a; --axis:#383835; --chart-surface:#151a15;
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --page:#0c0f0b; --surface:#151a15; --surface-2:#1c221b; --surface-3:#242c23;
  --ink:#f1f4ec; --ink-2:#c0c7b6; --muted:#8b9182;
  --line:#283027; --line-strong:#3a4438;
  --ring:rgba(135,194,72,.18); --shadow:0 1px 2px rgba(0,0,0,.5), 0 10px 28px -14px rgba(0,0,0,.8);
  --shadow-lg:0 2px 6px rgba(0,0,0,.55), 0 28px 60px -22px rgba(0,0,0,.9);
  --brand-100:#22301c; --brand-700:#87c248; --brand-600:#9ed35f; --on-brand:#0c0f0b;
  --ink-warning:#fab219; --ink-serious:#ec835a;
  --series-1:#3987e5; --series-2:#d95926; --series-3:#199e70;
  --seq-100:#0d366b; --seq-250:#184f95; --seq-400:#2a78d6; --seq-550:#5598e7; --seq-700:#b7d3f6;
  --grid:#2c2c2a; --axis:#383835; --chart-surface:#151a15;
}

*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin:0; background:var(--page); color:var(--ink);
  font:400 15px/1.55 var(--sans); -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4 { font-family:var(--display); font-weight:400; letter-spacing:-.01em; margin:0; line-height:1.2; }
h1 { font-size:1.7rem; } h2 { font-size:1.3rem; } h3 { font-size:1.05rem; }
p { margin:0 0 .6em; }
a { color:var(--brand-700); text-decoration:none; }
a:hover { text-decoration:underline; }
img { max-width:100%; display:block; }
:focus-visible { outline:2px solid var(--brand-400); outline-offset:2px; border-radius:6px; }
.hide { display:none !important; }
.sr { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }

/* ---------- shell -------------------------------------------------------- */
.app { display:grid; grid-template-columns:var(--nav-w) 1fr; min-height:100vh; }

.side {
  background:var(--brand-900); color:#e8efe2; display:flex; flex-direction:column;
  position:sticky; top:0; height:100vh; overflow-y:auto;
}
.brand { padding:20px 18px 16px; border-bottom:1px solid rgba(255,255,255,.09); }
.brand-mark { display:flex; flex-direction:column; align-items:flex-start; gap:11px; }
/* The complete church lockup is used everywhere, uncropped. Its wordmark is
   dark forest green on an opaque white background, so on the dark sidebar and
   sign-in panel it sits on a white plaque rather than being recoloured. */
.brand-logo { width:100%; max-width:224px; height:auto; display:block;
  background:#fff; border-radius:10px; padding:9px 11px; }
.brand-name { font-family:var(--sans); font-weight:800; font-size:1.2rem; letter-spacing:-.02em;
  line-height:1.15; color:#fff; }
.brand-sub { font-size:.7rem; letter-spacing:.11em; text-transform:uppercase; color:var(--brand-400); margin-top:3px; }

.nav { padding:12px 10px; display:flex; flex-direction:column; gap:2px; flex:1; }
.nav-group { font-size:.66rem; letter-spacing:.13em; text-transform:uppercase; color:#7d8f73; padding:14px 10px 6px; }
.nav a {
  display:flex; align-items:center; gap:11px; padding:9px 11px; border-radius:10px;
  color:#cfdcc6; font-size:.9rem; text-decoration:none; transition:background .12s, color .12s;
}
.nav a:hover { background:rgba(255,255,255,.07); color:#fff; text-decoration:none; }
.nav a.on { background:var(--brand-700); color:#fff; font-weight:600; }
.nav a.on .ico { color:var(--sun); }
.ico { width:18px; height:18px; flex:none; color:#93a888; }
.nav a.on .ico, .nav a:hover .ico { color:inherit; }
.nav-badge { margin-left:auto; background:var(--sun); color:#3a3300; font-size:.68rem; font-weight:700; padding:1px 7px; border-radius:99px; }

.side-foot { padding:12px; border-top:1px solid rgba(255,255,255,.09); }
.whoami { display:flex; align-items:center; gap:10px; padding:8px; border-radius:10px; }
.whoami:hover { background:rgba(255,255,255,.06); }
.whoami .name { font-size:.85rem; color:#fff; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.whoami .role { font-size:.7rem; color:var(--brand-400); text-transform:uppercase; letter-spacing:.08em; }

.main { min-width:0; display:flex; flex-direction:column; }
.top {
  height:var(--top-h); display:flex; align-items:center; gap:14px; padding:0 24px;
  background:var(--surface); border-bottom:1px solid var(--line); position:sticky; top:0; z-index:30;
}
.top h1 { font-size:1.22rem; }
.top .sub { color:var(--muted); font-size:.82rem; }
.top-actions { margin-left:auto; display:flex; align-items:center; gap:8px; }
.view { padding:24px; flex:1; max-width:1500px; width:100%; }
/* The menu button works at every width, so it is always shown. */
.burger { display:inline-flex; }

/* Wide screens: the menu is a page column, and hiding it gives the width back
   to the content. Narrow screens are handled in the responsive block below,
   where the menu is a drawer instead. */
@media (min-width: 901px) {
  .app { transition:grid-template-columns .2s ease; }
  .app.nav-hidden { grid-template-columns:0 1fr; }
  /* The column closes to nothing, so the menu must clip rather than spill its
     links over the page behind it. */
  .app.nav-hidden > .side { overflow:hidden; border-right:0; }
}

/* ---------- primitives --------------------------------------------------- */
.card {
  background:var(--surface); border:1px solid var(--line); border-radius:var(--radius);
  box-shadow:var(--shadow); padding:18px;
}
.card-head { display:flex; align-items:flex-start; gap:12px; margin-bottom:14px; }
.card-head h2, .card-head h3 { margin:0; }
.card-head .hint { color:var(--muted); font-size:.82rem; margin-top:2px; }
.card-head .spacer { margin-left:auto; }

.grid { display:grid; gap:16px; }
.g2 { grid-template-columns:repeat(2, minmax(0,1fr)); }
.g3 { grid-template-columns:repeat(3, minmax(0,1fr)); }
.g4 { grid-template-columns:repeat(4, minmax(0,1fr)); }
.g-auto { grid-template-columns:repeat(auto-fill, minmax(260px,1fr)); }
.row { display:flex; gap:10px; align-items:center; flex-wrap:wrap; }
.stack { display:flex; flex-direction:column; gap:14px; }
.right { margin-left:auto; }

.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:7px;
  padding:9px 15px; border-radius:10px; border:1px solid var(--line-strong);
  background:var(--surface); color:var(--ink); font:600 .875rem var(--sans);
  cursor:pointer; transition:background .12s, border-color .12s, transform .06s; white-space:nowrap;
}
.btn:hover { background:var(--surface-2); border-color:var(--muted); }
.btn:active { transform:translateY(1px); }
.btn:disabled { opacity:.5; cursor:not-allowed; }
.btn-primary { background:var(--brand-700); border-color:var(--brand-700); color:var(--on-brand); }
.btn-primary:hover { background:var(--brand-600); border-color:var(--brand-600); }
.btn-danger { background:var(--critical); border-color:var(--critical); color:#fff; }
.btn-ghost { background:transparent; border-color:transparent; }
.btn-ghost:hover { background:var(--surface-2); border-color:var(--line); }
.btn-sm { padding:6px 11px; font-size:.8rem; border-radius:8px; }
.btn-icon { padding:8px; width:36px; height:36px; }

label, .lbl { display:block; font-size:.78rem; font-weight:600; color:var(--ink-2); margin-bottom:5px; letter-spacing:.01em; }
.req::after { content:" *"; color:var(--critical); }
input, select, textarea {
  width:100%; padding:9px 11px; border:1px solid var(--line-strong); border-radius:10px;
  background:var(--surface); color:var(--ink); font:400 .9rem var(--sans);
}
input[type="date"] { min-height:38px; }
input:focus, select:focus, textarea:focus { outline:none; border-color:var(--brand-400); box-shadow:0 0 0 3px var(--ring); }
input:disabled, select:disabled { background:var(--surface-2); color:var(--muted); }
textarea { resize:vertical; min-height:78px; }
select { appearance:none; background-image:linear-gradient(45deg,transparent 50%,var(--muted) 50%),linear-gradient(135deg,var(--muted) 50%,transparent 50%);
  background-position:calc(100% - 16px) 17px, calc(100% - 11px) 17px; background-size:5px 5px, 5px 5px; background-repeat:no-repeat; padding-right:32px; }
.field { margin-bottom:14px; }
.field .help { font-size:.75rem; color:var(--muted); margin-top:4px; }
.field .err { font-size:.76rem; color:var(--critical); margin-top:4px; }
.check { display:flex; align-items:center; gap:9px; font-size:.87rem; font-weight:400; color:var(--ink); margin:0; cursor:pointer; }
.check input { width:16px; height:16px; flex:none; accent-color:var(--brand-700); }

.badge { display:inline-flex; align-items:center; gap:5px; padding:3px 9px; border-radius:99px;
  font-size:.73rem; font-weight:600; background:var(--surface-2); color:var(--ink-2); border:1px solid var(--line); }
.badge .dot { width:7px; height:7px; border-radius:99px; background:currentColor; flex:none; }
.badge.good { color:var(--good); border-color:color-mix(in srgb, var(--good) 30%, transparent); background:color-mix(in srgb, var(--good) 9%, transparent); }
.badge.warning { color:var(--ink-warning); border-color:color-mix(in srgb, var(--warning) 40%, transparent); background:color-mix(in srgb, var(--warning) 14%, transparent); }
.badge.serious { color:var(--ink-serious); border-color:color-mix(in srgb, var(--serious) 40%, transparent); background:color-mix(in srgb, var(--serious) 13%, transparent); }
.badge.critical { color:var(--critical); border-color:color-mix(in srgb, var(--critical) 33%, transparent); background:color-mix(in srgb, var(--critical) 10%, transparent); }
.chip { padding:5px 12px; border-radius:99px; border:1px solid var(--line-strong); background:var(--surface);
  font-size:.8rem; cursor:pointer; color:var(--ink-2); }
.chip:hover { border-color:var(--brand-400); }
.chip.on { background:var(--brand-700); border-color:var(--brand-700); color:var(--on-brand); font-weight:600; }

.avatar { width:40px; height:40px; border-radius:99px; object-fit:cover; background:var(--surface-3); flex:none;
  display:grid; place-items:center; font-family:var(--display); color:var(--brand-700); font-size:.9rem; overflow:hidden; }
.avatar.lg { width:88px; height:88px; font-size:1.8rem; }
.avatar.xl { width:128px; height:128px; font-size:2.6rem; }
.avatar.sm { width:30px; height:30px; font-size:.72rem; }
.avatar img { width:100%; height:100%; object-fit:cover; }

table { width:100%; border-collapse:collapse; font-size:.87rem; }
th { text-align:left; font-weight:600; color:var(--muted); font-size:.73rem; letter-spacing:.07em;
  text-transform:uppercase; padding:9px 10px; border-bottom:1px solid var(--line); white-space:nowrap; }
td { padding:10px; border-bottom:1px solid var(--line); vertical-align:middle; }
tbody tr:hover td { background:var(--surface-2); }
tbody tr:last-child td { border-bottom:none; }
.num { text-align:right; font-variant-numeric:tabular-nums; }
.table-wrap { overflow-x:auto; margin:0 -18px -18px; padding:0 18px; }

.empty { text-align:center; padding:48px 20px; color:var(--muted); }
.empty h3 { color:var(--ink-2); margin-bottom:6px; }
.spinner { width:22px; height:22px; border:2.5px solid var(--line-strong); border-top-color:var(--brand-700);
  border-radius:99px; animation:spin .7s linear infinite; }
@keyframes spin { to { transform:rotate(360deg); } }
.loading { display:grid; place-items:center; padding:60px; }

.notice { padding:12px 14px; border-radius:10px; font-size:.86rem; border:1px solid; display:flex; gap:10px; align-items:flex-start; }
.notice.info { background:var(--brand-100); border-color:color-mix(in srgb, var(--brand-700) 25%, transparent); color:var(--ink); }
.notice.warn { background:color-mix(in srgb, var(--warning) 12%, transparent); border-color:color-mix(in srgb, var(--warning) 40%, transparent); }
.notice.error { background:color-mix(in srgb, var(--critical) 9%, transparent); border-color:color-mix(in srgb, var(--critical) 35%, transparent); color:var(--critical); }

/* ---------- stat tiles --------------------------------------------------- */
.tiles { display:grid; grid-template-columns:repeat(auto-fit, minmax(160px,1fr)); gap:12px; }
.tile { background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); padding:15px 16px; }
.tile .k { font-size:.73rem; text-transform:uppercase; letter-spacing:.08em; color:var(--muted); margin-bottom:6px; }
.tile .v { font-family:var(--display); font-size:2rem; line-height:1; color:var(--ink); }
.tile .v small { font-size:.95rem; color:var(--muted); margin-left:3px; }
.tile .m { font-size:.76rem; color:var(--muted); margin-top:6px; }
.tile.accent { background:var(--brand-700); border-color:var(--brand-700); }
.tile.accent .v { color:var(--on-brand); }
.tile.accent .k, .tile.accent .m { color:var(--on-brand); opacity:.78; }

/* ---------- charts ------------------------------------------------------- */
.chart { position:relative; }
.chart svg { display:block; width:100%; height:auto; overflow:visible; }
.chart .ax-label, .chart .tick { font:400 11px var(--sans); fill:var(--muted); }
.chart .val-label { font:600 11px var(--sans); fill:var(--ink-2); }
.chart .grid-line { stroke:var(--grid); stroke-width:1; }
.chart .axis-line { stroke:var(--axis); stroke-width:1; }
.chart .mark { transition:opacity .1s; }
.chart.dim .mark:not(.hot) { opacity:.35; }
.legend { display:flex; flex-wrap:wrap; gap:6px 16px; margin-top:12px; font-size:.8rem; color:var(--ink-2); }
.legend span { display:inline-flex; align-items:center; gap:7px; }
.legend i { width:11px; height:11px; border-radius:3px; flex:none; }
.chart-tip {
  position:absolute; pointer-events:none; z-index:20; background:var(--surface); color:var(--ink);
  border:1px solid var(--line-strong); border-radius:9px; padding:8px 11px; font-size:.8rem;
  box-shadow:var(--shadow-lg); min-width:110px; transform:translate(-50%,-115%); opacity:0; transition:opacity .1s;
}
.chart-tip.on { opacity:1; }
.chart-tip .t { font-weight:600; margin-bottom:3px; }
.chart-tip .r { display:flex; justify-content:space-between; gap:14px; color:var(--ink-2); }
.chart-tip .r b { font-variant-numeric:tabular-nums; color:var(--ink); }
.chart-actions { display:flex; gap:6px; align-items:center; }
.chart-note { font-size:.76rem; color:var(--muted); margin-top:10px; }

/* ---------- modal / drawer / toast --------------------------------------- */
.scrim { position:fixed; inset:0; background:rgba(12,15,11,.55); backdrop-filter:blur(2px);
  z-index:100; display:grid; place-items:center; padding:20px; overflow-y:auto; }
.modal { background:var(--surface); border-radius:var(--radius-lg); box-shadow:var(--shadow-lg);
  width:min(680px, 100%); max-height:calc(100vh - 40px); display:flex; flex-direction:column; border:1px solid var(--line); }
.modal.wide { width:min(1000px, 100%); }
.modal-head { padding:18px 20px; border-bottom:1px solid var(--line); display:flex; align-items:center; gap:12px; }
.modal-body { padding:20px; overflow-y:auto; }
.modal-foot { padding:14px 20px; border-top:1px solid var(--line); display:flex; gap:9px; justify-content:flex-end; }
.toasts { position:fixed; bottom:20px; right:20px; z-index:200; display:flex; flex-direction:column; gap:9px; }
.toast { background:var(--brand-900); color:#fff; padding:11px 16px; border-radius:11px; font-size:.86rem;
  box-shadow:var(--shadow-lg); max-width:380px; animation:pop .18s ease-out; display:flex; gap:9px; align-items:center; }
.toast.err { background:var(--critical); }
.toast.ok { background:var(--brand-700); }
@keyframes pop { from { opacity:0; transform:translateY(8px); } }

/* ---------- gallery / events --------------------------------------------- */
.photo-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(190px,1fr)); gap:12px; }
.photo { position:relative; border-radius:var(--radius-sm); overflow:hidden; background:var(--surface-2);
  aspect-ratio:4/3; cursor:zoom-in; border:1px solid var(--line); }
.photo img { width:100%; height:100%; object-fit:cover; transition:transform .3s; }
.photo:hover img { transform:scale(1.04); }
.photo .cap { position:absolute; inset:auto 0 0 0; padding:22px 10px 8px; font-size:.75rem; color:#fff;
  background:linear-gradient(transparent, rgba(0,0,0,.78)); }
.photo .del { position:absolute; top:6px; right:6px; opacity:0; background:rgba(0,0,0,.6); color:#fff; border:none; }
.photo .dl  { position:absolute; top:6px; left:6px;  opacity:0; background:rgba(0,0,0,.6); color:#fff; border:none;
              display:inline-flex; align-items:center; justify-content:center; }
.photo:hover .del, .photo:hover .dl, .photo:focus-within .del, .photo:focus-within .dl { opacity:1; }
/* A touch screen has no hover, so the controls stay visible there. */
@media (hover: none) {
  .photo .del, .photo .dl { opacity:1; }
}
.lightbox { position:fixed; inset:0; background:rgba(8,10,7,.93); z-index:150; display:grid;
  grid-template-rows:auto 1fr auto; padding:16px; }
.lightbox img { max-width:100%; max-height:100%; margin:auto; object-fit:contain; border-radius:8px; }
.lightbox .lb-bar { display:flex; align-items:center; gap:12px; color:#e8efe2; font-size:.85rem; }
.lightbox .lb-nav { display:flex; justify-content:center; gap:12px; padding-top:12px; }

.slide { position:relative; background:#0c0f0b; border-radius:var(--radius); overflow:hidden;
  aspect-ratio:16/9; max-height:min(62vh, 520px); margin:0 auto; }
.slide img { width:100%; height:100%; object-fit:contain; }
.slide-bar { position:absolute; inset:auto 0 0 0; padding:30px 16px 14px; color:#fff;
  background:linear-gradient(transparent, rgba(0,0,0,.85)); display:flex; align-items:flex-end; gap:12px; }
.slide-nav { position:absolute; top:50%; transform:translateY(-50%); background:rgba(0,0,0,.45); color:#fff;
  border:none; width:42px; height:42px; border-radius:99px; cursor:pointer; font-size:1.2rem; }
.slide-nav.prev { left:12px; } .slide-nav.next { right:12px; }
.slide-nav:hover { background:rgba(0,0,0,.7); }
.dots { display:flex; gap:6px; justify-content:center; margin-top:10px; flex-wrap:wrap; }
.dots i { width:7px; height:7px; border-radius:99px; background:var(--line-strong); cursor:pointer; }
.dots i.on { background:var(--brand-700); width:20px; }

/* ---------- events calendar ---------------------------------------------- */
.cal { display:grid; grid-template-columns:repeat(7,1fr); gap:3px; }
.cal-dow { font-size:.66rem; font-weight:700; letter-spacing:.08em; color:var(--muted);
  text-align:center; padding-bottom:4px; }
.cal-day { min-height:var(--cal-h,30px); border:1px solid var(--line); border-radius:7px;
  padding:3px 4px; background:var(--surface); position:relative; overflow:hidden;
  display:flex; flex-direction:column; gap:2px; }
.cal-day.empty { border:none; background:none; }
.cal-num { font-size:.72rem; color:var(--muted); font-variant-numeric:tabular-nums; }
.cal-day.today { border-color:var(--brand-400); box-shadow:inset 0 0 0 1px var(--brand-400); }
.cal-day.today .cal-num { color:var(--brand-700); font-weight:800; }
.cal-day.has { background:var(--brand-100); border-color:var(--brand-400); cursor:pointer; }
.cal-day.has:hover { border-color:var(--brand-700); box-shadow:var(--shadow); }
.cal-ev { font-size:.68rem; font-weight:600; line-height:1.2; color:var(--brand-700);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cal-ev.more { font-weight:400; color:var(--muted); }
.cal-dot { width:6px; height:6px; border-radius:99px; background:var(--brand-700);
  position:absolute; bottom:5px; left:50%; transform:translateX(-50%); }

/* ---------- map ---------------------------------------------------------- */
#map, .map { height:460px; border-radius:var(--radius); overflow:hidden; border:1px solid var(--line); background:var(--surface-2); }
.map-sm { height:240px; }
/* Given the full width of the card, the map earns the height to match. */
.map.tall { height:clamp(420px, 58vh, 640px); }
.leaflet-container { font:400 13px var(--sans); background:var(--surface-2); }
.area-pin { display:grid; place-items:center; border-radius:99px; color:#fff; font:700 12px var(--sans);
  border:2px solid var(--chart-surface); box-shadow:0 2px 8px rgba(0,0,0,.3); }

/* ---------- church layout ------------------------------------------------ */
.plan { background:var(--surface-2); border:1px solid var(--line); border-radius:var(--radius); padding:18px;
  overflow-x:auto; }
.plan svg { width:100%; min-width:1180px; height:auto; }
.zone .block-shape { transition:filter .15s, stroke-width .15s; }
.zone:hover .block-shape { stroke-width:3; filter:brightness(.97); }
.zone.sel .block-shape { stroke-width:3.5; filter:saturate(1.25) brightness(.99); }
.zone:not(.sel) .block-shape { }
/* The aisle name is the point of this drawing, so it is the loudest thing in it. */
.aisle-name { font-family:var(--sans); font-weight:800; letter-spacing:-.01em; fill:#22301c; pointer-events:none; }
.aisle-team { font-family:var(--sans); font-weight:700; fill:#3d5a2c; pointer-events:none; }
.aisle-occupants { font-family:var(--sans); font-weight:600; fill:#5b6152; pointer-events:none; }
.aisle-count { font-family:var(--sans); font-weight:400; fill:#7c8274; pointer-events:none; }
.zone-meta { font:400 10.5px var(--sans); fill:var(--muted); pointer-events:none; }
.door-mark text { pointer-events:none; }
.altar-shape { fill:var(--brand-900); stroke:none; }
.altar-label { font-family:var(--display); fill:var(--sun); pointer-events:none; }
/* Block fills are fixed tints so aisles stay distinguishable; in dark mode the
   plan keeps a light ground rather than inverting those tints illegibly. */
:root[data-theme="dark"] .plan, :root:where(:not([data-theme="light"])) .plan { background:#e9ece4; }
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) .plan { background:var(--surface-2); } }

/* ---------- auth pages --------------------------------------------------- */
.auth-wrap { min-height:100vh; display:grid; grid-template-columns:1.05fr 1fr; }
.auth-art { background:var(--brand-900); color:#e8efe2; padding:56px 48px; display:flex; flex-direction:column; justify-content:center; gap:36px; }
.logo-plaque { background:#fff; border-radius:16px; padding:14px 18px; display:inline-block;
  box-shadow:0 10px 30px -14px rgba(0,0,0,.6); }
.logo-plaque img { width:100%; max-width:268px; height:auto; display:block; }
/* The same lockup on the light form panel: a hairline instead of a drop shadow,
   since its white background sits on an off-white surface. */
.logo-plaque.on-light { box-shadow:none; border:1px solid var(--line); padding:12px 16px;
  margin-bottom:20px; }
.logo-plaque.on-light img { max-width:228px; }

/* Links that are the next step for the reader are always underlined, never
   underlined only on hover — a phone has no hover. */
.link-strong { font-weight:600; text-decoration:underline; text-underline-offset:3px;
  text-decoration-thickness:2px; }
.link-strong:hover { color:var(--brand-600); }
.auth-art h2 { color:#fff; font-size:2.1rem; max-width:15ch; margin:.7em 0 .3em; }
.auth-art .lede { color:#b9c9ae; max-width:42ch; font-size:.95rem; }
.auth-art .points { list-style:none; padding:0; margin:26px 0 0; display:flex; flex-direction:column; gap:11px; }
.auth-art .points li { display:flex; gap:10px; align-items:flex-start; font-size:.88rem; color:#cfdcc6; }
.auth-art .points i { color:var(--sun); flex:none; margin-top:2px; }
.auth-form { display:grid; place-items:center; padding:40px 24px; background:var(--page); overflow-y:auto; }
.auth-box { width:min(440px, 100%); }
.auth-box h1 { font-family:var(--sans); font-weight:800; letter-spacing:-.02em; font-size:1.8rem; }
.auth-box.wide { width:min(720px, 100%); }

/* ---------- leadership portfolios ---------------------------------------- */
.portfolio-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(268px,1fr)); gap:12px; }
.portfolio-card { position:relative; background:var(--surface-2); border:1px solid var(--line);
  border-radius:var(--radius); padding:14px; display:flex; flex-direction:column; gap:9px; }
.portfolio-card .p-title { font-size:.7rem; text-transform:uppercase; letter-spacing:.09em;
  color:var(--brand-700); font-weight:700; line-height:1.35; padding-right:64px; min-height:2.7em; }
.portfolio-card .p-who { display:flex; align-items:center; gap:10px; min-width:0; }
.portfolio-card .p-name { font-weight:600; font-size:.94rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.portfolio-card .p-meta { font-size:.77rem; color:var(--muted); }
.portfolio-card .p-desc { font-size:.79rem; color:var(--muted); margin:0; line-height:1.45; }
.portfolio-card .p-actions { position:absolute; top:9px; right:9px; display:flex; gap:2px; }

/* ---------- member profile ----------------------------------------------- */
.profile-head { display:flex; gap:20px; align-items:flex-start; flex-wrap:wrap; }
.kv { display:grid; grid-template-columns:auto 1fr; gap:9px 18px; font-size:.88rem; align-items:baseline; }
.kv dt { color:var(--muted); font-size:.78rem; text-transform:uppercase; letter-spacing:.06em; white-space:nowrap; }
.kv dd { margin:0; color:var(--ink); }
.locked { color:var(--muted); font-style:italic; font-size:.83rem; }

.member-card { display:flex; gap:12px; align-items:center; padding:11px; border:1px solid var(--line);
  border-radius:var(--radius-sm); background:var(--surface); cursor:pointer; transition:border-color .12s, box-shadow .12s; }
.member-card:hover { border-color:var(--brand-400); box-shadow:var(--shadow); }
.member-card .nm { font-weight:600; font-size:.9rem; }
.member-card .mt { font-size:.77rem; color:var(--muted); }

.ac-list { position:absolute; z-index:40; left:0; right:0; top:100%; margin-top:4px; background:var(--surface);
  border:1px solid var(--line-strong); border-radius:10px; box-shadow:var(--shadow-lg); max-height:260px; overflow-y:auto; }
.ac-list button { display:block; width:100%; text-align:left; padding:9px 12px; border:none; background:none;
  font:400 .84rem var(--sans); color:var(--ink); cursor:pointer; border-bottom:1px solid var(--line); }
.ac-list button:hover { background:var(--brand-100); }
.ac-wrap { position:relative; }

/* ---------- attendance register ------------------------------------------ */
.reg-row { display:grid; grid-template-columns:1fr auto; gap:12px; align-items:center; padding:9px 12px;
  border-bottom:1px solid var(--line); }
.reg-row:hover { background:var(--surface-2); }
.marks { display:flex; gap:4px; }
.mark-btn { padding:5px 10px; border-radius:8px; border:1px solid var(--line-strong); background:var(--surface);
  font:600 .74rem var(--sans); cursor:pointer; color:var(--ink-2); }
.mark-btn:hover { border-color:var(--muted); }
.mark-btn.on[data-v="present"] { background:var(--good); border-color:var(--good); color:#fff; }
.mark-btn.on[data-v="late"] { background:var(--warning); border-color:var(--warning); color:#3a2a00; }
.mark-btn.on[data-v="excused"] { background:var(--serious); border-color:var(--serious); color:#3a1400; }
.mark-btn.on[data-v="absent"] { background:var(--critical); border-color:var(--critical); color:#fff; }
.team-head { background:var(--surface-2); padding:7px 12px; font-size:.76rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.07em; color:var(--ink-2); border-bottom:1px solid var(--line);
  display:flex; align-items:center; gap:10px; }
.team-head .btn { text-transform:none; letter-spacing:0; font-weight:600; }

/* ---------- permission matrix -------------------------------------------- */
.matrix td, .matrix th { text-align:center; }
.matrix td:first-child, .matrix th:first-child { text-align:left; }
.tri { display:inline-flex; border:1px solid var(--line-strong); border-radius:8px; overflow:hidden; }
.tri button { border:none; background:var(--surface); padding:4px 9px; font:600 .72rem var(--sans);
  color:var(--muted); cursor:pointer; border-right:1px solid var(--line); }
.tri button:last-child { border-right:none; }
.tri button.on { background:var(--brand-700); color:var(--on-brand); }
.tri button.on[data-v="0"] { background:var(--critical); }

/* ---------- responsive --------------------------------------------------- */
@media (max-width: 1100px) { .g4 { grid-template-columns:repeat(2,minmax(0,1fr)); } .g3 { grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (max-width: 900px) {
  .app { grid-template-columns:1fr; }
  .side { position:fixed; left:0; top:0; bottom:0; width:var(--nav-w); z-index:90; transform:translateX(-100%);
    transition:transform .2s; height:100dvh; }
  .side.open { transform:none; box-shadow:var(--shadow-lg); }
  .burger { display:inline-flex; }
  .view { padding:16px; }
  .top { padding:0 16px; }
  .g2, .g3, .g4 { grid-template-columns:1fr; }
  .auth-wrap { grid-template-columns:1fr; }
  .auth-art { display:none; }
  .table-wrap { margin:0 -18px -18px; }
}
@media print {
  .side, .top-actions, .burger, .chart-actions, .btn { display:none !important; }
  .app { grid-template-columns:1fr; } body { background:#fff; }
  .card { box-shadow:none; border-color:#ccc; break-inside:avoid; }
}

/* ---------- installing to a home screen ----------------------------------- */
/* One stack at the foot of the screen, clear of the iPhone home indicator.
   The install offer and the update notice share it, so they can never land on
   top of one another however they happen to arrive. */
.bottom-stack {
  position:fixed; left:50%; transform:translateX(-50%);
  bottom:calc(16px + env(safe-area-inset-bottom)); z-index:120;
  display:flex; flex-direction:column; align-items:stretch; gap:10px;
  width:min(520px, calc(100vw - 24px));
}

.install-banner, .update-bar {
  display:flex; align-items:center; gap:12px;
  padding:12px 14px; border-radius:var(--radius);
  background:var(--surface); border:1px solid var(--line); box-shadow:var(--shadow-lg);
}
.install-banner img { border-radius:22%; flex:none; box-shadow:0 1px 4px #0002; }
.install-copy { display:flex; flex-direction:column; gap:2px; min-width:0; flex:1 1 auto; }
.install-copy strong { font-size:.94rem; }
.install-copy span { color:var(--muted); font-size:.82rem; }
.install-actions { display:flex; gap:6px; flex:none; }

.update-bar { font-size:.9rem; flex-wrap:wrap; }
.update-bar span { flex:1 1 auto; min-width:0; }
.update-bar .btn { flex:none; }

/* Narrow: the words take a row of their own and the buttons sit beneath them,
   rather than a button breaking away on its own line. */
@media (max-width: 520px) {
  .install-banner { flex-wrap:wrap; }
  .install-actions { width:100%; justify-content:flex-end; }
  .update-bar span { flex:1 1 100%; }
  .update-bar { justify-content:flex-end; }
}

.steps { margin:0 0 12px; padding-left:1.3em; }
.steps li { margin-bottom:8px; }
.plain-list { margin:0 0 12px; padding-left:1.3em; }
.plain-list li { margin-bottom:6px; }
/* Apple's own SF Symbol for the Share button; it renders on Apple devices,
   where these instructions are shown, and is decorative everywhere else. */
.ios-share { font-family:"SF Pro Text","Apple Color Emoji",system-ui; }

/* The installed app has no address bar, so its own chrome carries the inset. */
@media (display-mode: standalone) {
  .top { padding-top:env(safe-area-inset-top); }
  .side { padding-top:env(safe-area-inset-top); }
}

/* Shown only when the browser reports no connection. */
.offline-bar {
  position:fixed; left:0; right:0; top:0; z-index:140;
  padding:calc(8px + env(safe-area-inset-top)) 14px 8px;
  /* The bar is always this yellow, in either theme, so its ink is fixed too —
     --ink-warning flips to yellow in dark mode and would vanish here. */
  background:var(--warning); color:#3d2b00;
  font-size:.86rem; text-align:center; font-weight:600;
}
