/* ==========================================================================
   Help The Poor Initiative — Shared stylesheet
   Loaded by EVERY page. Contains design tokens, reset, typography, buttons,
   the shared header + footer, and the media placeholder system.
   Page-specific styles live in their own file (e.g. css/home.css).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens
   -------------------------------------------------------------------------- */
:root {
  /* Brand palette
     The greens are derived from the logo itself: sampling logo.jpeg gives a
     dominant #207626 (hue 124°, sat 57%). The scale below keeps that hue and
     deepens it for large areas — a saturated green at ~150° is what made the
     earlier palette feel generic. */
  --green:        #1E5C26;   /* primary: buttons, headings, links            */
  --green-mid:    #2A7A34;   /* hover / gradient partner                     */
  --green-deep:   #123A19;   /* footer + newsletter card background          */
  --green-soft:   #E8F1E8;   /* tints, icon wells                            */
  --green-logo:   #207626;   /* the raw logo green, for exact-match moments  */
  --orange:       #EE7C20;   /* accent: sun, CTAs, icons, subscribe          */
  --orange-warm:  #F79420;   /* gradient partner for the sun mark            */
  --orange-deep:  #D9660E;   /* accent hover                                 */
  --red:          #D42A28;   /* UI red: heart, healthcare accent             */
  --red-logo:     #D00000;   /* sampled from "INITIATIVE" in logo.jpeg       */
  --navy:         #12285C;   /* UI navy                                      */
  --navy-logo:    #001743;   /* sampled from "HELP THE POOR" in logo.jpeg    */
  --blue:         #1565C0;   /* clothing & essentials accent                 */
  --cream:        #FBF6EC;   /* "Our Impact Together" card background        */

  /* Neutrals */
  --ink:          #16211A;   /* primary text                                 */
  --ink-strong:   #0C120E;   /* hero headline                                */
  --muted:        #5C665E;   /* body / secondary text                        */
  --muted-light:  #8A938C;   /* captions on dark surfaces                    */
  --line:         #E5E7E1;   /* hairlines, dividers                          */
  --surface:      #FFFFFF;
  --surface-alt:  #F6F7F4;   /* page background behind card bands            */

  /* Typography */
  --font-display: 'Plus Jakarta Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-body:    'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* Layout */
  --container:  1160px;
  --gutter:     24px;
  --header-h:   88px;

  /* Shape + depth */
  --radius-sm:  10px;
  --radius:     14px;
  --radius-lg:  22px;
  --shadow-sm:  0 2px 10px rgba(16, 32, 20, .06);
  --shadow-md:  0 10px 34px rgba(16, 32, 20, .10);
  --shadow-lg:  0 22px 60px rgba(16, 32, 20, .16);

  /* Motion */
  --ease:       cubic-bezier(.22, .61, .36, 1);
  --speed:      .28s;
}

/* --------------------------------------------------------------------------
   2. Reset + base
   -------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

* { margin: 0; padding: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 16px);
}

body {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  color: var(--muted);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* Locked while the mobile drawer is open */
body.is-locked { overflow: hidden; }

img,
svg,
video {
  display: block;
  max-width: 100%;
}

img { height: auto; }

a {
  color: var(--green);
  text-decoration: none;
  transition: color var(--speed) var(--ease);
}

a:hover { color: var(--orange); }

button,
input,
textarea,
select {
  font: inherit;
  color: inherit;
}

button { background: none; border: 0; cursor: pointer; }

ul, ol { list-style: none; }

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  color: var(--ink);
  line-height: 1.18;
  font-weight: 800;
  letter-spacing: -.012em;
}

/* Visible focus for keyboard users only — never a mouse-click halo */
:focus-visible {
  outline: 3px solid var(--orange);
  outline-offset: 3px;
  border-radius: 4px;
}

::selection {
  background: var(--green);
  color: #fff;
}

/* --------------------------------------------------------------------------
   3. Utilities
   -------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -100px;
  left: 16px;
  z-index: 999;
  padding: 12px 20px;
  background: var(--green);
  color: #fff;
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  font-weight: 600;
  transition: top var(--speed) var(--ease);
}

.skip-link:focus {
  top: 0;
  color: #fff;
}


/* --------------------------------------------------------------------------
   4. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 13px 26px;
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: .875rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition: transform var(--speed) var(--ease),
              box-shadow var(--speed) var(--ease),
              background-color var(--speed) var(--ease),
              color var(--speed) var(--ease);
}

.btn:hover  { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn svg { flex: none; }

.btn--green {
  background: var(--green);
  color: #fff;
  box-shadow: 0 6px 18px rgba(30, 92, 38, .30);
}

.btn--green:hover {
  background: var(--green-mid);
  color: #fff;
  box-shadow: 0 12px 28px rgba(30, 92, 38, .40);
}

.btn--orange {
  background: var(--orange);
  color: #fff;
  box-shadow: 0 6px 18px rgba(238, 124, 32, .30);
}

.btn--orange:hover {
  background: var(--orange-deep);
  color: #fff;
  box-shadow: 0 10px 26px rgba(238, 124, 32, .40);
}

.btn--block { width: 100%; }

/* "View all …" style text link with a chevron */
.link-more {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-size: .8125rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;   /* never break "View All Programs" across two lines */
  color: var(--green);
}

.link-more svg { transition: transform var(--speed) var(--ease); }
.link-more:hover svg { transform: translateX(4px); }

/* --------------------------------------------------------------------------
   5. Media + placeholder system
   Images that have not been supplied yet fall back to a branded tinted panel.
   The `onerror` handler is inline in the markup because an image can fail
   before main.js has executed.
   -------------------------------------------------------------------------- */
