/* ==========================================================================
   Kidz Tour Family — design system
   Palette: brand navy, gold and red taken from the logo.
   Loaded after Bootstrap 5.3; Bootstrap's own variables are remapped onto
   these tokens so form controls and utilities inherit the palette.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Brand */
  --navy:        #1D3C8E;
  --navy-deep:   #12265C;
  --navy-hover:  #16317A;
  --navy-tint:   #E8EDF9;
  --gold:        #FBC109;
  --gold-hover:  #E3A800;
  --gold-ink:    #7D5800;   /* the palette's #8A6100, darkened a shade: it only
                              clears AA on plain white, and this text also sits
                              on gold tints and patterned backgrounds */
  --gold-tint:   #FFF4D6;
  --red:         #CE251E;
  --red-tint:    #FDECEA;

  /* Surfaces and text */
  --ink:         #1F2937;
  --muted:       #5B6472;
  --line:        #E5E7EB;
  --surface:     #FFFFFF;
  --surface-2:   #F0F2F7;
  --bg:          #F7F8FB;

  /* Role tokens — components reference these, never the raw brand colours */
  --on-navy:      #FFFFFF;
  --on-gold:      #12265C;
  --link:         var(--navy);
  --link-hover:   var(--navy-hover);
  --rail:         var(--gold);
  --rail-past:    #C9D2E8;
  --header-bg:    rgba(255, 255, 255, .88);
  /* Panels keep their own ramp: in dark mode the brand navy lightens for
     contrast on text, which would make these panels lighter than the page. */
  /* Filled controls keep a dark navy in both themes so white labels stay
     legible; --navy lightens in dark mode for link text and would not. */
  --btn-primary:       #1D3C8E;
  --btn-primary-hover: #16317A;
  --panel-from:   #1D3C8E;
  --panel-mid:    #16317A;
  --panel-to:     #12265C;
  --band-bg:      #12265C;
  --footer-bg:    var(--navy-deep);
  --footer-ink:   #C5D0EA;

  /* Type */
  --font-display: "Bricolage Grotesque", "Segoe UI", system-ui, sans-serif;
  --font-body:    "Public Sans", "Segoe UI", system-ui, -apple-system, Roboto, Helvetica, Arial, sans-serif;

  /* Radii — deliberately different by role, not one value everywhere */
  --r-sm:   8px;
  --r-md:   14px;
  --r-lg:   22px;
  --r-pill: 999px;

  /* Elevation — reserved for things that genuinely float */
  --shadow-sm: 0 1px 2px rgba(18, 38, 92, .06);
  --shadow:    0 8px 24px -12px rgba(18, 38, 92, .22);
  --shadow-lg: 0 32px 64px -32px rgba(18, 38, 92, .40);

  /* Decorative washes — tuned per theme so text contrast never drops below AA */
  --wash-gold: 14%;
  --wash-navy: 5%;
  --wash-warm: 20%;

  /* Rhythm */
  --gutter:  clamp(1rem, 4vw, 2rem);
  --section: clamp(3.5rem, 7vw, 6rem);
}

[data-theme="dark"] {
  --navy:        #6C8DE8;
  --navy-deep:   #0A1027;
  --navy-hover:  #8AA4F0;
  --navy-tint:   #18224A;
  --gold:        #FBC109;
  --gold-hover:  #FFD24D;
  --gold-ink:    #F5C53D;
  --gold-tint:   #2A2107;
  --red:         #F2685F;
  --red-tint:    #2E1513;

  --ink:         #E6EBF7;
  --muted:       #99A4BE;
  --line:        #27325C;
  --surface:     #141C3A;
  --surface-2:   #1B2550;
  --bg:          #0C122A;

  --on-navy:     #FFFFFF;
  --on-gold:     #12265C;
  --rail-past:   #2E3A66;
  --header-bg:   rgba(12, 18, 42, .86);
  --btn-primary:       #3F66D8;
  --btn-primary-hover: #5077E4;
  --panel-from:  #1E3372;
  --panel-mid:   #16255A;
  --panel-to:    #0D1738;
  --band-bg:     #111A3C;
  --footer-bg:   #080D20;
  --footer-ink:  #96A3C4;

  --wash-gold: 7%;
  --wash-navy: 12%;
  --wash-warm: 9%;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow:    0 8px 24px -12px rgba(0, 0, 0, .7);
  --shadow-lg: 0 32px 64px -28px rgba(0, 0, 0, .8);
}

/* Hand the palette to Bootstrap so its components come along for the ride. */
:root,
[data-theme] {
  --bs-body-bg:            var(--bg);
  --bs-body-color:         var(--ink);
  --bs-body-font-family:   var(--font-body);
  --bs-border-color:       var(--line);
  --bs-secondary-color:    var(--muted);
  --bs-emphasis-color:     var(--ink);
  --bs-link-color:         var(--link);
  --bs-link-hover-color:   var(--link-hover);
  --bs-primary:            var(--navy);
  --bs-primary-rgb:        29, 60, 142;
  --bs-focus-ring-color:   rgba(29, 60, 142, .30);
  --bs-border-radius:      var(--r-sm);
  --bs-heading-color:      var(--ink);
}
[data-theme="dark"] { --bs-focus-ring-color: rgba(108, 141, 232, .40); }

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; scroll-padding-top: 5.5rem; }

body {
  margin: 0;
  /* A backstop, not the fix: anything that still reaches past the right edge
     is clipped rather than widening the page and, with it, the mobile layout
     viewport. `clip` creates no scroll container, so the sticky header and the
     in-page scrollers keep working. */
  overflow-x: clip;
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; height: auto; }

h1, h2, h3, h4, .display-face {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -.015em;
  color: var(--ink);
}

h1 { font-size: clamp(2.4rem, 5.4vw, 3.9rem); font-weight: 800; letter-spacing: -.03em; }
h2 { font-size: clamp(1.9rem, 3.6vw, 2.7rem); letter-spacing: -.022em; }
h3 { font-size: clamp(1.25rem, 2vw, 1.5rem); }
h4 { font-size: 1.0625rem; }

p { margin-bottom: 1.1rem; }
.lead-text { font-size: 1.15rem; color: var(--muted); max-width: 62ch; }
.prose p { max-width: 68ch; }

a { color: var(--link); text-decoration-thickness: 1px; text-underline-offset: .18em; }
a:hover { color: var(--link-hover); }

::selection { background: var(--gold); color: var(--on-gold); }

:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 2px;
  border-radius: 3px;
}

.shell { width: min(1180px, 100% - (var(--gutter) * 2)); margin-inline: auto; }

.section { padding-block: var(--section); }
.section--tint { background: var(--surface-2); }
.section--surface { background: var(--surface); }

.skip-link {
  position: absolute; left: 1rem; top: -4rem; z-index: 2000;
  background: var(--navy); color: var(--on-navy);
  padding: .7rem 1.1rem; border-radius: var(--r-sm); font-weight: 600;
  transition: top .15s ease;
}
.skip-link:focus { top: 1rem; color: var(--on-navy); }

/* Section headings — a rule and a short label carry the structure,
   rather than a decorative eyebrow above every block. */
.section-head { max-width: 64ch; margin-bottom: clamp(2rem, 4vw, 3rem); }
.section-head__kicker {
  display: block;
  font-family: var(--font-body);
  font-size: .8125rem;
  font-weight: 700;
  color: var(--gold-ink);
  margin-bottom: .5rem;
}
.section-head p { color: var(--muted); margin-top: .85rem; margin-bottom: 0; }
.section-head--center { margin-inline: auto; text-align: center; }

/* --------------------------------------------------------------------------
   3. Buttons and pills
   -------------------------------------------------------------------------- */
.btn-ktf,
.btn-ktf-gold,
.btn-ktf-ghost {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .78rem 1.5rem;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: .975rem;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color .16s ease, color .16s ease, border-color .16s ease;
}
.btn-ktf { background: var(--btn-primary); color: var(--on-navy); }
.btn-ktf:hover { background: var(--btn-primary-hover); color: var(--on-navy); }

