/* GiveScore — production stylesheet.  Identity: "STANDARD SEAL".
   ---------------------------------------------------------------------------
   The argument this design makes: GiveScore behaves like a standards body. It
   issues a mark against a published standard, so the page is built out of hard
   civic-blue fields, a struck gold seal as the score, and shared-edge cells
   instead of floating cards. Nothing is rounded except the seal — which is what
   makes the seal mean anything.

   EVERYTHING a future change needs is a custom property below. Colour and type
   are declared once in :root (and once more, token-for-token, in the dark
   block); no component invents its own hex. That is deliberate: it is what lets
   an unrelated feature — the hero tax estimator — inherit this identity without
   knowing it exists.

   Radius is a token too (--r / --r-sm are 0). The ONE exception is --r-seal.  */
:root{
  /* --- ground & paper --- */
  --paper:#FFFFFF; --surface:#FFFFFF; --surface-2:#F2F6F9; --sunken:#F2F6F9;
  --tint:#E6EDF2;
  /* --- ink --- */
  --ink:#0F1A22; --ink-2:#3B4C58; --muted:#576976; --faint:#5F707C;
  --hairline:#DCE5EC; --hairline-2:#CBD8E1;
  /* --- the civic field: the colour the institution speaks in --- */
  --brand:#0A3A5A; --brand-ink:#07293F; --brand-soft:#E6EDF2; --brand-mute:#17587F;
  /* The ink that goes ON --brand-soft. Its own token because --brand-ink cannot
     do this job in both themes: --brand-ink is also the DEEPEST brand fill (the
     footer, a button hover), so it has to stay dark, while --brand-soft is a
     light tint on paper and a DARK panel on a dark page. Pairing the two
     directly measured 1.15:1 on the dark theme - invisible text. */
  --on-brand-soft:#07293F;
  /* Text ON the civic field. Named, because "white" is not the only value:
     secondary copy on a deep field needs to step down without going grey-mud. */
  --on-field:#FFFFFF; --on-field-2:#C6D8E5; --on-field-3:#9FBBCD;
  --field-rule:rgba(255,255,255,.18);
  /* --- the seal --- */
  --seal:#E0A21A;        /* the struck mark: gold, only ever on a dark field or as a rule */
  --brass:#8A5E12;       /* the same gold as TEXT on paper — 5.7:1, which #E0A21A is not */
  --brass-soft:#FBF1DA;
  /* --- verdict bands, split three ways because one hex cannot do three jobs:
         *       plain  = graphic only (the seal's arc, the component bars)
         *       -text  = the same verdict as a NUMERAL or word on the page ground
         *       -fill  = a filled chip/swatch, paired with --on-fill for its ink
         Measured with tools/contrast-audit.py, not chosen by eye. --- */
  --good:#2E7A55; --good-soft:#E3F0EA; --good-text:#2E7A55; --good-fill:#2E7A55;
  --warn:#B5791A; --warn-soft:#F7EED9; --warn-text:#9A6614; --warn-fill:#9A6614;
  --crit:#B03A2A; --crit-soft:#F8E4E0; --crit-text:#B03A2A; --crit-fill:#B03A2A;
  --mut-fill:#576976;
  /* The ink a filled band carries. On paper that is white; on a dark page the
     fills brighten and this flips to near-black, which is why it is a token. */
  --on-fill:#FFFFFF;
  --seg-mission:#2E7A55; --seg-officer:#B03A2A; --seg-staff:#B5791A; --seg-other:#8496A3;
  /* The ground a charity's LOGO sits on in the drawer. Light in BOTH themes: logos are
     drawn for white paper, and dark ink on a dark panel would vanish. */
  --logo-panel:#F2F6F9;
  /* A standards body does not float. Depth comes from rules and fields, so the
     shadow tokens resolve to nothing — kept as tokens so components (and the
     tax estimator, which asks for --shadow-lift) stay declarative. */
  --shadow:none;
  --shadow-lift:none;
  --r:0; --r-sm:0; --r-seal:50%;
  /* One family, four weights. A standards body speaks in one voice; the jump
     from 400 to 900 IS the hierarchy. --serif is kept as a token, and kept
     pointing at the same stack, so every rule that asked for a display face
     still resolves — there is simply no second voice any more. */
  --sans:"Schibsted Grotesk","Helvetica Neue",Helvetica,Arial,sans-serif;
  --serif:"Schibsted Grotesk","Helvetica Neue",Helvetica,Arial,sans-serif;
}

/* DARK — FOLLOWS THE BROWSER (owner, 2026-09-23, reversing the earlier "light unless
   you click Dark" rule). app/static/theme.js reads prefers-color-scheme and stamps
   `data-theme` on the root; this block applies when it says dark. The palette lives HERE
   ONCE — a media-query copy would be a second definition of every colour token.

   Every token above is redefined here; none is introduced. The civic field lightens so
   it still separates from the page instead of vanishing into it, and the seal brightens. */
:root[data-theme="dark"]{
  --paper:#0C1419; --surface:#121C24; --surface-2:#16212A; --sunken:#16212A;
  --tint:#16242F;
  --ink:#E7EDF2; --ink-2:#BDCAD4; --muted:#93A4B1; --faint:#8A9BA8;
  --hairline:#22303B; --hairline-2:#31414E;
  --brand:#103F60; --brand-ink:#0B3049; --brand-soft:#16242F; --brand-mute:#6FA8CE;
  --on-brand-soft:#C6D8E5;
  --on-field:#FFFFFF; --on-field-2:#C6D8E5; --on-field-3:#9FBBCD;
  --field-rule:rgba(255,255,255,.16);
  --seal:#E9B446; --brass:#E9B446; --brass-soft:#2A2113;
  --good:#49A177; --good-soft:#15291F; --good-text:#49A177; --good-fill:#49A177;
  --warn:#D79B2A; --warn-soft:#2A2113; --warn-text:#D79B2A; --warn-fill:#D79B2A;
  --crit:#E07E6C; --crit-soft:#2C1915; --crit-text:#E07E6C; --crit-fill:#E07E6C;
  --mut-fill:#93A4B1; --on-fill:#0C1419;
  --seg-mission:#49A177; --seg-officer:#E07E6C; --seg-staff:#D79B2A; --seg-other:#71838F;
  --logo-panel:#E4EAEF;
}

*{box-sizing:border-box}
/* color-scheme follows the STAMP, not the OS: it paints the scrollbar, the
   <select>'s own dropdown and the form-control defaults, so leaving it at
   `light dark` would frame a light page in dark browser chrome. */
html{scroll-behavior:smooth;color-scheme:light}
:root[data-theme="dark"]{color-scheme:dark}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--sans);font-size:15px;line-height:1.55;
  -webkit-font-smoothing:antialiased;font-variant-numeric:proportional-nums}
img{max-width:100%}
[hidden]{display:none!important}
/* Schibsted Grotesk's tabular figures make the COMMA digit-width too, which
   renders "583 , 558". Big display figures therefore stay proportional; only
   columns that must align vertically ask for tabular. */
.num{font-variant-numeric:proportional-nums;font-feature-settings:normal}
h1,h2,h3{font-family:var(--serif);font-weight:900;text-wrap:balance;margin:0;
  line-height:1.08;letter-spacing:-.032em;color:var(--ink)}
p{margin:0}
a{color:var(--brand-mute);text-decoration:none;text-underline-offset:3px}
a:hover{text-decoration:underline}
button{font-family:inherit}
:focus-visible{outline:3px solid var(--brand-mute);outline-offset:2px;border-radius:0}
/* On a civic field the brand-blue focus ring is invisible. The seal is the only
   thing guaranteed to read against it. */
.topbar :focus-visible,.hero :focus-visible,.foot :focus-visible{outline-color:var(--seal)}
.wrap{max-width:1160px;margin:0 auto;padding-inline:26px}
.eyebrow{font-size:11px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--brass)}