.media {
  position: relative;
  overflow: hidden;
  background:
    linear-gradient(140deg,
      color-mix(in srgb, var(--ph, var(--green)) 22%, #fff),
      color-mix(in srgb, var(--ph, var(--green)) 8%,  #fff));
  border-radius: inherit;
}

/* Placeholder glyph — sits under the image, revealed when the image fails */
.media::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 34px;
  height: 34px;
  opacity: .5;
  background-color: var(--ph, var(--green));
  -webkit-mask: var(--ph-icon) center / contain no-repeat;
          mask: var(--ph-icon) center / contain no-repeat;
  --ph-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='16' rx='2'/%3E%3Ccircle cx='8.5' cy='9.5' r='1.5'/%3E%3Cpath d='m21 16-4.5-4.5L9 19'/%3E%3C/svg%3E");
}

.media > img {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .5s var(--ease), opacity var(--speed) var(--ease);
}

/* Set by the inline onerror handler when the file is not there yet */
.media > img.is-missing { opacity: 0; }

/* Aspect ratios — locked so nothing reflows when real photos are dropped in */
.media--16x10 { aspect-ratio: 16 / 10; }
.media--4x3   { aspect-ratio: 4 / 3;   }
.media--1x1   { aspect-ratio: 1 / 1;   }

/* --------------------------------------------------------------------------
   6. Site header
   Transparent while over the hero, solid + fixed once the page scrolls.
   -------------------------------------------------------------------------- */
.site-header {
  position: absolute;
  inset: 0 0 auto;
  z-index: 100;
  height: var(--header-h);
  display: flex;
  align-items: center;
  transition: background-color var(--speed) var(--ease),
              box-shadow var(--speed) var(--ease),
              height var(--speed) var(--ease);
}

.site-header.is-scrolled {
  position: fixed;
  height: 74px;
  background: rgba(255, 255, 255, .96);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: var(--shadow-sm);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 22px;
  width: 100%;
  max-width: 1440px;
  margin-inline: auto;
  padding-inline: 28px;
}

/* Brand ------------------------------------------------------------------ */
.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: none;
}

/* The supplied logo.jpeg has an OPAQUE WHITE background (no alpha), so it is
   always framed in a white circle — deliberate, never bare on a dark surface. */
.logo-badge {
  width: 62px;
  height: 62px;
  flex: none;
  border-radius: 50%;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 2px 12px rgba(0, 0, 0, .18);
  transition: width var(--speed) var(--ease), height var(--speed) var(--ease);
}

.logo-badge img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.04);
}

.site-header.is-scrolled .logo-badge {
  width: 52px;
  height: 52px;
}

/* Primary navigation ----------------------------------------------------- */
.primary-nav { margin-left: auto; }

.nav-list {
  display: flex;
  align-items: center;
  gap: 4px;
}

.nav-item { position: relative; }

.nav-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 10px 13px;
  font-family: var(--font-display);
  font-size: .9375rem;
  font-weight: 600;
  color: #fff;
  border-radius: 8px;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .35);
  transition: color var(--speed) var(--ease),
              background-color var(--speed) var(--ease);
}

.nav-link .caret {
  width: 10px;
  height: 10px;
  transition: transform var(--speed) var(--ease);
}

.nav-link:hover,
.nav-item:focus-within > .nav-link,
.nav-link[aria-expanded="true"] {
  color: var(--orange-warm);
}

.nav-link[aria-expanded="true"] .caret { transform: rotate(180deg); }

.nav-link.is-active { color: var(--orange-warm); }

/* Solid-header variant of the nav links */
.site-header.is-scrolled .nav-link {
  color: var(--ink);
  text-shadow: none;
}

.site-header.is-scrolled .nav-link:hover,
.site-header.is-scrolled .nav-item:focus-within > .nav-link,
.site-header.is-scrolled .nav-link.is-active {
  color: var(--green);
}

/* Dropdowns -------------------------------------------------------------- */
.dropdown {
  position: absolute;
  top: calc(100% + 10px);
  left: 0;
  min-width: 232px;
  padding: 10px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition: opacity var(--speed) var(--ease),
              transform var(--speed) var(--ease),
              visibility var(--speed) var(--ease);
}

/* `.is-open` is the ONLY thing that opens a dropdown. Hover and focus are
   applied by main.js rather than by :hover/:focus-within here, so that the
   visible state and aria-expanded can never drift apart. */
.dropdown.is-open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

/* Last two menus flip to the right edge so they never overflow the viewport */
.nav-item:nth-last-child(-n+2) .dropdown {
  left: auto;
  right: 0;
}

.dropdown a {
  display: block;
  padding: 9px 14px;
  font-size: .9375rem;
  font-weight: 500;
  color: var(--muted);
  border-radius: 8px;
  transition: background-color var(--speed) var(--ease),
              color var(--speed) var(--ease),
              padding-left var(--speed) var(--ease);
}

.dropdown a:hover {
  background: var(--green-soft);
  color: var(--green);
  padding-left: 18px;
}

/* Header actions --------------------------------------------------------- */
.header-actions {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: none;
}

.btn-donate {
  padding: 12px 22px;
  font-size: .8125rem;
}

.btn-donate .heart { color: var(--red); }

.nav-toggle {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  color: #fff;
  transition: background-color var(--speed) var(--ease),
              color var(--speed) var(--ease);
}

.nav-toggle:hover { background: rgba(255, 255, 255, .16); }

.site-header.is-scrolled .nav-toggle { color: var(--ink); }
.site-header.is-scrolled .nav-toggle:hover { background: var(--surface-alt); }

.nav-toggle .bar {
  display: block;
  width: 24px;
  height: 2.5px;
  margin: 3px 0;
  border-radius: 2px;
  background: currentColor;
  transition: transform var(--speed) var(--ease),
              opacity var(--speed) var(--ease);
}

.nav-toggle[aria-expanded="true"] .bar:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .bar:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }

/* --------------------------------------------------------------------------
   7. Mobile drawer
   -------------------------------------------------------------------------- */
.nav-backdrop {
  position: fixed;
  inset: 0;
  z-index: 110;
  background: rgba(10, 20, 13, .55);
  backdrop-filter: blur(2px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--speed) var(--ease), visibility var(--speed) var(--ease);
}

.nav-backdrop.is-open {
  opacity: 1;
  visibility: visible;
}