.btn-ktf-gold { background: var(--gold); color: var(--on-gold); }
.btn-ktf-gold:hover { background: var(--gold-hover); color: var(--on-gold); }

.btn-ktf-ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.btn-ktf-ghost:hover { color: var(--ink); border-color: var(--ink); }

.btn-ktf--sm { padding: .5rem 1.05rem; font-size: .875rem; }

/* On the navy hero panel the ghost button needs the inverted treatment. */
.on-navy .btn-ktf-ghost { color: #fff; border-color: rgba(255, 255, 255, .38); }
.on-navy .btn-ktf-ghost:hover { color: #fff; border-color: #fff; background: rgba(255, 255, 255, .08); }

.pill {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .35rem .85rem;
  border-radius: var(--r-pill);
  font-size: .8125rem; font-weight: 600;
  background: var(--navy-tint); color: var(--navy);
  border: 1px solid transparent;
}
.pill--gold { background: var(--gold-tint); color: var(--gold-ink); }
.pill--glass {
  background: rgba(255, 255, 255, .14);
  border-color: rgba(255, 255, 255, .24);
  color: #fff;
}
.pill__dot { width: .45rem; height: .45rem; border-radius: 50%; background: var(--gold); flex: none; }

/* --------------------------------------------------------------------------
   4. Header
   -------------------------------------------------------------------------- */
.topbar {
  background: var(--navy-deep);
  color: var(--footer-ink);
  font-size: .82rem;
}
.topbar__inner { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding-block: .5rem; }
.topbar a { color: var(--footer-ink); text-decoration: none; }
.topbar a:hover { color: var(--gold); }
.topbar__meta { display: flex; gap: 1.4rem; align-items: center; min-width: 0; }
.topbar__meta span { display: inline-flex; align-items: center; gap: .4rem; white-space: nowrap; }
.topbar__actions { display: flex; gap: 1rem; align-items: center; }

.site-header {
  position: sticky; top: 0; z-index: 1030;
  background: var(--header-bg);
  border-bottom: 1px solid var(--line);
}
/* The frost lives on a pseudo-element. On the header itself, backdrop-filter
   makes the header a containing block for fixed children, which left the nav
   drawer sized to the header instead of to the screen. */
.site-header::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  backdrop-filter: saturate(1.6) blur(12px);
  pointer-events: none;
}
.site-header__inner { display: flex; align-items: center; gap: 1.25rem; padding-block: .7rem; }

.brand { display: inline-flex; align-items: center; gap: .65rem; text-decoration: none; flex: none; }
.brand img { height: 42px; width: auto; }
.brand__name {
  font-family: var(--font-display);
  font-weight: 800; font-size: 1.06rem; line-height: 1.05;
  color: var(--ink); letter-spacing: -.02em;
}
.brand__name small { display: block; font-family: var(--font-body); font-size: .68rem; font-weight: 600; color: var(--muted); letter-spacing: .02em; }

.nav { margin-left: auto; display: flex; align-items: center; gap: .35rem; }
.nav a {
  padding: .5rem .8rem; border-radius: var(--r-sm);
  font-size: .95rem; font-weight: 600; color: var(--ink); text-decoration: none;
  transition: background-color .15s ease, color .15s ease;
}
.nav a:hover { background: var(--navy-tint); color: var(--navy); }
.nav a[aria-current="page"] { color: var(--navy); background: var(--navy-tint); }

.header-actions { display: flex; align-items: center; gap: .6rem; flex: none; }

.icon-btn {
  display: inline-grid; place-items: center;
  width: 40px; height: 40px; padding: 0;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: transparent; color: var(--ink); font-size: 1.05rem; line-height: 1;
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease;
}
.icon-btn:hover { color: var(--navy); border-color: var(--navy); }

.nav-toggle { display: none; }
.nav-close { display: none; }

@media (max-width: 991.98px) {
  /* One row, always. The brand gives up width so the buttons never drop to a
     second line and double the height of the header. */
  .site-header__inner { gap: .75rem; flex-wrap: nowrap; }
  .brand { flex: 1 1 auto; min-width: 0; gap: .55rem; }
  .brand img { height: 36px; }
  .brand__name { font-size: .98rem; min-width: 0; }
  .header-actions { gap: .4rem; }

  /* Without JS there is nothing to open the drawer, so the links stay in the
     flow and simply wrap under the header. */
  html:not(.js) .site-header__inner { flex-wrap: wrap; }
  .nav {
    flex-wrap: wrap;
    justify-content: center;
    width: 100%;
    margin: .5rem 0 0;
    order: 3;
  }

  .js .nav-toggle { display: inline-grid; }
  .js .nav {
    position: fixed; inset: 0 0 0 auto;
    width: min(320px, 82vw);
    margin: 0;
    order: 0;
    z-index: 1040;
    flex-direction: column; align-items: stretch; gap: .2rem;
    /* Must be reset from the no-JS rule above: centred content in a scrolling
       flex column starts above the scroll origin, putting the top of the menu
       permanently out of reach on a short screen. */
    justify-content: flex-start;
    flex-wrap: nowrap;
    background: var(--surface);
    border-left: 1px solid var(--line);
    padding: 1rem 1.1rem 2rem;
    transform: translateX(100%);
    /* Hidden while parked, so the links stay out of the tab order. */
    visibility: hidden;
    transition: transform .24s ease, visibility .24s ease;
    overflow-y: auto;
    overscroll-behavior: contain;
    box-shadow: var(--shadow-lg);
  }
  .js body.nav-open .nav { transform: translateX(0); visibility: visible; }
  .nav a { padding: .85rem 1rem; font-size: 1.05rem; }

  /* The panel sits over the header, so it carries its own way out. */
  .js .nav-close { display: inline-grid; margin: 0 0 .35rem auto; }

  .nav-scrim {
    position: fixed; inset: 0; z-index: 1029;
    background: rgba(10, 16, 39, .5);
    opacity: 0; visibility: hidden;
    transition: opacity .24s ease, visibility .24s ease;
  }
  body.nav-open .nav-scrim { opacity: 1; visibility: visible; }
  body.nav-open { overflow: hidden; }
  .topbar__meta span:not(:first-child) { display: none; }
}

/* The top bar keeps to one line too: the login link is the part that must stay
   whole, so the location truncates instead of wrapping. */
@media (max-width: 575.98px) {
  .topbar { font-size: .78rem; }
  .topbar__inner { gap: .6rem; }
  .topbar__meta { gap: .6rem; min-width: 0; }
  .topbar__meta span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .topbar__actions { flex: none; }
  .topbar__actions a { white-space: nowrap; }
}

/* A phone held sideways: tighten the menu so it fits without scrolling. */
@media (max-width: 991.98px) and (max-height: 540px) {
  .js .nav { padding-top: .5rem; padding-bottom: 1rem; }
  .js .nav a { padding: .55rem 1rem; font-size: 1rem; }
  .js .nav .btn-ktf { margin-top: .6rem !important; }
}

/* Narrow phones: the tagline is the first thing that can go. */
@media (max-width: 400px) {
  .brand img { height: 32px; }
  .brand__name { font-size: .94rem; }
  .brand__name small { display: none; }
}

/* --------------------------------------------------------------------------
   5. Hero
   -------------------------------------------------------------------------- */
.hero { padding-block: clamp(2rem, 5vw, 3.5rem) 0; }

.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: clamp(1.25rem, 3vw, 2rem);
  align-items: stretch;
}

.hero__panel {
  position: relative; overflow: hidden;
  border-radius: var(--r-lg);
  padding: clamp(1.75rem, 3.2vw, 2.75rem);
  background: linear-gradient(155deg, var(--panel-from) 0%, var(--panel-mid) 48%, var(--panel-to) 100%);
  color: #fff;
  display: flex; flex-direction: column; justify-content: center;
}
/* Two soft discs, echoing the logo's roundness, keep the panel from reading flat. */
.hero__panel::after {
  content: ""; position: absolute; right: -90px; bottom: -110px;
  width: 320px; height: 320px; border-radius: 50%;
  background: rgba(255, 255, 255, .06);
}
.hero__panel > * { position: relative; z-index: 1; }
.hero__panel > .pill { align-self: flex-start; }