/* ---------- top bar: the institution's nameplate ---------- */
.topbar{position:sticky;top:0;z-index:40;background:var(--brand);border-bottom:1px solid var(--brand-ink)}
.topbar .row{display:flex;align-items:center;gap:12px 18px;padding-block:12px;flex-wrap:wrap}
.brand{display:flex;align-items:center;gap:0;color:var(--on-field);flex:none}
.brand b{font-family:var(--serif);font-size:19px;font-weight:900;letter-spacing:-.03em;text-transform:uppercase}
.brand b i{color:var(--seal);font-style:normal}
.navlinks{display:flex;gap:24px;margin-left:14px}
.navlinks a{font-size:13.5px;font-weight:500;color:var(--on-field-2)}
.navlinks a:hover{color:var(--seal);text-decoration:none}
.topbar .sp{flex:1}
.tsearch{display:flex;align-items:center;gap:9px;background:var(--surface);
  border:1px solid var(--surface);border-radius:0;padding:9px 14px;width:min(380px,42vw)}
.tsearch:focus-within{border-color:var(--seal);box-shadow:inset 0 0 0 2px var(--seal)}
.tsearch svg{color:var(--muted);flex:none}
.tsearch input{border:0;background:transparent;color:var(--ink);font-size:14px;width:100%;outline:none;font-family:inherit}
/* A visible submit (owner, 2026-09-23: "there's no submit button"). Enter works too. */
.tsearch-go{flex:none;border:0;background:var(--seal);color:var(--brand-ink);font:inherit;font-size:12px;
  font-weight:800;letter-spacing:.06em;text-transform:uppercase;padding:7px 12px;margin-right:-6px;cursor:pointer}
.tsearch-go:hover{filter:brightness(1.06)}
.pill{display:inline-flex;align-items:center;gap:7px;font-size:11.5px;font-weight:600;color:var(--on-field-2);
  border:1px solid var(--field-rule);background:transparent;border-radius:0;padding:6px 11px;white-space:nowrap;flex:none}
.pill .dot{width:7px;height:7px;border-radius:var(--r-seal);background:var(--seal)}
.pill.off .dot{background:var(--crit)}
/* The seal control. It reuses the research view-toggle WHOLESALE - same two
   segments, same aria-pressed contract - rather than inventing a switch shape,
   because a standards body that already has one toggle should not grow a second
   vocabulary for its second one. Only the colours change, to sit on the field:
   the pressed segment takes the seal gold, which is the same signal the page uses
   everywhere else for "this is the mark". State is carried by aria-pressed alone,
   so nothing here is ever `hidden` and there is no author `display` rule for the
   UA's [hidden] to lose to. */

/* ---------- hero: one hard field, asymmetric, claim + lookup ----------
   Zero photographs above the fold, which is what give.org measurably does: the
   page's first offer is a lookup, the way a reference source behaves.
   The right-hand column is left free ON PURPOSE — see `:has(.taxcalc)` below. */
.hero{position:relative;background:var(--brand);border-bottom:6px solid var(--seal)}
/* The field's ink is scoped to the COPY column, not to .hero. Putting it on .hero
   looks equivalent and is not: anything else dropped into this section inherits
   white, and a white panel (the tax estimator) then renders white text on white.
   That is not hypothetical - it measured 1:1 on three rows of the estimator's
   breakdown before this line moved. A panel in the other column keeps the page's
   own ink, which is what a panel should do. */
.hero .herocopy{color:var(--on-field)}
.hero .in{max-width:none;margin-inline:auto;text-align:left;padding-block:clamp(34px,5vw,56px);
  display:grid;gap:40px;grid-template-columns:minmax(0,1fr);align-items:center}
.hero .kick{display:inline-block;font-size:11px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--brand-ink);background:var(--seal);border:0;border-radius:0;padding:5px 10px;margin-bottom:18px}
.hero h1{font-size:clamp(32px,5.2vw,54px);line-height:1.03;letter-spacing:-.035em;font-weight:900;
  color:var(--on-field);max-width:15ch;margin-inline:0}
.hero h1 em{font-style:normal;color:var(--seal);font-weight:900}
.hero .lede{font-size:clamp(15.5px,1.5vw,17.5px);color:var(--on-field-2);max-width:52ch;
  margin:16px 0 0;line-height:1.58}
.hero .lede strong{color:var(--on-field);font-weight:700}
.bigsearch{margin:26px 0 0;max-width:620px;display:flex;gap:0;flex-wrap:wrap;justify-content:flex-start}
.bigsearch .box{flex:1;min-width:230px;display:flex;align-items:center;gap:11px;background:var(--surface);
  border:0;border-radius:0;padding:14px 16px;box-shadow:none}
.bigsearch .box:focus-within{box-shadow:inset 0 0 0 2px var(--seal)}
.bigsearch input{border:0;background:transparent;color:var(--ink);font-size:16px;width:100%;outline:none;font-family:inherit}
.bigsearch svg{color:var(--brand);flex:none}
.bigsearch .btn{background:var(--seal);color:var(--brand-ink);border-color:var(--seal);
  font-size:13px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;padding:0 22px}
.bigsearch .btn:hover{background:var(--on-field);border-color:var(--on-field);color:var(--brand-ink)}
.btn{cursor:pointer;border-radius:0;border:1px solid transparent;font-size:14.5px;font-weight:700;padding:14px 22px;
  background:var(--brand);color:#fff;display:inline-flex;align-items:center;gap:8px;white-space:nowrap;letter-spacing:.01em}
.btn:hover{background:var(--brand-ink);text-decoration:none}
.btn.ghost{background:var(--surface);color:var(--ink);border-color:var(--hairline-2)}
.btn.ghost:hover{border-color:var(--brand);color:var(--brand-mute);background:var(--surface)}
.btn.sm{padding:10px 15px;font-size:13.5px;font-weight:700}
.btn:disabled{opacity:.4;cursor:not-allowed}
/* The three headline figures, ruled like a register rather than centred. */
.trustrow{display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));gap:0;
  margin-top:30px;padding-top:20px;border-top:1px solid var(--field-rule)}
.trustrow .stat + .stat{border-left:1px solid var(--field-rule);padding-left:22px}
.trustrow .stat b{font-family:var(--serif);font-size:26px;font-weight:900;display:block;line-height:1.1;
  letter-spacing:-.03em;color:var(--on-field)}
.trustrow .stat span{font-size:12px;color:var(--on-field-3);display:block;margin-top:6px;font-weight:500}

/* WHAT SITS IN THE HERO'S SECOND COLUMN — CHANGED 2026-09-18.
   It used to be the tax estimator, which measured 34% of a 1440x1000 fold and
   made a tax form the first thing a donor met. Ron: "Giving should be the
   priority... the widget should not be front and center." The column now holds the
   rotating photograph; the register of figures sits under the claim, and the
   estimator is a closed strip across the foot of the same grid. */
@media (min-width:1041px){
  .hero .in:has(.heroshot){grid-template-columns:minmax(0,1.04fr) minmax(400px,.96fr)}
}
/* THE INK, RE-SCOPED. .hero's white text is scoped to the copy column and not to
   .hero on purpose (see above) — so the figures block, now a sibling rather than a
   child of .herocopy, has to declare it or the register renders as dark-on-dark. */
.hero .herofoot{color:var(--on-field)}
.hero .herofoot .trustrow{margin-top:26px}

.spot{background:var(--surface);border:1px solid var(--hairline-2);border-radius:0;box-shadow:none;padding:24px;min-height:230px}
.spot .tag{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:18px}
.spot .tag .lab{font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--brass)}
.spot .body{display:flex;gap:20px;align-items:center}
.spot .meta .nm{font-family:var(--serif);font-size:20px;font-weight:700;line-height:1.2;letter-spacing:-.02em}
.spot .meta .loc{font-size:13px;color:var(--muted);margin-top:4px}
.spot .verdict{display:inline-flex;align-items:center;gap:7px;font-size:13px;font-weight:700;margin-top:11px}
.spot .facts{display:flex;margin-top:22px;border-top:1px solid var(--hairline-2);padding-top:16px}
.spot .facts .f{flex:1;padding-right:14px}
.spot .facts .f + .f{border-left:1px solid var(--hairline);padding-left:16px}
.spot .facts .k{font-size:10.5px;color:var(--muted);font-weight:700;letter-spacing:.07em;text-transform:uppercase}
.spot .facts .v{font-family:var(--serif);font-size:19px;font-weight:700;margin-top:3px}
.spot .caption{font-size:11.5px;color:var(--muted);margin-top:16px}
.spot.skeleton{display:grid;place-items:center;color:var(--faint);font-size:13px}

