/* Inter (self-hosted) — public pages load only public.css (+charts.css), so the
   full face set is declared here. */
@font-face { font-family: "Inter"; src: url("../fonts/inter-400.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Inter"; src: url("../fonts/inter-500.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Inter"; src: url("../fonts/inter-600.woff2") format("woff2"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "Inter"; src: url("../fonts/inter-700.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Inter"; src: url("../fonts/inter-800.woff2") format("woff2"); font-weight: 800; font-style: normal; font-display: swap; }

/* ==========================================================================
   IntegrityShield — OpenHumanitarian public transparency surface
   Marketing site + public dashboard. Light-only; ink hero/footer bands.
   FMHAPR · XtraDot Technologies · Fidelity Bank Plc
   Hand-authored, token-driven, no framework.
   ========================================================================== */

:root {
  /* Ink — deep institutional bands */
  --ink:   #0c1b2a;
  --ink-2: #071219;
  --ink-3: #14293d;

  /* Brand greens */
  --green-900: #063b25;
  --green-700: #0a5c39;
  --green-600: #0e7a4b;
  --green-500: #12945c;
  --green-100: #e3f4ec;
  --primary:   #0a5c39;

  /* Gold — integrity accent */
  --gold:        #c19a2e;
  --gold-bright: #d9b64a;
  --gold-deep:   #8f6f1c;

  /* Semantic */
  --success: #0e7a4b; --success-bg: #e3f4ec;
  --warning: #94660a; --warning-bg: #fbf3e0;
  --danger:  #b3261e; --danger-bg:  #fbeceb;
  --info:    #1d5fbf; --info-bg:    #eaf1fb;
  --flagged: #7f2ef0; --flagged-bg: #f2ebfd;

  /* Slate ramp */
  --slate-50:  #f7f9fb; --slate-100: #eef2f6; --slate-200: #e1e7ee;
  --slate-300: #c9d3df; --slate-400: #93a1b4; --slate-500: #64748b;
  --slate-600: #48566d; --slate-700: #32405a; --slate-800: #1d2a42;
  --slate-900: #0f1a2c;

  /* Surfaces (light) */
  --bg:         #f4f6f8;
  --surface:    #ffffff;
  --surface-2:  #f7f9fb;
  --border:     #e3e8ef;
  --text:       #15202f;
  --text-muted: #5b6879;

  /* Sidebar tokens (unused on public pages, kept for the shared contract) */
  --side-bg:    #0c1b2a;
  --side-bg-2:  #071219;
  --side-text:  rgba(255,255,255,0.84);
  --side-muted: rgba(255,255,255,0.44);
  --side-hover: rgba(255,255,255,0.07);
  --side-line:  rgba(255,255,255,0.08);

  --radius: 10px; --radius-sm: 6px; --radius-lg: 14px;

  /* The card gutter, as one value. Header, body, footer and a table's
     outer columns all derive from it, so the first column of a table can
     never drift from the title above it — which it did at every width
     below 400px, where the gutter shrank to 16px while the cells went to
     12px and the data ended up outside the card. */
  --card-gutter: 20px;
  --sidebar-w: 262px; --topbar-h: 62px;

  --shadow:    0 1px 3px rgba(12,27,42,.07), 0 1px 2px rgba(12,27,42,.04);
  --shadow-md: 0 4px 10px -2px rgba(12,27,42,.10), 0 2px 4px -2px rgba(12,27,42,.05);
  --shadow-lg: 0 14px 34px -10px rgba(12,27,42,.20), 0 8px 14px -8px rgba(12,27,42,.10);
  --shadow-xl: 0 28px 60px -16px rgba(7,18,25,.35);

  --font: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: "Cascadia Code", "SF Mono", Consolas, ui-monospace, monospace;
  --transition: .18s cubic-bezier(.4,0,.2,1);

  /* Faint repeating chain-link texture used on ink bands */
  --chain-pattern: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='84' viewBox='0 0 140 84'%3E%3Cg fill='none' stroke='%23ffffff' stroke-opacity='0.045' stroke-width='2'%3E%3Crect x='4' y='14' width='40' height='18' rx='9'/%3E%3Crect x='36' y='14' width='40' height='18' rx='9'/%3E%3Crect x='68' y='14' width='40' height='18' rx='9'/%3E%3Crect x='100' y='14' width='40' height='18' rx='9'/%3E%3Crect x='-28' y='56' width='40' height='18' rx='9'/%3E%3Crect x='4' y='56' width='40' height='18' rx='9'/%3E%3Crect x='36' y='56' width='40' height='18' rx='9'/%3E%3Crect x='68' y='56' width='40' height='18' rx='9'/%3E%3Crect x='100' y='56' width='40' height='18' rx='9'/%3E%3C/g%3E%3C/svg%3E");
}

/* Author rules beat the UA [hidden] rule — one global guard. */
[hidden] { display: none !important; }

/* ---- Reset / base ---- */
* { margin: 0; padding: 0; box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}
body {
  font-family: var(--font); font-size: 15px; line-height: 1.6;
  color: var(--text); background: var(--bg);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
a { color: var(--green-700); text-decoration: none; }
a:hover { text-decoration: underline; }
img, svg { vertical-align: middle; max-width: 100%; }
/* --gold (#c19a2e) is only 2.65:1 on white and 2.44:1 on --bg, under the 3:1
   WCAG 2.2 minimum for a focus indicator. --gold-deep clears it on every
   ground the public surface uses: 4.71:1 on white, 4.35:1 on --bg, and still
   3.70:1 on the ink hero and footer bands. */
:focus-visible { outline: 2px solid var(--gold-deep); outline-offset: 2px; border-radius: 4px; }
::selection { background: rgba(193,154,46,.22); }
h1, h2, h3, h4 { line-height: 1.22; letter-spacing: -.01em; }

.wrap { max-width: 1180px; margin: 0 auto; padding: 0 24px; }
.wrap--narrow { max-width: 860px; }

/* ==========================================================================
   Buttons (public subset of the shared vocabulary)
   ========================================================================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 10px 18px; border-radius: var(--radius-sm);
  font: 600 14px/1.2 var(--font); letter-spacing: .01em;
  border: 1px solid transparent; cursor: pointer; white-space: nowrap;
  transition: background var(--transition), border-color var(--transition),
              color var(--transition), box-shadow var(--transition), transform var(--transition);
  text-decoration: none;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .55; cursor: not-allowed; }

.btn--primary { background: var(--green-700); color: #fff; box-shadow: 0 1px 2px rgba(6,59,37,.3); }
.btn--primary:hover { background: var(--green-600); color: #fff; }

.btn--ghost { background: transparent; color: var(--text); border-color: var(--border); }
.btn--ghost:hover { background: var(--surface-2); border-color: var(--slate-300); }

.btn--danger { background: var(--danger); color: #fff; }
.btn--danger:hover { background: #9a201a; }

.btn--gold { background: linear-gradient(180deg, var(--gold-bright), var(--gold)); color: var(--ink-2); border-color: var(--gold-deep); box-shadow: 0 1px 2px rgba(143,111,28,.4); }
.btn--gold:hover { background: linear-gradient(180deg, #e2c258, var(--gold-bright)); }

.btn--sm { padding: 6px 12px; font-size: 13px; }
.btn--icon { padding: 8px; width: 36px; height: 36px; }

.btn.is-loading { position: relative; color: transparent !important; pointer-events: none; }
.btn.is-loading::after {
  content: ""; position: absolute; inset: 0; margin: auto; width: 16px; height: 16px;
  border: 2px solid rgba(255,255,255,.4); border-top-color: #fff; border-radius: 50%;
  animation: isd-spin .7s linear infinite;
}
.btn--ghost.is-loading::after { border-color: var(--slate-300); border-top-color: var(--slate-600); }
@keyframes isd-spin { to { transform: rotate(360deg); } }

/* Ink-band button treatments */
.btn--on-ink { background: rgba(255,255,255,.08); color: #fff; border-color: rgba(255,255,255,.22); }
.btn--on-ink:hover { background: rgba(255,255,255,.14); color: #fff; }

/* ==========================================================================
   Public navigation — sticky white header
   ========================================================================== */
.pubnav {
  position: sticky; top: 0; z-index: 90;
  background: rgba(255,255,255,.92); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.pubnav__inner {
  max-width: 1180px; margin: 0 auto; padding: 0 24px;
  height: 66px; display: flex; align-items: center; gap: 28px;
}
.pubnav__brand { display: inline-flex; align-items: center; gap: 10px; font-weight: 800; font-size: 16px; color: var(--ink); letter-spacing: -.01em; }
.pubnav__brand:hover { text-decoration: none; }
.pubnav__links { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.pubnav__links a {
  display: inline-block; padding: 8px 12px; border-radius: var(--radius-sm);
  font-size: 14px; font-weight: 500; color: var(--slate-600);
}
.pubnav__links a:hover { color: var(--ink); background: var(--surface-2); text-decoration: none; }
.pubnav__links a.is-active { color: var(--green-700); font-weight: 600; }
.pubnav__cta { display: flex; align-items: center; gap: 10px; }

/* ==========================================================================
   Hero — deep ink band with chain-link texture and gold accents
   ========================================================================== */
.hero {
  position: relative; color: #fff; overflow: hidden;
  background:
    radial-gradient(900px 420px at 85% -10%, rgba(18,148,92,.28), transparent 60%),
    radial-gradient(700px 380px at -10% 110%, rgba(193,154,46,.14), transparent 55%),
    linear-gradient(160deg, var(--ink-3) 0%, var(--ink) 45%, var(--ink-2) 100%);
}
.hero::before {
  content: ""; position: absolute; inset: 0;
  background-image: var(--chain-pattern);
  background-size: 140px 84px; pointer-events: none;
}

/* ---- Banner artwork -----------------------------------------------------
 * Every ink band can carry a scene behind it: Abuja on the homepage, the
 * savannah road on "How it works", farmland on Programmes, the confluence on
 * the transparency pages, the ledger seal on the verification page, and the
 * meeting under the tree on the grievance pages. The drawings are original
 * vector work kept in public/assets/img/banners — a federal platform should
 * not carry photographs whose licence it cannot produce on request.
 *
 * Three things make this safe to put behind text:
 *   - it paints at z-index 0 while the content sits at 1, because ::after is
 *     the last child and would otherwise paint OVER the headline;
 *   - the top of the image is masked away, so the first line of the heading
 *     always meets flat ink rather than a roofline;
 *   - opacity is a variable, so a band with more text can turn it down.
 */
.hero::after,
.page-hero::after,
.grievance::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image: var(--banner, none);
  background-position: 50% 100%;
  background-size: cover;
  background-repeat: no-repeat;
  opacity: var(--banner-opacity, .5);
  -webkit-mask-image: linear-gradient(180deg, transparent 0, rgba(0,0,0,.55) 18%, #000 46%, #000 100%);
          mask-image: linear-gradient(180deg, transparent 0, rgba(0,0,0,.55) 18%, #000 46%, #000 100%);
}
.hero > *, .page-hero > *, .grievance > * { position: relative; z-index: 1; }

/* A page hero is about 150px tall, so background-size:cover shows barely a
   third of a 1600x480 drawing. Anchored to the bottom that third is all
   ground and nothing to look at. Lifting the focal point puts the horizon —
   the rooflines, the treeline, the river mouth — inside the visible band. */
.page-hero::after, .grievance::after { background-position: 50% 72%; }

.hero                    { --banner: url("../img/banners/abuja.svg"); --banner-opacity: .92; }
.page-hero--how          { --banner: url("../img/banners/savannah.svg"); --banner-opacity: .8; }
.page-hero--programmes   { --banner: url("../img/banners/harvest.svg"); --banner-opacity: .8; }
.page-hero--transparency { --banner: url("../img/banners/confluence.svg"); --banner-opacity: .8; }
.page-hero--verify       { --banner: url("../img/banners/ledger.svg"); --banner-opacity: .85; }
.page-hero--grievance    { --banner: url("../img/banners/community.svg"); --banner-opacity: .8; }
.grievance               { --banner: url("../img/banners/community.svg"); --banner-opacity: .38; }

/* A short band crops the artwork to almost nothing; let it sit lower and
   lighter rather than showing a strip of roofline. */
@media (max-width: 700px) {
  .hero::after, .page-hero::after, .grievance::after { opacity: var(--banner-opacity-sm, .34); }
}
@media print {
  .hero::after, .page-hero::after, .grievance::after { display: none; }
}

.hero__inner { position: relative; padding: 84px 0 150px; max-width: 780px; }
.hero__eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--gold-bright); margin-bottom: 18px;
}
.hero__eyebrow::before { content: ""; width: 26px; height: 2px; background: var(--gold); border-radius: 1px; }
.hero h1 {
  font-size: clamp(30px, 5vw, 52px); font-weight: 800; line-height: 1.08;
  letter-spacing: -.02em; margin-bottom: 18px;
}
.hero h1 em, .hero h1 .u-gold { font-style: normal; color: var(--gold-bright); }
.hero__sub { font-size: clamp(15px, 1.8vw, 18px); line-height: 1.65; color: rgba(255,255,255,.78); max-width: 620px; margin-bottom: 30px; }
.hero__cta { display: flex; flex-wrap: wrap; gap: 12px; }
.hero__cta .btn { padding: 12px 22px; font-size: 15px; }
.hero__note { margin-top: 18px; font-size: 13px; color: rgba(255,255,255,.55); }

/* ---- Floating counter card, overlapping the hero's bottom edge ---- */
.counter-card {
  position: relative; z-index: 5;
  margin: -84px auto 0; max-width: 1180px; padding: 0 24px;
}
.counter-card__inner {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  display: grid; grid-template-columns: repeat(4, 1fr);
  padding: 26px 8px;
}
.counter { padding: 6px 24px; border-left: 1px solid var(--border); }
.counter:first-child { border-left: 0; }
.counter__value {
  font-size: 30px; font-weight: 800; letter-spacing: -.02em; color: var(--ink);
  font-variant-numeric: tabular-nums; line-height: 1.15;
}
.counter__value .u-naira { color: var(--green-700); }
.counter__label {
  margin-top: 4px; font-size: 12px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-muted);
  display: flex; align-items: center; gap: 8px;
}
.counter__foot { margin-top: 12px; text-align: right; padding: 0 24px; font-size: 12px; color: var(--text-muted); }

.live-dot {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 10px; font-weight: 800; letter-spacing: .12em; color: var(--green-600);
}
.live-dot::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--green-500); box-shadow: 0 0 0 0 rgba(18,148,92,.5);
  animation: isd-pulse 2s ease-out infinite;
}
@keyframes isd-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(18,148,92,.5); }
  70%  { box-shadow: 0 0 0 9px rgba(18,148,92,0); }
  100% { box-shadow: 0 0 0 0 rgba(18,148,92,0); }
}

/* ==========================================================================
   Trust strip — muted consortium / oversight row
   ========================================================================== */
.trust-strip { padding: 40px 0 8px; }
.trust-strip__inner {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 18px 44px; opacity: .75;
}
.trust-strip__label {
  width: 100%; text-align: center; font-size: 11px; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--slate-400); margin-bottom: 4px;
}
.trust-strip__item {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: 14px; font-weight: 700; color: var(--slate-600); letter-spacing: .01em;
  filter: grayscale(1);
}
.trust-strip__item svg, .trust-strip__item img { height: 26px; width: auto; }

/* ==========================================================================
   Section shells
   ========================================================================== */
.section { padding: 76px 0; }
.section--tight { padding: 48px 0; }
.section--alt { background: var(--surface); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.section--ink {
  position: relative; color: #fff; overflow: hidden;
  background: linear-gradient(165deg, var(--ink-3), var(--ink) 55%, var(--ink-2));
}
.section--ink::before { content: ""; position: absolute; inset: 0; background-image: var(--chain-pattern); background-size: 140px 84px; pointer-events: none; }
.section--ink > .wrap { position: relative; }

.section__head { max-width: 640px; margin-bottom: 42px; }
.section__head--center { margin-left: auto; margin-right: auto; text-align: center; }
.section__eyebrow {
  display: block; font-size: 12px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--green-600); margin-bottom: 10px;
}
.section--ink .section__eyebrow { color: var(--gold-bright); }
.section__head h2 { font-size: clamp(24px, 3.2vw, 34px); font-weight: 800; letter-spacing: -.02em; color: var(--ink); }
.section--ink .section__head h2 { color: #fff; }
.section__sub { margin-top: 12px; font-size: 16px; color: var(--text-muted); line-height: 1.65; }
.section--ink .section__sub { color: rgba(255,255,255,.72); }

/* ==========================================================================
   How it works — 4 numbered step cards with a connecting dotted line
   ========================================================================== */
.steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 26px; position: relative; }
.step {
  position: relative; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 26px 22px; box-shadow: var(--shadow);
  transition: box-shadow var(--transition), transform var(--transition), border-color var(--transition);
}
.step:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); border-color: var(--slate-300); }
.step__num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--green-100); color: var(--green-700);
  font-size: 17px; font-weight: 800; margin-bottom: 16px;
  border: 1px solid rgba(10,92,57,.18);
}
.step:not(:last-child)::after {
  content: ""; position: absolute; top: 48px; right: -26px; width: 26px;
  border-top: 2px dotted var(--gold); opacity: .7;
}
.step h3 { font-size: 16px; font-weight: 700; color: var(--ink); margin-bottom: 8px; }
.step p { font-size: 14px; color: var(--text-muted); line-height: 1.6; }
.step__badge { margin-top: 14px; display: inline-flex; gap: 6px; }