.hero__title { color: #fff; margin: 1.2rem 0 0; font-size: clamp(2.2rem, 4.6vw, 3.4rem); }
.hero__lead { color: rgba(255, 255, 255, .84); max-width: 46ch; margin: 1.1rem 0 0; font-size: 1.08rem; }
.hero__actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1.6rem; }

.hero__figure {
  position: relative; overflow: hidden;
  border-radius: var(--r-lg);
  min-height: 340px;
  background: var(--surface-2);
}
.hero__figure img { width: 100%; height: 100%; object-fit: cover; display: block; }

@media (max-width: 860px) {
  .hero__grid { grid-template-columns: 1fr; }
  .hero__figure { min-height: 260px; order: -1; }
}

/* --- The route rail: seven years, seven communities. The one bold element. */
.route {
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
  border-top: 1px solid var(--line);
  padding-top: 1.5rem;
}
.route__label {
  font-size: .8125rem; font-weight: 700; color: var(--muted);
  margin-bottom: 1.1rem;
}
.route__track {
  display: flex; gap: 0;
  overflow-x: auto;
  scrollbar-width: thin;
  padding-bottom: .5rem;
  scroll-snap-type: x proximity;
}
.route__stop {
  position: relative;
  flex: 1 0 auto;
  min-width: 132px;
  padding: 1.5rem .75rem 0 0;
  scroll-snap-align: start;
}
/* The line runs behind every stop; the last one stops at its own tick. */
.route__stop::before {
  content: ""; position: absolute; left: 0; right: 0; top: 6px;
  height: 2px; background: var(--rail-past);
}
.route__stop:last-child::before { right: calc(100% - 12px); }
.route__stop::after {
  content: ""; position: absolute; left: 0; top: 0;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--bg);
  border: 3px solid var(--rail-past);
}
.route__stop--current::after { background: var(--gold); border-color: var(--gold); }
.route__stop--current .route__year { color: var(--gold-ink); }

.route__year {
  font-family: var(--font-display);
  font-size: 1.45rem; font-weight: 800; letter-spacing: -.03em;
  color: var(--ink); line-height: 1;
}
.route__place { font-weight: 600; font-size: .9rem; margin-top: .35rem; }
.route__region { font-size: .78rem; color: var(--muted); }

/* Below this width the rail always overflows, so fade the right edge to show
   there is more of the route to swipe through. On wider screens all seven
   stops fit and a fade would just dim the most recent one. */
@media (max-width: 860px) {
  .route__track {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 3rem), transparent 100%);
    mask-image: linear-gradient(to right, #000 calc(100% - 3rem), transparent 100%);
  }
}

/* The single orchestrated motion moment on the page. */
@media (prefers-reduced-motion: no-preference) {
  .js .route__stop { opacity: 0; transform: translateY(8px); }
  .js .route.is-drawn .route__stop {
    opacity: 1; transform: none;
    transition: opacity .45s ease, transform .45s ease;
    transition-delay: calc(var(--i) * 90ms);
  }
}

/* --------------------------------------------------------------------------
   6. Impact band
   -------------------------------------------------------------------------- */
.impact { background: var(--band-bg); color: #fff; }
.impact__grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.25rem, 3vw, 2.5rem);
  padding-block: clamp(2.25rem, 4vw, 3.25rem);
}
.impact__item { border-left: 2px solid rgba(251, 193, 9, .55); padding-left: 1.1rem; }
.impact__value {
  font-family: var(--font-display);
  font-size: clamp(2rem, 3.6vw, 2.85rem); font-weight: 800;
  letter-spacing: -.035em; line-height: 1; color: #fff;
}
.impact__label { font-weight: 700; margin-top: .4rem; color: var(--gold); font-size: .95rem; }
.impact__note { font-size: .83rem; color: rgba(255, 255, 255, .62); margin: .3rem 0 0; line-height: 1.45; }

@media (max-width: 760px) { .impact__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 420px) { .impact__grid { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   7. About
   -------------------------------------------------------------------------- */
.about__grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(1.75rem, 4vw, 3.5rem); align-items: start;
}
.about__figure { border-radius: var(--r-lg); overflow: hidden; position: sticky; top: 6rem; }
/* These are always group photographs, so they get a landscape frame. */
.about__figure img { width: 100%; display: block; aspect-ratio: 3 / 2; object-fit: cover; }

.about blockquote {
  margin: 1.75rem 0; padding: 1.1rem 0 1.1rem 1.4rem;
  border-left: 3px solid var(--gold);
  font-family: var(--font-display); font-size: 1.2rem; line-height: 1.45;
  color: var(--ink);
}
.about blockquote cite { display: block; margin-top: .6rem; font-family: var(--font-body); font-size: .85rem; font-style: normal; color: var(--muted); }

.chip-row { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: 1.25rem; }
.chip {
  padding: .32rem .7rem; border-radius: var(--r-sm);
  background: var(--surface-2); border: 1px solid var(--line);
  font-size: .82rem; font-weight: 600; color: var(--muted);
}

@media (max-width: 860px) {
  .about__grid { grid-template-columns: 1fr; }
  .about__figure { position: static; }
  .about__figure img { aspect-ratio: 3 / 2; }
}

/* --------------------------------------------------------------------------
   8. Programmes
   -------------------------------------------------------------------------- */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
}
.programme {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 1.6rem;
}
.programme__icon {
  display: inline-grid; place-items: center;
  width: 46px; height: 46px; border-radius: var(--r-sm);
  background: var(--navy-tint); color: var(--navy);
  font-size: 1.3rem; margin-bottom: 1rem;
}
.programme :is(h2, h3, h4) { font-size: 1.18rem; margin: 0 0 .55rem; }
.programme p { color: var(--muted); font-size: .95rem; margin: 0; }

/* Appeal — the one place red is allowed, because it is genuinely urgent. */
.appeal {
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
  display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
  gap: clamp(1.25rem, 3vw, 2rem);
  align-items: start;
}
.appeal__notice {
  background: var(--red-tint);
  border: 1px solid color-mix(in srgb, var(--red) 26%, transparent);
  border-radius: var(--r-md);
  padding: 1.5rem;
}
.appeal__notice h3 { color: var(--red); font-size: 1.1rem; margin: 0 0 .6rem; }
.appeal__notice p { margin: 0 0 1rem; font-size: .95rem; color: var(--ink); }
[data-theme="dark"] .appeal__notice p { color: var(--ink); }

.progress-line { height: 8px; border-radius: var(--r-pill); background: color-mix(in srgb, var(--red) 16%, transparent); overflow: hidden; margin-bottom: .5rem; }
.progress-line span { display: block; height: 100%; background: var(--red); border-radius: inherit; }
.progress-note { font-size: .8125rem; color: var(--muted); margin: 0; }

.needs {
  background: var(--gold-tint);
  border: 1px solid color-mix(in srgb, var(--gold) 40%, transparent);
  border-radius: var(--r-md);
  padding: 1.5rem;
}
.needs h3 { font-size: 1.1rem; margin: 0 0 .85rem; color: var(--gold-ink); }
.needs ul { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: .35rem .9rem; }
.needs li { font-size: .92rem; font-weight: 600; display: flex; align-items: center; gap: .45rem; color: var(--ink); }
.needs li::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--gold-ink); flex: none; }