/* ---------- the photo strip in the hero ----------
   The study for this direction called for zero photographs above the fold. These
   five stay, squared off and small, because they are documentary furniture with a
   caption rather than the emotional argument — and because the suite pins them
   (tests/test_photo_assets.py::test_hero_strip_photos_all_exist). Noted as the one
   place this build argues with its own study. */
.avstrip{display:flex;align-items:center;justify-content:flex-start;margin-top:26px;flex-wrap:wrap}
.avstrip .av{width:44px;height:44px;border-radius:0;margin-left:0;border:0;
  box-shadow:none;overflow:hidden;flex:none}
.avstrip .av + .av{margin-left:2px}
.avstrip .av svg{display:block;width:100%;height:100%}
.avstrip .cap{margin-left:16px;font-size:12.5px;color:var(--on-field-3);line-height:1.45;
  max-width:44ch;text-align:left}
.avstrip .cap b{color:var(--on-field);font-weight:700}
.people{background:var(--tint);border-block:1px solid var(--hairline-2)}
.people .in{display:grid;grid-template-columns:1fr 1.02fr;gap:46px;align-items:center;padding-block:48px}
.people .art{position:relative;aspect-ratio:1.3/1;background:var(--hairline);
  border:1px solid var(--hairline-2);box-shadow:none;overflow:hidden}
.people .art svg{position:absolute;inset:0;width:100%;height:100%}
.people .copy .eyebrow{display:block;margin-bottom:12px}
.people .copy h2{font-size:clamp(24px,3vw,33px);letter-spacing:-.03em}
.people .copy > p{color:var(--ink-2);font-size:15.5px;line-height:1.65;margin-top:14px;max-width:52ch}
.evlist{display:flex;flex-direction:column;gap:0;margin-top:24px}
.evlist .ev{display:flex;gap:14px;align-items:flex-start;font-size:14.5px;
  padding:13px 0;border-top:1px solid var(--hairline-2)}
.evlist .ev:last-child{border-bottom:1px solid var(--hairline-2)}
/* Numbered, not ticked. A ✓ bullet is decoration; a numeral is a clause. */
.evlist .ev .ic{width:26px;height:22px;border-radius:0;background:var(--brand);color:var(--on-field);
  display:grid;place-items:center;flex:none;margin-top:2px;font-size:11px;font-weight:700;letter-spacing:.02em}
.evlist .ev b{font-weight:700}.evlist .ev span{color:var(--ink-2)}

/* ---------- section frame ---------- */
section.band{padding-block:44px}
.shead{display:flex;align-items:flex-end;justify-content:space-between;gap:24px;margin-bottom:24px;flex-wrap:wrap;
  border-bottom:3px solid var(--ink);padding-bottom:12px}
.shead .eyebrow{display:block;margin-bottom:9px}
.shead h2{font-size:clamp(23px,3.1vw,31px);letter-spacing:-.03em}
.shead p{color:var(--muted);font-size:14.5px;margin-top:8px;max-width:58ch}
.sechead{display:flex;align-items:flex-end;justify-content:space-between;gap:24px;flex-wrap:wrap;
  border-bottom:3px solid var(--ink);padding-bottom:12px;margin-bottom:6px}
.sechead h2{font-size:clamp(23px,3.1vw,31px);letter-spacing:-.03em;margin-top:8px}
.sechead .lede{color:var(--muted);font-size:14.5px;margin-top:8px;max-width:58ch}
.ghostlink{font-size:13.5px;font-weight:700;color:var(--brand-mute);white-space:nowrap}

/* ---------- banners ---------- */
.alert{border-radius:0;padding:13px 16px;font-size:14px;margin-bottom:20px;border:1px solid var(--hairline-2);
  border-left:4px solid var(--muted);background:var(--surface-2);color:var(--ink-2)}
.alert.warn{background:var(--warn-soft);border-color:var(--hairline-2);border-left-color:var(--warn);color:var(--ink)}
.alert.empty{background:var(--brand-soft);border-color:var(--hairline-2);border-left-color:var(--brand);color:var(--ink)}
.alert code{background:var(--hairline);padding:1px 6px;border-radius:0;font-size:12.5px}
.alert .lnk{all:unset;color:var(--brand-mute);cursor:pointer;text-decoration:underline;font-weight:700}

/* ---------- the standard, stated once ---------- */
.explainer{background:var(--surface);border:1px solid var(--hairline-2);border-radius:0;box-shadow:none;overflow:hidden}
.explainer .top{display:grid;grid-template-columns:1.15fr 1fr}
.explainer .lede{padding:32px 34px;border-right:1px solid var(--hairline-2)}
.explainer .lede h3{font-size:22px;margin-bottom:12px;letter-spacing:-.025em}
.explainer .lede > p{color:var(--ink-2);font-size:14.5px;margin-bottom:20px;line-height:1.62}
.legend{display:flex;flex-direction:column;gap:0}
.legend .lg{display:flex;align-items:center;gap:13px;font-size:14px;padding:9px 0;border-top:1px solid var(--hairline)}
.legend .lg:first-child{border-top:0}
.legend .lg .sw{width:44px;height:24px;border-radius:0;flex:none;display:grid;place-items:center;
  font-size:11px;font-weight:700;color:var(--on-fill);background:var(--mut-fill)}
.legend .lg .sw.good{background:var(--good-fill)}
.legend .lg .sw.warn{background:var(--warn-fill)}
.legend .lg .sw.crit{background:var(--crit-fill)}
.legend .lg b{font-weight:700;white-space:nowrap}.legend .lg span{color:var(--muted)}
/* The specimen seal, on the field it is struck against. Overriding the band
   tokens here (rather than in app.js) keeps the seal drawing logic identical
   everywhere and simply gives it lighter ink where the ground is dark. */
.explainer .ringside{display:grid;place-items:center;padding:34px;background:var(--brand);
  --good:#49A177;--warn:#D79B2A;--crit:#E07E6C;
  --good-text:#49A177;--warn-text:#D79B2A;--crit-text:#E07E6C;
  --hairline-2:rgba(255,255,255,.22);--muted:var(--on-field-3)}
.explainer .ringside #demoRing{display:flex;flex-direction:column;align-items:center;gap:14px}
.sealcap{font-size:10.5px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--on-field-3);text-align:center;line-height:1.7}
.pillars{display:grid;grid-template-columns:repeat(4,1fr);padding:28px 34px;gap:28px;background:var(--sunken);border-top:1px solid var(--hairline-2)}
.pillar .wt{font-family:var(--serif);font-size:25px;font-weight:900;color:var(--brand-mute);letter-spacing:-.03em}
.pillar h4{font-size:14px;margin:4px 0 5px;font-weight:700;font-family:var(--sans);letter-spacing:-.015em}
.pillar p{font-size:12.5px;color:var(--muted);line-height:1.5}
.pillar .track{height:5px;border-radius:0;background:var(--hairline-2);margin-top:12px;overflow:hidden}
.pillar .track i{display:block;height:100%;background:var(--brand-mute);border-radius:0}

/* ---------- the seal ----------
   Drawn in app.js; this only positions the numeral inside it. */
.ring{position:relative;flex:none}
.ring svg{display:block}
.ring .lab{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center}
.ring .lab b{font-family:var(--serif);font-weight:900;line-height:1;letter-spacing:-.035em}
.ring .lab span{font-size:9.5px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;color:var(--muted);margin-top:4px}