.drawer {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 120;
  width: min(400px, 88vw);
  height: 100dvh;
  padding: 26px 24px 40px;
  background: #fff;
  overflow-y: auto;
  overscroll-behavior: contain;
  transform: translateX(102%);
  box-shadow: var(--shadow-lg);
  /* visibility:hidden does two jobs the transform alone cannot: it keeps the
     off-canvas panel out of the document's scroll width (otherwise it forces
     a horizontal scrollbar), and it takes its links out of the tab order so
     keyboard users cannot tab into an invisible menu. */
  visibility: hidden;
  /* visibility is stepped, not eased. Easing it means that at the instant
     .is-open is added the computed value is still `hidden`, so main.js cannot
     move focus to the close button and the menu opens with focus stranded on
     the hamburger behind it. So: hold visibility until the slide-out finishes
     when closing (0s delay .34s), and flip it immediately when opening. */
  transition: transform .34s var(--ease), visibility 0s linear .34s;
}

.drawer.is-open {
  transform: translateX(0);
  visibility: visible;
  transition: transform .34s var(--ease), visibility 0s linear 0s;
}

.drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 20px;
  margin-bottom: 12px;
  border-bottom: 1px solid var(--line);
}

.drawer-close {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 10px;
  color: var(--ink);
  transition: background-color var(--speed) var(--ease);
}

.drawer-close:hover { background: var(--surface-alt); }

.drawer-nav > li { border-bottom: 1px solid var(--line); }

.drawer-trigger,
.drawer-nav > li > a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 15px 4px;
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 700;
  color: var(--ink);
  text-align: left;
}

.drawer-trigger .caret { transition: transform var(--speed) var(--ease); }
.drawer-trigger[aria-expanded="true"] { color: var(--green); }
.drawer-trigger[aria-expanded="true"] .caret { transform: rotate(180deg); }

.drawer-sub {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .32s var(--ease);
}

.drawer-sub.is-open { grid-template-rows: 1fr; }

.drawer-sub > div { overflow: hidden; }

.drawer-sub a {
  display: block;
  padding: 10px 4px 10px 18px;
  font-size: .9375rem;
  font-weight: 500;
  color: var(--muted);
  border-left: 2px solid var(--line);
}

.drawer-sub a:hover {
  color: var(--green);
  border-left-color: var(--green);
}

.drawer-sub > div > :last-child { margin-bottom: 14px; }

.drawer-cta { margin-top: 26px; }

/* --------------------------------------------------------------------------
   8. Site footer
   -------------------------------------------------------------------------- */
.site-footer {
  background: var(--green-deep);
  color: rgba(255, 255, 255, .74);
  font-size: .9375rem;
}

.footer-top {
  display: grid;
  grid-template-columns: 1.5fr repeat(4, 1fr);
  gap: 40px 32px;
  padding: 72px 0 56px;
}

.footer-brand-row {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 18px;
}

.footer-brand-row .logo-badge {
  width: 54px;
  height: 54px;
  box-shadow: none;
}

.footer-wordmark {
  font-family: var(--font-display);
  line-height: 1.1;
}

.footer-wordmark strong {
  display: block;
  font-size: 1.125rem;
  font-weight: 800;
  color: #fff;
  letter-spacing: .01em;
}

.footer-wordmark span {
  display: block;
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .34em;
  color: var(--orange-warm);
}

.footer-blurb {
  max-width: 34ch;
  margin-bottom: 22px;
  line-height: 1.75;
}

.socials {
  display: flex;
  gap: 10px;
}

.socials a {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  color: #fff;
  background: rgba(255, 255, 255, .12);
  transition: background-color var(--speed) var(--ease),
              transform var(--speed) var(--ease);
}

.socials a:hover {
  background: var(--orange);
  color: #fff;
  transform: translateY(-3px);
}

.footer-col h3 {
  margin-bottom: 20px;
  font-size: .8125rem;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #fff;
}

.footer-col li + li { margin-top: 11px; }

.footer-col a {
  color: rgba(255, 255, 255, .74);
  transition: color var(--speed) var(--ease), padding-left var(--speed) var(--ease);
}

.footer-col a:hover {
  color: var(--orange-warm);
  padding-left: 5px;
}

.contact-list li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  line-height: 1.6;
}

.contact-list svg {
  flex: none;
  margin-top: 3px;
  color: var(--orange-warm);
}

.contact-list a:hover { padding-left: 0; }

.footer-bottom {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px 26px;
  padding: 22px 0;
  border-top: 1px solid rgba(255, 255, 255, .13);
  font-size: .875rem;
}

.footer-bottom nav {
  display: flex;
  align-items: center;
  gap: 26px;
}

.footer-bottom a { color: rgba(255, 255, 255, .74); }
.footer-bottom a:hover { color: var(--orange-warm); }

/* The footer's "Cookie Preferences" trigger. A <button>, not a link — it
   reopens the notice on this page rather than navigating anywhere — but it
   sits among links and must read as one of them, so it inherits the same
   colour, size and hover as its siblings. */
.footer-legal-link {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: rgba(255, 255, 255, .74);
  cursor: pointer;
  transition: color var(--speed) var(--ease);
}

.footer-legal-link:hover { color: var(--orange-warm); }
.footer-legal-link:focus-visible { outline: 2px solid var(--orange-warm); outline-offset: 3px; }

.footer-sep {
  width: 1px;
  height: 14px;
  background: rgba(255, 255, 255, .24);
}

/* --------------------------------------------------------------------------
   8b. Inner-page banner
   Used by every page except the homepage (which has the full-bleed hero).
   The site header sits transparently over it, so it must clear --header-h.
   -------------------------------------------------------------------------- */
.page-hero {
  position: relative;
  padding: calc(var(--header-h) + 54px) 0 58px;
  /* Fallback for pages that supply no photo — the veil sits on top of this. */
  background: linear-gradient(160deg, var(--green) 0%, var(--green-deep) 78%);
  color: rgba(255, 255, 255, .78);
  overflow: hidden;
  isolation: isolate;
}

