/* =============================================================================
   Give-Kit theme layer
   -----------------------------------------------------------------------------
   Loaded AFTER vendor/bootstrap.min.css. Bootstrap 5.3 is vendored unmodified so
   upgrading is "replace one file"; everything Give-Kit-specific lives here.

   THE RULE THAT MATTERS (this bug has already bitten this codebase once):
   the complete LIGHT palette is declared on :root. Dark is only ever an
   OVERRIDE of those same tokens under [data-bs-theme="dark"]. A page that
   renders before the theme script runs, or with JavaScript off, therefore gets
   a complete, correct light page — never light text on a white background.
   Every surface sets its background-color explicitly; nothing inherits "none".

   Sections
     1. Brand tokens (light)        5. Public donor pages
     2. Brand tokens (dark)         6. Dashboard shell
     3. Bootstrap re-skin           7. Data display: stats, status, bars
     4. Focus + base                8. Print
   ========================================================================== */

/* -----------------------------------------------------------------------------
   0. Type. Figtree, self-hosted, SIL Open Font License (see fonts/OFL.txt).
      Variable 300–800 in one 20 KB file, so a light display weight and a 600
      label cost one request between them. Propshaft digests and serves it from
      the asset load path; nothing is fetched from a font CDN, which keeps the
      dashboard working on a machine that cannot reach one.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "Figtree";
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url("/assets/figtree-f7c28c58.woff2") format("woff2");
}

/* -----------------------------------------------------------------------------
   1. Brand tokens — LIGHT. The full palette. Dark only overrides these.
   -------------------------------------------------------------------------- */
:root {
  color-scheme: light;

  /* Brand. --gk-brand is the readable-as-text navy; --gk-brand-solid is the
     one that always carries --gk-on-brand text on top of it. In light they are
     the same colour; in dark they deliberately diverge (see §2). */
  --gk-brand:            #1F4E79;   /* 8.3:1 on --gk-bg  */
  --gk-brand-strong:     #163A5A;   /* hover             */
  --gk-brand-stronger:   #102B43;   /* active            */
  --gk-brand-solid:      #1F4E79;   /* button / fill bg  */
  --gk-on-brand:         #FFFFFF;   /* 8.7:1 on solid    */
  --gk-brand-subtle:     #E9F0F7;   /* cool block ground */
  --gk-brand-border:     #C3D6E8;

  /* The warm accent was doing two unrelated jobs under one name: "a human must
     act now" and "this goal has been met". Those are opposite messages, and a
     reader who learns the colour means one will misread the other. They are
     split here so they CAN diverge; they share a hue today because goal-met is
     deliberately coupled to the amber thermometer, and recolouring that is a
     semantic change to the dashboard rather than a palette change.

     --gk-accent stays as the shared hue so nothing downstream breaks. */
  --gk-accent:           #B45309;
  --gk-accent-subtle:    #FDEEDC;
  --gk-accent-border:    #EFC894;

  /* Alarm: forms needed, gifts waiting. The only thing on the overview allowed
     to interrupt, so it keeps a saturated ground rather than becoming a block
     at the same volume as the six tiles that are merely reporting. */
  --gk-alert:            #9C4707;   /* 5.1:1 on --gk-alert-subtle. Darker than
                                      the shared accent because the alert
                                      ground is deliberately the strongest
                                      tint in the palette, and #B45309 only
                                      managed 4.0:1 on it. */
  --gk-alert-subtle:     #FBE3C4;
  --gk-alert-border:     #E0A961;

  /* Celebration: goal met. Same hue, quieter ground — "well done" should not
     shout as loudly as "fix this". */
  --gk-celebrate:        #B45309;
  --gk-celebrate-subtle: #FDF2E3;   /* the shared accent reads 4.5:1 here; the
                                      darker tint I first tried was 4.4:1 */
  --gk-celebrate-border: #EFC894;

  /* Surfaces. White ground AND white cards: the ring is what separates them,
     not a change of tone. The previous arrangement put the page at #FFFFFF and
     a card at #FAFAFA, which reads as a faint grey wash once a screen carries
     eight tiles and two tables — the dashboard is mostly cards, so mostly the
     page was the darker colour.

     With both at white the hairline has to carry the whole job, so --gk-line
     is a little stronger than it was, and the remaining greys are neutral
     rather than warm: a warm tint only reads as warmth next to something
     cooler, and against pure white it reads as dirty. */
  --gk-bg:               #FFFFFF;
  --gk-surface:          #FFFFFF;
  --gk-surface-sunk:     #F5F5F5;
  --gk-line:             #DEDEDE;
  --gk-line-soft:        #ECECEC;
  --gk-ink:              #1F2022;   /* near-black, never pure black */
  --gk-ink-muted:        #55585C;   /* 7.9:1 on --gk-bg */

  /* Progress track and fill. WCAG 1.4.11 wants >=3:1 between them, because the
     bar is a graphical object carrying meaning. Light: 7.0:1. */
  --gk-track:            #E9E9E9;
  --gk-fill:             #1F4E79;

  --gk-focus:            #1F4E79;
  --gk-focus-ring:       rgba(31, 78, 121, 0.35);

  /* Shape. 12px cards, 16px for the largest panels, pills for actions and
     progress, and 8px for form controls — a 12px radius on an input reads as a
     toy. --gk-radius is consumed in 16 places, so the value moves all of them. */
  --gk-radius:           0.75rem;
  --gk-radius-lg:        1rem;
  --gk-radius-control:   0.5rem;
  --gk-radius-pill:      9999px;

  /* A ring, not a lift. Both of these are consumed by exactly one rule each
     (a card and the one lifted surface), so re-pointing the token restyles
     them without touching a component — and an inset ring, unlike a border,
     never moves the box it is added to. */
  --gk-shadow:           inset 0 0 0 1px var(--gk-line);

  /* --- Bootstrap tokens re-pointed at the brand --- */
  --bs-body-bg:                  var(--gk-bg);
  --bs-body-color:               var(--gk-ink);
  --bs-emphasis-color:           var(--gk-ink);
  --bs-secondary-color:          var(--gk-ink-muted);
  --bs-border-color:             var(--gk-line);
  --bs-border-color-translucent: var(--gk-line);
  --bs-tertiary-bg:              var(--gk-surface-sunk);
  --bs-secondary-bg:             var(--gk-surface-sunk);
  --bs-heading-color:            var(--gk-ink);

  --bs-primary:              #1F4E79;
  --bs-primary-rgb:          31, 78, 121;
  --bs-primary-text-emphasis:#102B43;
  --bs-primary-bg-subtle:    #E7EFF7;
  --bs-primary-border-subtle:#B9CFE4;

  --bs-link-color:           var(--gk-brand);
  --bs-link-color-rgb:       31, 78, 121;
  --bs-link-hover-color:     var(--gk-brand-strong);
  --bs-link-hover-color-rgb: 22, 58, 90;

  --bs-focus-ring-color:     var(--gk-focus-ring);
  --bs-border-radius:        var(--gk-radius-control);
  --bs-border-radius-lg:     var(--gk-radius);

  /* One token carries the typeface to every Bootstrap component at once. */
  --gk-font-sans: "Figtree", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --bs-body-font-family: var(--gk-font-sans);
  --bs-body-font-size: 1rem;
}