/* ---------- the register: shared-edge cells, not floating cards ----------
   Real names here are long, ALL-CAPS and straight off the 990, and the top of
   the board is a wall of identical 99.9s. So the cell is built to survive that:
   the name gets four lines before it is in trouble, and the seal is a constant-
   width mark on the left rather than a number the eye is asked to compare. */
.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:0;
  border:1px solid var(--hairline-2);border-right:0;border-bottom:0}
.grid > p{padding:34px 20px}
.ocard{text-align:left;background:var(--surface);border:0;border-right:1px solid var(--hairline-2);
  border-bottom:1px solid var(--hairline-2);border-radius:0;
  padding:0;cursor:pointer;box-shadow:none;display:flex;flex-direction:column;gap:0;width:100%;
  font-family:inherit;color:inherit;transition:background .12s ease}
.ocard .ocard-cat{width:100%;aspect-ratio:16/9;height:auto;object-fit:contain;object-position:center;
  margin:0;border-radius:0;display:block;background:var(--surface);border-bottom:1px solid var(--hairline);padding:14px 18px}
.ocard .ocard-cat.is-stock{object-fit:cover;padding:0;border-bottom:1px solid var(--hairline-2);
  background:var(--hairline);filter:saturate(.88)}
.ocard:hover{background:var(--tint)}
.ocard .hd{display:flex;gap:14px;align-items:flex-start;padding:16px 18px 0}
.ocard .hd .nm{font-family:var(--serif);font-size:16px;font-weight:700;line-height:1.24;letter-spacing:-.022em}
.ocard .hd .loc{font-size:12px;color:var(--muted);margin-top:4px;font-weight:500}
/* margin-top:auto — the names are 990 legal names, so they run to three lines on
   one card and one on the next. In a shared-edge grid an unaligned rule between
   name and figures is immediately visible as a mistake, so the figures row is
   pinned to the bottom of every cell and the rules line up across the row. */
.ocard .facts{display:flex;gap:12px;padding-top:11px;margin:14px 18px 18px 18px;margin-top:auto;border-top:1px solid var(--hairline-2)}
.ocard .facts .f{flex:1;min-width:0}
.ocard .facts .f .k{font-size:10px;color:var(--muted);font-weight:700;letter-spacing:.07em;text-transform:uppercase}
.ocard .facts .f .v{font-size:16px;font-weight:700;margin-top:4px;font-family:var(--serif);letter-spacing:-.02em}
.chips{display:flex;gap:5px;flex-wrap:wrap}
/* Filled rectangles, white ink. Each band colour here is the *-ink variant, the
   one measured to clear 4.5:1 against white at this size. */
.chip{font-size:11px;font-weight:700;padding:3px 8px;border-radius:0;border:0;
  color:var(--on-fill);background:var(--mut-fill);white-space:nowrap;display:inline-flex;gap:5px;align-items:center;letter-spacing:.01em}
.chip.good{background:var(--good-fill)}
.chip.warn{background:var(--warn-fill)}
.chip.crit{background:var(--crit-fill)}
.chip.mut{background:var(--mut-fill)}

/* ---------- research controls ---------- */
.controls{display:flex;gap:12px;flex-wrap:wrap;align-items:flex-end;margin-bottom:0;
  background:var(--sunken);border:1px solid var(--hairline-2);border-radius:0;padding:14px 16px;box-shadow:none}
.controls .fld{display:flex;flex-direction:column;gap:4px}
.controls label{font-size:10px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}
.controls select,.controls .fld input{border:1px solid var(--hairline-2);background:var(--surface);color:var(--ink);
  border-radius:0;padding:9px 12px;font-size:14px;font-family:inherit;font-weight:500}
.controls select:focus,.controls .fld input:focus{outline:none;border-color:var(--brand);box-shadow:inset 0 0 0 1px var(--brand)}
.controls .searchmini{flex:1;min-width:190px}
.controls .spacer{flex:1}
.toggle{display:inline-flex;background:var(--surface);border:1px solid var(--hairline-2);border-radius:0;padding:0}
.toggle button{border:0;background:transparent;color:var(--muted);font-size:13px;font-weight:700;padding:8px 14px;border-radius:0;cursor:pointer;display:flex;gap:6px;align-items:center}
.toggle button[aria-pressed="true"]{background:var(--brand);color:#fff;box-shadow:none}
.switch{display:inline-flex;align-items:center;gap:9px;font-size:13px;font-weight:700;color:var(--ink-2);cursor:pointer;user-select:none}
.switch input{position:absolute;opacity:0;pointer-events:none}
.switch .sl{width:38px;height:20px;border-radius:0;background:var(--hairline-2);position:relative;transition:background .15s;flex:none}
.switch .sl::after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:0;background:var(--surface);transition:transform .15s}
.switch input:checked + .sl{background:var(--brand)}
.switch input:checked + .sl::after{transform:translateX(18px)}
.switch input:focus-visible + .sl{outline:3px solid var(--brand-mute);outline-offset:2px}
.resultmeta{font-size:13px;color:var(--muted);margin:14px 2px 14px;font-weight:500}
.pager{display:flex;align-items:center;justify-content:center;gap:16px;margin-top:24px}
.pager .info{font-size:13px;color:var(--muted)}

/* ---------- analyst table ---------- */
.tablewrap{overflow-x:auto;background:var(--surface);border:1px solid var(--hairline-2);border-radius:0;box-shadow:none}
table{border-collapse:collapse;width:100%;min-width:860px;font-size:13.5px;font-variant-numeric:tabular-nums}
thead th{text-align:right;font-size:10.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--muted);
  padding:13px 15px;border-bottom:2px solid var(--ink);cursor:pointer;white-space:nowrap;background:var(--tint)}
thead th:first-child{text-align:left}
thead th .ar{color:var(--brand-mute);font-size:10px;margin-left:3px}
tbody td{padding:12px 15px;border-bottom:1px solid var(--hairline);text-align:right;white-space:nowrap}
tbody td:first-child{text-align:left;white-space:normal}
tbody tr{cursor:pointer}tbody tr:hover{background:var(--tint)}
tbody tr:last-child td{border-bottom:0}
.org b{font-weight:700;font-family:var(--serif);font-size:14.5px;letter-spacing:-.02em}
.org .loc{font-size:12px;color:var(--muted)}
.scpill{display:inline-grid;place-items:center;width:38px;height:28px;border-radius:0;font-weight:900;color:#fff;font-size:14px;letter-spacing:-.02em}

/* ---------- detail drawer ---------- */
.scrim{position:fixed;inset:0;background:rgba(7,25,38,.55);opacity:0;pointer-events:none;transition:opacity .2s;z-index:60}
.scrim.on{opacity:1;pointer-events:auto}
.drawer{position:fixed;top:0;right:0;bottom:0;width:min(580px,95vw);background:var(--surface);z-index:70;
  transform:translateX(102%);transition:transform .26s cubic-bezier(.4,0,.2,1);box-shadow:none;
  overflow-y:auto;border-left:4px solid var(--brand)}
.drawer.on{transform:none}
.dh{position:sticky;top:0;background:var(--surface);
  display:flex;gap:12px;align-items:flex-start;padding:20px 22px;border-bottom:2px solid var(--ink);z-index:2}
.dh h3{font-size:20px;line-height:1.16;letter-spacing:-.028em}
.dh .loc{font-size:12.5px;color:var(--muted);margin-top:5px}
.dbody{padding:22px}
.scoreblock{display:flex;gap:20px;align-items:center;padding:18px;border-radius:0;background:var(--tint);border:1px solid var(--hairline-2);margin-bottom:4px}
.scoreblock .verdict{font-family:var(--serif);font-size:19px;font-weight:900;letter-spacing:-.025em}
.scoreblock p{font-size:12.5px;color:var(--muted);margin-top:5px;line-height:1.5}
.comp{display:flex;flex-direction:column;gap:11px;margin:20px 0}
.comp .row{display:grid;grid-template-columns:128px 1fr 32px;align-items:center;gap:13px;font-size:13px}
.comp .row .bar{height:9px;border-radius:0;background:var(--hairline-2);overflow:hidden}
.comp .row .bar i{display:block;height:100%;border-radius:0}
.comp .row .n{text-align:right;font-weight:700;color:var(--ink-2);font-variant-numeric:tabular-nums}
.subhead{font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);
  margin:24px 0 11px;padding-bottom:7px;border-bottom:1px solid var(--hairline-2)}