/* Optional photograph, sitting behind the green.
   Layer order inside the banner: photo (-3) → green veil (-2) → sun glow (-1). */
.page-hero-bg {
  position: absolute;
  inset: 0;
  z-index: -3;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 42%;
}

/* The green tints the photograph rather than hiding it. Legibility is bought
   back by the text-column scrim below plus the text's own shadow, which cost
   nothing on the side of the banner where there are no words — so the picture
   stays a picture. Measured: white headline >=3:1 and lede >=4.5:1 against the
   lightest pixel behind them on every page. */
.page-hero-veil {
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(120% 140% at 15% 0%, rgba(42, 122, 52, .06) 0%, transparent 62%),
    linear-gradient(160deg, rgba(30, 92, 38, .12) 0%, rgba(18, 58, 25, .20) 78%);
  pointer-events: none;
}

/* Shade concentrated behind the text column only, so the headline keeps its
   contrast while the right-hand side of the photograph stays clearly visible. */
.page-hero-veil::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, rgba(8, 26, 12, .90) 0%, rgba(8, 26, 12, .62) 56%, transparent 84%);
}

/* Below 992px the title and lede span nearly the whole banner, so a
   left-weighted scrim leaves the right-hand words sitting on bare photograph —
   measured as low as 3.0:1. Shade top-to-bottom instead, which covers the full
   text width and actually shows MORE of the picture than the desktop scrim. */
@media (max-width: 992px) {
  .page-hero-veil::after {
    background: linear-gradient(180deg, rgba(8, 26, 12, .30) 0%, rgba(8, 26, 12, .78) 100%);
  }
}

/* Faint watermark of the sun motif, echoing the homepage hero */
.page-hero::after {
  content: "";
  position: absolute;
  right: -60px;
  bottom: -110px;
  z-index: -1;
  width: 340px;
  height: 340px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(238, 124, 32, .30) 0%, transparent 68%);
  pointer-events: none;
}

.breadcrumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
  font-size: .8125rem;
  font-weight: 500;
  color: rgba(255, 255, 255, .8);
  text-shadow: 0 1px 8px rgba(8, 26, 12, .5);
}

.breadcrumb a { color: rgba(255, 255, 255, .78); }
.breadcrumb a:hover { color: var(--orange-warm); }
.breadcrumb svg { flex: none; opacity: .5; }
.breadcrumb [aria-current] { color: var(--orange-warm); font-weight: 600; }

.page-title {
  max-width: 20ch;
  font-size: clamp(2rem, 4.6vw, 3.15rem);
  font-weight: 800;
  line-height: 1.06;
  color: #fff;
  /* Separates the letterforms from photographic detail, which lets the veil
     above stay light enough for the picture to read. */
  text-shadow: 0 2px 16px rgba(8, 26, 12, .55);
}

.page-lede {
  max-width: 56ch;
  margin-top: 16px;
  font-size: clamp(1rem, 1.5vw, 1.125rem);
  line-height: 1.7;
  /* Nearly opaque, unlike the .78 inherited from .page-hero — the lede is body
     text over a photograph and needs the contrast the title gets from size. */
  color: rgba(255, 255, 255, .95);
  text-shadow: 0 1px 10px rgba(8, 26, 12, .5);
}

/* --------------------------------------------------------------------------
   8c. Form controls (shared — donate, contact, volunteer…)
   -------------------------------------------------------------------------- */
.field { margin-bottom: 18px; }

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}

.label {
  display: block;
  margin-bottom: 7px;
  font-family: var(--font-display);
  font-size: .8125rem;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--ink);
}

.label .req { color: var(--red); }

.input,
.select {
  width: 100%;
  padding: 13px 15px;
  font-size: .9375rem;
  color: var(--ink);
  background: #fff;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-sm);
  transition: border-color var(--speed) var(--ease),
              box-shadow var(--speed) var(--ease);
}

.input::placeholder { color: #A2AAA4; }

.input:focus,
.select:focus {
  outline: none;
  border-color: var(--green);
  box-shadow: 0 0 0 4px rgba(30, 92, 38, .13);
}

.input[aria-invalid="true"],
.select[aria-invalid="true"] {
  border-color: var(--red);
  box-shadow: 0 0 0 4px rgba(212, 42, 40, .12);
}

.select {
  appearance: none;
  padding-right: 42px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' stroke='%235C665E' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 15px center;
  background-size: 13px;
  cursor: pointer;
}

.field-error {
  display: none;
  margin-top: 6px;
  font-size: .8125rem;
  font-weight: 500;
  color: var(--red);
}

.field.has-error .field-error { display: block; }

/* Overall submit-result banner (as opposed to .field-error, which is
   per-field). Used by contact.js/volunteer.js/main.js/stories.js's shared
   pattern: JS resets to the bare `.form-status` class before every submit
   attempt, then adds exactly one of `.is-error`/`.is-ok` depending on the
   outcome — the two states never appear at once. */
.form-status {
  display: block;
  margin-top: 14px;
  padding: 0;
  font-size: .875rem;
  font-weight: 600;
  line-height: 1.5;
  border-radius: var(--radius);
  transition: padding var(--speed) var(--ease), background-color var(--speed) var(--ease);
}

/* Empty by default (no text set yet) — collapses to nothing rather than
   reserving a visible empty banner before the visitor has submitted. */
.form-status:empty { margin-top: 0; }

.form-status.is-error,
.form-status.is-ok {
  padding: 13px 16px;
}

.form-status.is-error {
  color: var(--red);
  background: color-mix(in srgb, var(--red) 8%, #fff);
}

.form-status.is-ok {
  color: var(--green-deep);
  background: color-mix(in srgb, var(--green) 10%, #fff);
}

/* Checkbox */
.check {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  cursor: pointer;
  font-size: .9375rem;
  line-height: 1.55;
}

.check input {
  flex: none;
  width: 20px;
  height: 20px;
  margin-top: 2px;
  accent-color: var(--green);
  cursor: pointer;
}

/* --------------------------------------------------------------------------
   8d. Accordion (shared — FAQ blocks)
   -------------------------------------------------------------------------- */
.accordion-item {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
  transition: border-color var(--speed) var(--ease),
              box-shadow var(--speed) var(--ease);
}

.accordion-item + .accordion-item { margin-top: 12px; }

.accordion-item:has(.accordion-trigger[aria-expanded="true"]) {
  border-color: color-mix(in srgb, var(--green) 34%, var(--line));
  box-shadow: var(--shadow-sm);
}

.accordion-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  width: 100%;
  padding: 18px 22px;
  text-align: left;
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 700;
  color: var(--ink);
  transition: color var(--speed) var(--ease);
}

.accordion-trigger:hover { color: var(--green); }
.accordion-trigger[aria-expanded="true"] { color: var(--green); }

.accordion-icon {
  position: relative;
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--green-soft);
  transition: background-color var(--speed) var(--ease),
              transform .45s var(--ease);
}

.accordion-icon::before,
.accordion-icon::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  background: var(--green);
  border-radius: 2px;
  transition: transform .45s var(--ease), opacity .45s var(--ease);
}