/* -----------------------------------------------------------------------------
   2. Brand tokens — DARK. Overrides only. Never introduces a new token.
   -------------------------------------------------------------------------- */
[data-bs-theme="dark"] {
  color-scheme: dark;

  --gk-brand:            #5FA3DC;   /* 6.8:1 on --gk-bg — safe as text   */
  --gk-brand-strong:     #83BCEA;
  --gk-brand-stronger:   #A3CFF2;
  --gk-brand-solid:      #2F6FA8;   /* 5.6:1 under white text            */
  --gk-on-brand:         #FFFFFF;
  --gk-brand-subtle:     #1A2D40;
  --gk-brand-border:     #2E4A63;

  --gk-accent:           #E8A33D;   /* 8.5:1 on --gk-bg */
  --gk-accent-subtle:    #3A2A12;
  --gk-accent-border:    #5F4824;

  --gk-alert:            #E8A33D;
  --gk-alert-subtle:     #4A3415;
  --gk-alert-border:     #7A5A28;

  --gk-celebrate:        #E8A33D;
  --gk-celebrate-subtle: #3A2A12;
  --gk-celebrate-border: #5F4824;

  --gk-bg:               #141517;
  --gk-surface:          #1C1D1F;
  --gk-surface-sunk:     #26282A;
  --gk-line:             #313336;
  --gk-line-soft:        #26282A;
  --gk-ink:              #EDEDEE;
  --gk-ink-muted:        #B0B4B8;   /* 8.6:1 on --gk-bg */

  --gk-track:            #2A2C2F;
  --gk-fill:             #5FA3DC;   /* 5.5:1 on --gk-track; the solid navy is 2.5:1 */

  --gk-focus:            #8CC2F0;
  --gk-focus-ring:       rgba(140, 194, 240, 0.40);

  --gk-shadow:           inset 0 0 0 1px var(--gk-line);

  --bs-primary:              #5FA3DC;
  --bs-primary-rgb:          95, 163, 220;
  --bs-primary-text-emphasis:#A3CFF2;
  --bs-primary-bg-subtle:    #16242F;
  --bs-primary-border-subtle:#2A4258;

  --bs-link-color:           var(--gk-brand);
  --bs-link-color-rgb:       95, 163, 220;
  --bs-link-hover-color:     var(--gk-brand-strong);
  --bs-link-hover-color-rgb: 131, 188, 234;
}