.kgrid{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--hairline-2);border:1px solid var(--hairline-2);border-radius:0;overflow:hidden}
.kgrid .c{background:var(--surface);padding:12px 14px}
.kgrid .c .k{font-size:10.5px;color:var(--muted);font-weight:700;letter-spacing:.07em;text-transform:uppercase}
.kgrid .c .v{font-size:17px;font-weight:700;margin-top:4px;font-family:var(--serif);letter-spacing:-.025em}
.alloc{display:flex;height:30px;border-radius:0;overflow:hidden;gap:0;background:var(--surface);border:1px solid var(--hairline-2)}
.alloc i{display:block;height:100%}
.alloclegend{display:flex;flex-direction:column;gap:0;margin-top:12px}
.alloclegend .lg{display:flex;align-items:center;gap:9px;font-size:13px;padding:7px 0;border-top:1px solid var(--hairline)}
.alloclegend .dot{width:12px;height:12px;border-radius:0;flex:none}
.alloclegend .lg .amt{margin-left:auto;font-weight:700}
.sparks{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--hairline-2);border:1px solid var(--hairline-2)}
.spark{background:var(--surface);border:0;border-radius:0;padding:13px}
.spark .k{font-size:10.5px;color:var(--muted);font-weight:700;letter-spacing:.07em;text-transform:uppercase}
.spark .v{font-size:16px;font-weight:700;margin-top:3px;font-family:var(--serif);letter-spacing:-.025em}
.note{font-size:12.7px;color:var(--ink-2);background:var(--tint);border:1px solid var(--hairline-2);
  border-left:4px solid var(--brand);border-radius:0;padding:14px 16px;margin-top:22px;line-height:1.55}
.note b{color:var(--ink)}
.give{display:flex;gap:10px;margin-top:20px;flex-wrap:wrap}

/* ---------- footer: the colophon, back on the field ---------- */
.foot{border-top:0;background:var(--brand-ink);color:var(--on-field-2)}
.foot .in{display:grid;grid-template-columns:1.5fr 1fr 1fr;gap:34px;padding-block:38px}
.foot h4{font-family:var(--sans);font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--seal);margin:0 0 14px}
.foot p{font-size:13.5px;color:var(--on-field-2);line-height:1.6;margin:0 0 11px}
.foot .brand b{color:var(--on-field)}
.foot .fbrand .brand{margin-bottom:14px}
.foot ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:9px;font-size:13.5px;color:var(--on-field-2)}
.foot a{color:var(--on-field)}
.foot a:hover{color:var(--seal)}
.foot .base{border-top:1px solid var(--field-rule);padding-block:18px;font-size:12.5px;color:var(--on-field-3);display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap}

@media (max-width:940px){
  .hero .in{padding-block:32px 36px}
  .navlinks,.tsearch{display:none}
  /* Below 940 the nameplate is brand + seal control + freshness pill. Those three
     overflow 390px on one line, so the row wraps rather than scrolling the page
     sideways - the control must stay reachable, since it is the only way back to
     the light seal once someone has left it. */
  .topbar .sp{flex:1 0 100%;height:0}
    .people .in{grid-template-columns:1fr;gap:34px}
  .explainer .top{grid-template-columns:1fr}
  .explainer .lede{border-right:0;border-bottom:1px solid var(--hairline-2)}
  .pillars{grid-template-columns:repeat(2,1fr)}
  .grid{grid-template-columns:repeat(2,1fr)}
  .foot .in{grid-template-columns:1fr 1fr}
}
@media (max-width:560px){
  .grid{grid-template-columns:1fr}.pillars{grid-template-columns:1fr}
  .kgrid,.sparks,.foot .in{grid-template-columns:1fr}
  .comp .row{grid-template-columns:96px 1fr 30px}
  .spot .facts{flex-wrap:wrap;gap:14px}.spot .facts .f + .f{border-left:0;padding-left:0}
  /* Three figures side by side become three ruled rows; the vertical rule that
     separates them on a wide field would otherwise hang off the wrong edge. */
  .trustrow{grid-template-columns:1fr}
  .trustrow .stat + .stat{border-left:0;border-top:1px solid var(--field-rule);padding-left:0;padding-top:12px;margin-top:12px}
  /* Keeping the label on one line squeezes the description into a sliver, so on a
     phone drop it to its own row, indented under the swatch (44 + gap 13). */
  .legend .lg{flex-wrap:wrap;row-gap:2px}
  .legend .lg span{flex-basis:100%;margin-left:57px}
  .avstrip{flex-wrap:wrap;gap:2px}
  .avstrip .cap{margin-left:0;margin-top:12px;text-align:left;max-width:38ch}
  /* The search field and its button are flush on a wide field; stacked, the
     button needs its own full-width row or it reads as a stray chip. */
  .bigsearch .btn{width:100%;justify-content:center;padding:14px}
  .shead,.sechead{border-bottom-width:2px}
}
/* `*` loses to `html{scroll-behavior:smooth}` on specificity (0,0,0 vs 0,0,1), so
   the old rule here never actually stopped the smooth scroll - measured in
   Chromium under a reduced-motion context, where scroll-behavior still computed
   to `smooth`. Name the element. (app.js also passes behavior:"smooth" to
   scrollIntoView/scrollTo, which overrides CSS outright; that is handled there.) */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *{transition:none!important;animation:none!important}
}


/* Recent-events band */
#events .events-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:0;margin-top:20px;
  border:1px solid var(--hairline-2);border-right:0;border-bottom:0}
.ev-card{background:var(--surface);border:0;border-right:1px solid var(--hairline-2);border-bottom:1px solid var(--hairline-2);
  border-radius:0;padding:0 18px 18px;box-shadow:none;display:flex;flex-direction:column;gap:9px}
.ev-top{display:flex;align-items:center;gap:10px}
.ev-badge{text-transform:uppercase;font-size:10.5px;font-weight:700;letter-spacing:.09em;color:#fff;background:var(--brand);padding:3px 8px}
.ev-loc{font-size:12px;color:var(--muted);font-weight:500}
.ev-title{font-family:var(--serif);font-size:18px;font-weight:700;line-height:1.22;margin:0;letter-spacing:-.025em}
.ev-sum{font-size:13.5px;color:var(--muted);line-height:1.55;margin:0}
.ev-charrow{display:flex;flex-wrap:wrap;gap:8px;margin-top:4px;padding-top:12px;border-top:1px solid var(--hairline-2)}
.ev-char{display:flex;align-items:center;gap:8px;border:1px solid var(--hairline-2);border-radius:0;padding:4px 10px 4px 4px;cursor:pointer;font-size:12.5px;font-weight:700;color:inherit;background:transparent;max-width:100%;font-family:inherit}
.ev-char:hover{border-color:var(--brand);background:var(--tint)}
.ev-cn{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:150px}
.ev-none{font-size:12.5px;color:var(--muted)}
.ev-past{margin-top:22px;border-top:1px solid var(--hairline-2);padding-top:14px}
.ev-past>summary{cursor:pointer;font-weight:700;font-size:14px;list-style-position:inside}
.ev-past>summary:hover{color:var(--brand)}
.ev-past-lede{font-size:13px;color:var(--muted);margin:8px 0 4px}
.ev-past-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:0;margin-top:10px}
.ev-past-row{display:flex;flex-direction:column;gap:8px;padding:14px 18px;background:var(--surface);
  border-right:1px solid var(--hairline-2);border-bottom:1px solid var(--hairline-2)}