@media (max-width: 800px) { .appeal { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   9. Gallery
   -------------------------------------------------------------------------- */
.filters { display: flex; flex-wrap: wrap; gap: .45rem; margin-bottom: 1.5rem; }
.filters button {
  padding: .45rem 1rem; border-radius: var(--r-pill);
  border: 1px solid var(--line); background: var(--surface);
  font-family: var(--font-display); font-weight: 700; font-size: .95rem;
  color: var(--muted); cursor: pointer;
  transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
.filters button:hover { color: var(--ink); border-color: var(--ink); }
.filters button[aria-pressed="true"] { background: var(--btn-primary); border-color: var(--btn-primary); color: var(--on-navy); }

.gallery-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
  gap: .85rem;
}
/* Larger tiles on the home page, so six photos fill two tidy rows. */
.gallery-grid--teaser { grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); }
.shot {
  position: relative; display: block; width: 100%; padding: 0;
  border: 0; background: var(--surface-2);
  border-radius: var(--r-md); overflow: hidden; cursor: zoom-in;
  aspect-ratio: 4 / 3;
}
.shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.shot__meta {
  position: absolute; inset: auto 0 0 0;
  background: linear-gradient(to top, rgba(10, 16, 39, .86), rgba(10, 16, 39, 0));
  color: #fff; text-align: left;
  padding: 2.5rem .9rem .8rem;
}
.shot__year { font-family: var(--font-display); font-weight: 800; font-size: 1.05rem; line-height: 1; }
.shot__place { font-size: .8rem; color: rgba(255, 255, 255, .82); }
.shot[hidden] { display: none; }

.lightbox {
  border: 0; padding: 0; background: transparent;
  max-width: min(1100px, 94vw); max-height: 94vh;
  color: #fff;
}
.lightbox::backdrop { background: rgba(8, 13, 32, .92); }
.lightbox img { display: block; max-width: 100%; max-height: 82vh; width: auto; margin-inline: auto; border-radius: var(--r-md); }
.lightbox__bar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .85rem .25rem 0; }
.lightbox__caption { font-size: .9rem; color: rgba(255, 255, 255, .8); }
.lightbox__caption strong { font-family: var(--font-display); color: #fff; display: block; }
.lightbox__close {
  border: 1px solid rgba(255, 255, 255, .3); background: transparent; color: #fff;
  border-radius: var(--r-pill); padding: .45rem 1rem; font-weight: 600; cursor: pointer; flex: none;
}
.lightbox__close:hover { background: rgba(255, 255, 255, .12); }

.albums { list-style: none; margin: clamp(2rem, 4vw, 3rem) 0 0; padding: 0; border-top: 1px solid var(--line); }
.albums li { border-bottom: 1px solid var(--line); }
.albums a {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: .95rem .25rem; text-decoration: none; color: var(--ink); font-weight: 600; font-size: .96rem;
  transition: color .15s ease, transform .15s ease;
}
.albums a:hover { color: var(--navy); transform: translateX(.5rem); }
.albums i { color: var(--muted); flex: none; }

/* --------------------------------------------------------------------------
   10. Testimonials
   -------------------------------------------------------------------------- */
.quotes { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: clamp(1rem, 2vw, 1.5rem); align-items: start; }
.quote-card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 1.75rem;
}
.quote-card__mark { font-family: var(--font-display); font-size: 2.6rem; line-height: .6; color: var(--gold); display: block; margin-bottom: .75rem; }
.quote-card p { font-size: 1rem; color: var(--ink); margin-bottom: 1.4rem; }
.quote-card__by { display: flex; align-items: center; gap: .8rem; border-top: 1px solid var(--line); padding-top: 1.1rem; }
.quote-card__by img { width: 46px; height: 46px; border-radius: 50%; object-fit: cover; flex: none; }
.quote-card__name { font-weight: 700; font-size: .95rem; }
.quote-card__role { font-size: .82rem; color: var(--muted); }

/* --------------------------------------------------------------------------
   11. The family
   -------------------------------------------------------------------------- */
.people {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(178px, 100%), 1fr));
  gap: clamp(.85rem, 2vw, 1.35rem);
}
.person { text-align: center; }
.person__pic {
  border-radius: var(--r-md); overflow: hidden; background: var(--surface-2);
  aspect-ratio: 1; margin-bottom: .75rem;
}
.person__pic img { width: 100%; height: 100%; object-fit: cover; display: block; }
.person__name { font-family: var(--font-display); font-weight: 700; font-size: .98rem; line-height: 1.25; }
.person__role { font-size: .8125rem; color: var(--muted); }
.person__country { font-size: .75rem; color: var(--gold-ink); font-weight: 600; }
.person__social { display: flex; justify-content: center; gap: .5rem; margin-top: .5rem; }
.person__social a { color: var(--muted); font-size: .95rem; }
.person__social a:hover { color: var(--navy); }

.people--compact { grid-template-columns: repeat(auto-fill, minmax(min(136px, 100%), 1fr)); }
.people--compact .person__name { font-size: .88rem; }
.people--compact .person__pic { border-radius: var(--r-sm); }

.roster-toggle { margin-top: clamp(1.5rem, 3vw, 2rem); text-align: center; }

/* --------------------------------------------------------------------------
   12. Donate
   -------------------------------------------------------------------------- */
.give-band {
  background: linear-gradient(120deg, var(--panel-to) 0%, var(--panel-from) 100%);
  color: #fff; border-radius: var(--r-lg);
  padding: clamp(2rem, 4vw, 3rem);
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 1.75rem; align-items: center;
}
.give-band h2 { color: #fff; margin: 0 0 .6rem; }
.give-band p { color: rgba(255, 255, 255, .82); margin: 0; max-width: 52ch; }
@media (max-width: 760px) { .give-band { grid-template-columns: 1fr; } }

.give-card {
  display: grid; grid-template-columns: 170px minmax(0, 1fr);
  gap: clamp(1.25rem, 3vw, 2rem); align-items: center;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: clamp(1.25rem, 3vw, 2rem);
}
.give-card + .give-card { margin-top: 1rem; }
.give-card__logo { display: grid; place-items: center; background: var(--surface-2); border-radius: var(--r-sm); padding: 1rem; min-height: 96px; }
.give-card__logo img { max-height: 64px; width: auto; }
.give-card__method { font-size: .82rem; font-weight: 700; color: var(--gold-ink); }
.give-card__detail {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.6rem, 3.4vw, 2.2rem); letter-spacing: -.02em;
  color: var(--ink); margin: .2rem 0; word-break: break-word;
}
.give-card__holder { font-size: .92rem; color: var(--muted); margin: 0; }
.give-card__note { font-size: .85rem; color: var(--muted); margin: .7rem 0 0; }
.copy-btn { margin-top: .9rem; }
@media (max-width: 620px) { .give-card { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   13. Contact
   -------------------------------------------------------------------------- */
.contact__grid { display: grid; grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); gap: clamp(1.75rem, 4vw, 3.5rem); }
.contact-list { list-style: none; margin: 0; padding: 0; }
.contact-list li { display: flex; gap: .85rem; padding-block: .9rem; border-bottom: 1px solid var(--line); }
.contact-list li:first-child { padding-top: 0; }
.contact-list i { color: var(--navy); font-size: 1.15rem; margin-top: .15rem; flex: none; }
.contact-list a { text-decoration: none; font-weight: 600; }
.contact-list span { display: block; font-size: .78rem; color: var(--muted); font-weight: 400; }

.field { margin-bottom: 1rem; }
.field label { display: block; font-size: .875rem; font-weight: 700; margin-bottom: .35rem; }
.field input, .field textarea {
  width: 100%;
  padding: .8rem 1rem;
  font: inherit; font-size: .975rem;
  color: var(--ink); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.field input::placeholder, .field textarea::placeholder { color: var(--muted); opacity: .7; }
.field input:focus, .field textarea:focus {
  outline: none;
  border-color: var(--navy);
  box-shadow: 0 0 0 3px var(--bs-focus-ring-color);
}
.field textarea { resize: vertical; min-height: 8.5rem; }
.field--row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 560px) { .field--row { grid-template-columns: 1fr; } }
.field-hint { font-size: .8rem; color: var(--muted); margin-top: .35rem; }
.hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.alert-ktf {
  display: flex; gap: .7rem; align-items: flex-start;
  border-radius: var(--r-sm); padding: .9rem 1.1rem; margin-bottom: 1.25rem;
  font-size: .92rem; border: 1px solid transparent;
}
.alert-ktf i { font-size: 1.1rem; margin-top: .1rem; flex: none; }
.alert-ktf--success { background: var(--navy-tint); border-color: color-mix(in srgb, var(--navy) 24%, transparent); color: var(--ink); }
.alert-ktf--success i { color: var(--navy); }
.alert-ktf--error { background: var(--red-tint); border-color: color-mix(in srgb, var(--red) 26%, transparent); color: var(--ink); }
.alert-ktf--error i { color: var(--red); }

.map-frame { border-radius: var(--r-lg); overflow: hidden; border: 1px solid var(--line); line-height: 0; background: var(--surface-2); }
.map-frame iframe { width: 100%; height: 340px; border: 0; display: block; }

@media (max-width: 860px) { .contact__grid { grid-template-columns: 1fr; } }

/* --------------------------------------------------------------------------
   14. Page hero (sub-pages)
   A photograph carries the warmth; the navy wash keeps the words readable.
   -------------------------------------------------------------------------- */
.page-hero { padding-top: clamp(1.25rem, 3vw, 2rem); }
.page-hero__card {
  position: relative; overflow: hidden;
  border-radius: var(--r-lg);
  min-height: clamp(260px, 32vw, 400px);
  display: flex; align-items: flex-end;
  /* The photograph itself is set inline on the element: a url() inside a
     custom property would resolve against this stylesheet's folder. */
  background-color: var(--navy-deep);
  background-size: cover;
  background-position: var(--hero-pos, center);
  color: #fff;
}
.page-hero__card::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg,
    rgba(9, 14, 34, .94) 0%,
    rgba(9, 14, 34, .80) 46%,
    rgba(9, 14, 34, .30) 100%);
}
.page-hero__body {
  position: relative; z-index: 1;
  padding: clamp(1.75rem, 4vw, 3rem);
  max-width: 62ch;
}
.page-hero h1 { color: #fff; margin: .7rem 0 .65rem; }
.page-hero p { color: rgba(255, 255, 255, .86); margin: 0; font-size: 1.08rem; }

.crumbs { font-size: .82rem; color: rgba(255, 255, 255, .72); }
.crumbs a { color: rgba(255, 255, 255, .92); text-decoration: none; }
.crumbs a:hover { color: var(--gold); }

/* A quiet lead-in between the hero and the first block of a page. */
.page-intro { max-width: 68ch; }
.page-intro p { font-size: 1.12rem; color: var(--muted); }

/* Section footer link — "see all of something" without shouting. */
.more-link {
  display: inline-flex; align-items: center; gap: .45rem;
  font-weight: 700; font-size: .95rem; text-decoration: none;
  border-bottom: 2px solid var(--gold);
  padding-bottom: .15rem;
}
.more-link:hover { border-bottom-color: var(--navy); }

/* --------------------------------------------------------------------------
   15. News
   -------------------------------------------------------------------------- */
/* One feed, newest first, whichever section a post belongs to. */
.feed {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(330px, 100%), 1fr));
  gap: clamp(1rem, 2.5vw, 1.5rem);
  align-items: stretch;   /* cards in a row share a height, footers line up */
}