/* -----------------------------------------------------------------------------
   3. Bootstrap re-skin
   Bootstrap's component colours are compile-time literals (--bs-btn-bg: #0d6efd),
   not references to --bs-primary, so overriding --bs-primary alone is not enough.
   These blocks re-point the component-level variables. Theme-aware: they read
   the tokens above, so there is no second copy for dark.
   -------------------------------------------------------------------------- */
.btn-primary {
  --bs-btn-color:                var(--gk-on-brand);
  --bs-btn-bg:                   var(--gk-brand-solid);
  --bs-btn-border-color:         var(--gk-brand-solid);
  --bs-btn-hover-color:          var(--gk-on-brand);
  --bs-btn-hover-bg:             var(--gk-brand-strong);
  --bs-btn-hover-border-color:   var(--gk-brand-strong);
  --bs-btn-active-color:         var(--gk-on-brand);
  --bs-btn-active-bg:            var(--gk-brand-stronger);
  --bs-btn-active-border-color:  var(--gk-brand-stronger);
  --bs-btn-disabled-color:       var(--gk-on-brand);
  --bs-btn-disabled-bg:          var(--gk-brand-solid);
  --bs-btn-disabled-border-color:var(--gk-brand-solid);
  --bs-btn-focus-shadow-rgb:     var(--bs-primary-rgb);
}

[data-bs-theme="dark"] .btn-primary {
  /* The solid navy is readable under white but too dark to hover *into*;
     hovering should get lighter in dark mode, not darker. */
  --bs-btn-hover-bg:            #3B81C0;
  --bs-btn-hover-border-color:  #3B81C0;
  --bs-btn-active-bg:           #4A90CE;
  --bs-btn-active-border-color: #4A90CE;
}

.btn-outline-primary {
  --bs-btn-color:                var(--gk-brand);
  --bs-btn-border-color:         var(--gk-brand);
  --bs-btn-hover-color:          var(--gk-on-brand);
  --bs-btn-hover-bg:             var(--gk-brand-solid);
  --bs-btn-hover-border-color:   var(--gk-brand-solid);
  --bs-btn-active-color:         var(--gk-on-brand);
  --bs-btn-active-bg:            var(--gk-brand-strong);
  --bs-btn-active-border-color:  var(--gk-brand-strong);
  --bs-btn-disabled-color:       var(--gk-brand);
  --bs-btn-disabled-border-color:var(--gk-brand);
  --bs-btn-focus-shadow-rgb:     var(--bs-primary-rgb);
}

/* Bootstrap's outline-secondary is a fixed #6c757d, which measures 3.5:1 on
   the dark surface — it failed the contrast sweep on the unmatched queue,
   where it is the "other suggestion" button. Theme-aware instead. */
.btn-outline-secondary {
  --bs-btn-color:                var(--gk-ink);
  --bs-btn-border-color:         var(--gk-line);
  --bs-btn-hover-color:          var(--gk-ink);
  --bs-btn-hover-bg:             var(--gk-surface-sunk);
  --bs-btn-hover-border-color:   var(--gk-ink-muted);
  --bs-btn-active-color:         var(--gk-ink);
  --bs-btn-active-bg:            var(--gk-surface-sunk);
  --bs-btn-active-border-color:  var(--gk-ink-muted);
  --bs-btn-disabled-color:       var(--gk-ink-muted);
  --bs-btn-disabled-border-color:var(--gk-line);
  --bs-btn-focus-shadow-rgb:     var(--bs-primary-rgb);
}

/* Bootstrap hardcodes white on .text-bg-primary / .bg-primary, which would be
   white-on-light-blue in dark mode. Point them at the solid pair instead. */
.bg-primary      { background-color: var(--gk-brand-solid) !important; }
.text-bg-primary { color: var(--gk-on-brand) !important;
                   background-color: var(--gk-brand-solid) !important; }

.progress, .progress-stacked {
  --bs-progress-bg:     var(--gk-track);
  --bs-progress-bar-bg: var(--gk-fill);
  --bs-progress-box-shadow: none;
}

.form-control:focus,
.form-select:focus {
  border-color: var(--gk-brand);
  box-shadow: 0 0 0 .25rem var(--gk-focus-ring);
}
.form-check-input:checked { background-color: var(--gk-brand-solid);
                            border-color: var(--gk-brand-solid); }