.ev-status{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);
  border:1px solid var(--hairline-2);padding:2px 6px}
.ev-status.on{color:var(--brand-mute);border-color:var(--brand-mute)}   /* --brand is unreadable on dark */
.ev-when{font-size:12px;color:var(--muted);margin-left:auto}


/* "What they do" — the charity's own mission text from its 990 */
.mission{background:var(--surface);border:1px solid var(--hairline-2);border-radius:0;padding:14px 16px;margin-top:8px}
.mission p{margin:0 0 8px;font-size:14px;line-height:1.6}
.mission p.prog{color:var(--muted);font-size:13.5px}
.mission .msrc{font-size:11.5px;color:var(--muted);border-top:1px solid var(--hairline);padding-top:8px;margin-top:2px}


/* Hero spotlight: the featured charity's own words + real logo */
.spot .spotmission{margin:10px 0 0;font-size:13.5px;line-height:1.55;color:var(--muted)}
.spot .spotlogo{width:26px;height:26px;object-fit:contain;border-radius:0;background:var(--surface);margin-right:8px;vertical-align:middle}
.spot .spotmission[hidden],.spot .spotlogo[hidden]{display:none!important}


/* "Top stewards near me" */
.shead-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.nearnote{margin:0 0 14px;font-size:13px;line-height:1.5;color:var(--muted)}
.nearnote[hidden]{display:none!important}
.ocard .loc .mi{color:var(--ink);font-variant-numeric:tabular-nums}
.linkish{background:none;border:0;padding:0;font:inherit;color:var(--brand-mute);cursor:pointer;text-decoration:underline}
.linkish:hover{opacity:.8}


/* ── Photography ─────────────────────────────────────────────────────────────
   Real charity work is the subject of this site; clip-art next to real financial
   data read as a placeholder. Under this identity the photographs are squared
   off and slightly desaturated — article furniture, never the argument. */
.people .art{margin:0;border-radius:0;overflow:hidden;background:var(--hairline);aspect-ratio:1000/680}
.people .art img{display:block;width:100%;height:100%;object-fit:cover;filter:saturate(.88)}

/* Hero strip: squared photographs, flush, in place of overlapping circles. */
#avstrip .av{display:inline-block;width:44px;height:44px;border-radius:0;overflow:hidden;
  border:0;background:var(--hairline);vertical-align:middle;margin-right:0}
#avstrip .av img{display:block;width:100%;height:100%;object-fit:cover;filter:saturate(.88)}

/* Event cards lead with a GENERIC photograph chosen by event type — never a picture of
   the event in the headline, so it carries the same disclosure the charity cards do.
   MEASURED 2026-09-23 (red team): it carried none, and this comment said "of the event". */
.ev-card{position:relative}
.ev-card.is-stock::before{
  content:"stock photo";
  position:absolute;top:0;left:0;z-index:1;
  font-size:1pt;line-height:1;font-weight:700;letter-spacing:0;text-transform:uppercase;
  color:#fff;background:rgba(7,25,38,.78);
  padding:0 1px;border-radius:0;pointer-events:none;
}
.ev-card .ev-photo{display:block;width:calc(100% + 36px);height:150px;object-fit:cover;
  margin:0 -18px 12px;border-radius:0;background:var(--hairline);filter:saturate(.88)}
/* NO PHOTO (owner HARD RULE 2026-09-28: no image twice on one view). The server gives each
   generic photo to ONE event per board (store.assign_event_photos); a second hurricane gets
   none. The card then opens on its type header under the seal rule — the same answer as the
   drawer's no-picture header (.dh.is-plate) — never a grey box and never a "stock photo" mark. */
.ev-card.no-photo{padding-top:18px;box-shadow:inset 0 4px 0 var(--seal)}


/* Drawer opens on a photograph rather than a wall of figures. */
.dhero{display:block;width:100%;height:172px;object-fit:cover;background:var(--hairline);filter:saturate(.88)}
/* A charity's own LOGO (store.get_org drawer_image="logo"): contained on a neutral panel,
   never stretched or cropped, never desaturated. */
.dhero.is-logo{object-fit:contain;background:var(--logo-panel);padding:22px 28px;filter:none}
@media (max-width:760px){.dhero{height:132px}}


/* ── composing with the hero tax estimator (PR #53) ─────────────────────────
   That feature ships its own fenced CSS block and inherits this identity through
   the tokens, which is how it should be. ONE interaction needs a shim, and it is
   a consequence of the typeface this direction chose rather than of anything the
   estimator did: Schibsted Grotesk's TABULAR figures make the comma and the full
   stop digit-width too, so `font-variant-numeric:tabular-nums` on the money
   inputs renders "85,000" as "85 , 000". Measured in Chromium on the merged
   tree, not predicted. The selector is deliberately one class more specific than
   the estimator's own, so this holds regardless of which block the build emits
   last; it is inert on a tree where the estimator is absent. */
.taxcalc .tc-money input{font-variant-numeric:proportional-nums}
/* The estimator's "your next $1,000" strip is --brand-ink on --brand-soft, which
   was a sound pairing when this site had only a light theme. On the dark theme it
   measured 1.15:1 - the text is simply not there. Repaired with the pairing token
   above rather than by weakening --brand-ink, which the footer and button hovers
   still need dark. Found by rendering the merged tree in a dark context. */
.taxcalc .tc-next span,.taxcalc .tc-next b{color:var(--on-brand-soft)}

/* ── "stock photo" marking ───────────────────────────────────────────────────
   A generic photograph next to a named charity reads as a picture OF that charity.
   It is not: it is illustrative stock, chosen by category. Say so, quietly, wherever
   one is shown — the charity's OWN picture is never marked. */
.ocard{position:relative}
.ocard:has(.ocard-cat.is-stock)::before{
  content:"stock photo";
  position:absolute;top:0;left:0;z-index:1;
  font-size:1pt;line-height:1;font-weight:700;letter-spacing:0;text-transform:uppercase;
  color:#fff;background:rgba(7,25,38,.78);
  padding:0 1px;border-radius:0;pointer-events:none;
}
.dherowrap{position:relative;margin:0}
.dherowrap.is-stock::after{
  content:"stock photo";
  position:absolute;right:0;bottom:0;
  font-size:1pt;line-height:1;font-weight:600;color:#fff;background:rgba(7,25,38,.78);
  padding:0 1px;border-radius:0;pointer-events:none;
}


/* GS-HEROSHOT-CSS-START — the rotating front-page photograph ─────────────────
   Ron, 2026-09-18: "the 'give where the money reaches the mission' should rotate
   amongst the best charity centered stock image. That way the immediate look and
   feel helps make people feel empathetic."

   FIVE THINGS THIS HAS TO GET RIGHT, and how each is done:

   NO LAYOUT SHIFT. The plate's height is not its own: `align-self:stretch` takes
   it from the copy column beside it, and every frame is absolutely stacked inside
   it. Swapping, adding or removing a photograph cannot move a pixel of the page,
   and there is no aspect-ratio box to reflow when the first image decodes.

   NO FLASH OF THE WRONG THING. Frame 1 carries a real `src` in index.html and
   `data-hs="1"` is in the markup, so the right photograph and the right credit are
   painted by the first stylesheet, before app.js exists. Frames 2-5 carry
   `data-src` and are hydrated after load: five hero JPEGs on first paint would be
   649 KB spent to show one of them.

   THE CREDIT CANNOT DESYNC FROM THE PHOTOGRAPH. These are CC BY images, so the
   wrong name on a frame is an attribution breach, not a cosmetic slip. Since
   2026-09-23 (owner decision) the credit is a HOVER TOOLTIP, not a caption: the
   tooltip is read from the hovered <img>'s own file, and `[data-hs="n"]` gives
   pointer-events to frame n ONLY — so the image answering the hover is always the
   one on screen, never a transparent frame stacked above it.

   IT SAYS IT IS STOCK. `.hs-frame.is-stock::before` prints the same "stock photo"
   mark the charity cards use. A photograph on the front page of a site that rates
   charities must never read as one of them.

   REDUCED MOTION. The crossfade is dropped and the rotation never starts under
   `prefers-reduced-motion: reduce`; the dots still work, so the whole set stays
   reachable, just never in motion. */