.post {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); overflow: hidden;
  display: flex; flex-direction: column;
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}
@media (hover: hover) {
  .post:hover {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--gold) 50%, transparent);
    box-shadow: var(--shadow);
  }
}
.post[hidden] { display: none; }

.post__tag {
  display: inline-flex; align-items: center; gap: .4rem;
  align-self: flex-start;
  padding: .25rem .7rem; border-radius: var(--r-pill);
  font-size: .74rem; font-weight: 700; letter-spacing: .01em;
  margin-bottom: .6rem;
}
.post__tag--1 { background: var(--navy-tint); color: var(--navy); }
.post__tag--2 { background: var(--gold-tint); color: var(--gold-ink); }
.post__media { aspect-ratio: 16 / 9; background: var(--surface-2); }
.post__media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .4s cubic-bezier(.2,.7,.3,1); }
@media (hover: hover) { .post:hover .post__media img { transform: scale(1.05); } }
.post__body { padding: 1.35rem; display: flex; flex-direction: column; flex: 1; }
.post__date { font-size: .8rem; color: var(--gold-ink); font-weight: 700; }
.post h3 { font-size: 1.15rem; margin: .35rem 0 .7rem; }
.post__content { color: var(--muted); font-size: .95rem; }
.post__content--clamp { display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; }
.post__content p:last-child { margin-bottom: 0; }
.post__content img { border-radius: var(--r-sm); margin-block: .75rem; }

.empty-note {
  border: 1px dashed var(--line); border-radius: var(--r-md);
  padding: 2rem 1.5rem; text-align: center; color: var(--muted); font-size: .95rem;
}

/* --------------------------------------------------------------------------
   16. Footer
   -------------------------------------------------------------------------- */
.site-footer { background: var(--footer-bg); color: var(--footer-ink); margin-top: var(--section); }
.site-footer__grid {
  display: grid; grid-template-columns: minmax(0, 1.6fr) repeat(2, minmax(0, 1fr));
  gap: clamp(1.75rem, 4vw, 3rem);
  padding-block: clamp(2.5rem, 5vw, 3.5rem);
}
.site-footer h3 { color: #fff; font-size: .9rem; margin: 0 0 .9rem; }
.site-footer p { font-size: .9rem; margin: 0 0 1rem; max-width: 44ch; }
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: .5rem; }
.site-footer a { color: var(--footer-ink); text-decoration: none; font-size: .9rem; }
.site-footer a:hover { color: var(--gold); }
.site-footer .brand__name { color: #fff; }
.site-footer .brand__name small { color: var(--footer-ink); }

.footer-bar {
  border-top: 1px solid rgba(255, 255, 255, .1);
  padding-block: 1.1rem;
  display: flex; flex-wrap: wrap; gap: .5rem 1.5rem;
  justify-content: space-between; align-items: center;
  font-size: .82rem;
}
.social-row { display: flex; gap: .6rem; }
.social-row a {
  display: inline-grid; place-items: center; width: 36px; height: 36px;
  border: 1px solid rgba(255, 255, 255, .18); border-radius: var(--r-sm);
  font-size: 1rem;
}
.social-row a:hover { border-color: var(--gold); }

@media (max-width: 760px) { .site-footer__grid { grid-template-columns: 1fr; } }

.to-top {
  position: fixed; right: 1.25rem; bottom: 1.25rem; z-index: 1020;
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--btn-primary); color: #fff; border: 0; font-size: 1.25rem;
  box-shadow: var(--shadow);
  opacity: 0; visibility: hidden; cursor: pointer;
  transition: opacity .2s ease, visibility .2s ease, background-color .15s ease;
}
.to-top.is-visible { opacity: 1; visibility: visible; }
.to-top:hover { background: var(--btn-primary-hover); color: #fff; }

/* --------------------------------------------------------------------------
   17. Motion and print
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

@media print {
  .topbar, .site-header, .to-top, .filters, .give-band, .nav-scrim { display: none !important; }
  body { background: #fff; color: #000; }
  .section { padding-block: 1rem; }
}

/* ==========================================================================
   18. Warmth and motion
   This is a children's charity, so the surfaces are soft, the edges curve and
   things move a little when you arrive. All of it is transform/opacity only —
   no layout thrash — and all of it stops under prefers-reduced-motion.
   ========================================================================== */

/* --- Soft coloured washes ----------------------------------------------- */
/* Two very low-opacity pools of brand colour give each band some depth
   without another image request. */
.section { position: relative; }

.section--tint {
  background:
    radial-gradient(60rem 30rem at 92% -10%, color-mix(in srgb, var(--gold) var(--wash-gold), transparent), transparent 58%),
    radial-gradient(50rem 26rem at -8% 108%, color-mix(in srgb, var(--navy) var(--wash-navy), transparent), transparent 60%),
    var(--surface-2);
}

.section--warm {
  background:
    radial-gradient(52rem 28rem at 92% -14%, color-mix(in srgb, var(--gold) var(--wash-warm), transparent), transparent 58%),
    var(--surface);
}

/* A confetti of faint dots, the sort of thing on a party invitation. */
.section--dots::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: radial-gradient(currentColor 1.5px, transparent 1.5px);
  background-size: 28px 28px;
  color: var(--navy);
  opacity: .06;
}
.section--dots > * { position: relative; }