.form-check-input:focus   { border-color: var(--gk-brand);
                            box-shadow: 0 0 0 .25rem var(--gk-focus-ring); }

.nav-pills { --bs-nav-pills-link-active-bg: var(--gk-brand-solid);
             --bs-nav-pills-link-active-color: var(--gk-on-brand); }

.card      { --bs-card-bg: var(--gk-surface);
             --bs-card-border-color: var(--gk-line);
             --bs-card-cap-bg: transparent; }
.table     { --bs-table-bg: transparent;
             --bs-table-border-color: var(--gk-line-soft); }
.list-group{ --bs-list-group-bg: var(--gk-surface);
             --bs-list-group-border-color: var(--gk-line);
             --bs-list-group-action-hover-bg: var(--gk-brand-subtle); }

/* -----------------------------------------------------------------------------
   4. Focus + base
   -------------------------------------------------------------------------- */

/* Headings across both layouts: the compressed scale. Bootstrap ships h1-h6 at
   weight 500 already, so this is mostly about tracking — at Figtree's display
   sizes the default letter-spacing reads loose. */
h1, h2, h3, .h1, .h2, .h3 { letter-spacing: -.02em; }
h1, .h1 { font-weight: 500; }

/* Actions are pills. --bs-border-radius stays at the control radius so inputs
   and selects keep an 8px corner; a button is not an input. */
.btn { border-radius: var(--gk-radius-pill); }

html { background-color: var(--gk-bg); }

body {
  /* Explicit, always. Never inherit the background. */
  background-color: var(--gk-bg);
  color: var(--gk-ink);
  -webkit-text-size-adjust: 100%;
}

:focus-visible {
  outline: 3px solid var(--gk-focus);
  outline-offset: 2px;
  border-radius: 2px;
}
.btn:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible {
  outline: 3px solid var(--gk-focus);
  outline-offset: 2px;
}

/* Skip link: first thing in the tab order on every page. */
.gk-skip {
  position: absolute;
  left: .5rem;
  top: -4rem;
  z-index: 1080;
  padding: .6rem 1rem;
  background-color: var(--gk-surface);
  color: var(--gk-brand);
  border: 2px solid var(--gk-brand);
  border-radius: var(--gk-radius);
  font-weight: 600;
  text-decoration: none;
  transition: top .15s ease-out;
}
.gk-skip:focus { top: .5rem; }

.gk-muted   { color: var(--gk-ink-muted); }
.gk-surface { background-color: var(--gk-surface); }

/* A card that is genuinely a surface in both themes. */
.gk-panel {
  background-color: var(--gk-surface);
  /* The ring, not a border. Carrying both drew them adjacent — a 2px hairline
     where a .gk-stat beside it draws 1px. */
  border-radius: var(--gk-radius-lg);
  box-shadow: var(--gk-shadow);
}

.gk-tabular { font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  .gk-thermo__fill, .gk-bar__fill, .gk-skip { transition: none !important; }
}

/* -----------------------------------------------------------------------------
   5. Public donor pages
   Phone-first. No webfont, no above-the-fold image, no JavaScript needed to
   render — the LCP element is the "to go" figure, which is plain text.
   -------------------------------------------------------------------------- */
.gk-public {
  max-width: 33rem;
  margin: 0 auto;
  padding: 1.25rem 1.125rem 4rem;
}

/* A donor page with a side panel needs more than the reading measure above.
   Measured by the give-kit.com session on the real markup at a 1440 viewport:
   the ask column goes 315px -> 567px and the panel 177px -> 357px, with 309px
   of content inside it. The panel is what the extra width is for.

   309px matters because the unit label comes from the campaign: "Meals funded"
   is the easy case and "Training hours funded" is the real one, and it renders
   on one line at 217px.

   62em is Bootstrap's lg exactly. Below it the single column is already right
   and a wider prose measure would be a straight loss, so this does nothing
   there — the phone layout is the one that was never broken. */
@media (min-width: 62em) {
  .gk-public--wide { max-width: 60rem; }
}

.gk-eyebrow {
  display: block;
  font-size: .8125rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--gk-ink-muted);
  margin-bottom: .375rem;
}

.gk-public h1 {
  font-size: 1.875rem;
  line-height: 1.08;
  /* Weight goes DOWN as size goes up. A 500 at this size reads as composed;
     the 700 it replaces read as a headline shouting at a donor. */
  font-weight: 500;
  letter-spacing: -.025em;
  color: var(--gk-ink);
  margin: 0 0 .25rem;
}
@media (min-width: 36em) { .gk-public h1 { font-size: 2.5rem; letter-spacing: -.03em; } }