.accordion-icon::before { width: 10px; height: 2px; }
.accordion-icon::after  { width: 2px; height: 10px; }

.accordion-trigger[aria-expanded="true"] .accordion-icon { transform: rotate(180deg); }
.accordion-trigger[aria-expanded="true"] .accordion-icon::after { opacity: 0; transform: scaleY(0); }

/* Grid-rows trick: animates to the panel's natural height, no fixed values */
.accordion-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .42s var(--ease);
}

.accordion-panel.is-open { grid-template-rows: 1fr; }

.accordion-panel > div { overflow: hidden; }

.accordion-panel p {
  padding: 0 22px 20px;
  line-height: 1.72;
  color: var(--muted);
}

/* --------------------------------------------------------------------------
   8e. Closing CTA band (shared — the dark green "next step" block that ends
   most inner pages)
   -------------------------------------------------------------------------- */
.cta-band {
  padding: 78px 0;
  background:
    radial-gradient(110% 130% at 82% 0%, rgba(42, 122, 52, .5) 0%, transparent 62%),
    linear-gradient(150deg, var(--green) 0%, var(--green-deep) 80%);
  text-align: center;
  color: rgba(255, 255, 255, .82);
}

.cta-band h2 {
  max-width: 22ch;
  margin: 0 auto 14px;
  font-size: clamp(1.6rem, 3.4vw, 2.4rem);
  color: #fff;
}

.cta-band p {
  max-width: 56ch;
  margin: 0 auto 26px;
  line-height: 1.75;
}

.cta-band-actions {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 14px;
}

.btn--ghost {
  background: transparent;
  color: #fff;
  box-shadow: inset 0 0 0 1.6px rgba(255, 255, 255, .42);
}

.btn--ghost:hover {
  background: rgba(255, 255, 255, .12);
  color: #fff;
  box-shadow: inset 0 0 0 1.6px rgba(255, 255, 255, .7);
}

/* --------------------------------------------------------------------------
   8f. Sticky jump bar (shared)
   A horizontal row of in-page chips that sticks under the header. Used by
   the programmes page and the get-involved hub; pair it with data-spy so
   the current chip highlights itself.
   -------------------------------------------------------------------------- */
.jump {
  position: sticky;
  top: 0;
  z-index: 90;
  background: rgba(255, 255, 255, .96);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}

.site-header.is-scrolled ~ main .jump { top: 74px; }

.jump-list {
  display: flex;
  gap: 4px;
  overflow-x: auto;
  scrollbar-width: none;
  scroll-snap-type: x proximity;
}

.jump-list::-webkit-scrollbar { display: none; }

.jump-list a {
  position: relative;
  flex: none;
  padding: 17px 15px;
  scroll-snap-align: start;
  font-family: var(--font-display);
  font-size: .8125rem;
  font-weight: 700;
  letter-spacing: .02em;
  white-space: nowrap;
  color: var(--muted);
  transition: color var(--speed) var(--ease);
}

.jump-list a::after {
  content: "";
  position: absolute;
  left: 15px;
  right: 15px;
  bottom: 0;
  height: 3px;
  border-radius: 3px 3px 0 0;
  background: var(--accent, var(--green));
  transform: scaleX(0);
  transition: transform .4s var(--ease);
}

.jump-list a:hover,
.jump-list a.is-current { color: var(--accent, var(--green)); }
.jump-list a:hover::after,
.jump-list a.is-current::after { transform: scaleX(1); }

/* --------------------------------------------------------------------------
   8g. Draft / review notice (shared)
   An amber callout marking content that is illustrative and must be replaced
   or signed off before launch. Deliberately conspicuous: it is a safety catch,
   not decoration. Delete the markup once the real content is in.
   -------------------------------------------------------------------------- */
.draft-note,
.legal-notice {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  margin-top: 30px;
  padding: 18px 22px;
  border-radius: var(--radius);
  border: 1px solid #E9D8A6;
  border-left: 4px solid var(--orange);
  background: #FDF7EA;
}

.draft-note svg,
.legal-notice svg { flex: none; margin-top: 2px; color: var(--orange-deep); }

.draft-note p,
.legal-notice p {
  font-size: .9375rem;
  line-height: 1.68;
  color: #6B5526;
}

.draft-note strong,
.legal-notice strong { color: #4A3A15; }

/* --------------------------------------------------------------------------
   9. Shared section furniture
   -------------------------------------------------------------------------- */
.section { padding: 84px 0; }

.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 34px;
}

.section-title {
  font-size: clamp(1.4rem, 2.4vw, 1.75rem);
  font-weight: 800;
  letter-spacing: .01em;
  text-transform: uppercase;
  color: var(--green);
}

.section-sub {
  margin-top: 8px;
  color: var(--muted);
}

/* --------------------------------------------------------------------------
   10. Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 1200px) {
  .header-inner { padding-inline: 20px; gap: 14px; }
  .nav-link { padding: 10px 9px; font-size: .875rem; }
  .footer-top { gap: 36px 24px; }
}

@media (max-width: 1080px) {
  /* Desktop nav gives way to the drawer */
  .primary-nav { display: none; }
  .header-actions { margin-left: auto; }
}