/* ==========================================================================
   Programme cards
   ========================================================================== */
.prog-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.prog-card {
  display: flex; flex-direction: column; gap: 12px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: 24px; box-shadow: var(--shadow); position: relative;
  transition: box-shadow var(--transition), transform var(--transition), border-color var(--transition);
}
.prog-card:hover { box-shadow: var(--shadow-lg); transform: translateY(-3px); border-color: rgba(10,92,57,.35); }
.prog-card__chip {
  width: 46px; height: 46px; border-radius: 12px;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(150deg, var(--green-100), #f0f9f4);
  color: var(--green-700); border: 1px solid rgba(10,92,57,.14);
}
.prog-card__chip svg { width: 24px; height: 24px; }
.prog-card--gold .prog-card__chip { background: linear-gradient(150deg, #faf3dd, #fbf6e6); color: var(--gold-deep); border-color: rgba(143,111,28,.22); }
.prog-card h3 { font-size: 17px; font-weight: 700; color: var(--ink); }
.prog-card__desc { font-size: 14px; color: var(--text-muted); line-height: 1.6; flex: 1; }
.prog-card__amount { font-size: 22px; font-weight: 800; letter-spacing: -.01em; color: var(--green-700); font-variant-numeric: tabular-nums; }
.prog-card__amount small { display: block; font-size: 11px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--text-muted); margin-top: 2px; }
.prog-card__meta { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; font-size: 12px; color: var(--text-muted); }
.prog-card__link {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 4px;
  font-size: 14px; font-weight: 600; color: var(--green-700);
}
.prog-card__link::after { content: "\2192"; transition: transform var(--transition); }
.prog-card:hover .prog-card__link::after { transform: translateX(3px); }
.prog-card__link:hover { text-decoration: none; color: var(--green-600); }

/* ---- Progress bars (shared vocabulary) ---- */
.progress { height: 8px; border-radius: 999px; background: var(--slate-100); overflow: hidden; border: 1px solid var(--slate-200); }
.progress__bar {
  height: 100%; border-radius: 999px; min-width: 4px;
  background: linear-gradient(90deg, var(--green-600), var(--green-500));
  transition: width .5s ease;
}
.progress--budget { height: 10px; }
.progress--budget .progress__bar { background: linear-gradient(90deg, var(--gold-deep), var(--gold-bright)); }
.progress__meta { display: flex; justify-content: space-between; font-size: 12px; color: var(--text-muted); margin-top: 6px; font-variant-numeric: tabular-nums; }

/* ==========================================================================
   Accountability split — copy left, chained-blocks frame right
   ========================================================================== */
.integrity-split { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }
.integrity-split__copy h2 { font-size: clamp(24px, 3vw, 32px); font-weight: 800; letter-spacing: -.02em; margin-bottom: 16px; }
.section--ink .integrity-split__copy h2 { color: #fff; }
.integrity-split__copy p { font-size: 15px; line-height: 1.7; color: var(--text-muted); margin-bottom: 14px; }
.section--ink .integrity-split__copy p { color: rgba(255,255,255,.74); }
.integrity-split__copy a { color: var(--gold-deep); font-weight: 600; }
.section--ink .integrity-split__copy a { color: var(--gold-bright); }
.integrity-split__points { list-style: none; margin: 20px 0 26px; display: grid; gap: 12px; }
.integrity-split__points li { display: flex; gap: 12px; font-size: 14.5px; line-height: 1.55; color: var(--text); }
.section--ink .integrity-split__points li { color: rgba(255,255,255,.85); }
.integrity-split__points li::before {
  content: "\2713"; flex: none; width: 22px; height: 22px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 800;
  background: var(--green-100); color: var(--green-700); margin-top: 1px;
}
.section--ink .integrity-split__points li::before { background: rgba(18,148,92,.22); color: #6fe0ab; }

.integrity-split__frame {
  position: relative; border-radius: var(--radius-lg); overflow: hidden;
  background:
    radial-gradient(420px 260px at 80% 15%, rgba(193,154,46,.16), transparent 60%),
    linear-gradient(155deg, var(--ink-3), var(--ink-2));
  border: 1px solid rgba(255,255,255,.09);
  box-shadow: var(--shadow-lg), inset 0 1px 0 rgba(255,255,255,.06);
  padding: 34px; min-height: 340px;
  display: flex; align-items: center; justify-content: center;
}
.integrity-split__frame::before { content: ""; position: absolute; inset: 0; background-image: var(--chain-pattern); background-size: 140px 84px; pointer-events: none; }
.integrity-split__frame svg, .integrity-split__frame .chain-blocks { position: relative; width: 100%; max-width: 440px; height: auto; }
.integrity-split__caption {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 12px 18px;
  font-size: 12px; letter-spacing: .05em; color: rgba(255,255,255,.55);
  background: linear-gradient(0deg, rgba(7,18,25,.85), transparent);
  text-align: center;
}

/* ==========================================================================
   FAQ — native details/summary accordion
   ========================================================================== */
.faq { max-width: 780px; margin: 0 auto; display: grid; gap: 12px; }
.faq details {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); overflow: hidden;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.faq details[open] { border-color: rgba(10,92,57,.35); box-shadow: var(--shadow-md); }
.faq summary {
  list-style: none; cursor: pointer; user-select: none;
  padding: 17px 52px 17px 20px; position: relative;
  font-size: 15px; font-weight: 600; color: var(--ink);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; position: absolute; right: 18px; top: 50%; transform: translateY(-50%);
  width: 26px; height: 26px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 17px; font-weight: 600; color: var(--green-700);
  background: var(--green-100); transition: transform var(--transition), background var(--transition);
}
.faq details[open] summary::after { content: "\2013"; background: var(--green-700); color: #fff; }
.faq summary:hover { color: var(--green-700); }
.faq__body { padding: 0 20px 18px; font-size: 14px; line-height: 1.7; color: var(--text-muted); }
.faq__body a { font-weight: 600; }

/* ==========================================================================
   Grievance strip — CTA band
   ========================================================================== */
.grievance {
  position: relative; overflow: hidden; color: #fff;
  background:
    radial-gradient(620px 300px at 90% 20%, rgba(193,154,46,.22), transparent 60%),
    linear-gradient(135deg, var(--green-900), var(--ink) 75%);
}
.grievance::before { content: ""; position: absolute; inset: 0; background-image: var(--chain-pattern); background-size: 140px 84px; pointer-events: none; }
.grievance__inner {
  position: relative; padding: 52px 0;
  display: flex; align-items: center; justify-content: space-between; gap: 32px; flex-wrap: wrap;
}
.grievance__copy h2 { font-size: clamp(20px, 2.6vw, 28px); font-weight: 800; letter-spacing: -.015em; margin-bottom: 8px; }
.grievance__copy p { font-size: 15px; color: rgba(255,255,255,.75); max-width: 560px; }
.grievance__copy .u-gold { color: var(--gold-bright); }
.grievance__actions { display: flex; gap: 12px; flex-wrap: wrap; }
.grievance__hotline { font-size: 13px; color: rgba(255,255,255,.6); margin-top: 10px; }
.grievance__hotline b { color: var(--gold-bright); font-variant-numeric: tabular-nums; }

/* ==========================================================================
   Public footer — ink, 4 columns, credits line
   ========================================================================== */
.pubfooter { background: linear-gradient(180deg, var(--ink), var(--ink-2)); color: rgba(255,255,255,.72); position: relative; overflow: hidden; }
.pubfooter::before { content: ""; position: absolute; inset: 0; background-image: var(--chain-pattern); background-size: 140px 84px; opacity: .6; pointer-events: none; }
.pubfooter__grid {
  position: relative; display: grid; grid-template-columns: 1.6fr 1fr 1fr 1.2fr;
  gap: 40px; padding: 56px 0 44px;
}
.pubfooter__brand { display: flex; align-items: center; gap: 10px; font-size: 17px; font-weight: 800; color: #fff; margin-bottom: 14px; }
.pubfooter__about { font-size: 13.5px; line-height: 1.7; color: rgba(255,255,255,.6); max-width: 300px; }
.pubfooter h4 {
  font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--gold-bright); margin-bottom: 16px;
}
.pubfooter ul { list-style: none; display: grid; gap: 10px; }
.pubfooter ul a { font-size: 14px; color: rgba(255,255,255,.72); }
.pubfooter ul a:hover { color: #fff; }
.pubfooter__contact { font-style: normal; font-size: 14px; line-height: 1.8; color: rgba(255,255,255,.72); }
.pubfooter__contact a { color: var(--gold-bright); }
.pubfooter__bar {
  position: relative; border-top: 1px solid rgba(255,255,255,.1);
  padding: 20px 0; display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; font-size: 12.5px; color: rgba(255,255,255,.5);
}
.pubfooter__credits { letter-spacing: .02em; }
.pubfooter__credits b { color: rgba(255,255,255,.75); font-weight: 600; }
.pubfooter__bar a { color: rgba(255,255,255,.6); }
.pubfooter__bar a:hover { color: #fff; }

/* ==========================================================================
   Public dashboard — slim ink page hero + filters
   ========================================================================== */
.page-hero {
  position: relative; color: #fff; overflow: hidden;
  background: linear-gradient(150deg, var(--ink-3), var(--ink) 60%, var(--ink-2));
}
.page-hero::before { content: ""; position: absolute; inset: 0; background-image: var(--chain-pattern); background-size: 140px 84px; pointer-events: none; }
.page-hero__inner { position: relative; padding: 38px 0 42px; }
.page-hero__crumb { font-size: 12.5px; color: rgba(255,255,255,.55); margin-bottom: 10px; }
.page-hero__crumb a { color: rgba(255,255,255,.7); }
.page-hero__crumb a:hover { color: #fff; }
.page-hero h1 { font-size: clamp(22px, 3vw, 30px); font-weight: 800; letter-spacing: -.015em; }
.page-hero__sub { margin-top: 8px; font-size: 14.5px; color: rgba(255,255,255,.7); max-width: 680px; }
.page-hero__meta { margin-top: 14px; display: flex; align-items: center; gap: 16px; flex-wrap: wrap; font-size: 12.5px; color: rgba(255,255,255,.55); }

.page-body { padding: 34px 0 64px; }

/* ---- Filter pill-selects ---- */
.pubfilters {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  margin-bottom: 24px;
}
.pubfilters__label { font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--text-muted); margin-right: 4px; }
.pubfilters select, .pubfilters input[type="search"], .pubfilters input[type="text"] {
  appearance: none; -webkit-appearance: none;
  font: 500 13.5px/1.2 var(--font); color: var(--text);
  background: var(--surface); border: 1px solid var(--border); border-radius: 999px;
  padding: 9px 34px 9px 16px; cursor: pointer; box-shadow: var(--shadow);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%2364748b' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.pubfilters input[type="search"], .pubfilters input[type="text"] { cursor: text; background-image: none; padding-right: 16px; min-width: 200px; }
.pubfilters select:hover { border-color: var(--slate-300); }
.pubfilters select:focus-visible, .pubfilters input:focus-visible { outline: 2px solid var(--green-500); outline-offset: 1px; border-color: var(--green-500); }
.pubfilters .btn { border-radius: 999px; }
.pubfilters__reset { font-size: 13px; font-weight: 600; color: var(--text-muted); padding: 8px 10px; }
.pubfilters__reset:hover { color: var(--danger); text-decoration: none; }

/* ==========================================================================
   Shared component subset (public pages load ONLY public.css + charts.css,
   so the needed portal vocabulary is redeclared here)
   ========================================================================== */

/* ---- Cards ---- */
.card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); margin-bottom: 24px;
}
.card--flush .card__body { padding: 0; }
.card--accent { border-top: 3px solid var(--green-700); }
.card--sealed { border: 1px solid rgba(143,111,28,.4); box-shadow: 0 0 0 3px rgba(193,154,46,.1), var(--shadow); }
.card__header {
  padding: 16px var(--card-gutter); border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
}
.card__title { font-size: 15px; font-weight: 700; color: var(--ink); display: flex; align-items: center; gap: 8px; }
.card__sub { font-size: 12.5px; color: var(--text-muted); margin-top: 2px; width: 100%; }
.card__title + .card__sub { margin-top: 4px; }
.card__body { padding: var(--card-gutter); }
.card__footer { padding: 13px var(--card-gutter); border-top: 1px solid var(--border); background: var(--surface-2); border-radius: 0 0 var(--radius) var(--radius); font-size: 13px; color: var(--text-muted); display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }

/* ---- Stat grid ---- */
.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; margin-bottom: 26px; }
.stat-card {
  position: relative; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow); padding: 18px;
  display: flex; flex-direction: column; gap: 6px; overflow: hidden;
}
.stat-card::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: var(--slate-300); }
.stat-card--primary::before { background: var(--green-700); }
.stat-card--success::before { background: var(--success); }
.stat-card--warning::before { background: var(--warning); }
.stat-card--danger::before  { background: var(--danger); }
.stat-card--info::before    { background: var(--info); }
.stat-card--gold::before    { background: linear-gradient(90deg, var(--gold-deep), var(--gold-bright)); }
.stat-card__icon {
  width: 38px; height: 38px; border-radius: 10px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--green-100); color: var(--green-700); margin-bottom: 4px;
}
.stat-card--warning .stat-card__icon { background: var(--warning-bg); color: var(--warning); }
.stat-card--danger .stat-card__icon  { background: var(--danger-bg); color: var(--danger); }
.stat-card--info .stat-card__icon    { background: var(--info-bg); color: var(--info); }
.stat-card--gold .stat-card__icon    { background: #faf3dd; color: var(--gold-deep); }
.stat-card__label { font-size: 12px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); }
.stat-card__value { font-size: 26px; font-weight: 800; letter-spacing: -.02em; color: var(--ink); font-variant-numeric: tabular-nums; line-height: 1.15; }
.stat-card__delta { font-size: 12.5px; font-weight: 600; color: var(--text-muted); display: inline-flex; align-items: center; gap: 4px; }
.stat-card__delta.is-up { color: var(--success); }
.stat-card__delta.is-down { color: var(--danger); }

/* ---- Tables ---- */
.table-wrap { overflow-x: auto; border-radius: var(--radius); -webkit-overflow-scrolling: touch; }
.card .table-wrap { border-radius: 0 0 var(--radius) var(--radius); }
table.table { width: 100%; border-collapse: collapse; font-size: 13.5px; background: var(--surface); }
/* 20px, matching .card__header and .card__body on this site — the admin theme
   uses 18px for the same reason. A table is nearly always the body of a card,
   and at 16px its first column sat four pixels inside the title above it: not
   enough to look deliberate, exactly enough to look careless, on every public
   table at once. */
.table th {
  text-align: left; padding: 11px var(--card-gutter); white-space: nowrap;
  font-size: 11.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-muted); background: var(--surface-2); border-bottom: 1px solid var(--border);
}
.table td { padding: 12px var(--card-gutter); border-bottom: 1px solid var(--slate-100); vertical-align: middle; color: var(--text); }

/* A table inside a PADDED body indents twice — 20px of body plus its own 20px —
   stepping its first column away from the title above it. The table brings its
   own gutter, so the body must not add one. Scoped away from .card--flush,
   whose body has no padding to cancel: cancelling it there would drag the table
   outside the card. */
/* Any table that is a direct child of a padded body, not only a lone one:
   a table brings its own gutter whatever sits beside it, and one placed
   after a chart was left indented past the title by exactly the body's
   padding. The vertical rule below stays scoped to the lone case, where
   collapsing the body's top and bottom padding is what is wanted. */
.card:not(.card--flush) > .card__body > .table-wrap,
.card:not(.card--flush) > .card__body > table.table {
  margin-left: calc(-1 * var(--card-gutter)); margin-right: calc(-1 * var(--card-gutter));
  width: calc(100% + 2 * var(--card-gutter));
}
.card:not(.card--flush) > .card__body > .table-wrap:first-child:last-child {
  margin-top: calc(-1 * var(--card-gutter)); margin-bottom: calc(-1 * var(--card-gutter));
}
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover td { background: var(--surface-2); }
.table tbody tr[data-href] { cursor: pointer; }
.table__num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
th.table__num { text-align: right; }
.table__mono { font-family: var(--mono); font-size: 12.5px; letter-spacing: 0; }
.table__actions { text-align: right; white-space: nowrap; }
.table .row--flagged td { background: var(--flagged-bg); border-bottom-color: #e5d8fb; }
.table .row--flagged:hover td { background: #ece0fb; }
.table tfoot td { background: var(--surface-2); font-weight: 700; border-top: 1px solid var(--border); }

/* ---- Pills ---- */
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 999px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .03em; line-height: 1.5;
  white-space: nowrap; text-transform: capitalize;
  background: var(--slate-100); color: var(--slate-600); border: 1px solid var(--slate-200);
}
.pill--active, .pill--settled, .pill--verified, .pill--completed, .pill--approved,
.pill--passed, .pill--matched, .pill--green, .pill--success {
  background: var(--success-bg); color: var(--success); border-color: #c7e8d6;
}
.pill--pending, .pill--processing, .pill--awaiting_approval, .pill--queued,
.pill--partial, .pill--amber, .pill--pending_approval, .pill--warning {
  background: var(--warning-bg); color: var(--warning); border-color: #eedcae;
}
.pill--failed, .pill--rejected, .pill--suspended, .pill--breach, .pill--unmatched,
.pill--red, .pill--quarantined, .pill--danger {
  background: var(--danger-bg); color: var(--danger); border-color: #f2c8c5;
}
.pill--dispatched, .pill--sent_to_bank, .pill--in_transit, .pill--open, .pill--info {
  background: var(--info-bg); color: var(--info); border-color: #c5d7f2;
}
.pill--flagged, .pill--under_review, .pill--exception, .pill--investigating {
  background: var(--flagged-bg); color: var(--flagged); border-color: #ddc9fa;
}
.pill--draft, .pill--inactive, .pill--archived, .pill--closed, .pill--cancelled, .pill--slate {
  background: var(--slate-100); color: var(--slate-500); border-color: var(--slate-200);
}

/* ---- Verification badges ---- */
.vbadge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; border-radius: 5px;
  font-size: 10.5px; font-weight: 800; letter-spacing: .06em;
  border: 1px solid transparent;
}
.vbadge--nin { background: var(--info-bg); color: var(--info); border-color: #c5d7f2; }
.vbadge--bvn { background: var(--green-100); color: var(--green-700); border-color: #c7e8d6; }
.vbadge--bio { background: var(--flagged-bg); color: var(--flagged); border-color: #ddc9fa; }
.vbadge--geo { background: var(--slate-100); color: var(--slate-600); border-color: var(--slate-200); }
.vbadge--gold { background: #faf3dd; color: var(--gold-deep); border-color: #eedcae; }

/* ---- Key/value list ---- */
.kv { display: grid; grid-template-columns: minmax(140px, 34%) 1fr; font-size: 14px; }
.kv > dt, .kv > .kv__key {
  padding: 10px 14px 10px 0; color: var(--text-muted); font-weight: 500;
  border-bottom: 1px solid var(--slate-100);
}
.kv > dd, .kv > .kv__val {
  padding: 10px 0; color: var(--text); font-weight: 500;
  border-bottom: 1px solid var(--slate-100); overflow-wrap: anywhere;
}
.kv > dt:last-of-type, .kv > dd:last-of-type { border-bottom: 0; }
.kv .table__mono, .kv code { font-family: var(--mono); font-size: 12.5px; }

/* ---- Alerts ---- */
/* An alert with no icon is a paragraph, so lay it out as one. In a flex row an
   inline child is blockified into its own flex item, so a sentence carrying a
   <strong> or an <em> is not one paragraph but several items each squeezed to
   its own minimum — which is why the grievance notices rendered a few
   characters to a line on a phone. Alerts with an icon keep the row. */
.alert:not(:has(> svg)) { display: block; }
.alert {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 14px 16px; border-radius: var(--radius);
  font-size: 14px; line-height: 1.55; margin-bottom: 18px;
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text);
}
.alert svg { flex: none; margin-top: 2px; }
.alert--success { background: var(--success-bg); border-color: #c7e8d6; color: #0a4a2f; }
.alert--warning { background: var(--warning-bg); border-color: #eedcae; color: #6d4b07; }
.alert--danger  { background: var(--danger-bg); border-color: #f2c8c5; color: #7e1b15; }
.alert--info    { background: var(--info-bg); border-color: #c5d7f2; color: #16457e; }
.alert--integrity {
  background: linear-gradient(135deg, #fbf7ea, #f6f9f4);
  border: 1px solid rgba(143,111,28,.35); border-left: 4px solid var(--gold);
  color: #4d3c10;
}
.alert--integrity b, .alert--integrity strong { color: var(--gold-deep); }
.alert__close { margin-left: auto; background: none; border: 0; cursor: pointer; color: inherit; opacity: .55; font-size: 16px; line-height: 1; padding: 2px; }
.alert__close:hover { opacity: 1; }

/* ---- Tabs ---- */
.tabs {
  display: flex; gap: 2px; border-bottom: 2px solid var(--border);
  margin-bottom: 22px; overflow-x: auto; scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs > a, .tabs > button {
  appearance: none; background: none; border: 0; cursor: pointer;
  padding: 10px 16px; margin-bottom: -2px; white-space: nowrap;
  font: 600 14px/1.2 var(--font); color: var(--text-muted);
  border-bottom: 2px solid transparent;
  transition: color var(--transition), border-color var(--transition);
}
.tabs > a:hover, .tabs > button:hover { color: var(--ink); text-decoration: none; }
.tabs > .is-active { color: var(--green-700); border-bottom-color: var(--green-700); }

/* ---- Empty state ---- */
.empty-state { text-align: center; padding: 56px 24px; color: var(--text-muted); }
.empty-state__icon {
  width: 58px; height: 58px; border-radius: 16px; margin: 0 auto 16px;
  display: flex; align-items: center; justify-content: center;
  background: var(--slate-100); color: var(--slate-400);
}
.empty-state h3, .empty-state__title { font-size: 16px; font-weight: 700; color: var(--text); margin-bottom: 6px; }
.empty-state p { font-size: 14px; max-width: 420px; margin: 0 auto 18px; }

/* ---- Copy button (used beside hashes on public ledger pages) ---- */
.copy-btn {
  appearance: none; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-sm); cursor: pointer;
  font: 600 11.5px/1.2 var(--font); color: var(--text-muted);
  padding: 4px 9px; transition: color var(--transition), border-color var(--transition);
}
.copy-btn:hover { color: var(--green-700); border-color: var(--green-500); }
.copy-btn.is-copied { color: var(--success); border-color: #c7e8d6; background: var(--success-bg); }

/* ---- Hash / chain helpers ---- */
.hash {
  font-family: var(--mono); font-size: 12px; color: var(--slate-600);
  background: var(--slate-50); border: 1px solid var(--slate-100);
  border-radius: 5px; padding: 2px 7px; overflow-wrap: anywhere;
}
.seal-note {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12px; font-weight: 600; color: var(--gold-deep);
}

/* ---- Forms (public grievance intake / beneficiary lookup) ---- */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px 20px; }
.form-grid--single { grid-template-columns: 1fr; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field--full { grid-column: 1 / -1; }
.field > label { font-size: 13px; font-weight: 600; color: var(--text); }
.field > label .req { color: var(--danger); }
.field input, .field select, .field textarea {
  font: 400 14px/1.45 var(--font); color: var(--text);
  background: var(--surface); border: 1px solid var(--slate-300);
  border-radius: var(--radius-sm); padding: 10px 12px; width: 100%;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.field textarea { min-height: 110px; resize: vertical; }
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible {
  outline: none; border-color: var(--green-600); box-shadow: 0 0 0 3px rgba(14,122,75,.14);
}
.field input::placeholder, .field textarea::placeholder { color: var(--slate-400); }
.field input[disabled], .field select[disabled] { background: var(--slate-50); color: var(--text-muted); cursor: not-allowed; }
.field__help { font-size: 12px; color: var(--text-muted); }
.field__error { font-size: 12.5px; font-weight: 600; color: var(--danger); }
.field.has-error input, .field.has-error select, .field.has-error textarea { border-color: var(--danger); }
.input--mono { font-family: var(--mono) !important; letter-spacing: .02em; }
.input-group { display: flex; align-items: stretch; }
.input-group input { border-radius: var(--radius-sm) 0 0 var(--radius-sm); border-right: 0; flex: 1; }
.input-group .btn, .input-group__addon { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.input-group__addon {
  display: inline-flex; align-items: center; padding: 0 12px;
  background: var(--surface-2); border: 1px solid var(--slate-300);
  font-size: 13px; color: var(--text-muted); white-space: nowrap;
}

/* ---- Timeline (public payment trail / ledger chain) ---- */
.timeline { list-style: none; position: relative; padding-left: 26px; }
.timeline::before { content: ""; position: absolute; left: 8px; top: 6px; bottom: 6px; width: 2px; background: var(--slate-200); }
.timeline__item { position: relative; padding: 0 0 22px 8px; }
.timeline__item:last-child { padding-bottom: 0; }
.timeline__item::before {
  content: ""; position: absolute; left: -24px; top: 5px;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--surface); border: 3px solid var(--green-600);
}
.timeline__item.is-warning::before { border-color: var(--warning); }
.timeline__item.is-danger::before { border-color: var(--danger); }
.timeline__item.is-muted::before { border-color: var(--slate-300); }
.timeline__title { font-size: 14px; font-weight: 700; color: var(--ink); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.timeline__meta { font-size: 12.5px; color: var(--text-muted); margin-top: 2px; }
.timeline__body { font-size: 13.5px; color: var(--text); margin-top: 6px; line-height: 1.6; }
.timeline--chain::before { background: repeating-linear-gradient(180deg, var(--gold) 0 6px, transparent 6px 12px); width: 2px; }
.timeline--chain .timeline__item::before { border-color: var(--gold); border-radius: 4px; }
.timeline--chain .hash { display: inline-block; margin-top: 4px; }

/* ---- Pagination ---- */
.pager { display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 26px; }
.pager a, .pager span {
  min-width: 34px; height: 34px; padding: 0 10px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-sm); font-size: 13.5px; font-weight: 600;
  border: 1px solid var(--border); background: var(--surface); color: var(--text-muted);
}
.pager a:hover { border-color: var(--green-500); color: var(--green-700); text-decoration: none; }
.pager .is-current { background: var(--green-700); border-color: var(--green-700); color: #fff; }
.pager .is-disabled { opacity: .45; pointer-events: none; }

/* ---- Toasts (flash messages on public forms) ---- */
.toast-stack { position: fixed; right: 18px; bottom: 18px; z-index: 300; display: grid; gap: 10px; max-width: 380px; }
.toast {
  background: var(--ink); color: #fff; border-radius: var(--radius);
  padding: 13px 16px; font-size: 14px; box-shadow: var(--shadow-lg);
  display: flex; gap: 10px; align-items: flex-start; cursor: pointer;
  border-left: 4px solid var(--green-500);
  animation: isd-toast-in .25s ease;
}
.toast--error, .toast--danger { border-left-color: var(--danger); }
.toast--warning { border-left-color: var(--gold); }
.toast.is-leaving { opacity: 0; transform: translateY(6px); transition: opacity .4s ease, transform .4s ease; }
@keyframes isd-toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ---- Skeleton shimmer ---- */
.skeleton {
  position: relative; overflow: hidden; background: var(--slate-100);
  border-radius: var(--radius-sm); color: transparent !important; min-height: 1em;
}
.skeleton::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.7), transparent);
  animation: isd-shimmer 1.4s infinite;
}
@keyframes isd-shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }

/* ---- Layout utilities ---- */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.split-main { display: grid; grid-template-columns: 2fr 1fr; gap: 24px; align-items: start; }
.muted { color: var(--text-muted); }
.small { font-size: 12.5px; }
.mono { font-family: var(--mono); }
.text-right { text-align: right; }
.mb-0 { margin-bottom: 0; }
.mt-24 { margin-top: 24px; }
.flex-between { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 1080px) {
  .stat-grid { grid-template-columns: repeat(2, 1fr); }
  .prog-grid { grid-template-columns: repeat(2, 1fr); }
  .pubfooter__grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 900px) {
  .pubnav__links { display: none; }
  .pubnav__inner { height: 60px; gap: 16px; }
  .pubnav__cta { margin-left: auto; }

  .hero__inner { padding: 56px 0 130px; }
  .hero__cta .btn { padding: 11px 18px; font-size: 14px; }

  .counter-card { margin-top: -76px; }
  .counter-card__inner { grid-template-columns: 1fr 1fr; padding: 10px 8px; }
  .counter { padding: 16px 20px; border-left: 0; }
  .counter:nth-child(even) { border-left: 1px solid var(--border); }
  .counter:nth-child(n+3) { border-top: 1px solid var(--border); }
  .counter__value { font-size: 24px; }

  .section { padding: 52px 0; }
  .section__head { margin-bottom: 30px; }

  .steps { grid-template-columns: 1fr 1fr; }
  .step:not(:last-child)::after { display: none; }

  .integrity-split { grid-template-columns: 1fr; gap: 32px; }
  .integrity-split__frame { min-height: 260px; }

  .grievance__inner { padding: 42px 0; }

  .split-main, .grid-2, .grid-3 { grid-template-columns: 1fr; }

  .form-grid { grid-template-columns: 1fr; }

  .kv { grid-template-columns: 1fr; }
  .kv > dt, .kv > .kv__key { padding-bottom: 2px; border-bottom: 0; font-size: 12.5px; }
  .kv > dd, .kv > .kv__val { padding-top: 0; }
}

@media (max-width: 560px) {
  .wrap { padding: 0 18px; }
  .counter-card { padding: 0 18px; }
  .steps { grid-template-columns: 1fr; }
  .prog-grid { grid-template-columns: 1fr; }
  .stat-grid { grid-template-columns: 1fr; }
  .pubfooter__grid { grid-template-columns: 1fr; gap: 30px; padding: 42px 0 34px; }
  .pubfooter__bar { justify-content: center; text-align: center; }
  .counter-card__inner { grid-template-columns: 1fr; }
  .counter { border-left: 0 !important; border-top: 1px solid var(--border); }
  .counter:first-child { border-top: 0; }
  .hero__inner { padding: 44px 0 120px; }
  .pubfilters select, .pubfilters input[type="search"], .pubfilters input[type="text"] { flex: 1 1 100%; }
}

/* ==========================================================================
   Print — public pages double as citizen-printable records
   ========================================================================== */
@media print {
  body { background: #fff; font-size: 12px; }
  .pubnav, .pubfilters, .grievance, .hero__cta, .btn, .copy-btn, .toast-stack, .pager, .live-dot::before { display: none !important; }
  .hero, .section--ink, .page-hero, .pubfooter, .grievance {
    background: #fff !important; color: #000 !important;
  }
  .hero::before, .section--ink::before, .page-hero::before, .pubfooter::before { display: none; }
  .hero h1, .page-hero h1, .section--ink .section__head h2 { color: #000; }
  .hero__sub, .page-hero__sub, .section--ink .section__sub { color: #333; }
  .card, .stat-card, .step, .prog-card { box-shadow: none; border: 1px solid #bbb; break-inside: avoid; }
  .counter-card__inner { box-shadow: none; border: 1px solid #bbb; }
  .table th { background: #f0f0f0; color: #000; }
  .table td { border-bottom: 1px solid #ddd; }
  a { color: #000; text-decoration: underline; }
  .pubfooter__grid { display: none; }
  .pubfooter__bar { color: #333; border-top: 1px solid #bbb; }
}

/* ==========================================================================
   PART 2 — the public dashboard surface (Module D)
   Appended, never edited above: everything here either completes a contract
   the markup already assumes, or belongs to /transparency, /verify,
   /how-it-works and /programmes.
   ========================================================================== */

/* ---- Tokens charts.css expects but public.css never declared ---- */
:root {
  /* Was #8593a6 — 3.12:1 on white and 2.88:1 on --bg, below AA for the
     timestamps and footnotes it carries. Matched to app.css. */
  --text-faint:    #657185;
  --border-strong: #c9d3df;
  /* charts.css and the shared vocabulary reference these; the public
     surface is light-only, so both roles resolve to their light values. */
  --gold-fg:       #826316;
  --primary-fg:    #0a5c39;
  --green-550:     #0e8450;
  --on-solid:      #ffffff;
  --on-gold:       #0c1b2a;
  --danger-solid:  #b3261e;  --danger-solid-hover:  #941f18;
  --success-solid: #0e7a4b;  --success-solid-hover: #0a5c39;
  --warning-solid: #94660a;  --warning-solid-hover: #7a5308;
  --info-solid:    #1d5fbf;  --info-solid-hover:    #17509f;
}

/* ==========================================================================
   Layout contract — classes views/layouts/site.php uses
   ========================================================================== */
.container {
  max-width: 1180px; margin-left: auto; margin-right: auto;
  /* Longhands on purpose: .pubfooter__grid sets a padding shorthand for its
     own vertical rhythm and must keep it. */
  padding-left: 24px; padding-right: 24px;
}
.flash-slot { padding-top: 18px; }

/* nav_active() emits "active"; the original rule only knew "is-active". */
.pubnav__links a.active, .pubnav__links a.is-active { color: var(--green-700); font-weight: 600; }
.pubnav__toggle {
  display: none; appearance: none; background: none; border: 0; cursor: pointer;
  color: var(--ink); padding: 6px; border-radius: var(--radius-sm);
}
.pubnav__toggle:hover { background: var(--surface-2); }
.pubnav__drawer {
  border-top: 1px solid var(--border); background: var(--surface);
  padding: 12px 24px 18px; display: grid; gap: 4px;
}
.pubnav__drawer .pubnav__link {
  display: block; padding: 10px 12px; border-radius: var(--radius-sm);
  font-size: 15px; font-weight: 500; color: var(--slate-600);
}
.pubnav__drawer .pubnav__link:hover { background: var(--surface-2); color: var(--ink); text-decoration: none; }
.pubnav__drawer .btn { margin-top: 8px; justify-content: center; }

.pubfooter__brand { flex-direction: column; align-items: flex-start; gap: 12px; }
.pubfooter__ministry { font-size: 13px; font-weight: 500; line-height: 1.6; color: rgba(255,255,255,.6); }
.pubfooter__tagline { font-size: 13px; font-weight: 600; color: var(--gold-bright); letter-spacing: .01em; }
.pubfooter__col { display: grid; gap: 10px; align-content: start; }
.pubfooter__col a { font-size: 14px; color: rgba(255,255,255,.72); }
.pubfooter__col a:hover { color: #fff; }
.pubfooter__bottom {
  position: relative; border-top: 1px solid rgba(255,255,255,.1);
  padding-top: 20px; padding-bottom: 22px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; font-size: 12.5px; color: rgba(255,255,255,.5);
}
.pubfooter__fresh { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }

@media (max-width: 900px) {
  .pubnav__toggle { display: inline-flex; }
}
@media (min-width: 901px) {
  .pubnav__drawer { display: none !important; }
}
@media (max-width: 560px) {
  .container { padding-left: 18px; padding-right: 18px; }
  .pubfooter__bottom { justify-content: center; text-align: center; }
}

/* ==========================================================================
   Chart.php class contract
   App\Support\Chart emits its own vocabulary (tilemap__tile--hN, tilemap__val,
   hbars, hbar__value, chart--empty, chart__axis on a text node). charts.css
   skins a neighbouring one. These rules bind the two so a server-rendered
   chart is styled on a public page.
   ========================================================================== */
/* Same sequential ramp as charts.css .heat-N and kept in step with it: the
   ramp values are a theme-independent data encoding, but the label on each
   step is picked for contrast (#fff was 2.40:1 on h3, 3.88:1 on h4). */
.tilemap__tile--h0 { background: var(--slate-100); color: var(--text-faint); }
.tilemap__tile--h1 { background: #e3f4ec; color: #0a5c39; }
.tilemap__tile--h2 { background: #a8dcc3; color: #063b25; }
.tilemap__tile--h3 { background: #5cb98a; color: #063b25; }
.tilemap__tile--h4 { background: #0e8450; color: #fff; }
.tilemap__tile--h5 { background: #0a5c39; color: #fff; }
.tilemap__val { font-size: 8.5px; font-weight: 600; opacity: .88; font-variant-numeric: tabular-nums; display: block; }
.tilemap__tile--h4 .tilemap__val, .tilemap__tile--h5 .tilemap__val { opacity: .82; }
@media (max-width: 480px) { .tilemap__val { display: none; } }

.hbars { display: flex; flex-direction: column; gap: 12px; }
.hbars .hbar { color: inherit; text-decoration: none; }
.hbars a.hbar:hover { text-decoration: none; }
.hbars a.hbar:hover .hbar__label { color: var(--green-700); }
.hbar__value { color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; }

.chart--empty {
  display: flex; align-items: center; justify-content: center;
  min-height: 140px; height: auto;
  color: var(--text-faint); font-size: 12.5px; text-align: center;
  border: 1px dashed var(--border); border-radius: var(--radius);
}
/* Chart.php labels axes with text.chart__axis; the stroke rule in charts.css
   is meant for the axis LINE and would outline the glyphs. */
text.chart__axis {
  stroke: none; fill: var(--text-muted);
  font-family: var(--font); font-size: 10.5px; font-variant-numeric: tabular-nums;
}
.chart-legend__item { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.chart-legend__pct { color: var(--text); font-weight: 700; }

/* ==========================================================================
   Public dashboard
   ========================================================================== */

/* ---- Hero meta: live pulse + freshness stamp ---- */
.page-hero__meta .live-dot { color: #6fe0ab; }
.page-hero__meta .live-dot::before { background: #6fe0ab; box-shadow: 0 0 0 0 rgba(111,224,171,.5); }
.page-hero__promise {
  margin-top: 12px; font-size: 14px; color: rgba(255,255,255,.82);
  border-left: 2px solid var(--gold); padding-left: 12px; max-width: 640px;
}
.page-hero__actions { margin-top: 20px; display: flex; gap: 10px; flex-wrap: wrap; }

/* ---- Headline counters, floating over the page hero ---- */
.tp-counters {
  position: relative; z-index: 4; margin-top: -26px; margin-bottom: 28px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  display: grid; grid-template-columns: repeat(5, 1fr); padding: 22px 6px;
}
.tp-counters .counter { padding: 4px 20px; }
.tp-counters .counter__value { font-size: 27px; }
.tp-counters .counter__note { margin-top: 6px; font-size: 11.5px; color: var(--text-muted); }
.tp-counters .counter--ghost .counter__value { color: var(--gold-deep); }
.chip-estimate {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 9.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--gold-deep); background: #faf3dd; border: 1px solid #eedcae;
  border-radius: 4px; padding: 1px 5px;
}
@media (max-width: 1080px) { .tp-counters { grid-template-columns: repeat(3, 1fr); row-gap: 22px; } }
@media (max-width: 700px)  { .tp-counters { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 460px)  { .tp-counters { grid-template-columns: 1fr; } }

/* ---- Ghost Buster feature card (proposal 4.5.1) ---- */
.ghost-card { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 30px; align-items: start; }
.ghost-card__figure { font-size: 46px; font-weight: 800; letter-spacing: -.03em; color: var(--ink); line-height: 1; font-variant-numeric: tabular-nums; }
.ghost-card__caption { margin-top: 6px; font-size: 12px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--text-muted); }
.ghost-card__lede { margin-top: 14px; font-size: 14.5px; line-height: 1.65; color: var(--text); }
.ghost-card__split { margin-top: 18px; }
.ghost-card__split .segbar { height: 14px; border-radius: 7px; }
.ghost-card__keys { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 10px; font-size: 12.5px; color: var(--text-muted); }
.ghost-card__keys span { display: inline-flex; align-items: center; gap: 6px; }
.ghost-card__keys i { width: 9px; height: 9px; border-radius: 3px; display: inline-block; }
.ghost-card__keys b { color: var(--text); font-variant-numeric: tabular-nums; }
.ghost-card__estimate {
  background: linear-gradient(135deg, #fbf7ea, #f6f9f4);
  border: 1px solid rgba(143,111,28,.32); border-left: 4px solid var(--gold);
  border-radius: var(--radius); padding: 18px;
}
.ghost-card__estimate .amount { font-size: 26px; font-weight: 800; color: var(--gold-deep); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.ghost-card__formula { margin-top: 10px; font-size: 12.5px; line-height: 1.65; color: #5c4a17; }
.ghost-card__formula code { font-family: var(--mono); font-size: 12px; background: rgba(255,255,255,.65); border-radius: 4px; padding: 1px 5px; }
@media (max-width: 860px) { .ghost-card { grid-template-columns: 1fr; gap: 22px; } }

/* ---- Segmented switcher (metric / trend toggles) ---- */
.seg-switch {
  display: inline-flex; padding: 3px; gap: 2px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 999px;
}
.seg-switch a {
  padding: 6px 14px; border-radius: 999px; font-size: 12.5px; font-weight: 600;
  color: var(--text-muted); white-space: nowrap;
}
.seg-switch a:hover { color: var(--ink); text-decoration: none; }
.seg-switch a.is-active { background: var(--surface); color: var(--green-700); box-shadow: var(--shadow); }

/* ---- KPI board ---- */
.kpi-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
.kpi-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 18px; display: flex; flex-direction: column; gap: 8px;
}
.kpi-card__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.kpi-card__name { font-size: 13px; font-weight: 700; color: var(--ink); line-height: 1.35; }
.kpi-card__value { font-size: 30px; font-weight: 800; letter-spacing: -.025em; color: var(--ink); font-variant-numeric: tabular-nums; line-height: 1.1; }
.kpi-card__target { font-size: 12.5px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.kpi-card__target b { color: var(--text); }
.kpi-card__desc { font-size: 12px; line-height: 1.55; color: var(--text-muted); margin-top: auto; }
.kpi-card__basis { font-size: 11.5px; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.kpi-card--met { border-top: 3px solid var(--success); }
.kpi-card--missed { border-top: 3px solid var(--warning); }
.kpi-card--neutral { border-top: 3px solid var(--slate-300); }
.kpi-chip {
  display: inline-flex; align-items: center; gap: 4px; flex: none;
  padding: 3px 9px; border-radius: 999px; font-size: 11px; font-weight: 700; letter-spacing: .03em;
  background: var(--slate-100); color: var(--slate-600); border: 1px solid var(--slate-200);
}
.kpi-chip--met { background: var(--success-bg); color: var(--success); border-color: #c7e8d6; }
.kpi-chip--missed { background: var(--warning-bg); color: var(--warning); border-color: #eedcae; }
.kpi-card__meter { height: 6px; border-radius: 3px; background: var(--slate-100); overflow: hidden; }
.kpi-card__meter i { display: block; height: 100%; border-radius: 3px; background: var(--green-600); }
.kpi-card--missed .kpi-card__meter i { background: var(--warning); }
@media (max-width: 1080px) { .kpi-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px)  { .kpi-grid { grid-template-columns: 1fr; } }

/* ---- Integrity strip (ink band with the published head hash) ---- */
.integrity-strip { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)) auto; gap: 26px; align-items: center; }
.integrity-strip__item { min-width: 0; }
.integrity-strip__label { font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: rgba(255,255,255,.5); margin-bottom: 6px; }
.integrity-strip__value { font-size: 21px; font-weight: 800; color: #fff; letter-spacing: -.01em; font-variant-numeric: tabular-nums; }
.integrity-strip__sub { font-size: 12.5px; color: rgba(255,255,255,.55); margin-top: 4px; }
.hash-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.hash-line .hash {
  background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.14);
  color: rgba(255,255,255,.86); font-size: 12.5px; padding: 4px 9px;
}
.hash-line .copy-btn { background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.18); color: rgba(255,255,255,.72); }
.hash-line .copy-btn:hover { color: #fff; border-color: var(--gold); }
.hash-line .copy-btn.is-copied { background: rgba(18,148,92,.22); border-color: rgba(111,224,171,.5); color: #9ff0c6; }
@media (max-width: 900px) { .integrity-strip { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .integrity-strip { grid-template-columns: 1fr; gap: 20px; } }

/* ---- Open-data cards ---- */
.ds-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
.ds-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 20px; display: flex; flex-direction: column; gap: 10px;
}
.ds-card__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.ds-card__title { font-size: 15px; font-weight: 700; color: var(--ink); }
.ds-card__desc { font-size: 13.5px; line-height: 1.6; color: var(--text-muted); }
.ds-card__meta { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.ds-card__meta b { color: var(--text); font-weight: 600; }
.ds-card__foot { margin-top: auto; padding-top: 12px; border-top: 1px solid var(--slate-100); display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.format-chip {
  display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 5px;
  font-size: 10.5px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
  background: var(--info-bg); color: var(--info); border: 1px solid #c5d7f2;
}
.format-chip--json { background: var(--flagged-bg); color: var(--flagged); border-color: #ddc9fa; }
@media (max-width: 860px) { .ds-grid { grid-template-columns: 1fr; } }

/* ---- Suppression / withheld cells ---- */
.withheld {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px; font-weight: 600; color: var(--text-muted); font-style: italic;
}
.table tr.is-withheld td { background: repeating-linear-gradient(135deg, var(--surface-2) 0 8px, #fbfcfd 8px 16px); }
.table tr.is-withheld:hover td { background: var(--surface-2); }

/* ---- Source note under a published figure ---- */
.source-note {
  display: flex; gap: 10px; align-items: flex-start;
  font-size: 12.5px; line-height: 1.65; color: var(--text-muted);
  border-top: 1px solid var(--border); padding-top: 14px; margin-top: 6px;
}
.source-note svg { flex: none; margin-top: 2px; opacity: .7; }
.source-note b { color: var(--text); font-weight: 600; }

/* ---- Pillars (how it works) ---- */
.pillars { display: grid; gap: 22px; }
.pillar {
  display: grid; grid-template-columns: 68px minmax(0, 1fr) minmax(0, 300px); gap: 26px; align-items: start;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  padding: 26px; box-shadow: var(--shadow);
}
.pillar__num {
  width: 56px; height: 56px; border-radius: 16px;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(150deg, var(--green-100), #f0f9f4); color: var(--green-700);
  border: 1px solid rgba(10,92,57,.16); font-size: 20px; font-weight: 800;
}
.pillar__title { font-size: 19px; font-weight: 800; color: var(--ink); letter-spacing: -.01em; }
.pillar__lede { margin-top: 8px; font-size: 14.5px; line-height: 1.7; color: var(--text-muted); }
.pillar__mech { list-style: none; margin-top: 16px; display: grid; gap: 10px; }
.pillar__mech li { display: flex; gap: 10px; font-size: 13.5px; line-height: 1.6; color: var(--text); }
.pillar__mech li::before { content: "\2192"; color: var(--gold-deep); font-weight: 800; flex: none; }
.pillar__mech b { font-weight: 700; }
.pillar__stat {
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 16px; display: grid; gap: 4px;
}
.pillar__stat-value { font-size: 24px; font-weight: 800; color: var(--green-700); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.pillar__stat-label { font-size: 11.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--text-muted); }
.pillar__stat-note { font-size: 12px; color: var(--text-muted); line-height: 1.55; }
@media (max-width: 900px) {
  .pillar { grid-template-columns: 52px minmax(0, 1fr); }
  .pillar__stat { grid-column: 1 / -1; }
  .pillar__num { width: 46px; height: 46px; font-size: 17px; }
}

/* ---- Verify page ---- */
.verify-form { display: grid; grid-template-columns: 1fr auto; gap: 12px; align-items: end; }
.verify-form input { font-family: var(--mono); font-size: 13px; letter-spacing: .01em; }
@media (max-width: 640px) { .verify-form { grid-template-columns: 1fr; } .verify-form .btn { justify-content: center; } }
.verdict { display: flex; gap: 14px; align-items: flex-start; border-radius: var(--radius); padding: 18px; margin-bottom: 20px; border: 1px solid var(--border); }
.verdict__icon { width: 40px; height: 40px; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; flex: none; }
.verdict__title { font-size: 16px; font-weight: 800; }
.verdict__body { font-size: 13.5px; line-height: 1.65; margin-top: 4px; }
.verdict--match { background: var(--success-bg); border-color: #c7e8d6; color: #0a4a2f; }
.verdict--match .verdict__icon { background: rgba(14,122,75,.14); color: var(--success); }
.verdict--miss { background: var(--warning-bg); border-color: #eedcae; color: #6d4b07; }
.verdict--miss .verdict__icon { background: rgba(148,102,10,.14); color: var(--warning); }
.verdict--error { background: var(--danger-bg); border-color: #f2c8c5; color: #7e1b15; }
.verdict--error .verdict__icon { background: rgba(179,38,30,.12); color: var(--danger); }
.verdict .hash { display: inline-block; margin-top: 8px; }
.proves { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.proves h3 { font-size: 14px; font-weight: 800; color: var(--ink); margin-bottom: 10px; display: flex; align-items: center; gap: 8px; }
.proves ul { list-style: none; display: grid; gap: 10px; }
.proves li { display: flex; gap: 10px; font-size: 13.5px; line-height: 1.6; color: var(--text-muted); }
.proves li::before { content: "\2713"; font-weight: 800; color: var(--success); flex: none; }
.proves--not li::before { content: "\00D7"; color: var(--danger); }
@media (max-width: 760px) { .proves { grid-template-columns: 1fr; gap: 18px; } }

/* ---- Small shared bits ---- */
.zone-chip {
  display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 700; letter-spacing: .04em;
  background: var(--slate-100); color: var(--slate-600); border: 1px solid var(--slate-200);
}
.rank-num { display: inline-block; min-width: 22px; font-size: 12px; font-weight: 700; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.mini-progress { height: 6px; border-radius: 3px; background: var(--slate-100); overflow: hidden; margin-top: 10px; }
.mini-progress i { display: block; height: 100%; border-radius: 3px; background: linear-gradient(90deg, var(--green-600), var(--green-500)); }
.card__title .pill, .card__title .format-chip { text-transform: none; }
.stat-grid--5 { grid-template-columns: repeat(5, 1fr); }
@media (max-width: 1080px) { .stat-grid--5 { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 700px)  { .stat-grid--5 { grid-template-columns: repeat(2, 1fr); } }

/* --------------------------------------------------------------------------
   Print — the public transparency surfaces the ministry hands out on paper:
   /transparency, /datasets and the /verify ledger-proof page. Same contract as
   the console (app.css §16): chrome gone, light palette forced, chips become
   bordered text, and the print_head partial's masthead/footer appear.
   -------------------------------------------------------------------------- */
.print-head, .print-foot { display: none; }

@media print {
  @page { margin: 12mm 12mm 18mm; }

  .seg-switch, .page-hero__actions, .copy-btn, .pubnav__drawer,
  .pubnav, .pubfilters, .filters, .page-actions, .btn, .pager,
  .dropdown, .dropdown__menu, .modal, .modal__backdrop, .modal-overlay,
  .toast, .toast-stack, .grievance, .hero__cta, .no-print {
    display: none !important;
  }
  .print-only { display: block !important; }

  /* The footer's bottom bar is .pubfooter__bottom in the markup. */
  .pubfooter__bottom { color: #333; border-top: 1px solid #bbb; }

  /* Ministry masthead + repeating footer (views/components/print_head.php). */
  .print-head {
    display: block !important; padding: 0 0 12px; margin-bottom: 18px;
    border-bottom: 2px solid #0a5c39;
  }
  .print-head__org {
    font-size: 11.5px; font-weight: 800; letter-spacing: .02em;
    color: #0a5c39; text-transform: uppercase;
  }
  .print-head__platform { font-size: 10.5px; color: #32405a; margin-top: 1px; }
  .print-head__title { font-size: 15px; font-weight: 800; color: #0c1b2a; margin-top: 7px; }
  .print-head__meta { font-size: 10px; color: #64748b; margin-top: 4px; font-variant-numeric: tabular-nums; }
  .print-head__chain { font-size: 9px; color: #32405a; margin-top: 3px; word-break: break-all; }
  .print-foot {
    display: block !important;
    position: fixed; left: 0; right: 0; bottom: 0;
    background: #fff; border-top: 1px solid #c9d3df;
    padding: 3px 0 0; font-size: 8.5px; line-height: 1.45; color: #64748b;
  }
  .print-foot__line, .print-foot__chain { display: block; }
  .print-foot__chain { word-break: break-all; }

  /* Cards flatten to a 1px outline and never split across a sheet. */
  .card, .stat-card, .tp-counters, .kpi-card, .ds-card, .pillar,
  .counter-card__inner, .step, .prog-card {
    box-shadow: none !important; border: 1px solid #bbb;
  }
  .card, .stat-card, .tp-counters, .kpi-card, .ds-card, .pillar,
  .counter-card__inner, .step, .prog-card, tr {
    page-break-inside: avoid; break-inside: avoid;
  }

  /* Chips become bordered text — colour may not survive a mono printer. */
  .pill, .vbadge, .tag, .chip, .hash-chip, .format-chip, .kpi-badge {
    background: #fff !important; background-image: none !important;
    color: #111 !important; border: 1px solid #93a1b4 !important;
    border-radius: 3px !important; box-shadow: none !important;
    padding: 1px 5px !important; font-weight: 700;
  }
  .pill::before { display: none !important; }

  /* The state tile map is a data figure: its ramp must survive. */
  .tilemap__tile--h0, .tilemap__tile--h1, .tilemap__tile--h2,
  .tilemap__tile--h3, .tilemap__tile--h4, .tilemap__tile--h5, svg {
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }

  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ==========================================================================
   PART 3 — responsive hardening (375 / 768 / 1024). Appended, never edited
   above. The public surface is deliberately light-only (site.php declares
   <meta name="color-scheme" content="light"> and there is no theme toggle
   on it), so nothing here is theme-conditional — only width-conditional.
   ========================================================================== */

/* The body must never scroll horizontally. The hero and the ink bands are
   full-bleed with absolutely-positioned texture layers; a single overflow
   guard on the root stops any of them from widening the document.
   `clip`, not `hidden`: overflow-x:hidden turns the body into a scroll
   container and .pubnav (position: sticky) would stop sticking. */
html, body { max-width: 100%; overflow-x: clip; }

/* Any px grid minimum floored at the container width. */
.stat-grid, .stat-grid--5, .kpi-grid, .prog-grid, .ds-grid,
.tp-counters, .proves, .counter-card__inner, .integrity-strip { min-width: 0; }
.stat-grid > *, .stat-grid--5 > *, .kpi-grid > *, .prog-grid > *,
.ds-grid > *, .tp-counters > *, .counter-card__inner > * { min-width: 0; }

@media (max-width: 768px) {
  /* Tablet — the two-up marketing splits are already 1fr at 900; this is
     the row furniture that still tried to sit inline. */
  .section__head { flex-wrap: wrap; }
  .pubfilters { flex-wrap: wrap; }
  .hash-line { row-gap: 6px; }
}

@media (max-width: 460px) {
  /* 375px reference device. */
  .stat-grid--5 { grid-template-columns: 1fr; }
  .counter__value { font-size: 26px; }
  .counter { padding: 14px 16px; }
  .counter-card { margin-top: -60px; padding: 0 14px; }
  .hero__inner { padding: 40px 0 104px; }
  .hero__cta { display: grid; }
  .hero__cta .btn { justify-content: center; }
  .wrap, .container { padding-left: 14px; padding-right: 14px; }
  .section { padding: 40px 0; }
  .verdict .hash, .hash { font-size: 11px; }
  /* 8 columns of tiles in ~347px is a 39px tile — the map shrinks with the
     viewport because .tilemap is max-width, not fixed width, and every tile
     is aspect-ratio:1 inside a 1fr track. The value label drops at 480. */
  .tilemap { gap: 2px; }
}

/* ==========================================================================
   PART 4 — device pass (360 / 390 / 414 / 768 / 1024 / 1280), measured in
   headless Chrome under device emulation. Appended, never edited above.

   THE HEADER DEFECT, and why it looked like "misalignment" rather than a
   scrollbar. `.pubnav__inner` is a flex row of brand + links + `.pubnav__cta`.
   Below 900px the links are hidden, but `.pubnav__cta` still carried BOTH
   call-to-action buttons plus the hamburger. Its two `.btn` children are
   `white-space: nowrap`, so they cannot shrink; the only flex item left that
   could give ground was the hamburger, which was squeezed from 34px to 12px
   while its 22px icon spilled out of its own box. Measured intrinsic width of
   the cluster was 260px, putting the header's right edge at 422px — 62px past
   a 360px viewport, 32px past 390, 8px past 414.

   `html, body { overflow-x: clip }` (PART 3) then hid the scrollbar, so the
   page did not scroll sideways; instead mobile Chrome widened the layout
   viewport to the overflowing width (390 → 445 measured), re-evaluating every
   media query at the wrong width. That viewport stretch is what reads on a
   phone as "the header is not aligned": the brand sits off its gutter, the
   buttons are clipped, and the rest of the page is laid out for a viewport
   the device does not have.

   The cure is structural, not cosmetic: the cluster is made unshrinkable and
   is given only as many children as the width can actually hold. Both CTAs
   already exist inside `.pubnav__drawer`, so nothing is lost when the bar
   drops them.
   ========================================================================== */

/* Nothing in the bar may be squeezed below its own intrinsic size. */
.pubnav__inner { min-width: 0; }
.pubnav__brand { flex: 0 1 auto; min-width: 0; }
.pubnav__brand svg, .pubnav__brand img { max-width: 100%; height: auto; }
.pubnav__links { min-width: 0; }
.pubnav__cta { flex: 0 0 auto; margin-left: auto; }
/* flex: none is the load-bearing declaration — it is what stops the hamburger
   absorbing the overflow of its siblings. */
.pubnav__toggle {
  flex: none; width: 44px; height: 44px; padding: 0;
  align-items: center; justify-content: center;
  /* Optical alignment: the button is 44px but its glyph is 22px, so the box
     is pulled out by half the difference. The glyph's right edge then lands
     on the same 14px page gutter the brand's left edge starts from — the
     target stays 44px while the icon looks aligned. */
  margin-right: -11px;
}

@media (max-width: 900px) {
  /* Tablet and below: the secondary CTA lives in the drawer only. */
  .pubnav__inner { gap: 12px; }
  .pubnav__cta { gap: 8px; }
  .pubnav__cta .btn--ghost { display: none; }
}

@media (max-width: 480px) {
  /* Phone: brand + hamburger, the one arrangement that cannot overflow at
     any width down to 320px. The drawer opens with a full-width
     "Report an issue" as its primary action. */
  .pubnav__cta .btn { display: none; }
}

/* ---- Drawer: a real menu, not an overflowing list ---- */
.pubnav__drawer {
  max-height: calc(100dvh - 60px); overflow-y: auto;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  box-shadow: var(--shadow-lg);
}
.pubnav__drawer .pubnav__link {
  display: flex; align-items: center; min-height: 44px;
}
/* The drawer's primary action is separated from navigation so it reads as an
   action rather than a sixth link. */
.pubnav__drawer .btn {
  min-height: 46px; margin-top: 12px;
  border-top: 0; width: 100%;
}
.pubnav__drawer .btn + .btn { margin-top: 8px; }

/* ==========================================================================
   Grid tracks that were floored by a child's intrinsic width
   ========================================================================== */

/* `.pillar__mech` is a grid whose implicit column is `auto`, and an auto track
   is floored at its items' min-content contribution. Each <li> is a flex row
   (marker + <b> + text), whose min-content is the SUM of its parts, so the
   track was pinned near 326px and the list ran out of its own pillar. An
   explicit minmax(0, 1fr) floors the track at zero and lets the copy wrap. */
.pillar__mech { grid-template-columns: minmax(0, 1fr); }
.pillar__mech li { min-width: 0; }
.pillar__mech li > * { min-width: 0; }

/* Same defect class, same cure, for the other intrinsic-width lists. */
.integrity-split__points { grid-template-columns: minmax(0, 1fr); }
.integrity-split__points li { min-width: 0; }
.proves ul { grid-template-columns: minmax(0, 1fr); }
.proves li { min-width: 0; }
.faq { grid-template-columns: minmax(0, 1fr); }

/* ==========================================================================
   Touch targets — applied only where the pointer is actually coarse, so the
   desktop surface keeps its density. WCAG 2.2 AAA target size is 44×44.
   ========================================================================== */
@media (pointer: coarse) {
  /* The public surface has no dense operator tables to protect, so every
     control here clears 44 outright — including the small variants, which on
     these pages are primary citizen actions ("Download CSV", "Copy hash"),
     not row furniture. */
  .btn, .btn--sm { min-height: 44px; }
  .btn--sm { padding-top: 8px; padding-bottom: 8px; }
  .pubfilters select,
  .pubfilters input[type="search"],
  .pubfilters input[type="text"] { min-height: 44px; }
  .pubfilters__reset { min-height: 44px; display: inline-flex; align-items: center; }
  .field input, .field select { min-height: 44px; }
  /* Generic floor for inputs outside .field / .pubfilters. min-height rather
     than height so an inline height in a view is still clamped upward. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="range"]),
  select, textarea { min-height: 44px; }
  .copy-btn { min-height: 44px; padding-left: 14px; padding-right: 14px; }
  .pager a, .pager span { min-width: 44px; height: 44px; }
  .seg-switch a { min-height: 40px; display: inline-flex; align-items: center; }
  .faq summary { min-height: 52px; display: flex; align-items: center; }
  .tabs > a, .tabs > button { min-height: 44px; }
  /* The Nigeria cartogram is deliberately exempt: its 8×7 cell size is
     essential to the map (WCAG 2.2 SC 2.5.8 "Essential"), and a 44px cell
     would need 388px of grid in a 332px page. Cells stay ~40px at 360. */
}

/* ==========================================================================
   Width pass — the surfaces the measurement rig walked page by page
   ========================================================================== */

@media (max-width: 1024px) {
  /* Laptop/tablet: the marketing splits are already single-column at 900;
     these are the wide data figures on /transparency. */
  .ghost-card { gap: 24px; }
  .integrity-strip { gap: 20px; }
}

@media (max-width: 768px) {
  .page-hero__inner { padding: 30px 0 34px; }
  .page-hero__actions .btn { flex: 1 1 auto; justify-content: center; }
  .card__header { align-items: flex-start; }
  /* A two-line card title plus a chip cluster must not fight for one row. */
  .card__header > .btn, .card__header > .seg-switch { flex: 0 0 auto; }
}

@media (max-width: 560px) {
  .hero__eyebrow { font-size: 11px; letter-spacing: .1em; }
  .trust-strip__inner { gap: 14px 24px; }
  .grievance__inner { padding: 36px 0; }
  .grievance__actions { width: 100%; }
  .grievance__actions .btn { flex: 1 1 auto; justify-content: center; }
  .page-hero__meta { gap: 10px; }
  .verdict { flex-direction: column; gap: 10px; }
  .card__footer { flex-direction: column; align-items: stretch; }
  .flex-between { align-items: flex-start; }
  /* A 64-hex head hash and its copy button share the width rather than
     pushing the ink band sideways. */
  .hash-line { width: 100%; }
  .hash-line .hash { flex: 1 1 100%; overflow-wrap: anywhere; }
}

@media (max-width: 400px) {
  .counter__label { font-size: 11px; letter-spacing: .04em; }
  .prog-card, .step { padding: 20px 16px; }
  /* One override; the header, the body and the table all follow it. */
  :root { --card-gutter: 16px; }
  .empty-state { padding: 40px 16px; }
  .ds-card, .kpi-card, .pillar { padding: 18px 16px; }
  /* Inner columns tighten, outer columns keep the card gutter so the
     first column still starts under the title. */
  .table th, .table td { padding-left: 12px; padding-right: 12px; }
  .table th:first-child, .table td:first-child { padding-left: var(--card-gutter); }
  .table th:last-child, .table td:last-child { padding-right: var(--card-gutter); }
}

/* Safe-area gutters so a notched handset in landscape never clips the page.
   The three tiers mirror the existing 24 / 18 / 14 ladder exactly — the only
   change is the floor, never the value. */
@supports (padding: max(0px)) {
  .wrap, .container {
    padding-left: max(24px, env(safe-area-inset-left));
    padding-right: max(24px, env(safe-area-inset-right));
  }
  @media (max-width: 560px) {
    .wrap, .container {
      padding-left: max(18px, env(safe-area-inset-left));
      padding-right: max(18px, env(safe-area-inset-right));
    }
  }
  @media (max-width: 460px) {
    .wrap, .container {
      padding-left: max(14px, env(safe-area-inset-left));
      padding-right: max(14px, env(safe-area-inset-right));
    }
  }
}

/* --------------------------------------------------------------------------
   Error pages (404 / 403 / 419 / 500)
   These carried no styling at all, so a "page not found" rendered as bare
   left-aligned text jammed under the header — which is what an operator
   reads as the page being broken rather than the record being missing.
   -------------------------------------------------------------------------- */
.error-page {
  max-width: 520px; margin: 0 auto; padding: 64px 20px 88px; text-align: center;
}
.error-page__code {
  display: inline-block; font-size: 11.5px; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--text-faint);
  border: 1px solid var(--border); border-radius: 999px; padding: 4px 12px;
}
.error-page h1 {
  font-size: 28px; line-height: 1.2; letter-spacing: -.02em;
  margin: 18px 0 10px; color: var(--text);
}
.error-page p {
  color: var(--text-muted); line-height: 1.65; font-size: 14.5px; margin: 0 auto 24px;
}
.error-page .btn { display: inline-flex; }

@media (max-width: 560px) {
  .error-page { padding: 44px 16px 64px; }
  .error-page h1 { font-size: 23px; }
}