/* --- The impact band gets a curved top and bottom ------------------------ */
/* The curves sit outside the band, so the band reserves that much room above
   and below itself; without this they paint over the section above. */
.impact {
  position: relative;
  margin-block: var(--wave-h);
  --wave-h: 46px;
}
.impact__wave {
  position: absolute; left: 0; width: 100%; height: var(--wave-h);
  display: block; fill: var(--band-bg);
}
.impact__wave--top    { top: 0;    transform: translateY(-99%); }
.impact__wave--bottom { bottom: 0; transform: translateY(99%) scaleY(-1); }

/* --- Micro-interactions -------------------------------------------------- */
/* Photographs lean in slightly when pointed at — the kind of movement that
   answers the pointer rather than decorating the page. */
.shot img,
.person__pic img,
.hero__figure img,
.about__figure img {
  transition: transform .4s cubic-bezier(.2, .7, .3, 1);
}
@media (hover: hover) {
  .shot:hover img,
  .person:hover .person__pic img { transform: scale(1.06); }
  .about__figure:hover img       { transform: scale(1.02); }
}

.shot { transition: box-shadow .25s ease, transform .25s ease; }
@media (hover: hover) {
  .shot:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
}

.person__pic { transition: box-shadow .25s ease; }
@media (hover: hover) {
  .person:hover .person__pic { box-shadow: 0 0 0 3px var(--gold); }
}

/* Programme cards warm up and grow a gold edge on hover. */
.programme { transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease; }
@media (hover: hover) {
  .programme:hover {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--gold) 55%, transparent);
    box-shadow: var(--shadow);
  }
}
.programme__icon {
  background: linear-gradient(140deg,
    color-mix(in srgb, var(--gold) 30%, var(--navy-tint)),
    var(--navy-tint));
  transition: transform .3s cubic-bezier(.2, .7, .3, 1);
}
@media (hover: hover) {
  .programme:hover .programme__icon { transform: rotate(-6deg) scale(1.08); }
}

.tile, .card-ktf { transition: transform .2s ease, border-color .2s ease; }
.btn-ktf, .btn-ktf-gold, .btn-ktf-ghost { transition: background-color .16s ease, color .16s ease, border-color .16s ease, transform .16s ease; }
@media (hover: hover) {
  .btn-ktf:hover, .btn-ktf-gold:hover { transform: translateY(-2px); }
}
.btn-ktf:active, .btn-ktf-gold:active, .btn-ktf-ghost:active { transform: translateY(0); }

/* --- Arrival ------------------------------------------------------------- */
/* One gentle rise as each block scrolls into view, staggered across the
   children of a grid so a row arrives like a row rather than all at once. */
@media (prefers-reduced-motion: no-preference) {
  .js [data-reveal] {
    opacity: 0;
    transform: translateY(14px);
  }
  .js [data-reveal].is-in {
    opacity: 1;
    transform: none;
    transition: opacity .55s ease, transform .55s cubic-bezier(.2, .7, .3, 1);
  }
  .js [data-reveal-stagger] > * {
    opacity: 0;
    transform: translateY(16px);
  }
  .js [data-reveal-stagger].is-in > * {
    opacity: 1;
    transform: none;
    transition: opacity .5s ease, transform .5s cubic-bezier(.2, .7, .3, 1);
    transition-delay: calc(var(--d, 0) * 70ms);
  }

  /* The hero's soft disc drifts, slowly enough to read as light rather than
     movement. */
  .hero__panel::after { animation: drift 14s ease-in-out infinite alternate; }
  @keyframes drift {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to   { transform: translate3d(-18px, -14px, 0) scale(1.06); }
  }

  /* The live dot on the hero badge. */
  .pill__dot { animation: blip 2.4s ease-in-out infinite; }
  @keyframes blip {
    0%, 100% { transform: scale(1);   opacity: 1; }
    50%      { transform: scale(1.35); opacity: .65; }
  }
}

/* ==========================================================================
   19. Page decoration
   Everything here is generated by CSS — no image requests, nothing that
   forces layout. The page-wide layer is position:fixed, so scrolling never
   repaints it; the section motifs animate transform only. All of it stops
   under prefers-reduced-motion and none of it is in the tab order.
   ========================================================================== */

/* The ground colour moves to <html> so the fixed layer below can sit behind
   a transparent <body> without covering anything. */
html { background: var(--bg); }
body { background: transparent; }

.page-decor {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  contain: strict;
}

/* Three soft pools of brand colour, drifting slowly enough that you notice
   depth rather than movement. */
.page-decor span {
  position: absolute;
  display: block;
  border-radius: 50%;
  opacity: var(--decor-strength, .5);
}
.page-decor span:nth-child(1) {
  width: 46rem; height: 46rem; top: -14rem; right: -12rem;
  background: radial-gradient(circle, color-mix(in srgb, var(--gold) 22%, transparent), transparent 68%);
}
.page-decor span:nth-child(2) {
  width: 40rem; height: 40rem; top: 38%; left: -16rem;
  background: radial-gradient(circle, color-mix(in srgb, var(--navy) 22%, transparent), transparent 68%);
}
.page-decor span:nth-child(3) {
  width: 34rem; height: 34rem; bottom: -12rem; right: 12%;
  background: radial-gradient(circle, color-mix(in srgb, var(--red) 12%, transparent), transparent 70%);
}

:root { --decor-strength: .85; }
[data-theme="dark"] { --decor-strength: .6; }

@media (prefers-reduced-motion: no-preference) {
  .page-decor span:nth-child(1) { animation: float-a 34s ease-in-out infinite alternate; }
  .page-decor span:nth-child(2) { animation: float-b 44s ease-in-out infinite alternate; }
  .page-decor span:nth-child(3) { animation: float-a 38s ease-in-out infinite alternate-reverse; }

  @keyframes float-a {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to   { transform: translate3d(-4rem, 3rem, 0) scale(1.12); }
  }
  @keyframes float-b {
    from { transform: translate3d(0, 0, 0) scale(1.08); }
    to   { transform: translate3d(3.5rem, -2.5rem, 0) scale(1); }
  }
}

/* --- Section motifs ------------------------------------------------------ */
/* Each decorated section gets one treatment, never two — a pattern on top of
   a wash stacks two tints under the same text. The layer is inset past the
   edges so a drifting pattern never shows its seam. */
.section--speckle > .shell,
.section--rings > .shell,
.section--grid > .shell { position: relative; z-index: 1; }

/* The pattern layer is deliberately larger than its section and drifts, so the
   section has to clip it. Without that, the bleed and the drift both widen the
   page, which on a phone also stretches the layout viewport. `clip` creates no
   scroll container, so nothing else changes. */
.section--speckle,
.section--rings,
.section--grid { overflow: clip; }

.section--speckle::before,
.section--rings::before,
.section--grid::before {
  content: "";
  position: absolute;
  inset: -8rem -4rem;
  pointer-events: none;
  color: var(--navy);
  opacity: .10;
}
[data-theme="dark"] .section--speckle::before,
[data-theme="dark"] .section--rings::before,
[data-theme="dark"] .section--grid::before { opacity: .14; }

/* Confetti: dots of three sizes on an irregular tile, so it reads as thrown
   rather than printed. */
.section--speckle::before {
  background-image:
    radial-gradient(circle at 18% 22%, currentColor 2.4px, transparent 3px),
    radial-gradient(circle at 68% 44%, currentColor 1.6px, transparent 2.2px),
    radial-gradient(circle at 42% 78%, currentColor 3px,   transparent 3.6px),
    radial-gradient(circle at 88% 84%, currentColor 1.4px, transparent 2px);
  background-size: 104px 104px;
}

/* Bubbles: outlined circles, like a child's drawing of them. */
.section--rings::before {
  background-image:
    radial-gradient(circle at 25% 30%, transparent 13px, currentColor 13px 14.2px, transparent 15px),
    radial-gradient(circle at 75% 70%, transparent 8px,  currentColor 8px 9px,     transparent 10px);
  background-size: 180px 180px;
}