@media (max-width: 992px) {
  :root { --header-h: 78px; }
  .section { padding: 64px 0; }
  .footer-top {
    grid-template-columns: repeat(2, 1fr);
    padding: 56px 0 44px;
  }
  .footer-brand { grid-column: 1 / -1; }
}

@media (max-width: 768px) {
  .logo-badge { width: 52px; height: 52px; }
  .btn-donate { padding: 11px 16px; font-size: .75rem; }
  .section-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
  }
  .page-hero { padding: calc(var(--header-h) + 38px) 0 44px; }
  .cta-band { padding: 58px 0; }
  .field-row { grid-template-columns: 1fr; gap: 0; }
  .accordion-trigger { padding: 16px 18px; font-size: .9375rem; }
  .accordion-panel p { padding: 0 18px 18px; }
}

@media (max-width: 560px) {
  :root { --gutter: 18px; }
  /* The desktop nav is already hidden by this width, so the Donate label
     still fits comfortably — keep it rather than reducing the button to an
     unlabelled circle. */
  .btn-donate { padding: 11px 14px; font-size: .6875rem; }
  .footer-top {
    grid-template-columns: 1fr;
    text-align: center;
  }
  .footer-brand-row,
  .socials,
  .contact-list li { justify-content: center; }
  .footer-blurb { margin-inline: auto; }
  .contact-list li { text-align: left; }
  .footer-col a:hover { padding-left: 0; }
  .footer-bottom { flex-direction: column; gap: 12px; }
  .footer-sep { display: none; }
}

/* --------------------------------------------------------------------------
   11. Reduced motion
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   Amara — the site assistant (js/assistant.js)
   --------------------------------------------------------------------------
   Appended to style.css rather than shipped as its own file so the widget
   needs no extra <link> on all 17 pages — only the one <script> tag.

   The whole widget is built by JavaScript and only after the server confirms
   the assistant is switched on, so none of these rules match anything unless
   it is genuinely available. Nothing here affects a page without it.
   ========================================================================== */
.htpi-chat {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 900;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
  font-family: var(--font-body);
}

/* ---- Launcher: the floating customer-care bubble ----
   A circle at rest, not a labelled pill. It breathes with a slow vertical
   float and carries one soft ring pulse, so it reads as a live presence
   waiting to help rather than another button bolted to the corner. The
   label appears only on hover/focus, beside the bubble, which keeps the
   resting state clean while still naming the thing for anyone who needs it.
   Every bit of that motion is switched off under prefers-reduced-motion. */
.htpi-chat-launch {
  position: relative;
  display: grid;
  place-items: center;
  width: 62px;
  height: 62px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: linear-gradient(145deg, var(--green-mid), var(--green-deep));
  color: #fff;
  cursor: pointer;
  box-shadow:
    0 14px 34px rgba(18, 58, 25, .38),
    0 4px 10px rgba(18, 58, 25, .22),
    inset 0 1px 0 rgba(255, 255, 255, .18);
  animation: htpiFloat 3.6s var(--ease) infinite;
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
}

/* The ring. Sits behind the bubble and expands outward, once every few
   seconds — an invitation, not a klaxon. */
.htpi-chat-launch::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid var(--green-mid);
  opacity: 0;
  animation: htpiRing 3.6s var(--ease) infinite;
  pointer-events: none;
}

.htpi-chat-launch:hover {
  transform: scale(1.07);
  box-shadow:
    0 20px 44px rgba(18, 58, 25, .46),
    0 6px 14px rgba(18, 58, 25, .26),
    inset 0 1px 0 rgba(255, 255, 255, .22);
}

.htpi-chat-launch:active { transform: scale(1.02); }

.htpi-chat-launch:focus-visible {
  outline: 3px solid var(--orange);
  outline-offset: 4px;
}

@keyframes htpiFloat {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-7px); }
}

@keyframes htpiRing {
  0%      { opacity: .55; transform: scale(1); }
  70%     { opacity: 0;   transform: scale(1.45); }
  100%    { opacity: 0;   transform: scale(1.45); }
}

/* ---- Icon cross-fade ---- */
.htpi-chat-icon {
  grid-area: 1 / 1;
  transition: opacity .24s var(--ease), transform .3s var(--ease);
}

.htpi-chat-icon--close { opacity: 0; transform: rotate(-90deg) scale(.6); }

.htpi-chat.is-open .htpi-chat-icon--chat  { opacity: 0; transform: rotate(90deg) scale(.6); }
.htpi-chat.is-open .htpi-chat-icon--close { opacity: 1; transform: none; }

/* Open: settle. A bubble still bobbing under an open panel looks restless. */
.htpi-chat.is-open .htpi-chat-launch { animation: none; }
.htpi-chat.is-open .htpi-chat-launch::before { animation: none; opacity: 0; }

/* Streaming: the ring speeds up, so the bubble shows the reply is being
   written even if the panel is scrolled away from the newest message. */
.htpi-chat.is-streaming .htpi-chat-launch::before {
  animation-duration: 1.5s;
  opacity: .5;
}

/* ---- Hover label ---- */
.htpi-chat-launch-label {
  position: absolute;
  right: calc(100% + 12px);
  top: 50%;
  transform: translateY(-50%) translateX(8px);
  padding: 8px 14px;
  border-radius: 999px;
  background: var(--ink-strong);
  color: #fff;
  font-family: var(--font-display);
  font-size: .8125rem;
  font-weight: 700;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  box-shadow: 0 6px 18px rgba(16, 32, 20, .28);
  transition: opacity .24s var(--ease), transform .24s var(--ease);
}

.htpi-chat-launch:hover .htpi-chat-launch-label,
.htpi-chat-launch:focus-visible .htpi-chat-launch-label {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}

/* Nothing to name once the panel is open and titled. */
.htpi-chat.is-open .htpi-chat-launch-label { display: none; }

