﻿/* ============================================================
   AlertCommunities — Accra Flood Intelligence Platform
   Palette (map profile):
     paper/bg  #F1EBE4 · #E2DCD3      tan accent  #BC8A52
     water     #95B1AA                panel grad  #A2AEA1→#7B988C→#4F8577
     accent    #618D7C (interactive)  near-white  #F3F4F1
     track     #ADC3B9 (borders)      ink         #2C3B36
   Station status colors (preserved):
     active #1FA97A · deploying #2D6CDF · planned #E8A33D · impact #C0392B
   ============================================================ */

:root{
  --cream:     #F1EBE4;
  --land:      #E2DCD3;
  --tan:       #BC8A52;
  --tan-light: #DEC29A;
  --water:     #95B1AA;
  --sage1:     #A2AEA1;
  --sage2:     #7B988C;
  --deep:      #4F8577;
  --deep-2:    #3F6E62;
  --accent:    #618D7C;
  --paper:     #F3F4F1;
  --track:     #ADC3B9;
  --ink:       #2C3B36;
  --ink-soft:  #5C6E66;
  --mintbg:    #E7EDE6;

  /* station status colors — do not change */
  --st-active:      #1FA97A;
  --st-deploying:   #2D6CDF;
  --st-planned:     #8C959A;   /* grey */
  --st-impact:      #C0392B;
  --st-maintenance: #1F262B;   /* black */

  /* legacy aliases (old palette names used inline in HTML) */
  --navy:  #2C3B36;
  --blue:  #618D7C;
  --amber: #BC8A52;
  --red:   #C0392B;
  --green: #1FA97A;
  --gray:  #5C6E66;
  --mint:  #E7EDE6;
  --line:  #ADC3B9;
  --bg:    #F1EBE4;

  --shadow:    0 8px 30px rgba(44,59,54,.16);
  --shadow-sm: 0 3px 12px rgba(44,59,54,.10);
  --radius:    14px;
  --font: Calibri, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  --header-h: 64px;
  --panel-grad: linear-gradient(180deg, #7B988C 0%, #5C8A7B 55%, #4F8577 100%);
  --hero-grad:  linear-gradient(180deg, #A2AEA1 0%, #7B988C 48%, #4F8577 100%);
}

*{ box-sizing:border-box; margin:0; padding:0; }
html{ scroll-behavior:smooth; }
body{
  font-family:var(--font);
  color:var(--ink);
  background:var(--cream);
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
}
img{ max-width:100%; display:block; }
a{ color:var(--deep); text-decoration:none; }
a:hover{ text-decoration:underline; }

/* ---------- Sign-up bar (round-69b): signed-out visitors, above both headers ----------
   Visibility is driven by html.signup-bar-on (set by site.js after the dismiss check) so
   Blazor DOM patches can't resurrect a dismissed bar. When on, --header-h grows to
   64px + bar height, which shifts every offset that hangs off it (page padding, map
   islands, side panels) without touching those rules. */
#signupBar{ display:none; }
/* --signup-h starts at the one-line height; site.js overwrites it with the bar's real
   measured height after reveal and on resize, so the sentence may wrap on phones and
   the headers still sit exactly below it */
html.signup-bar-on{ --signup-h: 46px; --header-h: calc(64px + var(--signup-h)); }
/* no entry animation: a transform keyframe replayed by Blazor's enhanced-nav DOM patches
   (or held at its first frame) parked the bar off-screen, leaving a blank strip above the
   header — the bar simply appears in place */
html.signup-bar-on #signupBar{
  display:flex; align-items:center; gap:10px;
  /* min-height is a CONSTANT, never var(--signup-h): the JS writes the bar's measured
     height into --signup-h, and deriving min-height from it fed the measurement back
     into itself — every resize event ratcheted the bar taller, ending in a full-screen
     white sheet that buried the map's service chips */
  position:fixed; top:0; left:0; right:0; min-height:40px; z-index:1200;
  padding:7px 12px; color:var(--ink);
  background:#fff;
  border-bottom:1px solid var(--track);
  box-shadow:0 2px 12px rgba(44,59,54,.14);
}
/* desktop: single line anyway — slim vertical padding so the bar stays unobtrusive */
@media (min-width: 768px){
  html.signup-bar-on #signupBar{ min-height:32px; padding:3px 12px; }
}
#signupBar .sb-ico{ flex:0 0 auto; display:inline-flex; color:#E8A33D; /* weather amber */ }
#signupBar .sb-ico svg{ width:20px; height:20px; }
#signupBar .sb-text{
  flex:1 1 auto; min-width:0;
  font-size:.9rem; line-height:1.35;
}
#signupBar .sb-text b{ font-weight:800; }
#signupBar .sb-link{
  color:#4F8577; font-weight:800; text-decoration:underline; text-underline-offset:2px;
  white-space:nowrap;
}
#signupBar .sb-link:hover{ color:#2C3B36; }
#signupBar .sb-close{
  flex:0 0 auto; align-self:flex-start; background:transparent; border:0; color:inherit;
  opacity:.55; font-size:1rem; cursor:pointer; padding:4px 8px;
}
#signupBar .sb-close:hover{ opacity:1; }

/* ---------- Header / Nav ---------- */
.site-header{
  position:fixed; top:var(--signup-h, 0px); left:0; right:0; z-index:1100;
  height:64px;   /* literal: --header-h is header + sign-up bar when the bar shows */
  background:rgba(243,244,241,.95);
  backdrop-filter:blur(8px);
  color:var(--ink);
  display:flex; align-items:center;
  padding:0 20px;
  box-shadow:0 2px 14px rgba(44,59,54,.12);
  border-bottom:1px solid var(--track);
}
.brand{ display:flex; align-items:center; gap:10px; color:var(--ink); font-weight:700; font-size:1.25rem; letter-spacing:.3px; }
.brand:hover{ text-decoration:none; }
.brand svg{ width:36px; height:36px; flex:0 0 auto; }
.brand .tag{ display:block; font-size:.62rem; font-weight:400; color:var(--sage2); letter-spacing:1.6px; text-transform:uppercase; margin-top:-3px; }