/* The hero figure. What is LEFT, because that is the number that moves a donor.
   Raised-of-goal is true but it is a status report, not an ask. */
.gk-hero {
  display: flex;
  align-items: stretch;
  gap: 1.25rem;
  margin: 1.5rem 0;
}
.gk-hero__nums { flex: 1 1 auto; align-self: center; }

.gk-figure {
  display: block;
  font-size: 2.75rem;
  line-height: 1;
  /* 600 rather than the display 500: tabular numerals at a light weight read
     as thin where letterforms read as elegant, and this is the one number on
     the page a donor is meant to act on. */
  font-weight: 600;
  letter-spacing: -.03em;
  color: var(--gk-brand);
  font-variant-numeric: tabular-nums;
}
@media (min-width: 36em) { .gk-figure { font-size: 3.25rem; } }

/* Goal met: the figure switches to the warm accent so it agrees with the
   thermometer instead of sitting navy next to an amber tube. */
.gk-figure--met { color: var(--gk-celebrate); }

.gk-figure-label {
  display: block;
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--gk-ink);
  margin-top: .25rem;
}
.gk-figure-sub {
  display: block;
  font-size: .9375rem;
  color: var(--gk-ink-muted);
  margin-top: .5rem;
}

/* The thermometer. Fills from the bottom; height is the only thing that moves,
   so it is one paint and no layout. */
.gk-thermo {
  flex: 0 0 auto;
  width: 72px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.gk-thermo__tube {
  position: relative;
  width: 72px;
  height: 240px;
  border-radius: 36px;
  background-color: var(--gk-track);
  border: 1px solid var(--gk-line);
  overflow: hidden;
}
.gk-thermo__fill {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  background-color: var(--gk-fill);
  transition: height .5s cubic-bezier(.22, .61, .36, 1);
}
.gk-thermo--met .gk-thermo__fill { background-color: var(--gk-celebrate); }
.gk-thermo__pct {
  margin-top: .5rem;
  font-size: .875rem;
  font-weight: 700;
  color: var(--gk-ink-muted);
  font-variant-numeric: tabular-nums;
}

/* The ask. 56px tall, full width, thumb-reachable, and repeated at the bottom
   of a long donor list so nobody has to scroll back up. */
.gk-give {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 3.5rem;
  padding: .875rem 1.25rem;
  background-color: var(--gk-brand-solid);
  color: var(--gk-on-brand);
  border: 1px solid var(--gk-brand-solid);
  border-radius: var(--gk-radius-pill);
  font-size: 1.125rem;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
}
.gk-give:hover,
.gk-give:focus { background-color: var(--gk-brand-strong);
                 border-color: var(--gk-brand-strong);
                 color: var(--gk-on-brand); }
[data-bs-theme="dark"] .gk-give:hover,
[data-bs-theme="dark"] .gk-give:focus { background-color: #3B81C0; border-color: #3B81C0; }

.gk-reassure {
  display: block;
  text-align: center;
  font-size: .9375rem;
  color: var(--gk-ink-muted);
  margin-top: .625rem;
}

/* The unit maths, stated as what the donor's money does rather than what has
   already been raised. */
/* The business's own site, directly under their name. Small and quiet: a donor
   came here to give, not to browse, so this is available rather than offered. */
.gk-site-link {
  margin: .25rem 0 0;
  font-size: .9375rem;
}

/* Share links. A row of plain text links rather than branded buttons — using
   each network's logo and colour would mean shipping their marks and would
   read as an endorsement the nonprofit has not made. Text also degrades to a
   sensible list with no CSS at all. */
.gk-share__list {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem .75rem;
  list-style: none;
  margin: .75rem 0 0;
  padding: 0;
}
.gk-share__list a {
  display: inline-block;
  padding: .375rem .875rem;
  border-radius: var(--gk-radius-pill);
  background-color: var(--gk-brand-subtle);
  color: var(--gk-brand);
  font-size: .9375rem;
  font-weight: 500;
  text-decoration: none;
  box-shadow: inset 0 0 0 1px var(--gk-brand-border);
}
.gk-share__list a:hover {
  background-color: var(--gk-brand-solid);
  color: var(--gk-on-brand);
  box-shadow: inset 0 0 0 1px var(--gk-brand-solid);
}

.gk-impact {
  margin: 1.5rem 0;
  padding: .875rem 1rem;
  background-color: var(--gk-brand-subtle);
  border: 1px solid var(--gk-brand-border);
  border-radius: var(--gk-radius);
  color: var(--gk-ink);
  font-size: .9375rem;
  line-height: 1.5;
}
.gk-impact strong { color: var(--gk-brand); }

.gk-met {
  margin: 1.5rem 0;
  padding: .875rem 1rem;
  background-color: var(--gk-accent-subtle);
  border: 1px solid var(--gk-accent-border);
  border-left: 4px solid var(--gk-accent);
  border-radius: var(--gk-radius);
  color: var(--gk-ink);
}
.gk-met strong { color: var(--gk-accent); }

.gk-section-title {
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: .01em;
  color: var(--gk-ink);
  margin: 2rem 0 .5rem;
}

.gk-donors { list-style: none; padding: 0; margin: 0; }
.gk-donors li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: .625rem .25rem;
  border-bottom: 1px solid var(--gk-line-soft);
  color: var(--gk-ink);
}
.gk-donors li:last-child { border-bottom: 0; }
.gk-donors .amount { color: var(--gk-ink-muted); font-variant-numeric: tabular-nums; }

.gk-public footer {
  margin-top: 2.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--gk-line);
  color: var(--gk-ink-muted);
  font-size: .875rem;
}
.gk-public footer a { color: var(--gk-brand); }