/* ---- Panel ---- */
.htpi-chat-panel {
  display: flex;
  flex-direction: column;
  width: min(384px, calc(100vw - 32px));
  height: min(560px, calc(100vh - 130px));
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  animation: htpiChatIn .26s var(--ease) both;
}

.htpi-chat-panel[hidden] { display: none; }

@keyframes htpiChatIn {
  from { opacity: 0; transform: translateY(14px) scale(.98); }
  to   { opacity: 1; transform: none; }
}

.htpi-chat-head {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 14px 16px;
  background: linear-gradient(135deg, var(--green-deep), var(--green));
  color: #fff;
}

.htpi-chat-avatar {
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .2);
}

.htpi-chat-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

.htpi-chat-ident { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.htpi-chat-ident strong { font-family: var(--font-display); font-size: .9375rem; font-weight: 700; }
.htpi-chat-ident span { font-size: .75rem; opacity: .82; }

.htpi-chat-close {
  margin-left: auto;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .14);
  color: #fff;
  cursor: pointer;
  transition: background-color var(--speed) var(--ease);
}

.htpi-chat-close:hover { background: rgba(255, 255, 255, .26); }

/* ---- Thread ---- */
.htpi-chat-thread {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--surface-alt);
}

.htpi-msg { display: flex; max-width: 88%; }
.htpi-msg--user { align-self: flex-end; }
.htpi-msg--assistant, .htpi-msg--error { align-self: flex-start; }

.htpi-msg-body {
  padding: 11px 14px;
  border-radius: var(--radius);
  font-size: .875rem;
  line-height: 1.6;
  /* The reply is plain text with real newlines — honour them without letting
     a long unbroken string (a pasted URL) stretch the panel. */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.htpi-msg--assistant .htpi-msg-body {
  background: var(--surface);
  border: 1px solid var(--line);
  border-bottom-left-radius: 4px;
  color: var(--ink);
}

.htpi-msg--user .htpi-msg-body {
  background: var(--green);
  border-bottom-right-radius: 4px;
  color: #fff;
}

.htpi-msg--error .htpi-msg-body {
  background: color-mix(in srgb, var(--red) 8%, #fff);
  border: 1px solid color-mix(in srgb, var(--red) 30%, #fff);
  color: var(--red);
}

/* ---- Typing indicator ---- */
.htpi-typing .htpi-msg-body { display: flex; gap: 4px; padding: 14px; }

.htpi-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--muted-light);
  animation: htpiBounce 1.3s var(--ease) infinite;
}

.htpi-dot:nth-child(2) { animation-delay: .16s; }
.htpi-dot:nth-child(3) { animation-delay: .32s; }

@keyframes htpiBounce {
  0%, 60%, 100% { transform: translateY(0); opacity: .45; }
  30%           { transform: translateY(-4px); opacity: 1; }
}

/* ---- Composer ---- */
.htpi-chat-form {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding: 12px;
  border-top: 1px solid var(--line);
  background: var(--surface);
}

.htpi-chat-input {
  flex: 1;
  resize: none;
  max-height: 120px;
  padding: 10px 13px;
  font: inherit;
  font-size: .875rem;
  line-height: 1.5;
  color: var(--ink);
  background: var(--surface-alt);
  border: 1.5px solid var(--line);
  border-radius: var(--radius);
  transition: border-color var(--speed) var(--ease), box-shadow var(--speed) var(--ease);
}

.htpi-chat-input:focus {
  outline: none;
  border-color: var(--green);
  box-shadow: 0 0 0 3px rgba(30, 92, 38, .12);
}

.htpi-chat-input:disabled { opacity: .6; }

.htpi-chat-send {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: var(--green);
  color: #fff;
  cursor: pointer;
  transition: background-color var(--speed) var(--ease), opacity var(--speed) var(--ease);
}

.htpi-chat-send:hover:not(:disabled) { background: var(--green-mid); }
.htpi-chat-send:disabled { opacity: .45; cursor: not-allowed; }

/* ---- Footnote ---- */
.htpi-chat-note {
  padding: 9px 14px 11px;
  background: var(--surface);
  border-top: 1px solid var(--line);
  font-size: .6875rem;
  line-height: 1.45;
  color: var(--muted-light);
  text-align: center;
}

@media (max-width: 480px) {
  .htpi-chat { right: 12px; bottom: 12px; left: 12px; align-items: stretch; }
  .htpi-chat-panel { width: 100%; height: min(70vh, calc(100vh - 120px)); }
  .htpi-chat-launch { align-self: flex-end; }
}

@media (prefers-reduced-motion: reduce) {
  .htpi-chat-panel { animation: none; }
  .htpi-dot { animation: none; opacity: .6; }
  .htpi-chat-launch:hover { transform: none; }
  /* The float and the ring are the whole point of the bubble, and the whole
     problem for anyone who asked not to see motion. Off completely — the
     bubble still sits there, still opens, just does not move. */
  .htpi-chat-launch { animation: none; }
  .htpi-chat-launch::before { animation: none; opacity: 0; }
  .htpi-chat.is-streaming .htpi-chat-launch::before { animation: none; opacity: .4; }
  .htpi-chat-icon, .htpi-chat-launch-label { transition: none; }
}

/* ==========================================================================
   Cookie & privacy consent notice (js/consent.js)
   --------------------------------------------------------------------------
   Bottom-LEFT on desktop, deliberately: the back-to-top button and the
   assistant launcher both live bottom-right. Full width on small screens,
   where there is no room to sit beside anything.

   Built entirely by JavaScript and only when a choice has not been made, so
   none of these rules match anything on a page whose visitor has already
   answered.
   ========================================================================== */

/* The page behind the card must not scroll until a choice is made — Accept
   all, Essential only, or Save my choices, all of which call close() and
   remove this class. Set on both <html> and <body> by consent.js: it is the
   root element that actually scrolls in standards mode, so body alone is
   not reliable across browsers. */
html.htpi-consent-open,
body.htpi-consent-open {
  overflow: hidden;
}

.htpi-consent {
  position: fixed;
  left: clamp(16px, 3vw, 32px);
  bottom: clamp(16px, 3vw, 32px);
  z-index: 940;
  width: min(430px, calc(100vw - 32px));
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .42s var(--ease), transform .42s var(--ease);
}

.htpi-consent.is-in { opacity: 1; transform: none; }
.htpi-consent.is-leaving { opacity: 0; transform: translateY(12px); pointer-events: none; }

.htpi-consent-card {
  padding: 22px 22px 18px;
  background: var(--surface);
  /* A hairline plus a deep, soft shadow — the card should read as lifted off
     the page rather than boxed in. */
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 64px rgba(16, 32, 20, .22), 0 2px 8px rgba(16, 32, 20, .08);
  /* The one accent: a green edge tying it to the brand without colouring the
     whole card, which at this size would shout. */
  border-top: 3px solid var(--green);
  max-height: calc(100vh - 64px);
  overflow-y: auto;
}

/* ---- Head ---- */
.htpi-consent-head { display: flex; gap: 14px; align-items: flex-start; }

.htpi-consent-mark {
  flex: none;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  overflow: hidden;
  box-shadow: 0 3px 10px rgba(16, 32, 20, .16);
}

.htpi-consent-mark img { width: 100%; height: 100%; object-fit: cover; display: block; }

.htpi-consent-heading h2 {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: -.01em;
  color: var(--ink-strong);
}

.htpi-consent-heading p {
  margin: 0;
  font-size: .8125rem;
  line-height: 1.6;
  color: var(--muted);
}

/* ---- Category switches ---- */
.htpi-consent-prefs {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.htpi-consent-prefs[hidden] { display: none; }

.htpi-consent-row-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.htpi-consent-switch {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  font-family: var(--font-display);
  font-size: .875rem;
  font-weight: 700;
  color: var(--ink);
}

/* The real checkbox stays in the DOM and keeps its semantics and keyboard
   behaviour — it is visually replaced, never removed. */
.htpi-consent-switch input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.htpi-consent-track {
  position: relative;
  flex: none;
  width: 38px;
  height: 22px;
  border-radius: 999px;
  background: #D4D9D3;
  transition: background-color var(--speed) var(--ease);
}

.htpi-consent-track::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
  transition: transform var(--speed) var(--ease);
}

.htpi-consent-switch input:checked + .htpi-consent-track { background: var(--green); }
.htpi-consent-switch input:checked + .htpi-consent-track::after { transform: translateX(16px); }

.htpi-consent-switch input:focus-visible + .htpi-consent-track {
  outline: 3px solid var(--orange);
  outline-offset: 2px;
}

/* Strictly necessary: on, and visibly not up for discussion. */
.htpi-consent-switch input:disabled + .htpi-consent-track { background: var(--green); opacity: .5; }
.htpi-consent-switch input:disabled ~ .htpi-consent-row-label { color: var(--muted); }
.htpi-consent-switch:has(input:disabled) { cursor: default; }

.htpi-consent-row-summary {
  font-size: .75rem;
  color: var(--muted-light);
  text-align: right;
}

.htpi-consent-row-detail {
  margin: 7px 0 0 48px;
  font-size: .78125rem;
  line-height: 1.55;
  color: var(--muted);
}

/* ---- Actions ---- */
.htpi-consent-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 9px;
  margin-top: 18px;
}