.heroshot{display:flex;flex-direction:column;align-self:stretch;
  min-height:clamp(300px,34vw,420px);
  margin:0;background:var(--brand-ink);border:0;overflow:hidden}
/* A FLEX COLUMN rather than absolute insets, because the credit line has to be
   allowed to WRAP: a credit cut off at "by US Department of E…" is not an
   attribution. Measured in Chromium at 1440, the longest of the five citations
   needs two lines in a 560px column — so the bar sizes itself and the frame takes
   what is left, and the bar's height is not a number here that a longer title
   could outgrow. */
.hs-frame{position:relative;flex:1 1 auto;min-height:120px;overflow:hidden;background:var(--brand-ink)}
.hs-frame.is-stock::before{
  content:"stock photo";
  position:absolute;top:0;left:0;z-index:2;
  font-size:1pt;line-height:1;font-weight:700;letter-spacing:0;text-transform:uppercase;
  color:#fff;background:rgba(7,25,38,.78);
  padding:0 1px;border-radius:0;pointer-events:none;
}
.hs-slide{position:absolute;inset:0;width:100%;height:100%;max-width:none;object-fit:cover;
  pointer-events:none;opacity:0;filter:saturate(.88);transition:opacity .9s ease}
.hs-bar{flex:none;display:flex;align-items:center;justify-content:space-between;
  gap:14px;padding:8px 10px 9px 12px;background:var(--brand-ink);color:var(--on-field-3);
  font-size:10.5px;line-height:1.45}
/* One grid CELL holding all five citations on top of one another. The cell takes
   the height of the TALLEST, so switching frames never moves the photograph above
   it, and each citation stays in normal inline flow — which matters: `display:flex`
   here made every text node its own flex item and ATE THE SPACES, rendering
   "photograph ·"SAD_Hortons_Kids 113"by US Department". Found in a screenshot,
   not predicted. */
/* ONE attribute selects the visible frame — and makes it the ONLY one that takes the pointer,
   so the hover tooltip always names the photograph you are looking at. */
.heroshot[data-hs="1"] .hs-slide:nth-of-type(1),
.heroshot[data-hs="2"] .hs-slide:nth-of-type(2),
.heroshot[data-hs="3"] .hs-slide:nth-of-type(3),
.heroshot[data-hs="4"] .hs-slide:nth-of-type(4),
.heroshot[data-hs="5"] .hs-slide:nth-of-type(5){opacity:1;pointer-events:auto}
.hs-ctl{display:flex;align-items:center;gap:10px;flex:none}
.hs-dots{display:flex;gap:3px}
.hs-dot{width:16px;height:6px;padding:0;border:0;border-radius:0;cursor:pointer;
  background:var(--field-rule);font-size:0}
.hs-dot:hover{background:var(--on-field-3)}
.heroshot[data-hs="1"] .hs-dot:nth-of-type(1),
.heroshot[data-hs="2"] .hs-dot:nth-of-type(2),
.heroshot[data-hs="3"] .hs-dot:nth-of-type(3),
.heroshot[data-hs="4"] .hs-dot:nth-of-type(4),
.heroshot[data-hs="5"] .hs-dot:nth-of-type(5){background:var(--seal)}
.hs-pause{background:transparent;border:0;padding:2px 0;cursor:pointer;
  color:var(--on-field-3);font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase}
.hs-pause:hover{color:var(--on-field)}
@media (max-width:1040px){
  .heroshot{margin-top:30px;min-height:clamp(230px,52vw,340px)}
}
@media (max-width:560px){
  /* At 390px the credit needs the full width, so the controls drop to their own row
     under it instead of squeezing it. The frame takes a fixed ratio because there is
     no tall copy column beside it any more to take its height from. */
  .heroshot{min-height:0}
  .hs-frame{flex:none;aspect-ratio:4/3}
  .hs-bar{flex-wrap:wrap;align-items:flex-start;padding:8px 12px 10px;gap:7px}
  .hs-ctl{width:100%;justify-content:space-between}
}
@media (prefers-reduced-motion: reduce){
  .hs-slide{transition:none}
}
/* GS-HEROSHOT-CSS-END */

/* GS-NAMEPLATE-CSS-START — the card with no photograph ───────────────────────
   Ron, 2026-09-18: "for the final 10% just abstain from the picture and just use
   the name of the charity."

   THIS IS THE MAJORITY CASE, NOT A PLACEHOLDER. Measured over 93,341 charities
   decided by app/image_match.py: 42,145 matched a photograph, 51,196 abstained —
   so ~57% of the cells in a results grid are this. It is designed as a normal
   state: a struck field with a seal rule, in the identity's own tokens, sized to
   the SAME 16/9 band a photograph would occupy so the shared-edge grid keeps its
   rows aligned whichever a cell gets.

   AND IT DOES NOT SAY THE NAME TWICE. On a plate card the plate IS the title, so
   `.has-plate .hd .nm` is suppressed. That is also why the plate is not
   aria-hidden: it carries the accessible name for the whole card button, and only
   one copy is in the accessibility tree.

   NOT MARKED "stock photo". A plate is not a photograph; labelling it as stock
   would be a false statement about the page's own artwork. */
.ocard .ocard-plate{display:none}
.ocard.has-plate .ocard-cat{display:none}
.ocard.has-plate .ocard-plate{display:flex}
.ocard.has-plate .hd .nm{display:none}
.ocard-plate{width:100%;aspect-ratio:16/9;align-items:center;padding:16px 18px;
  background:var(--brand-soft);color:var(--on-brand-soft);
  border-bottom:3px solid var(--seal);overflow:hidden}
/* SET BIG AND CENTRED, on purpose. The first attempt set the name small along the
   bottom edge of the same 16/9 box and it read exactly like an image that had not
   loaded — the one thing this must not be. Screenshot, then fixed: the name is the
   plate's subject and fills it, so an empty-looking cell means the charity has no
   name, not that the page is broken. */
.ocard-plate span{font-family:var(--serif);font-weight:900;
  font-size:clamp(17px,1.55vw,23px);line-height:1.13;
  letter-spacing:-.03em;text-wrap:balance;
  display:-webkit-box;-webkit-line-clamp:5;-webkit-box-orient:vertical;overflow:hidden}
/* The drawer has nowhere to put a plate — it already prints the name as its <h3>
   right below. So the header itself becomes the field and the name IS the opening;
   app.js omits the photo band entirely in that case. */
.dh.is-plate{background:var(--brand-soft);border-top:4px solid var(--seal)}
.dh.is-plate h3,.dh.is-plate .loc{color:var(--on-brand-soft)}
/* GS-NAMEPLATE-CSS-END */

/* GS-TAXCALC-CSS-START — the donation tax estimator, as a strip under the hero.
   Tokens only; no new palette, no new fonts.

   WHAT CHANGED 2026-09-18 AND WHY. This block used to give the estimator the
   hero's whole right-hand column: a 384px+ white panel, level with the headline,
   MEASURED at 34% of a 1440x1000 fold. Ron: "Why does the front page have the
   calculator so large? It should be smaller and less of the center of attention...
   the calculator can be like a widget that can start small and expand larger." So
   it is now a CLOSED STRIP across the foot of the hero grid — measured again after
   the change, 5% of the same fold — and it opens IN PLACE. The photograph took the
   column.

   The open panel lays the four fields out in ONE ROW on a wide screen instead of
   the old 2x2 in a narrow column: expanding sideways is what keeps a widget from
   turning back into a wall. */