/* Campaign page: one business per row, each a link to its own page. */
.gk-biz-list { list-style: none; padding: 0; margin: 0; display: grid; gap: .5rem; }
.gk-biz {
  display: block;
  padding: .75rem .875rem;
  background-color: var(--gk-surface);
  border: 1px solid var(--gk-line);
  border-radius: var(--gk-radius);
  color: var(--gk-ink);
  text-decoration: none;
}
.gk-biz:hover, .gk-biz:focus-visible { border-color: var(--gk-brand);
                                       background-color: var(--gk-brand-subtle);
                                       color: var(--gk-ink); }
.gk-biz__top { display: flex; justify-content: space-between; gap: .75rem;
               align-items: baseline; margin-bottom: .5rem; }
.gk-biz__name { font-weight: 600; }
.gk-biz__pct  { font-size: .875rem; color: var(--gk-ink-muted);
                font-variant-numeric: tabular-nums; white-space: nowrap; }

/* -----------------------------------------------------------------------------
   6. Dashboard shell — desktop-first, data-dense
   -------------------------------------------------------------------------- */
.gk-topbar {
  background-color: var(--gk-brand-solid);
  color: var(--gk-on-brand);
  border-bottom: 1px solid var(--gk-brand-stronger);
}
[data-bs-theme="dark"] .gk-topbar { border-bottom-color: var(--gk-line); }

.gk-topbar__inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  max-width: 88rem;
  margin: 0 auto;
  padding: .625rem 1rem;
}
.gk-topbar a { color: var(--gk-on-brand); }
.gk-wordmark {
  white-space: nowrap;
  font-weight: 800;
  letter-spacing: -.01em;
  font-size: 1.0625rem;
  text-decoration: none;
  color: var(--gk-on-brand);
}
.gk-topbar__spacer { margin-left: auto; }
.gk-topbar__who { font-size: .875rem; opacity: .9; }

/* Buttons that sit on the navy bar. */
.gk-bar-btn {
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  min-height: 2.25rem;
  padding: .3125rem .75rem;
  background-color: rgba(255, 255, 255, .14);
  color: var(--gk-on-brand);
  border: 1px solid rgba(255, 255, 255, .28);
  border-radius: var(--gk-radius);
  font-size: .875rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.gk-bar-btn:hover { background-color: rgba(255, 255, 255, .24); color: var(--gk-on-brand); }
.gk-bar-btn:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }

.gk-subnav {
  background-color: var(--gk-surface);
  border-bottom: 1px solid var(--gk-line);
}
.gk-subnav__inner {
  display: flex;
  align-items: center;
  gap: .25rem;
  max-width: 88rem;
  margin: 0 auto;
  padding: 0 1rem;
  overflow-x: auto;
}
.gk-subnav a {
  display: inline-block;
  padding: .75rem .875rem;
  border-bottom: 3px solid transparent;
  color: var(--gk-ink-muted);
  font-size: .9375rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.gk-subnav a:hover { color: var(--gk-brand); }
.gk-subnav a[aria-current="page"] { color: var(--gk-brand);
                                    border-bottom-color: var(--gk-brand); }

.gk-main {
  max-width: 88rem;
  margin: 0 auto;
  padding: 1.5rem 1rem 4rem;
}

.gk-page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: .75rem;
  margin-bottom: 1.25rem;
}
.gk-page-head h1 { font-size: 1.75rem; font-weight: 500; letter-spacing: -.025em; margin: 0; color: var(--gk-ink); }
.gk-page-head .gk-sub { color: var(--gk-ink-muted); font-size: .9375rem; margin: .25rem 0 0; }
.gk-actions { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }

.gk-crumb { font-size: .875rem; margin-bottom: .5rem; }
.gk-crumb a { color: var(--gk-ink-muted); text-decoration: none; }
.gk-crumb a:hover { color: var(--gk-brand); text-decoration: underline; }

/* The sign-in page is its own thing: centred, nothing else on screen. */
.gk-auth {
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: 1.5rem;
  background-color: var(--gk-bg);
}
.gk-auth__card { width: 100%; max-width: 26rem; padding: 1.75rem; }

/* -----------------------------------------------------------------------------
   7. Data display
   -------------------------------------------------------------------------- */
.gk-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr));
  gap: .75rem;
  margin-bottom: 1.25rem;
}
.gk-stat {
  padding: .875rem 1rem;
  background-color: var(--gk-surface);
  border: 1px solid var(--gk-line);
  border-radius: var(--gk-radius-lg);
}
.gk-stat__label {
  display: block;
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--gk-ink-muted);
  margin-bottom: .25rem;
}
.gk-stat__value {
  display: block;
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.15;
  color: var(--gk-ink);
  font-variant-numeric: tabular-nums;
}
.gk-stat__note { display: block; font-size: .8125rem; color: var(--gk-ink-muted); margin-top: .25rem; }
.gk-stat--brand .gk-stat__value { color: var(--gk-brand); }
/* Loud on purpose. This is the one tile permitted to interrupt the overview. */
.gk-stat--alert { border-color: var(--gk-alert-border); background-color: var(--gk-alert-subtle); }
.gk-stat--alert .gk-stat__value { color: var(--gk-alert); }
/* The link that acts on the alert belongs to the alert, not to the brand. The
   brand blue measured 4.33:1 on the dark alert ground; this is 5.4:1 and says
   "this tile is one thing" at the same time. */
.gk-stat--alert .gk-stat__note a { color: var(--gk-alert); }

/* Horizontal bar used in tables and on the campaign page. */
.gk-bar {
  /* Width is explicit so it still has a size as a flex item in a table cell. */
  width: 100%;
  min-width: 2.5rem;
  height: .5rem;
  border-radius: 999px;
  background-color: var(--gk-track);
  overflow: hidden;
}
.gk-bar__fill {
  height: 100%;
  /* No radius: the track clips it. A pill-shaped fill at 4% renders as a
     circle and reads as a slider handle rather than progress. */
  background-color: var(--gk-fill);
  transition: width .5s cubic-bezier(.22, .61, .36, 1);
}
.gk-bar--met .gk-bar__fill { background-color: var(--gk-celebrate); }
.gk-bar--lg { height: .875rem; }

/* Status badges. One class per pipeline state so the table scans by colour
   without relying on colour alone — the word is always there too. */
.gk-status {
  display: inline-block;
  padding: .1875rem .5rem;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: .75rem;
  font-weight: 700;
  line-height: 1.35;
  white-space: nowrap;
}
.gk-status--prospect      { background-color: var(--gk-surface-sunk); color: var(--gk-ink-muted);
                            border-color: var(--gk-line); }
/* Reused for the "Needed" badge in the businesses table's Form column. Inside
   a dense table a saturated chip fights every row around it, so this one takes
   the quiet ground and lets the word carry the meaning. */
.gk-status--asked         { background-color: var(--gk-celebrate-subtle); color: var(--gk-accent);
                            border-color: var(--gk-celebrate-border); }
.gk-status--committed,
.gk-status--kit_delivered { background-color: var(--gk-brand-subtle); color: var(--gk-brand);
                            border-color: var(--gk-brand-border); }
.gk-status--active        { background-color: var(--gk-brand-solid); color: var(--gk-on-brand);
                            border-color: var(--gk-brand-solid); }
.gk-status--goal_met      { background-color: var(--gk-celebrate); color: #fff;
                            border-color: var(--gk-celebrate); }