/* Graph paper, for the pages that are mostly words. */
.section--grid::before {
  background-image:
    linear-gradient(currentColor 1px, transparent 1px),
    linear-gradient(90deg, currentColor 1px, transparent 1px);
  background-size: 46px 46px;
  opacity: .05;
}
[data-theme="dark"] .section--grid::before { opacity: .09; }

@media (prefers-reduced-motion: no-preference) {
  .section--speckle::before { animation: pattern-drift 60s linear infinite; }
  .section--rings::before   { animation: pattern-drift 90s linear infinite reverse; }

  /* One tile's travel, so the loop is seamless. */
  @keyframes pattern-drift {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(104px, 104px, 0); }
  }
}

/* --- The footer gets the same curved edge as the impact band ------------- */
.site-footer { position: relative; --wave-h: 46px; margin-top: calc(var(--section) + var(--wave-h)); }
.site-footer__wave {
  position: absolute; top: 0; left: 0; width: 100%; height: var(--wave-h);
  transform: translateY(-99%);
  display: block; fill: var(--footer-bg);
}

/* Phones do this work on a battery, and the pattern is barely visible at that
   size anyway. Keep the colour, drop the animation. */
@media (max-width: 700px) {
  .page-decor span,
  .section--speckle::before,
  .section--rings::before { animation: none !important; }
}

/* ==========================================================================
   20. Announcement
   The poster that greets visitors on the home page. Confetti is drawn only
   when the dialog opens, is capped, and is skipped entirely under
   prefers-reduced-motion.
   ========================================================================== */
.announce {
  border: 0; padding: 0; background: transparent;
  width: fit-content;
  max-width: min(880px, 100% - 2rem);
  max-height: calc(100% - 2rem);
  margin: auto;
  overflow: visible;
}
.announce::backdrop {
  background:
    radial-gradient(70rem 40rem at 50% 0%, rgba(29, 60, 142, .55), transparent 70%),
    rgba(7, 11, 28, .93);
}
/* Hugs the poster rather than the dialog, so the corner button stays on the
   corner of the image whichever way round the screen is. */
.announce__inner {
  position: relative; text-align: center;
  width: fit-content; max-width: 100%; margin-inline: auto;
}

.announce__media {
  display: block; margin-inline: auto;
  max-width: 100%; max-height: 78vh; width: auto; height: auto;
  border-radius: var(--r-lg);
  box-shadow: 0 0 0 1px rgba(251, 193, 9, .35), 0 30px 70px -30px rgba(0, 0, 0, .85);
}
a.announce__media-link { display: block; }

.announce__caption {
  margin: 1rem auto 0; max-width: 52ch;
  color: rgba(255, 255, 255, .88); font-size: .98rem;
}

.announce__close {
  position: absolute; top: -.85rem; right: -.85rem; z-index: 3;
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  border: 1px solid rgba(255, 255, 255, .3);
  background: var(--navy-deep); color: #fff;
  font-size: 1.1rem; cursor: pointer;
  transition: transform .2s ease, background-color .2s ease;
}
.announce__close:hover { background: var(--red); transform: rotate(90deg); }

.announce__confetti {
  position: fixed; inset: 0; z-index: 2;
  overflow: hidden; pointer-events: none;
}
.announce__confetti i {
  position: absolute; top: -8vh;
  width: var(--w, 9px); height: var(--h, 14px);
  background: var(--c, var(--gold));
  border-radius: var(--br, 2px);
  opacity: 0;
  will-change: transform;
}

@media (prefers-reduced-motion: no-preference) {
  .announce[open] .announce__media { animation: announce-pop .5s cubic-bezier(.2, .9, .3, 1.25) both; }
  .announce__confetti i { animation: confetti-fall var(--dur, 4s) linear var(--delay, 0s) forwards; }

  @keyframes announce-pop {
    from { opacity: 0; transform: scale(.9) translateY(14px); }
    to   { opacity: 1; transform: none; }
  }
  @keyframes confetti-fall {
    0%   { opacity: 1; transform: translate3d(0, 0, 0) rotate(0); }
    100% { opacity: 0; transform: translate3d(var(--drift, 0), 108vh, 0) rotate(var(--spin, 540deg)); }
  }
}

@media (max-width: 600px) {
  /* There is no room outside the poster at this width, so the button tucks
     into the image instead of hanging off it. */
  .announce__close {
    top: .5rem; right: .5rem; width: 38px; height: 38px;
    background: rgba(7, 11, 28, .74);
    border-color: rgba(255, 255, 255, .45);
  }
  /* svh keeps clear of the browser's own chrome; vh first for anything that
     does not know the unit, since an unknown unit drops the declaration. */
  .announce__media { max-height: 62vh; max-height: 62svh; }
  .announce__caption { font-size: .92rem; margin-top: .75rem; }
}

/* Short screens, mostly phones held sideways. */
@media (max-height: 520px) {
  .announce__media { max-height: 74vh; max-height: 74svh; }
  .announce__caption { display: none; }
}

/* ==========================================================================
   21. Advertising
   Clearly separated from the charity's own words, and only ever on the blog.
   ========================================================================== */
.ad-slot {
  margin-block: clamp(1.75rem, 4vw, 2.75rem);
  padding: .75rem;
  border: 1px dashed var(--line);
  border-radius: var(--r-md);
  background: var(--surface-2);
  text-align: center;
  min-height: 100px;
  overflow: hidden;
}
.ad-slot__label {
  display: block;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: .5rem;
}
.ad-slot ins { max-width: 100%; }
@media print { .ad-slot { display: none !important; } }

/* ==========================================================================
   22. Blog
   ========================================================================== */

/* --- Listing: the lead post --------------------------------------------- */
.lead-post {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  margin-bottom: clamp(1.25rem, 3vw, 2rem);
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}
@media (hover: hover) {
  .lead-post:hover {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--gold) 55%, transparent);
    box-shadow: var(--shadow);
  }
  .lead-post:hover .lead-post__media img { transform: scale(1.04); }
}
.lead-post__media { background: var(--surface-2); min-height: 260px; overflow: hidden; }
.lead-post__media img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .45s cubic-bezier(.2, .7, .3, 1);
}
.lead-post__body { padding: clamp(1.5rem, 3vw, 2.5rem); align-self: center; }
.lead-post__body h2 { font-size: clamp(1.5rem, 2.6vw, 2.1rem); margin: 1rem 0 .7rem; }
.lead-post__body p { color: var(--muted); }
.lead-post__meta {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  font-size: .84rem; color: var(--muted);
}
@media (max-width: 820px) {
  .lead-post { grid-template-columns: 1fr; }
  .lead-post__media { min-height: 200px; aspect-ratio: 16 / 9; }
}

/* --- Listing: the cards -------------------------------------------------- */
.post-card {
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}
@media (hover: hover) {
  .post-card:hover {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--gold) 50%, transparent);
    box-shadow: var(--shadow);
  }
  .post-card:hover .post-card__media img { transform: scale(1.05); }
}
.post-card__link { text-decoration: none; color: inherit; display: flex; flex-direction: column; flex: 1; }
.post-card__media { position: relative; aspect-ratio: 16 / 9; background: var(--surface-2); overflow: hidden; }
.post-card__media img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .4s cubic-bezier(.2, .7, .3, 1);
}
.post-card__placeholder {
  position: absolute; inset: 0; display: grid; place-items: center;
  color: var(--muted); font-size: 2rem; opacity: .4;
}
.post-card__tag {
  position: absolute; left: .75rem; top: .75rem;
  padding: .25rem .7rem; border-radius: var(--r-pill);
  font-size: .72rem; font-weight: 700;
}
.post-card__body { padding: 1.25rem; display: flex; flex-direction: column; flex: 1; }
.post-card__date {
  display: flex; align-items: center; gap: .5rem;
  font-size: .8rem; color: var(--muted); margin-bottom: .5rem;
}
.post-card__dot { width: 3px; height: 3px; border-radius: 50%; background: currentColor; flex: none; opacity: .6; }
.post-card__title { font-size: 1.2rem; margin: 0 0 .6rem; }
.post-card__excerpt { color: var(--muted); font-size: .93rem; margin: 0 0 auto; }
.post-card__foot {
  display: flex; align-items: center; gap: 1rem;
  padding: .85rem 1.25rem; border-top: 1px solid var(--line);
  font-size: .84rem; color: var(--muted);
}
.post-card__foot i { color: var(--gold-ink); }
.post-card__more { margin-left: auto; font-weight: 700; text-decoration: none; font-size: .88rem; }