.btn--consent {
  padding: 11px 20px;
  font-size: .75rem;
  flex: 1 1 auto;
  min-width: 132px;
}

/* Equal weight to "Accept all" in size, lower in colour: a real choice,
   presented as one. Dark-pattern styling — a greyed-out reject next to a
   glowing accept — would undercut the honesty of the copy. */
.btn--consent-quiet {
  background: var(--surface-alt);
  color: var(--ink);
  box-shadow: inset 0 0 0 1.5px var(--line);
}

.btn--consent-quiet:hover {
  background: #EDEFEA;
  color: var(--ink);
  box-shadow: inset 0 0 0 1.5px var(--muted-light);
}

.htpi-consent-link {
  flex: none;
  padding: 6px 4px;
  border: 0;
  background: none;
  font-family: var(--font-display);
  font-size: .78125rem;
  font-weight: 700;
  color: var(--green);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

.htpi-consent-link:hover { color: var(--green-mid); }

.htpi-consent-note {
  margin-top: 13px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: .71875rem;
  line-height: 1.5;
  color: var(--muted-light);
}

.htpi-consent-note a { color: var(--green); text-decoration: underline; text-underline-offset: 2px; }

/* --------------------------------------------------------------------------
   Fixed-element traffic control
   --------------------------------------------------------------------------
   Three things want the bottom of the viewport: the back-to-top button, the
   assistant launcher, and (on small screens) this notice. Stack them rather
   than let them overlap.
   -------------------------------------------------------------------------- */

/* The assistant sits bottom-right where back-to-top already was, so lift
   back-to-top above it whenever the widget is actually on the page. */
/* Clears the 62px launcher plus the 12px column gap beneath it. */
body.htpi-has-chat .to-top { bottom: calc(clamp(16px, 3vw, 32px) + 78px); }

@media (max-width: 760px) {
  .htpi-consent {
    left: 12px;
    right: 12px;
    bottom: 12px;
    width: auto;
  }

  .htpi-consent-card { padding: 18px 18px 15px; max-height: calc(100vh - 96px); }
  .htpi-consent-row-detail { margin-left: 0; }
  .htpi-consent-row-head { flex-direction: column; align-items: flex-start; gap: 4px; }
  .htpi-consent-row-summary { text-align: left; }
  .btn--consent { flex: 1 1 100%; }

  /* While the notice occupies the bottom of a small screen, get the other two
     out of its way rather than layering them on top of it. */
  body.htpi-consent-open .to-top,
  body.htpi-consent-open .htpi-chat { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .htpi-consent { transition: none; opacity: 1; transform: none; }
  .htpi-consent.is-leaving { opacity: 0; }
  .htpi-consent-track, .htpi-consent-track::after { transition: none; }
}