.nav{ margin-left:auto; display:flex; align-items:center; gap:4px; }
.nav a{
  color:var(--ink-soft); padding:9px 13px; border-radius:8px; font-size:.98rem;
  transition:background .15s, color .15s;
}
.nav a:hover{ background:rgba(97,141,124,.12); color:var(--ink); text-decoration:none; }
.nav a.active{ color:var(--paper); background:var(--accent); }
.nav .btn{ margin-left:8px; }

.nav-toggle{
  display:none; margin-left:auto; background:none; border:0; color:var(--ink);
  width:44px; height:44px; cursor:pointer; font-size:1.5rem; line-height:1;
}

/* ---------- Buttons ---------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:11px 20px; border-radius:10px; border:0; cursor:pointer;
  font-family:var(--font); font-size:1rem; font-weight:700; letter-spacing:.2px;
  transition:transform .12s, box-shadow .15s, background .15s;
  text-decoration:none !important;
}
.btn:active{ transform:translateY(1px); }
.btn svg{ width:18px; height:18px; flex:0 0 auto; }
.btn-amber{ background:var(--tan); color:#fff!important; }
.btn-amber:hover{ background:#c99a63; box-shadow:0 4px 16px rgba(188,138,82,.45); }
.btn-blue{ background:var(--accent); color:var(--paper); }
.btn-blue:hover{ background:#6d9b89; box-shadow:0 4px 16px rgba(97,141,124,.45); }
.btn-green{ background:var(--deep); color:var(--paper); }
.btn-green:hover{ background:#5b937f; box-shadow:0 4px 16px rgba(79,133,119,.4); }
.btn-outline{ background:transparent; color:var(--paper); border:2px solid rgba(243,244,241,.6); }
.btn-outline:hover{ border-color:var(--paper); background:rgba(243,244,241,.1); }
.btn-outline-dark{ background:transparent; color:var(--deep); border:2px solid var(--deep); }
.btn-outline-dark:hover{ background:var(--deep); color:var(--paper); }
.btn-red{ background:var(--st-impact); color:#fff; }
.btn-red:hover{ background:#d64536; }
.btn-grey{ background:#8C959A; color:#fff!important; }
.btn-grey:hover{ background:#7b858b; box-shadow:0 4px 16px rgba(140,149,154,.45); }
.btn-lg{ padding:15px 28px; font-size:1.1rem; border-radius:12px; }
.btn-sm{ padding:7px 14px; font-size:.88rem; }
.btn-block{ width:100%; }

/* ---------- Layout helpers ---------- */
.page{ padding-top:var(--header-h); }
.container{ max-width:1120px; margin:0 auto; padding:0 20px; }
.section{ padding:64px 0; }
.section.tint{ background:var(--paper); }
.section.navy{ background:var(--panel-grad); color:var(--paper); }
.section.mint{ background:var(--mintbg); }