@media (min-width:1041px){
  /* margin-inline:auto — MEASURED 2026-09-23 on a ~1975px window: the hero's 1160px box sat
     pinned LEFT (37px..1384px) while the header and every .wrap band were centred, because
     the base rule above set margin-inline:0 and overrode .wrap's `margin:0 auto`. */
  .hero .in{max-width:1160px;margin-inline:auto;display:grid;
    grid-template-columns:minmax(0,1.03fr) minmax(384px,.97fr);
    grid-template-rows:auto auto auto;
    gap:0 48px;align-items:start;text-align:left;padding-block:52px 56px}
  /* Explicit placement, because the figures block is no longer a child of the copy
     column: claim and figures stack in column 1, the photograph spans both of their
     rows in column 2, and the estimator strip runs under the pair. */
  .hero .in .herocopy{grid-column:1;grid-row:1}
  .hero .in .herofoot{grid-column:1;grid-row:2;align-self:end}
  .hero .in .heroshot{grid-column:2;grid-row:1/3}
  /* A WIDGET, not a strip (owner, 2026-09-23): closed, it is a small card in the copy
     column carrying a live answer; opened, it takes the hero's full width. */
  .hero .in .taxcalc{grid-column:1;grid-row:3;max-width:560px}
  .hero .in .taxcalc[open]{grid-column:1/-1;max-width:none}
  .hero .in .herocopy h1{margin-inline:0;max-width:15ch}
  .hero .in .herocopy .lede{margin-inline:0;max-width:46ch}
  .hero .in .herocopy .bigsearch{margin-inline:0;justify-content:flex-start}
  .hero .in .herofoot .trustrow{justify-content:flex-start;gap:34px}
  .hero .in .herofoot .avstrip{justify-content:flex-start}
}
/* The widget. A small card on the civic field: title, one live line of the estimate, and an
   Expand cue. It stays quiet next to the photograph but is never empty — the closed face
   carries a real answer (tcRender writes #tcGlance from the same estimate the panel shows). */
.taxcalc{margin-top:26px;border:1px solid var(--field-rule);
  background:transparent;border-radius:var(--r);box-shadow:none;text-align:left}
.taxcalc > .tc-open{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px 14px;
  align-items:baseline;padding:13px 16px 14px;cursor:pointer;list-style:none;color:var(--on-field)}
.tc-glance{grid-column:1;grid-row:2;font-size:13.5px;line-height:1.45;color:var(--on-field-2)}
.tc-glance b{font-family:var(--serif);font-size:20px;font-weight:800;letter-spacing:-.02em;
  color:var(--on-field);margin-right:4px}
.tc-open-cue{grid-column:2;grid-row:1/3;align-self:center}
/* Both marker pseudo-elements: WebKit still uses ::-webkit-details-marker and
   would otherwise paint a disclosure triangle inside a flex row. */
.taxcalc > .tc-open::-webkit-details-marker{display:none}
.taxcalc > .tc-open::marker{content:""}
.tc-open-lab{font-size:11px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--seal);flex:none}
.tc-open-cue{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--on-field-2);flex:none;border-bottom:2px solid var(--seal);padding-bottom:2px}
.taxcalc > .tc-open:hover .tc-open-cue{color:var(--on-field)}
.tc-open-cue i{font-style:normal}
.tc-open-hide{display:none}
.taxcalc[open] > .tc-open .tc-open-shut{display:none}
.taxcalc[open] > .tc-open .tc-open-hide{display:inline}
/* The opened panel keeps the page's own ink on its own paper. It must NOT inherit
   the hero's white text — that is the 1:1-contrast bug this stylesheet already
   records for the estimator's old position, and it applies to any panel dropped on
   the civic field. */
.tc-panel{background:var(--surface);border:1px solid var(--hairline-2);color:var(--ink);
  padding:22px 24px 18px;margin-bottom:20px}
.taxcalc .tc-sub{font-size:13.5px;color:var(--ink-2);line-height:1.55;margin:0 0 18px;max-width:78ch}

.tc-form{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.tc-fld.tc-wide{grid-column:1/-1}
/* ORDER MATTERS AND IT BIT ME: this override was first written ABOVE
   `.tc-fld.tc-wide{grid-column:1/-1}`. Same specificity, so the later rule won and
   the strip still rendered 2 fields + 2 full-width rows with two empty cells —
   computed grid-template-columns said 4x254px while the screenshot said otherwise.
   Seen in the screenshot, not in the computed style. */
@media (min-width:860px){
  .tc-form{grid-template-columns:repeat(4,1fr);align-items:start}
  .tc-fld.tc-wide{grid-column:auto}
}
.tc-fld label{display:block;font-size:12.5px;font-weight:600;color:var(--ink-2);margin-bottom:6px}
.tc-opt{font-weight:500;color:var(--faint);font-size:11.5px}
.tc-fld select,.tc-money{width:100%;background:var(--sunken);border:1.5px solid var(--hairline-2);
  border-radius:var(--r-sm);padding:11px 13px;font-size:15px;color:var(--ink);font-family:inherit}
.tc-fld select{appearance:none;cursor:pointer;
  background-image:linear-gradient(45deg,transparent 50%,var(--muted) 50%),linear-gradient(135deg,var(--muted) 50%,transparent 50%);
  background-position:calc(100% - 17px) 50%,calc(100% - 12px) 50%;background-size:5px 5px,5px 5px;
  background-repeat:no-repeat;padding-right:34px}
.tc-money{display:flex;align-items:center;gap:6px}
.tc-money span{color:var(--faint);font-weight:600;flex:none}
.tc-money input{border:0;background:transparent;color:var(--ink);font-size:15px;width:100%;outline:none;
  font-variant-numeric:tabular-nums;font-family:inherit}
.tc-fld select:focus-visible,.tc-money:focus-within{border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-soft);outline:none}
.tc-help{font-size:11.5px;color:var(--muted);line-height:1.5;margin-top:6px}

.tc-out{margin-top:20px;border-top:1px solid var(--hairline);padding-top:18px}
.tc-out.is-idle .tc-idle{font-size:13.5px;color:var(--muted)}
.tc-big{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.tc-big b{font-family:var(--serif);font-size:44px;font-weight:600;line-height:1;letter-spacing:-.03em;color:var(--good)}
.tc-big span{font-size:13px;color:var(--muted);font-weight:500}
/* $0 is a real answer, not an error: it reads plain and grey, never alarming
   red and never dressed up as a win. */
.tc-out.is-zero .tc-big b{color:var(--ink)}
.tc-say{font-size:13.5px;color:var(--ink-2);line-height:1.6;margin-top:11px}
.tc-next{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:16px;
  background:var(--brand-soft);border-radius:var(--r-sm);padding:11px 14px}
.tc-next span{font-size:12.5px;font-weight:600;color:var(--brand-ink)}
.tc-next b{font-size:15px;font-weight:700;color:var(--brand-ink)}
.tc-rows{margin:16px 0 0;display:flex;flex-direction:column;gap:0}
.tc-row{display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  padding:8px 0;border-top:1px solid var(--hairline);font-size:13px}
.tc-row dt{color:var(--ink-2)}
.tc-row dd{margin:0;font-weight:600;white-space:nowrap}
.tc-row.mute dt,.tc-row.mute dd{color:var(--muted);font-weight:500}
.tc-row.strong{border-top-color:var(--hairline-2)}
.tc-row.strong dt{color:var(--ink);font-weight:600}
.tc-row.strong dd{font-size:14.5px}
.tc-note{font-size:11.5px;color:var(--muted);line-height:1.5;margin-top:12px}
.tc-fine{font-size:11.5px;color:var(--muted);line-height:1.6;margin-top:16px;
  border-top:1px solid var(--hairline);padding-top:13px}
.tc-fine b{color:var(--ink-2)}
.tc-year{display:block;margin-top:5px;color:var(--faint)}
@media (max-width:420px){
  .tc-form{grid-template-columns:1fr}
  .tc-panel{padding:18px 16px 14px}
  .tc-glance b{font-size:18px}
  .tc-big b{font-size:38px}
}
/* GS-TAXCALC-CSS-END */