/* --- Listing: filters and paging ----------------------------------------- */
.filter-link {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .45rem 1rem; border-radius: var(--r-pill);
  border: 1px solid var(--line); background: var(--surface);
  font-family: var(--font-display); font-weight: 700; font-size: .92rem;
  color: var(--muted); text-decoration: none;
  transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
.filter-link:hover { color: var(--ink); border-color: var(--ink); }
.filter-link.is-on { background: var(--btn-primary); border-color: var(--btn-primary); color: #fff; }
.filter-link span { font-family: var(--font-body); font-size: .78rem; font-weight: 600; opacity: .7; }
.filter-link--feed { color: var(--gold-ink); }

.pager {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: 1.5rem; border-top: 1px solid var(--line);
}
.pager__step {
  padding: .6rem 1.25rem; border-radius: var(--r-pill);
  border: 1px solid var(--line); text-decoration: none;
  font-weight: 700; font-size: .92rem; color: var(--ink);
}
.pager__step:hover { border-color: var(--navy); color: var(--navy); }
.pager__step.is-off { opacity: .35; pointer-events: none; }
.pager__count { font-size: .88rem; color: var(--muted); }

/* --- The post itself ----------------------------------------------------- */
.post-page__head { padding-block: clamp(1.75rem, 4vw, 3rem) clamp(1rem, 2vw, 1.5rem); }
.crumbs-dark { font-size: .82rem; color: var(--muted); }
.crumbs-dark a { text-decoration: none; }
.post-page__title { max-width: 20ch; margin: .85rem 0 .75rem; }
@media (min-width: 700px) { .post-page__title { max-width: 24ch; } }
.post-page__meta {
  display: flex; align-items: center; gap: .55rem; flex-wrap: wrap;
  font-size: .88rem; color: var(--muted); margin: 0;
}

.post-page__hero { border-radius: var(--r-lg); overflow: hidden; margin-bottom: clamp(1.5rem, 3vw, 2.5rem); }
.post-page__hero img { width: 100%; display: block; aspect-ratio: 16 / 9; object-fit: cover; }

.post-page__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 20rem;
  gap: clamp(1.75rem, 4vw, 3.5rem);
  align-items: start;
  padding-bottom: var(--section);
}
@media (max-width: 980px) { .post-page__grid { grid-template-columns: 1fr; } }

.post-page__content { font-size: 1.08rem; }
.post-page__content > * + * { margin-top: 1.1rem; }
.post-page__content h3 { font-size: 1.4rem; margin-top: 2rem; }
.post-page__content h4 { font-size: 1.15rem; margin-top: 1.5rem; }
.post-page__content img { border-radius: var(--r-md); }
.post-page__content blockquote {
  margin: 1.75rem 0; padding: .25rem 0 .25rem 1.4rem;
  border-left: 3px solid var(--gold);
  font-family: var(--font-display); font-size: 1.15rem; line-height: 1.5;
}
.post-page__content ul, .post-page__content ol { padding-left: 1.3rem; }
.post-page__content li { margin-bottom: .4rem; }

.post-page__actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 1.25rem;
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: 1.5rem; border-top: 1px solid var(--line);
}

/* --- Heart --------------------------------------------------------------- */
.heart {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .6rem 1.2rem; border-radius: var(--r-pill);
  border: 1px solid var(--line); background: var(--surface);
  font-family: var(--font-body); font-weight: 700; font-size: .95rem;
  color: var(--ink); cursor: pointer;
  transition: border-color .15s ease, color .15s ease, transform .15s ease;
}
.heart i { color: var(--red); font-size: 1.05rem; }
.heart:hover:not(:disabled) { border-color: var(--red); transform: translateY(-2px); }
.heart.is-on { background: var(--red-tint); border-color: color-mix(in srgb, var(--red) 35%, transparent); cursor: default; }
.heart:disabled { cursor: default; }
.heart__word { color: var(--muted); font-weight: 600; }
@media (prefers-reduced-motion: no-preference) {
  .heart.just-loved i { animation: heart-pop .45s cubic-bezier(.2, .9, .3, 1.4); }
  @keyframes heart-pop {
    0% { transform: scale(1); } 45% { transform: scale(1.45); } 100% { transform: scale(1); }
  }
}

/* --- Share --------------------------------------------------------------- */
.share { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
.share__label { font-size: .85rem; color: var(--muted); font-weight: 600; }
.share__links { display: flex; gap: .4rem; flex-wrap: wrap; }
.share__btn {
  display: inline-grid; place-items: center;
  width: 40px; height: 40px; padding: 0;
  border: 1px solid var(--line); border-radius: 50%;
  background: var(--surface); color: var(--muted);
  font-size: 1rem; cursor: pointer; text-decoration: none;
  transition: color .15s ease, border-color .15s ease, transform .15s ease;
}
.share__btn:hover { color: var(--navy); border-color: var(--navy); transform: translateY(-2px); }
.share__native { width: auto; padding-inline: 1rem; gap: .45rem; border-radius: var(--r-pill); font-weight: 700; }

/* --- Sidebar ------------------------------------------------------------- */
.post-page__aside { position: sticky; top: 6rem; display: grid; gap: 1rem; }
@media (max-width: 980px) { .post-page__aside { position: static; } }
.aside-card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 1.4rem;
}
.aside-card h2 { font-size: 1.05rem; margin: 0 0 .6rem; }
.aside-card p { font-size: .92rem; color: var(--muted); margin: 0 0 1rem; }
.aside-list { list-style: none; margin: 0; padding: 0; }
.aside-list li + li { margin-top: .7rem; padding-top: .7rem; border-top: 1px solid var(--line); }
.aside-list a { text-decoration: none; font-weight: 600; font-size: .93rem; }

/* --- Comments ------------------------------------------------------------ */
.comments { margin-top: clamp(2.5rem, 5vw, 4rem); }
.comments__heading { font-size: 1.35rem; margin: 0 0 1.5rem; }
.comments__empty { color: var(--muted); }
.comments__list { list-style: none; margin: 0 0 2.5rem; padding: 0; }
.comment { display: flex; gap: 1rem; padding: 1.1rem 0; border-bottom: 1px solid var(--line); }
.comment__avatar {
  width: 42px; height: 42px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  background: var(--navy-tint); color: var(--navy);
  font-family: var(--font-display); font-weight: 800;
}
.comment__by { font-size: .88rem; color: var(--muted); display: flex; gap: .6rem; align-items: baseline; flex-wrap: wrap; }
.comment__by strong { color: var(--ink); font-size: .95rem; }
.comment__text { margin: .35rem 0 0; }

.comment-form {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: clamp(1.25rem, 3vw, 1.75rem);
}
.comment-form h3 { font-size: 1.15rem; margin: 0 0 1.1rem; }

/* --- Forms that are working ---------------------------------------------- */
/* Mail is delivered during the request, so a send can sit for several seconds.
   These give the sender something definite to look at straight away, and stop a
   second submit sending the same message twice. */
.btn-spin {
  display: inline-block;
  width: .85em; height: .85em;
  margin-right: .55em; vertical-align: -.08em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: btn-spin .6s linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .btn-spin { animation-duration: 2.4s; } }

button.is-busy { pointer-events: none; opacity: .9; }
form.is-busy [data-busy-note] { display: block; }

.form-busy {
  display: flex; align-items: center; gap: .5rem;
  margin: .85rem 0 0;
  font-size: .94rem; font-weight: 600;
  color: var(--navy);
}
[data-theme="dark"] .form-busy { color: var(--gold); }
.form-busy::before {
  content: "";
  width: .85em; height: .85em; flex: none;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%;
  animation: btn-spin .6s linear infinite;
}
@media (prefers-reduced-motion: reduce) { .form-busy::before { animation-duration: 2.4s; } }