.kicker{
  display:inline-block; font-size:.78rem; font-weight:700; letter-spacing:2.2px;
  text-transform:uppercase; color:var(--deep); margin-bottom:10px;
}
.section.navy .kicker, .hero-inner .kicker{ color:var(--tan-light); }
h1.display{ font-size:clamp(2rem,5vw,3.2rem); line-height:1.12; color:var(--ink); }
.section.navy h1.display, .section.navy h2{ color:var(--paper); }
h2.title{ font-size:clamp(1.5rem,3.4vw,2.2rem); color:var(--ink); margin-bottom:14px; }
h3{ color:var(--ink); }
.section.navy h3{ color:var(--paper); }
.lead{ font-size:1.13rem; color:var(--ink-soft); max-width:760px; }
.section.navy .lead{ color:#E3EAE2; }
.center{ text-align:center; }
.center .lead{ margin:0 auto; }

.grid{ display:grid; gap:22px; }
.grid-2{ grid-template-columns:repeat(2,1fr); }
.grid-3{ grid-template-columns:repeat(3,1fr); }
.grid-4{ grid-template-columns:repeat(4,1fr); }

.card{
  background:var(--paper); border-radius:var(--radius); padding:26px;
  box-shadow:var(--shadow-sm); border:1px solid var(--track);
}
.card h3{ margin-bottom:8px; font-size:1.12rem; }
.card p{ color:var(--ink-soft); font-size:.98rem; }
.card .icon{
  width:46px; height:46px; border-radius:12px; display:flex; align-items:center;
  justify-content:center; background:var(--mintbg); margin-bottom:14px;
}
.card .icon svg{ width:24px; height:24px; stroke:var(--accent); fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }

/* stat blocks (on deep panels) */
.stats-row{ display:grid; grid-template-columns:repeat(3,1fr); gap:18px; margin-top:34px; }
.stat{
  background:rgba(243,244,241,.10); border:1px solid rgba(243,244,241,.24);
  border-radius:var(--radius); padding:20px 22px; text-align:left;
}
.stat .num{ font-size:2rem; font-weight:800; color:var(--tan-light); line-height:1.1; }
.stat .lbl{ font-size:.92rem; color:#DCE5DD; margin-top:4px; }
.stat .lbl a{ color:var(--tan-light); }

/* ---------- Hero (inner pages) ---------- */
.hero-inner{
  background:var(--hero-grad);
  color:var(--paper); padding:72px 0 56px;
  position:relative; overflow:hidden;
}
.hero-inner::after{
  content:""; position:absolute; right:-120px; bottom:-160px; width:420px; height:420px;
  border-radius:50%; background:radial-gradient(circle, rgba(241,235,228,.22), transparent 65%);
}
.hero-inner .lead{ color:#E9EEE7; margin-top:12px; }
.hero-inner h1{ color:var(--paper); font-size:clamp(1.9rem,4.6vw,2.9rem); line-height:1.15; }
.hero-inner b{ color:#fff; }
.hero-cta{ display:flex; flex-wrap:wrap; gap:12px; margin-top:26px; position:relative; z-index:1; }

/* ---------- Tables ---------- */
.table-wrap{ overflow-x:auto; border-radius:var(--radius); box-shadow:var(--shadow-sm); }
table.pro{ width:100%; border-collapse:collapse; background:var(--paper); min-width:520px; }
table.pro th{
  background:var(--deep); color:var(--paper); text-align:left; padding:13px 16px;
  font-size:.92rem; letter-spacing:.4px;
}
table.pro td{ padding:12px 16px; border-bottom:1px solid #DCE3DC; font-size:.96rem; color:var(--ink); }
table.pro tr:nth-child(even) td{ background:#ECEFEA; }
table.pro td.good{ color:var(--deep); font-weight:700; }
table.pro td.bad{ color:var(--st-impact); }

/* ---------- Forms ---------- */
.form-card{ background:var(--paper); border-radius:var(--radius); padding:30px; box-shadow:var(--shadow); border:1px solid var(--track); }
.field{ margin-bottom:18px; }
.field label{ display:block; font-weight:700; color:var(--ink); margin-bottom:6px; font-size:.95rem; }
.field input, .field select, .field textarea{
  width:100%; padding:12px 14px; border:1.5px solid var(--track); border-radius:10px;
  font-family:var(--font); font-size:1rem; color:var(--ink); background:#FBFBF8;
  transition:border-color .15s, box-shadow .15s;
}
.field input:focus, .field select:focus, .field textarea:focus{
  outline:none; border-color:var(--accent); box-shadow:0 0 0 3px rgba(97,141,124,.18);
}
.field textarea{ min-height:120px; resize:vertical; }
.field .hint{ font-size:.83rem; color:var(--ink-soft); margin-top:5px; }
.form-note{
  background:var(--mintbg); border:1px solid #C4D4C8; color:#2F5B4C;
  padding:14px 16px; border-radius:10px; font-size:.93rem; margin-top:16px; display:none;
}
.form-note.show{ display:block; }

/* choice chips */
.chip-row{ display:flex; flex-wrap:wrap; gap:10px; }
.chip{
  padding:10px 18px; border-radius:999px; border:1.5px solid var(--track); background:var(--paper);
  cursor:pointer; font-family:var(--font); font-weight:700; font-size:.95rem; color:var(--ink);
  transition:all .15s;
}
.chip:hover{ border-color:var(--accent); }
.chip.sel{ background:var(--accent); border-color:var(--accent); color:var(--paper); }
.chip.sel-amber{ background:var(--tan); border-color:var(--tan); color:#fff; }
.chip.sel-red{ background:var(--st-impact); border-color:var(--st-impact); color:#fff; }

/* ---------- Status pills (status colors preserved) ---------- */
.pill{
  display:inline-flex; align-items:center; gap:7px; padding:4px 12px; border-radius:999px;
  font-size:.8rem; font-weight:700; letter-spacing:.4px; text-transform:uppercase;
}
.pill .dot{ width:9px; height:9px; border-radius:50%; }
.pill-active   { background:rgba(31,169,122,.14); color:#0d7d58; }
.pill-active   .dot{ background:var(--st-active); }
.pill-deploying{ background:rgba(45,108,223,.13); color:#1c4fb0; }
.pill-deploying .dot{ background:var(--st-deploying); }
.pill-planned  { background:rgba(232,163,61,.18); color:#996414; }
.pill-planned  .dot{ background:var(--st-planned); }
.pill-maintenance{ background:rgba(91,100,114,.15); color:#454d59; }
.pill-maintenance .dot{ background:var(--st-maintenance); }
.pill-impact{ background:rgba(192,57,43,.12); color:var(--st-impact); }
.pill-impact .dot{ background:var(--st-impact); }

/* ============================================================
   MAP PAGE (home)
   ============================================================ */
.map-page{ height:100vh; height:100dvh; overflow:hidden; }
#map{
  position:fixed; top:0; left:0; right:0; bottom:0; /* map runs under the transparent map nav */
  background:var(--land);
  z-index:1;
}
.leaflet-container{ font-family:var(--font); }

/* floating UI cards over map — "panel rising from the map" */
.map-ui{ position:fixed; z-index:900; }
.map-card{
  background:var(--panel-grad);
  border:1px solid rgba(243,244,241,.3); border-radius:14px;
  color:var(--paper); /* round-15c: box-shadow removed */
}

/* network stats — top left */
.net-stats{ top:calc(var(--header-h) + 14px); left:14px; width:250px; padding:16px 18px; }
.net-stats h2{ font-size:.8rem; letter-spacing:2px; text-transform:uppercase; color:var(--tan-light); margin-bottom:10px; }
.net-grid{ display:grid; grid-template-columns:1fr 1fr; gap:10px; }
.net-item .n{ font-size:1.5rem; font-weight:800; line-height:1.05; }
.net-item .l{ font-size:.74rem; color:#DCE5DD; letter-spacing:.3px; }
.n-active{ color:#8FF2CB; } .n-deploying{ color:#A9C6FF; } .n-planned{ color:#FFD9A0; } .n-impact{ color:#FFB1A6; }
.net-foot{ margin-top:12px; padding-top:10px; border-top:1px solid rgba(243,244,241,.25);
  font-size:.78rem; color:#DCE5DD; }

/* legend + filters — bottom left */
.legend{ bottom:18px; left:14px; padding:14px 16px; max-width:250px; }
.legend h3{ font-size:.75rem; letter-spacing:2px; text-transform:uppercase; color:#DCE5DD; margin-bottom:9px; }
.legend .row{
  display:flex; align-items:center; gap:9px; padding:5px 8px; border-radius:8px;
  cursor:pointer; font-size:.88rem; user-select:none; border:1px solid transparent; color:var(--paper);
}
.legend .row:hover{ background:rgba(243,244,241,.14); }
.legend .row.off{ opacity:.4; }
.legend .swatch{ width:14px; height:14px; border-radius:50%; border:2px solid #fff; flex:0 0 auto; }
.sw-active{ background:var(--st-active); } .sw-deploying{ background:var(--st-deploying); }
.sw-planned{ background:var(--st-planned); } .sw-maintenance{ background:var(--st-maintenance); }
.legend .impact-note{ display:flex; align-items:center; gap:9px; margin-top:8px; padding:6px 8px;
  font-size:.78rem; color:#FFC9C1; border-top:1px solid rgba(243,244,241,.25); }
.legend .impact-ring{ width:14px; height:14px; border-radius:50%; border:2.5px dashed var(--st-impact); flex:0 0 auto; background:rgba(255,255,255,.7); }

/* action buttons — top right */
/* Round-94: the container now carries ONLY the relocated zoom control. Bottom-left, above the
   legal strip — the one corner free on every width: the legend is top-left, the right rail is
   centred right (its expanded Layers card was colliding with the zoom on iPad landscape), and
   the time bands are centred bottom. */
.map-actions{ bottom:44px; left:14px; display:flex; flex-direction:column; gap:10px; align-items:flex-start; }
.map-actions .btn{ box-shadow:0 6px 20px rgba(44,59,54,.3); }

.leaflet-bottom.leaflet-right .leaflet-control-attribution{
  background:rgba(243,244,241,.85); color:var(--ink-soft);
}
.leaflet-control-attribution a{ color:var(--deep); }
.leaflet-control-zoom a{
  background:var(--deep) !important; color:var(--paper) !important;
  border-color:rgba(243,244,241,.35) !important;
}
.leaflet-control-zoom a:hover{ background:var(--deep-2) !important; }
/* zoom control is relocated into .map-actions by map-engine (below the quick actions) */
.map-actions .leaflet-control-zoom{ margin:0; }

/* station markers — status colors preserved */
.st-marker{
  width:22px; height:22px; border-radius:50%;
  border:2.5px solid #fff; box-shadow:0 2px 8px rgba(44,59,54,.45);
  position:relative;
}
.st-marker.impact::after{
  content:""; position:absolute; inset:-7px; border-radius:50%;
  border:2.5px dashed var(--st-impact);
}
.st-marker.active    { background:var(--st-active); }
.st-marker.deploying { background:var(--st-deploying); }
.st-marker.planned   { background:var(--st-planned); }
.st-marker.maintenance{ background:var(--st-maintenance); }
.st-marker.active .ping{
  content:""; position:absolute; inset:-4px; border-radius:50%;
  border:2px solid var(--st-active); animation:ping 2.2s ease-out infinite;
}
@keyframes ping{ 0%{ transform:scale(.7); opacity:.9; } 100%{ transform:scale(2.1); opacity:0; } }

.leaflet-tooltip.st-tip{
  background:var(--tip-bg, var(--deep)); color:var(--tip-fg, var(--paper)); border:1px solid rgba(243,244,241,.4);
  border-radius:8px; font-family:var(--font); font-weight:700; padding:6px 11px;
  box-shadow:0 4px 14px rgba(44,59,54,.35);
}
.leaflet-tooltip.st-tip::before{ border-top-color:var(--tip-bg, var(--deep)); }
.leaflet-tooltip-bottom.st-tip::before{ border-top-color:transparent; border-bottom-color:var(--tip-bg, var(--deep)); }
.leaflet-tooltip-left.st-tip::before{ border-top-color:transparent; border-left-color:var(--tip-bg, var(--deep)); }
.leaflet-tooltip-right.st-tip::before{ border-top-color:transparent; border-right-color:var(--tip-bg, var(--deep)); }

/* ---------- Station detail panel ---------- */
.station-panel{
  position:fixed; top:var(--header-h); right:0; bottom:0; width:400px; max-width:100%;
  background:var(--paper); z-index:1000; box-shadow:-12px 0 40px rgba(44,59,54,.3);
  transform:translateX(105%); transition:transform .3s cubic-bezier(.2,.8,.25,1);
  display:flex; flex-direction:column;
}
.station-panel.open{ transform:translateX(0); }
.sp-head{ background:var(--panel-grad); color:var(--paper); padding:20px 22px 18px; position:relative; }
.sp-head h2{ font-size:1rem; text-transform:uppercase; margin:8px 0 3px; color:var(--paper); }
.sp-head .sub{ color:#DCE5DD; font-size:.88rem; }
.sp-close{
  position:absolute; top:14px; right:14px; background:rgba(243,244,241,.2); color:var(--paper);
  border:0; width:34px; height:34px; border-radius:50%; font-size:1.15rem; cursor:pointer;
}
.sp-close:hover{ background:rgba(243,244,241,.35); }
.sp-body{ flex:1; overflow-y:auto; padding:20px 22px 30px; }
.sp-body h4{ font-size:.78rem; letter-spacing:1.8px; text-transform:uppercase; color:var(--sage2); margin:22px 0 10px; }
.sp-body h4:first-child{ margin-top:0; }

.sp-metrics{ display:grid; grid-template-columns:1fr 1fr; gap:12px; }
.sp-metric{ background:var(--mintbg); border:1px solid var(--track); border-radius:12px; padding:12px 14px; }
.sp-metric .v{ font-size:1.35rem; font-weight:800; color:var(--ink); line-height:1.1; }
.sp-metric .v small{ font-size:.8rem; font-weight:600; color:var(--ink-soft); }
.sp-metric .k{ font-size:.78rem; color:var(--ink-soft); margin-top:2px; }
.sp-metric.warn .v{ color:var(--st-impact); }

.sp-chart{ background:var(--mintbg); border:1px solid var(--track); border-radius:12px; padding:14px; }
.sp-chart svg{ width:100%; height:110px; display:block; }
.sp-chart .cap{ font-size:.78rem; color:var(--ink-soft); margin-top:6px; display:flex; justify-content:space-between; }

.sp-img{ border-radius:12px; overflow:hidden; border:1px solid var(--track); }
.sp-img img{ width:100%; height:190px; object-fit:cover; display:block; }
.sp-img .cap{ font-size:.78rem; color:var(--ink-soft); padding:8px 12px; background:var(--mintbg); }

.sp-kv{ font-size:.92rem; }
.sp-kv div{ display:flex; justify-content:space-between; gap:12px; padding:7px 0; border-bottom:1px dashed var(--track); }
.sp-kv .k{ color:var(--ink-soft); }
.sp-kv .v{ font-weight:700; color:var(--ink); text-align:right; }

.sp-alertbox{ border-radius:12px; padding:13px 15px; font-size:.92rem; margin-top:10px; }
.sp-alertbox.ok{ background:var(--mintbg); color:#2F5B4C; border:1px solid #C4D4C8; }
.sp-alertbox.warn{ background:#F3E9D8; color:#7A5A22; border:1px solid #DECBA4; }
.sp-alertbox.danger{ background:#F4E3E0; color:#8e2a1f; border:1px solid #E2BFB9; }

.sp-cta{ display:flex; gap:10px; margin-top:22px; }
.sp-cta .btn{ flex:1; }

/* ---------- Footer ---------- */
.site-footer{ background:linear-gradient(180deg, var(--deep) 0%, var(--deep-2) 100%); color:#DCE5DD; padding:54px 0 26px; }
.site-footer h4{ color:var(--paper); font-size:1rem; margin-bottom:14px; letter-spacing:.5px; }
.foot-grid{ display:grid; grid-template-columns:2fr 1fr 1fr 1.4fr; gap:34px; }
.site-footer a{ color:#DCE5DD; display:block; padding:4px 0; font-size:.95rem; }
.site-footer a:hover{ color:#fff; }
.foot-brand{ display:flex; align-items:center; gap:10px; color:var(--paper); font-weight:700; font-size:1.2rem; margin-bottom:12px; }
.foot-brand svg{ width:32px; height:32px; }
.foot-note{ font-size:.9rem; color:#C9D6CB; max-width:340px; }
.foot-bottom{
  border-top:1px solid rgba(243,244,241,.22); margin-top:40px; padding-top:20px;
  display:flex; flex-wrap:wrap; gap:10px; justify-content:space-between; font-size:.85rem; color:#C9D6CB;
}
/* Round-84: the accent footer is DESKTOP-ONLY — on phones and tablets (and therefore inside
   the mobile app's WebView, which is always phone-width) it does not render at all. The two
   things that lived only there move surfaces on small screens: the language switcher goes to
   the nav grid menu (.grid-lang below), and the privacy link remains satisfied by the
   homepage's persistent legal strip. */
@media (max-width:1024px){
  .site-footer{ display:none; }
}
/* Round-85: SafeNet presence freshness. The colour IS the message — a glance must answer
   "is this where they are now?" without reading the words. */
.pres-dot{ display:inline-block; width:8px; height:8px; border-radius:50%; margin-right:6px;
           vertical-align:middle; background:var(--track, #ADC3B9); }
.pres-live{ background:#2E9E5B; box-shadow:0 0 0 3px rgba(46,158,91,.18); }
.pres-recent{ background:#8FB98C; }
.pres-stale{ background:#C9A227; }
.pres-paused{ background:#9AA3A0; }
.pres-none{ background:var(--track, #ADC3B9); }

/* Round-84 native-feel: app-scoped touch polish. html.in-app is set by site.js when the page
   runs inside the mobile app's WebView — browsers are untouched. */
.in-app *{ -webkit-tap-highlight-color: transparent; }
.in-app body{ overscroll-behavior-y: none; }
/* Round-93b: an inline icon beside a heading. OutlineIcons.Svg carries no width/height on
   purpose (nav containers size it), so anywhere without a sized container must supply one or the
   SVG fills the line. */
.plat-ico{ width:22px; height:22px; flex:none; display:inline-flex; }
.plat-ico svg{ width:100%; height:100%; display:block; }

/* Anything that makes no sense INSIDE the app (e.g. "Get the app") carries .web-only. */
.in-app .web-only{ display:none !important; }
/* ...and its mirror: controls only the APP can honour (native sensing switches). */
.app-only{ display:none; }
.in-app .app-only{ display:block; }
/* Round-93b: platform-specific copy inside app-only content (the wizard's Settings steps name
   real OS toggles, and the two platforms name them differently). Default = Android wording, so
   an app build too old to set the platform class still reads something rather than nothing. */
.ios-only{ display:none; }
.plat-ios .ios-only{ display:revert; }
.plat-ios .android-only{ display:none !important; }
/* /get-app: the desktop→phone handoff QR. Phones don't need to scan themselves. */
.getapp-qr{ display:none; }
@media (min-width:1025px){
  .getapp-qr{ display:flex; align-items:center; gap:14px; margin-top:16px; }
  .getapp-qr img{ border-radius:10px; border:1px solid var(--track, #ADC3B9); }
}

/* Language row inside the nav grid menu — the small-screen home of the switcher. Hidden on
   desktop, where the footer still carries it. */
.grid-lang{ display:none; }
@media (max-width:1024px){
  /* grid-column 1/-1: .grid-menu is itself a 3-column tile grid, and without this the whole
     language block gets squeezed into a single tile cell (same trick as .grid-base). */
  .grid-lang{ display:block; grid-column:1/-1; border-top:1px solid var(--track, #ADC3B9); margin-top:6px; padding-top:10px; }
  .grid-lang-row{ display:grid; grid-template-columns:repeat(3, 1fr); gap:2px 8px; font-size:.82rem; margin:0; }
  /* Override the tile styling .grid-menu a applies — these are compact text links, not tiles. */
  .grid-lang-row a{ display:block; flex-direction:row; text-align:start; padding:6px 4px; font-weight:600; border-radius:8px; }
}
.sdg-row{ display:flex; gap:8px; margin-top:14px; flex-wrap:wrap; }
.sdg{
  width:75px; height:52px; border-radius:8px; color:#fff; font-weight:800;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  font-size:.66rem; text-align:center; line-height:1.15; padding:3px;
}
.sdg b{ font-size:.95rem; }
.sdg-9 { background:#F36D25; } .sdg-11{ background:#F99D26; }
.sdg-13{ background:#3F7E44; } .sdg-17{ background:#19486A; }

/* partner logo strip */
.logo-strip{ display:flex; flex-wrap:wrap; gap:14px; align-items:center; justify-content:center; }
.logo-chip{
  background:#fff; border:1px solid var(--track); border-radius:12px; padding:14px 22px;
  font-weight:800; color:var(--ink); font-size:1rem; letter-spacing:.4px;
  box-shadow:var(--shadow-sm); display:flex; align-items:center; gap:12px;
}
.logo-chip small{ display:block; font-weight:600; color:var(--ink-soft); font-size:.72rem; letter-spacing:.2px; }
.logo-chip .mark{ width:38px; height:38px; border-radius:9px; display:flex; align-items:center; justify-content:center;
  background:var(--deep); color:var(--paper); font-size:.85rem; font-weight:900; flex:0 0 auto; }
.logo-chip img{ width:38px; height:38px; object-fit:contain; flex:0 0 auto; }

/* timeline */
.timeline{ position:relative; margin:26px 0; padding-left:26px; }
.timeline::before{ content:""; position:absolute; left:8px; top:6px; bottom:6px; width:3px; border-radius:3px;
  background:linear-gradient(var(--accent), var(--tan)); }
.tl-item{ position:relative; padding:0 0 24px 18px; }
.tl-item::before{ content:""; position:absolute; left:-25px; top:5px; width:15px; height:15px; border-radius:50%;
  background:var(--accent); border:3px solid var(--paper); box-shadow:0 0 0 2px var(--accent); }
.tl-item.amber::before{ background:var(--tan); box-shadow:0 0 0 2px var(--tan); }
.tl-item.red::before{ background:var(--st-impact); box-shadow:0 0 0 2px var(--st-impact); }
.tl-item.green::before{ background:var(--st-active); box-shadow:0 0 0 2px var(--st-active); }
.tl-item .t{ font-weight:800; color:var(--ink); font-size:1.02rem; }
.tl-item p{ color:var(--ink-soft); font-size:.96rem; margin-top:3px; }

/* architecture diagram */
.arch{ display:flex; flex-direction:column; align-items:center; gap:0; }
.arch-box{
  background:var(--paper); border:2px solid var(--accent); color:var(--ink); font-weight:700;
  border-radius:12px; padding:13px 26px; text-align:center; min-width:230px; box-shadow:var(--shadow-sm);
}
.arch-box small{ display:block; font-weight:600; color:var(--ink-soft); font-size:.8rem; }
.arch-box.amber{ border-color:var(--tan); }
.arch-box.green{ border-color:var(--deep); }
.arch-arrow{ color:var(--accent); font-size:1.3rem; line-height:1; padding:6px 0; font-weight:800; }

/* donation summary strip (on hero gradient) */
.impact-strip{ display:grid; grid-template-columns:repeat(3,1fr); gap:16px; margin-top:26px; position:relative; z-index:1; }
.impact-strip .box{ background:rgba(243,244,241,.14); border:1px solid rgba(243,244,241,.28);
  border-radius:12px; padding:16px; }
.impact-strip .n{ font-weight:800; font-size:1.5rem; color:var(--tan-light); }
.impact-strip .l{ font-size:.86rem; color:#E3EAE2; }

/* deploy tier cards */
.tier{ position:relative; display:flex; flex-direction:column; }
.tier .price{ font-size:2rem; font-weight:800; color:var(--ink); margin:6px 0 2px; }
.tier .price small{ font-size:.95rem; color:var(--ink-soft); font-weight:600; }
.tier ul{ list-style:none; margin:14px 0 20px; flex:1; }
.tier li{ padding:6px 0 6px 26px; position:relative; color:var(--ink-soft); font-size:.95rem; }
.tier li::before{ content:"✓"; position:absolute; left:0; color:var(--accent); font-weight:900; }
.tier.featured{ border:2.5px solid var(--tan); box-shadow:0 12px 34px rgba(188,138,82,.28); }
.tier .flag{ position:absolute; top:-13px; left:50%; transform:translateX(-50%);
  background:var(--tan); color:#fff; font-size:.72rem; font-weight:800; letter-spacing:1.4px;
  text-transform:uppercase; padding:4px 14px; border-radius:999px; }

/* FAQ */
details.faq{ background:var(--paper); border:1px solid var(--track); border-radius:12px; padding:0 20px; margin-bottom:12px; }
details.faq summary{ cursor:pointer; font-weight:700; color:var(--ink); padding:16px 0; list-style:none; position:relative; padding-right:30px; }
details.faq summary::after{ content:"+"; position:absolute; right:2px; top:12px; font-size:1.4rem; color:var(--accent); }
details.faq[open] summary::after{ content:"–"; }
details.faq p{ color:var(--ink-soft); padding-bottom:16px; font-size:.97rem; }

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width: 900px){
  .grid-3, .grid-4{ grid-template-columns:repeat(2,1fr); }
  .foot-grid{ grid-template-columns:1fr 1fr; }
  .net-stats{ left:12px; top:calc(var(--header-h) + 12px); width:210px; padding:13px 14px; }
  .net-item .n{ font-size:1.25rem; }
}

@media (max-width: 720px){
  .nav{
    position:fixed; top:var(--header-h); right:0; left:0; z-index:1099;
    background:var(--deep); flex-direction:column; align-items:stretch; gap:2px;
    padding:12px 16px 18px; box-shadow:0 14px 24px rgba(44,59,54,.35);
    display:none;
  }
  .nav.open{ display:flex; }
  .nav a{ padding:13px 14px; font-size:1.05rem; color:#E3EAE2; }
  .nav a:hover{ background:rgba(243,244,241,.12); color:#fff; }
  .nav a.active{ background:rgba(243,244,241,.2); color:#fff; }
  .nav .btn{ margin-left:0; margin-top:8px; }
  .nav-toggle{ display:block; }

  .grid-2, .grid-3, .grid-4{ grid-template-columns:1fr; }
  .stats-row{ grid-template-columns:1fr; }
  .impact-strip{ grid-template-columns:1fr; }
  .foot-grid{ grid-template-columns:1fr; gap:24px; }
  .section{ padding:46px 0; }

  /* map UI on mobile */
  .net-stats{ width:auto; right:12px; }
  .net-grid{ grid-template-columns:repeat(4,1fr); gap:6px; }
  .net-item .l{ font-size:.62rem; }
  .net-foot{ display:none; }
  .map-actions{
    top:auto; bottom:14px; right:12px; left:12px;
    flex-direction:row; justify-content:stretch;
  }
  .map-actions .btn{ flex:1; padding:12px 8px; font-size:.9rem; }
  .map-actions .btn svg{ width:15px; height:15px; }
  .legend{ bottom:76px; left:12px; padding:10px 12px; max-width:170px; }
  .legend .row{ font-size:.8rem; padding:4px 6px; }
  .leaflet-top.leaflet-left .leaflet-control-zoom{ display:none; }

  /* Round-85: z-index above the header (1100) and the sign-up bar (1200), on MOBILE ONLY.
     On desktop the panel is a side drawer starting at top:var(--header-h), so it never reaches
     the header and 1000 is correct — the deliberate stacking noted at p4.css:541 (the map FAB at
     900 passing behind it) depends on that and is left alone.
     As a bottom sheet it is 78dvh tall, which on a short screen like an iPhone SE reaches into
     the header band — and the first thing to disappear under it is .sp-head, which carries the
     CLOSE BUTTON. A panel you cannot dismiss is worse than one you cannot fully read. */
  .station-panel{ width:100%; top:auto; height:78vh; height:78dvh; bottom:0; border-radius:18px 18px 0 0;
    z-index:1250;
    transform:translateY(105%); box-shadow:0 -12px 40px rgba(44,59,54,.4); }
  .station-panel.open{ transform:translateY(0); }
  .sp-head{ border-radius:18px 18px 0 0; }
}

/* ============================================================
   Blazor app additions
   ============================================================ */
/* Round-93c: the only reconnect UI left — a thin banner, shown solely when the device itself
   is offline. Silent reconnection needs no chrome, and inside the app the native offline panel
   owns this moment entirely. */
#reconBanner{
  position:fixed; top:0; left:0; right:0; z-index:2600;
  padding:calc(6px + env(safe-area-inset-top, 0px)) 14px 6px;
  background:#2C3B36; color:#F3F4F1; text-align:center;
  font-size:.85rem; font-weight:600;
}
.in-app #reconBanner{ display:none !important; }

/* Round-93c: edge-to-edge, BOTH platforms. The app's WebView reaches the physical screen edges
   (iOS: UseSafeArea false + inset adjustment Never; Android: decorFitsSystemWindows false with
   transparent bars), so content shows through under the home bar/gesture bar — the transparent
   look — and the fixed chrome pads itself back out with these variables. iOS fills them from
   env() (viewport-fit=cover is on the meta tag); Android's WebView never wires system bars into
   env(), so the in-app bootstrap sets the SAME variables from AquaNative.safeInsets(). Browsers
   and old app builds resolve everything to 0 and are untouched. */
html.in-app{
  --safe-top:env(safe-area-inset-top, 0px);
  --safe-bottom:env(safe-area-inset-bottom, 0px);
  --safe-right:env(safe-area-inset-right, 0px);
}
/* Round-93d: no double-tap / pinch scale on app UI. Leaflet sets touch-action:none on its own
   container, which wins for the map — pan and pinch there are the map's, not the page's. */
html.in-app, html.in-app body{ touch-action:pan-x pan-y; }
/* Round-93f: no route to a Paystack checkout from inside the app — Play Billing / StoreKit
   rules treat credits as in-app digital goods. Credits are managed on the website. */
html.in-app .acct-tab[href="/account/top-up"]{ display:none; }
html.in-app #signupBar{ padding-top:calc(7px + var(--safe-top, 0px)); }
html.in-app:not(.signup-bar-on){ --header-h:calc(64px + var(--safe-top, 0px)); }
html.in-app:not(.signup-bar-on) .site-header{
  padding-top:var(--safe-top, 0px);
  height:calc(64px + var(--safe-top, 0px));
}
html.in-app .base-switch{ bottom:calc(18px + var(--safe-bottom, 0px)); }
/* The live map's transparent header sits at top:var(--signup-h); with no sign-up bar that is
   top:0 — under the clock and battery on an edge-to-edge phone. Same rule shape as .site-header. */
html.in-app:not(.signup-bar-on) .map-header{ top:var(--safe-top, 0px); }
/* Round-93c: the time-band strip (live map AND stories share .time-row) sat at 27px + the full
   home-bar inset — more than twice the gap it needs once content may run under the bar. Halved,
   at the product's request; the attribution text beneath is already tap-inert on phones. */
html.in-app .time-row{ bottom:calc((27px + var(--safe-bottom, 0px)) / 2); }
/* Ada's drawer is a full-height fixed panel: its dark header sat under the clock and battery on
   an edge-to-edge phone, and its composer under the home bar. Pad both ends with the insets. */
html.in-app .asst-drawer-head{ padding-top:calc(14px + var(--safe-top, 0px)); }
html.in-app .asst-drawer{ padding-bottom:var(--safe-bottom, 0px); }
html.in-app .asst-fab{ right:calc(16px + var(--safe-right, 0px)); }
html.in-app #blazor-error-ui{ padding-bottom:calc(12px + var(--safe-bottom, 0px)); }
html.in-app .map-actions{ bottom:calc(14px + var(--safe-bottom, 0px)); }

#blazor-error-ui{
  display:none; position:fixed; bottom:0; left:0; right:0; z-index:2000;
  background:#F3E9D8; color:#7A5A22; border-top:2px solid var(--tan);
  padding:12px 20px; font-size:.95rem;
}
#blazor-error-ui .dismiss{ float:right; cursor:pointer; font-weight:700; }
#blazor-error-ui .reload{ font-weight:700; margin-left:8px; }

.validation-message{ color:var(--st-impact); font-size:.85rem; margin-top:5px; display:block; }
.field input.invalid, .field select.invalid, .field textarea.invalid{ border-color:var(--st-impact); }
.field input.valid.modified, .field select.valid.modified, .field textarea.valid.modified{ border-color:var(--accent); }

/* social sign-in buttons */
.btn-google{ background:#fff; color:var(--ink); border:1.5px solid var(--track); }
.btn-google:hover{ border-color:var(--accent); box-shadow:var(--shadow-sm); }
.btn-facebook{ background:#1877F2; color:#fff; }
.btn-facebook:hover{ background:#2f86f6; box-shadow:0 4px 16px rgba(24,119,242,.4); }
.btn-google svg, .btn-facebook svg{ width:20px; height:20px; }

.auth-card{ max-width:440px; margin:0 auto; }
.auth-card .btn{ margin-bottom:12px; }
.auth-divider{ display:flex; align-items:center; gap:12px; color:var(--ink-soft); font-size:.85rem; margin:16px 0; }
.auth-divider::before, .auth-divider::after{ content:""; flex:1; height:1px; background:var(--track); }

/* ============================================================
   Map engine v2 — service pills, base switcher, incident markers
   ============================================================ */
.svc-wrap{
  /* Google-Maps style: chips row beside the map search box, inside the transparent nav.
     --signup-h keeps the row below the signed-out sign-up bar (0 when the bar is off). */
  position:fixed; top:calc(13px + var(--signup-h, 0px)); left:calc(var(--msearch-w, 400px) + 42px); right:370px;
  z-index:950; display:flex; align-items:center;
}
.svc-pills{
  display:flex; gap:8px; flex-wrap:nowrap; justify-content:flex-start; width:100%;
  overflow-x:auto; scrollbar-width:none; padding-bottom:2px;
}
.svc-pills::-webkit-scrollbar{ display:none; }
.pill-svc{
  --svc: var(--accent);
  display:inline-flex; align-items:center; gap:6px;
  padding:8px 14px; border-radius:999px; cursor:pointer;
  font-family:var(--font); font-weight:700; font-size:.9rem;
  background:rgba(243,244,241,.92); color:var(--ink-soft);
  border:2px solid var(--track); backdrop-filter:blur(6px);
  box-shadow:0 4px 14px rgba(44,59,54,.18);
  transition:all .15s;
  opacity:.75;
}
.pill-svc svg{ width:16px; height:16px; color:var(--svc); flex:0 0 auto; }
.pill-svc:hover{ border-color:var(--svc); opacity:1; }
a.pill-svc{ text-decoration:none; }
a.pill-svc:hover{ text-decoration:none; }
.pill-svc.on{
  background:var(--accent); border-color:var(--accent); color:#fff; opacity:1;
}
/* icons keep their service color even when the chip is selected */
.pill-svc.on svg{ color:var(--svc); }

/* base map style switcher — bottom center */
.base-switch{
  position:fixed; bottom:18px; left:50%; transform:translateX(-50%);
  z-index:940; display:flex; gap:0; border-radius:999px; overflow:hidden;
  border:1px solid rgba(243,244,241,.3); box-shadow:0 6px 20px rgba(44,59,54,.3);
  background:#fff;
}
.base-switch button{
  padding:8px 14px; border:0; cursor:pointer; font-family:var(--font); font-weight:700; font-size:.82rem;
  background:var(--panel-grad); color:#DCE5DD;
}
.base-switch button + button{ border-left:1px solid rgba(243,244,241,.25); }
.base-switch button.on{ background:var(--paper); color:var(--deep); }

/* incident markers */
.inc-marker{
  width:30px; height:30px; border-radius:50% 50% 50% 4px;
  display:flex; align-items:center; justify-content:center;
  font-size:15px; border:2.5px solid #fff;
  box-shadow:0 3px 10px rgba(44,59,54,.45);
  transform:rotate(0deg);
}
.inc-marker.sev{ animation:sevpulse 1.6s ease-in-out infinite; }
@keyframes sevpulse{ 0%,100%{ box-shadow:0 3px 10px rgba(192,57,43,.45); } 50%{ box-shadow:0 0 0 10px rgba(192,57,43,0); } }

.legend-svc .row{ cursor:default; }
.legend-svc .row:hover{ background:transparent; }
.legend .swatch{ border-radius:50%; }

@media (max-width: 720px){
  .svc-pills{
    padding-bottom:4px;
  }
  .pill-svc{ flex:0 0 auto; font-size:.82rem; padding:7px 12px; }
  .net-stats{ top:calc(var(--header-h) + 56px); }
  .base-switch{ bottom:76px; left:12px; transform:none; }
  html.in-app .base-switch{ bottom:calc(76px + var(--safe-bottom, 0px)); }
  .map-actions{ bottom:14px; }
  .legend{ bottom:128px; }
}

/* ============================================================
   Engagement — incident reactions + comment thread
   ============================================================ */
.inc-react{ display:flex; align-items:center; gap:10px; margin-bottom:12px; }
.react-btn{
  padding:5px 7px; border-radius:0.7rem; border:1.5px solid var(--track); background:var(--paper);
  cursor:pointer; font-family:var(--font); font-weight:400; font-size:.8rem; color:var(--ink);
  transition:all .15s;
}
.react-btn:hover{ border-color:var(--accent); }
.react-btn.on{ background:var(--accent); border-color:var(--accent); color:#fff; }
/* round-57: when a react button is selected its background turns accent — force the emoji
   silhouette to white so the accent-coloured heart doesn't vanish into the accent fill. */
.react-btn.on .ico-t{ text-shadow:0 0 0 #F3F4F1 !important; }

.cmt-list{ display:flex; flex-direction:column; gap:12px; }
.cmt{ display:flex; gap:10px; }
.cmt-av{ width:32px; height:32px; border-radius:50%; object-fit:cover; flex:0 0 auto; border:1.5px solid var(--track); }
.cmt-av-fallback{
  display:flex; align-items:center; justify-content:center;
  background:var(--sage2); color:#fff; font-weight:800; font-size:.9rem;
}
.cmt-body{ background:var(--mintbg); border:1px solid var(--track); border-radius:4px 14px 14px 14px; padding:9px 13px; flex:1; }
.cmt-head{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; font-size:.88rem; }
.cmt-badge{
  background:var(--deep); color:#fff; font-size:.68rem; font-weight:800; letter-spacing:.3px;
  padding:2px 8px; border-radius:999px;
}
.cmt-pts{ color:var(--tan); font-size:.75rem; font-weight:800; }
.cmt-body p{ font-size:.92rem; margin:4px 0; }
.cmt-actions{ display:flex; align-items:center; gap:10px; }
.cmt-actions small{ color:var(--ink-soft); font-size:.72rem; margin-left:auto; }
.cmt-btn{
  background:none; border:0; cursor:pointer; font-family:var(--font); font-size:.78rem;
  font-weight:700; color:var(--ink-soft); padding:2px 4px; border-radius:6px;
}
.cmt-btn:hover{ color:var(--deep); background:rgba(97,141,124,.12); }
.cmt-btn.on{ color:var(--deep); }
.cmt-btn.flagged{ color:var(--st-impact); }
.cmt-more{
  display:block; width:100%; text-align:center; background:none; border:0; cursor:pointer;
  font-family:var(--font); font-weight:700; font-size:.85rem; color:var(--deep);
  padding:8px 0; margin-bottom:4px;
}
.cmt-more:hover{ text-decoration:underline; }
.cmt-compose{ display:flex; gap:8px; margin-top:14px; align-items:flex-end; }
.cmt-compose textarea{
  flex:1; min-height:44px; max-height:120px; padding:10px 12px;
  border:1.5px solid var(--track); border-radius:12px; font-family:var(--font); font-size:.92rem;
  resize:vertical; background:#FBFBF8;
}
.cmt-compose textarea:focus{ outline:none; border-color:var(--accent); }

/* build r14b-2 */