[data-bs-theme="dark"] .gk-status--goal_met { color: #1B1304; }
.gk-status--declined      { background-color: var(--bs-danger-bg-subtle);
                            color: var(--bs-danger-text-emphasis);
                            border-color: var(--bs-danger-border-subtle); }

/* The pipeline, shown as counts so "where is this campaign stuck" is one look. */
.gk-pipeline { display: flex; flex-wrap: wrap; gap: .375rem; margin-bottom: 1.25rem; }
.gk-pipeline a {
  display: flex;
  flex-direction: column;
  gap: .125rem;
  min-width: 6.5rem;
  padding: .5rem .75rem;
  background-color: var(--gk-surface);
  border: 1px solid var(--gk-line);
  border-radius: var(--gk-radius);
  color: var(--gk-ink);
  text-decoration: none;
}
.gk-pipeline a:hover { border-color: var(--gk-brand); background-color: var(--gk-brand-subtle); }
.gk-pipeline a[aria-current="true"] { border-color: var(--gk-brand);
                                      box-shadow: inset 0 0 0 1px var(--gk-brand);
                                      background-color: var(--gk-brand-subtle); }
.gk-pipeline .n { font-size: 1.25rem; font-weight: 700; line-height: 1;
                  font-variant-numeric: tabular-nums; }
.gk-pipeline .k { font-size: .75rem; color: var(--gk-ink-muted); font-weight: 600; }

/* Tables: a surface with a sticky header, because these lists get long. */
.gk-table-wrap {
  background-color: var(--gk-surface);
  border: 1px solid var(--gk-line);
  border-radius: var(--gk-radius-lg);
  overflow: auto;
  max-height: 72vh;
}
.gk-table { width: 100%; margin: 0; border-collapse: separate; border-spacing: 0; }
.gk-table th, .gk-table td {
  padding: .625rem .75rem;
  border-bottom: 1px solid var(--gk-line-soft);
  vertical-align: middle;
  font-size: .9375rem;
}
.gk-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background-color: var(--gk-surface-sunk);
  border-bottom: 1px solid var(--gk-line);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--gk-ink-muted);
  white-space: nowrap;
}
.gk-table tbody tr:last-child td { border-bottom: 0; }
.gk-table tbody tr:hover td { background-color: var(--gk-brand-subtle); }
.gk-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.gk-table .shrink { width: 1%; white-space: nowrap; }

.gk-filters {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  align-items: end;
  padding: .875rem 1rem;
  background-color: var(--gk-surface);
  border: 1px solid var(--gk-line);
  border-radius: var(--gk-radius-lg);
  margin-bottom: 1rem;
}
.gk-filters .field { display: flex; flex-direction: column; gap: .25rem; }
.gk-filters label { font-size: .75rem; font-weight: 700; letter-spacing: .04em;
                    text-transform: uppercase; color: var(--gk-ink-muted); }

/* The unmatched queue: one decision per row, suggestions first. */
.gk-decide { display: flex; flex-wrap: wrap; gap: .375rem; align-items: center; }
.gk-decide form { display: flex; gap: .375rem; align-items: center; margin: 0; }
.gk-quote { color: var(--gk-ink); }

.gk-empty {
  padding: 2.5rem 1.5rem;
  text-align: center;
  background-color: var(--gk-surface);
  border: 1px dashed var(--gk-line);
  border-radius: var(--gk-radius-lg);
  color: var(--gk-ink-muted);
}
.gk-empty strong { display: block; color: var(--gk-ink); font-size: 1.0625rem; margin-bottom: .25rem; }

/* Forms: a fieldset is a titled panel, not a browser-default box. */
.gk-fieldset {
  border: 1px solid var(--gk-line);
  border-radius: var(--gk-radius-lg);
  background-color: var(--gk-surface);
  padding: 1rem 1.125rem 1.125rem;
  margin-bottom: 1.25rem;
}
.gk-fieldset > legend {
  float: none;
  width: auto;
  padding: 0 .375rem;
  margin: 0 0 .5rem -.375rem;
  font-size: .8125rem;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--gk-ink-muted);
}

.gk-form-grid { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 48em) { .gk-form-grid--2 { grid-template-columns: 1fr 1fr; } }

.gk-code {
  display: block;
  padding: .625rem .75rem;
  background-color: var(--gk-surface-sunk);
  border: 1px solid var(--gk-line);
  border-radius: var(--gk-radius);
  color: var(--gk-ink);
  font-size: .875rem;
  word-break: break-all;
}

/* -----------------------------------------------------------------------------
   8. Print — the counter sign and the gift list both get printed.
   -------------------------------------------------------------------------- */
@media print {
  .gk-topbar, .gk-subnav, .gk-skip, .gk-actions, .gk-filters { display: none !important; }
  .gk-table-wrap { max-height: none; overflow: visible; border: 0; }
  body { background: #fff; color: #000; }

  /* Print drops background colours, and the alert tile's loudest signal is its
     ground. On paper it keeps only the same 1px border every other tile has,
     so on a mono print of the board report "a human must act now" looks
     exactly like "here is a number". A heavier rule survives both the dropped
     background and a black-and-white printer. */
  .gk-stat--alert { border-width: 1px 1px 1px 6px; }

  /* The ring is a box-shadow and box-shadows do not print, so the panel would
     lose its edge entirely on paper. Borders do print. */
  .gk-panel { box-shadow: none; border: 1px solid var(--gk-line); }
}
