/*
Theme Name: The Jessica Project
Theme URI: https://github.com/chechman/the-jessica-project-wp
Description: GeneratePress child theme for The Jessica Project. The design system below is the signed-off prototype stylesheet, carried over unchanged; extend it through its tokens, never fork it.
Author: Goodside
Template: generatepress
Version: 0.1.0
Requires at least: 6.4
Requires PHP: 8.1
Text Domain: jessica
*/

/* ===== tokens/fonts.css ===== */
/* ===========================================================================
   The Jessica Project — Webfonts (self-hosted)
   ---------------------------------------------------------------------------
   Lora (serif)  — headings + the affirmation
   Mulish (sans) — body, UI, small text

   Self-hosted variable fonts (one file per family + italic) under
   /assets/fonts. No third-party request — important for a privacy-sensitive,
   possibly-monitored audience, and it keeps the site working offline.
   Licensed under the SIL Open Font License (see the OFL.txt files in uploads).

   Non-variable browsers render the default instance of each variable font,
   which is an acceptable HTML-first fallback.
   =========================================================================== */

/* ---- Lora (serif) — wght 400–700 ------------------------------------- */
@font-face {
  font-family: 'Lora';
  src: url('assets/fonts/Lora-Variable.ttf') format('truetype');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Lora';
  src: url('assets/fonts/Lora-Italic-Variable.ttf') format('truetype');
  font-weight: 400 700;
  font-style: italic;
  font-display: swap;
}

/* ---- Mulish (sans) — wght 200–1000 ----------------------------------- */
@font-face {
  font-family: 'Mulish';
  src: url('assets/fonts/Mulish-Variable.ttf') format('truetype');
  font-weight: 200 1000;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Mulish';
  src: url('assets/fonts/Mulish-Italic-Variable.ttf') format('truetype');
  font-weight: 200 1000;
  font-style: italic;
  font-display: swap;
}


/* ===== tokens/colors.css ===== */
/* ===========================================================================
   The Jessica Project — Colour tokens
   ---------------------------------------------------------------------------
   The palette is anchored on a bold FUCHSIA pink, given depth by a PLUM/BERRY
   family and warmed by neutrals. This reflects the live brand (Instagram), which evolved
   from the original single-hue brief into a survivor-led movement palette.

   COLOUR-BY-ROLE (accessibility is a hard constraint, not styling):
     • Fuchsia      #EF1367  — button FILLS, LARGE headings, ICONS only.
                               Never small text. ~3.5:1 on white (large only).
     • Deep pink    #B0124E  — links and small text on light. ~6.4:1 on white.
     • Charcoal     #1A1A1A  — body copy; the (sober) crisis bar.
     • Plum-deep    #320E22  — brand DARK surfaces (footer, donate). White text.
     • Berry        #6E1A44  — rich emotional field (survivor voice). White text.
     • Soft / pale pink — backgrounds & decoration only. Never text.
     • White-on-pink/plum/berry    — only at 19px BOLD or larger.

   Composition 60/30/10: warm neutrals dominate; pink is the accent; plum
   appears sparingly, never as the field.
   (Gold retired 2026-07 — not in the Goodside brand palette; pink/white/
   charcoal only. Former gold roles now map to the pink family.)
   =========================================================================== */

:root {
  /* ---- Pink — the core anchor ----------------------------------------- */
  --pink-bright:  #EF1367;  /* fuchsia — fills, large headings, icons      */
  --pink-deep:    #B0124E;  /* links, small text on light                  */
  --pink-soft:    #F490AC;  /* sunrise band, decorative fills (brand sheet) */
  --pink-pale:    #FCEAF0;  /* tinted section backgrounds (brand sheet)    */
  --pink-mist:    #FDF1F5;  /* faintest wash, large flat fields            */

  /* ---- Plum / berry — depth & contrast -------------------------------- */
  --plum-deep:    #320E22;  /* brand dark surfaces: footer, donate         */
  --plum:         #4A1230;  /* mid plum — secondary dark, hovers           */
  --berry:        #6E1A44;  /* rich emotional field (survivor voice)       */
  --berry-bright: #8A2455;  /* berry hover / lighter accent                */
  --berry-wash:   #F3E1E9;  /* faint plum-tinted wash on light             */

  /* Gold retired 2026-07 — off-palette per the Goodside brand sheet.
     Former gold roles (campaign accent, dividers, icons) now use the pink family. */

  /* ---- Warm neutral ramp ---------------------------------------------- */
  --charcoal:     #1A1A1A;  /* body copy; the crisis bar                   */
  --ink-700:      #514B49;  /* secondary text (warm grey)                  */
  --ink-500:      #7A726F;  /* muted captions, metadata                    */
  --line:         #E5DEDB;  /* hairline borders, card edges                */
  --line-strong:  #CFC6C2;  /* emphasised hairlines                        */
  --paper:        #FBF8F6;  /* warm off-white page background              */
  --white:        #FFFFFF;

  /* ---- Semantic aliases ----------------------------------------------- */
  --text-body:        var(--charcoal);
  --text-secondary:   var(--ink-700);
  --text-muted:       var(--ink-500);
  --text-link:        var(--pink-deep);
  --text-on-pink:     var(--white);     /* 19px bold+ only                */
  --text-on-dark:     var(--white);

  --heading-strong:   var(--pink-bright);
  --icon-accent:      var(--pink-bright);

  --surface-page:     var(--paper);
  --surface-card:     var(--white);
  --surface-tint:     var(--pink-pale);
  --surface-wash:     var(--pink-mist);
  --surface-dark:     var(--plum-deep);   /* brand dark bands             */
  --surface-voice:    var(--berry);       /* survivor-voice field         */
  --surface-campaign: var(--pink-mist);   /* advocacy field on light      */
  --surface-crisis:   var(--charcoal);    /* sober safety bar             */

  --sunrise-band:     var(--pink-soft);
  --sunrise-sun:      var(--pink-bright);

  --border-hairline:  var(--line);
  --border-strong:    var(--line-strong);

  --action-fill:      var(--pink-bright);
  --action-fill-press:#D10E59;            /* darker fuchsia for :active   */
  --action-outline:   var(--pink-deep);
  --action-campaign:  var(--action-fill);        /* advocacy CTA = brand pink */
  --action-campaign-press: var(--action-fill-press);
}


/* ===== tokens/typography.css ===== */
/* ===========================================================================
   The Jessica Project — Typography tokens
   ---------------------------------------------------------------------------
   Lora (serif)  — headings + the affirmation. Warm, human, editorial.
   Mulish (sans) — body, UI, captions. Highly legible, calm.

   Headings set in Lora may use --heading-strong (bright pink) only at LARGE
   sizes. Body is always charcoal in Mulish. Small text never uses bright pink.
   =========================================================================== */

:root {
  /* ---- Families ------------------------------------------------------- */
  --font-serif: 'Lora', Georgia, 'Times New Roman', serif;
  --font-sans:  'Mulish', system-ui, -apple-system, 'Segoe UI', sans-serif;

  --font-heading:     var(--font-serif);
  --font-body:        var(--font-sans);
  --font-affirmation: var(--font-serif);

  /* ---- Weights -------------------------------------------------------- */
  --weight-regular:   400;
  --weight-medium:    500;
  --weight-semibold:  600;
  --weight-bold:      700;
  --weight-extrabold: 800;

  /* ---- Type scale (editorial, generous) ------------------------------- */
  --text-display:   clamp(2.75rem, 1.6rem + 4.6vw, 4.5rem);  /* @kind other */ /* hero */
  --text-h1:        clamp(2.25rem, 1.6rem + 2.6vw, 3.25rem); /* @kind other */
  --text-h2:        clamp(1.75rem, 1.3rem + 1.8vw, 2.5rem);  /* @kind other */
  --text-h3:        clamp(1.375rem, 1.1rem + 1.1vw, 1.75rem);/* @kind other */
  --text-h4:        1.25rem;                                 /* @kind other */
  --text-affirm:    clamp(1.75rem, 1.2rem + 2.4vw, 2.75rem); /* @kind other */ /* reclaim, rise */
  --text-lead:      1.25rem;     /* intro paragraphs               */
  --text-body-lg:   1.125rem;
  --text-body:      1rem;        /* 16px base                      */
  --text-small:     0.9375rem;   /* 15px — min for deep-pink text  */
  --text-eyebrow:   0.8125rem;   /* 13px uppercase label           */

  /* ---- Line heights --------------------------------------------------- */
  --leading-tight:  1.12;   /* display / large headings */
  --leading-snug:   1.25;   /* sub-headings             */
  --leading-normal: 1.6;    /* body copy                */
  --leading-relaxed:1.7;    /* long-form reading        */

  /* ---- Letter spacing ------------------------------------------------- */
  --tracking-eyebrow: 0.14em;  /* uppercase eyebrows  */
  --tracking-tight:  -0.01em;  /* large serif headings */
  --tracking-normal: 0;
}


/* ===== tokens/spacing.css ===== */
/* ===========================================================================
   The Jessica Project — Spacing, radius, layout & elevation tokens
   ---------------------------------------------------------------------------
   4px base rhythm. Square-ish, editorial feel: tight radii (~5px), hairline
   borders rather than drop shadows. Shadows are used sparingly and softly.
   =========================================================================== */

:root {
  /* ---- Spacing scale (4px base) --------------------------------------- */
  --space-1:  0.25rem;   /*  4px */
  --space-2:  0.5rem;    /*  8px */
  --space-3:  0.75rem;   /* 12px */
  --space-4:  1rem;      /* 16px */
  --space-5:  1.5rem;    /* 24px */
  --space-6:  2rem;      /* 32px */
  --space-7:  3rem;      /* 48px */
  --space-8:  4rem;      /* 64px */
  --space-9:  6rem;      /* 96px */
  --space-10: 8rem;      /* 128px */

  /* ---- Radii (no full pills — buttons sit at ~5px) -------------------- */
  --radius-sm:   3px;
  --radius-base: 5px;    /* buttons, inputs, chips      */
  --radius-md:   8px;    /* cards, media                */
  --radius-lg:   12px;   /* large feature panels        */

  /* ---- Borders -------------------------------------------------------- */
  --border-width: 1px;
  --border-width-strong: 1.5px;

  /* ---- Elevation — layered light, hairline ring, tiny opacities ------- */
  /* Depth is the sum of several faint layers, not one dark blur. The 0.5px
     ring replaces a hard 1px border so edges read as light, not stroke. */
  --shadow-none:  none;
  --shadow-sm:
    0 1px 2px rgba(26, 26, 26, 0.05),
    0 2px 4px rgba(26, 26, 26, 0.02),
    0 0 0 0.5px rgba(26, 26, 26, 0.07);          /* hairline ring */
  --shadow-md:
    0 1px 2px rgba(26, 26, 26, 0.04),
    0 4px 8px rgba(26, 26, 26, 0.03),
    0 10px 20px rgba(26, 26, 26, 0.05),
    0 0 0 0.5px rgba(26, 26, 26, 0.08);          /* hairline ring */
  --shadow-focus: 0 0 0 3px rgba(176, 18, 78, 0.35);  /* deep-pink ring   */
  /* a ring on its own, for cards that want the hairline without a drop */
  --ring-hairline: 0 0 0 0.5px rgba(26, 26, 26, 0.08);

  /* ---- Motion — house easing + durations (default browser ease banned) */
  --ease-smooth: cubic-bezier(0.22, 1, 0.36, 1);   /* default for almost everything */
  --ease-out:    cubic-bezier(0.17, 1, 0.32, 1);   /* gentle decorative settle       */
  --ease-in-out: cubic-bezier(0.66, 0, 0.34, 1);   /* symmetric moves                */
  --duration-fast:   150ms;
  --duration-normal: 220ms;
  --duration-slow:   300ms;
  --press-scale: 0.985;   /* firm press, not a collapse */

  /* ---- Layout --------------------------------------------------------- */
  --container-max: 1200px;
  --container-text: 68ch;   /* long-form measure        */
  --gutter: clamp(1.25rem, 4vw, 4rem); /* @kind spacing */
  --crisis-bar-h: 44px;
  --header-h: 92px;
}


/* ===== base.css ===== */
/* ===========================================================================
   The Jessica Project — Base layer
   ---------------------------------------------------------------------------
   Light reset + element defaults wired to the tokens. Consuming pages get
   sensible, on-brand typography and colour for free.
   =========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

/* The HTML `hidden` attribute must always win, even on elements we give an
   explicit `display` (e.g. .jp-btn). The <form-wizard> relies on this to hide
   inactive steps + the Back/Submit buttons. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--leading-normal);
  color: var(--text-body);
  background: var(--surface-page);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--text-body);
  margin: 0 0 var(--space-4);
  text-wrap: balance;
}

h1 { font-size: var(--text-h1); }
h2 { font-size: var(--text-h2); }
h3 { font-size: var(--text-h3); line-height: var(--leading-snug); }
h4 { font-size: var(--text-h4); line-height: var(--leading-snug); }

p { margin: 0 0 var(--space-4); text-wrap: pretty; }

a {
  color: var(--text-link);
  text-decoration: underline;
  text-underline-offset: 0.15em;
  text-decoration-thickness: 1px;
}
a:hover { text-decoration-thickness: 2px; }
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
  border-radius: var(--radius-sm);
}

img, svg { display: block; max-width: 100%; }
svg { flex: none; }

strong, b { font-weight: var(--weight-bold); }

/* Eyebrow label — paired with the small sunrise mark beside section titles */
.jp-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--text-eyebrow);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--pink-deep);
  margin: 0;
}

/* Visually-hidden, still read by screen readers */
.jp-visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}


/* ===== components.css ===== */
/* ===========================================================================
   The Jessica Project — Component interaction states
   ---------------------------------------------------------------------------
   Hover = darker fill / tint (never lighter, never glow). Press = darker + a
   1px nudge down. No scale-bounce, no shadow flares.
   =========================================================================== */

/* ---- Buttons -------------------------------------------------------------- */
.jp-btn--primary:hover   { background: var(--action-fill-press); border-color: var(--action-fill-press); }
.jp-btn--primary:active  { background: #B80C53; border-color: #B80C53; transform: translateY(1px); }

/* Campaign / advocacy CTA — now the brand-pink primary treatment (gold retired). */
.jp-btn--campaign:hover  { background: var(--action-campaign-press); border-color: var(--action-campaign-press); }
.jp-btn--campaign:active { background: #B80C53; border-color: #B80C53; transform: translateY(1px); }

.jp-btn--secondary:hover { background: var(--pink-mist); }
.jp-btn--secondary:active{ background: var(--pink-pale); transform: translateY(1px); }

.jp-btn--ghost:hover     { background: var(--pink-mist); }
.jp-btn--ghost:active    { background: var(--pink-pale); }

/* On dark bands, secondary/ghost flip to a light outline.
   !important so they win over the components' inline variant colours. */
.jp-on-dark .jp-btn--secondary { color: var(--white) !important; border-color: rgba(255,255,255,0.6) !important; background: transparent !important; }
.jp-on-dark .jp-btn--secondary:hover { background: rgba(255,255,255,0.12) !important; border-color: var(--white) !important; }
.jp-on-dark .jp-btn--ghost { color: var(--white) !important; }
.jp-on-dark .jp-btn--ghost:hover { background: rgba(255,255,255,0.12) !important; }

/* ---- Support cards use the canonical .jp-card family (defined below) ------ */

/* ---- Quick exit ----------------------------------------------------------- */
.jp-crisisbar .jp-quick-exit { display: inline-flex; align-items: center; gap: 0.45em; font-family: var(--font-body); font-weight: 700; font-size: 1.1875rem; line-height: 1; color: var(--white); background: var(--pink-bright); border: 1.5px solid var(--pink-bright); border-radius: var(--radius-base); padding: 0.7em 0.95em; min-height: 44px; cursor: pointer; white-space: nowrap; text-decoration: none; }
.jp-quick-exit:hover { background: var(--action-fill-press); }
.jp-quick-exit:active { transform: translateY(1px); }

/* ---- Form fields + validation-enhancer ------------------------------------ */
.jp-field { display: flex; flex-direction: column; gap: 0.4rem; font-family: var(--font-body); }
.jp-field__label { font-size: 0.9375rem; font-weight: 700; color: var(--charcoal); }
.jp-field__label .req { color: var(--pink-deep); }            /* required mark */
.jp-field__hint { font-size: 0.875rem; color: var(--ink-500); }
.jp-field__control {
  font-family: var(--font-body); font-size: 1rem; color: var(--charcoal);
  background: var(--white); border: 1.5px solid var(--line-strong);
  border-radius: var(--radius-base); padding: 0.7rem 0.85rem; min-height: 48px; width: 100%;
  transition: border-color var(--duration-fast) var(--ease-smooth), box-shadow var(--duration-fast) var(--ease-smooth);
}
.jp-field__control:hover { border-color: var(--ink-500); }
.jp-field__control:focus { outline: none; border-color: var(--pink-deep); box-shadow: 0 0 0 3px rgba(176, 18, 78, 0.18); }
.jp-field__control::placeholder { color: var(--ink-500); opacity: 1; }
textarea.jp-field__control { min-height: 7rem; resize: vertical; }

/* Error text — deep pink (an approved small-text colour). Hidden until populated. */
.jp-field__error {
  margin: 0; font-size: 0.875rem; font-weight: 700; color: var(--pink-deep);
  display: flex; align-items: flex-start; gap: 0.35em;
}
.jp-field__error:empty { display: none; }
/* Small leading marker drawn in CSS (no icon dependency) */
.jp-field__error:not(:empty)::before {
  content: ""; flex: none; width: 1em; height: 1em; margin-top: 0.05em;
  background: var(--pink-deep);
  -webkit-mask: no-repeat center / contain; mask: no-repeat center / contain;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cline x1='12' y1='7.5' x2='12' y2='13'/%3E%3Cline x1='12' y1='16.5' x2='12' y2='16.6'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cline x1='12' y1='7.5' x2='12' y2='13'/%3E%3Cline x1='12' y1='16.5' x2='12' y2='16.6'/%3E%3C/svg%3E");
}

/* Invalid state — deep-pink edge + ring. Works for the React Input and the
   web-component-enhanced HTML form alike (both set aria-invalid="true"). */
.jp-field__control[aria-invalid="true"],
.jp-field.is-invalid .jp-field__control {
  border-color: var(--pink-deep);
  box-shadow: 0 0 0 1px var(--pink-deep);
}
.jp-field__control[aria-invalid="true"]:focus-visible,
.jp-field.is-invalid .jp-field__control:focus-visible {
  box-shadow: var(--shadow-focus);
}

/* ---- Multi-step wizard ---------------------------------------------------- */
/* Progress indicator */
.jp-wizard__steps { list-style: none; display: flex; flex-wrap: wrap; gap: 0.4rem 1.5rem; margin: 0 0 2rem; padding: 0; }
.jp-wizard__step { display: flex; align-items: center; gap: 0.55rem; font-family: var(--font-body); font-size: 0.9375rem; font-weight: 700; color: var(--ink-500); }
.jp-wizard__num { flex: none; width: 1.7rem; height: 1.7rem; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; border: 1.5px solid var(--line-strong); font-size: 0.875rem; color: var(--ink-500); background: var(--white); }
.jp-wizard__step.is-active { color: var(--charcoal); }
.jp-wizard__step.is-active .jp-wizard__num { border-color: var(--pink-deep); color: var(--white); background: var(--pink-deep); box-shadow: 0 0 0 2px var(--pink-bright); }
.jp-wizard__step.is-done { color: var(--ink-700); }
.jp-wizard__step.is-done .jp-wizard__num { border-color: var(--pink-deep); color: var(--white); background: var(--pink-deep); }

/* When NOT enhanced (no JS) the per-step numbers read as plain section markers
   and a quiet rule separates the stacked fieldsets. */
form-wizard:not(.is-enhanced) [data-step] { border-top: 1px solid var(--line); padding-top: 1.75rem; margin-top: 1.75rem; }
form-wizard:not(.is-enhanced) [data-step]:first-of-type { border-top: 0; padding-top: 0; margin-top: 0; }

[data-step] { border: 0; margin: 0; padding: 0; min-inline-size: 0; }
[data-step]:focus { outline: none; }
[data-step] > legend { padding: 0; }

.jp-wizard__nav { display: flex; align-items: center; gap: 1rem; margin-top: 2rem; flex-wrap: wrap; }
.jp-wizard__nav [data-wizard-next] { margin-left: auto; }
.jp-wizard__nav [data-wizard-back] { margin-right: auto; }


/* ===== ui_kits/website/home.css ===== */
/* The Jessica Project — homepage layout (UI kit).
   Holds four content energies in one system: Support & healing (light),
   Survivor voice (berry), Community & events (warm light), Advocacy & change
   (pale-pink). Composition stays 60/30/10: neutrals dominate, pink anchors,
   plum appears sparingly. */

.jp-page { background: var(--surface-page); }

/* Skip link (WCAG 2.4.1 Bypass Blocks) — first focusable element. Off-screen
   until focused, then it appears as a clear, high-contrast control above the
   sticky bar so keyboard users can jump straight past the nav to the content. */
.jp-skip { position: absolute; left: 1rem; top: -4rem; z-index: 1100;
  display: inline-block; padding: 0.75rem 1.25rem; border-radius: var(--radius-base);
  background: var(--plum-deep); color: var(--white); font-family: var(--font-body);
  font-weight: 700; font-size: 1rem; text-decoration: none; box-shadow: var(--shadow-md);
  transition: top var(--duration-fast) var(--ease-smooth); }
.jp-skip:focus { top: 1rem; outline: 3px solid var(--pink-bright); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .jp-skip { transition: none; } }
.jp-wrap { max-width: var(--container-max); margin: 0 auto; padding-inline: var(--gutter); }

/* ===========================================================================
   STICKY TOP — crisis bar + header (+ mobile nav) pin together as one unit.
   They share a single sticky wrapper so the header always sits directly under
   the crisis bar, however tall the crisis bar wraps (no magic-number offset).
   =========================================================================== */
.jp-stickytop { position: sticky; top: 0; z-index: 1000; }
/* the crisis bar sets its own inline position:sticky; inside the wrapper that is
   redundant — make it static so only the wrapper controls stickiness. */
.jp-stickytop .jp-crisisbar { position: static !important; }
/* a soft shadow appears once the page is scrolled, to lift the bar off content */
.jp-stickytop { box-shadow: 0 1px 1px rgba(26,26,26,0.04), 0 4px 12px rgba(26,26,26,0.05); }

/* ===========================================================================
   GRID SYSTEM — one source of truth (Müller-Brockmann discipline, warm brand).
   12 columns inside .jp-wrap; 8px baseline (24px leading). Every two-column
   section places its children on real column LINES, and the toggle overlay
   reads these SAME variables inside the SAME .jp-wrap box, so it can't drift.
   =========================================================================== */
:root {
  --gcols: 12;
  --col-gap: 24px;        /* column gutter — 3 x baseline */
  --bl: 8px;             /* baseline unit */
  --baseline-lh: 24px;   /* leading = 3 x baseline */
}
.jp-cols { display: grid; grid-template-columns: repeat(var(--gcols), 1fr); column-gap: var(--col-gap); }

/* ---- Grid overlay (toggle with the button or the "G" key) ---- */
.jp-gridguides { position: fixed; inset: 0; z-index: 1500; pointer-events: none; opacity: 0; transition: opacity .25s ease; }
body.jp-grid-on .jp-gridguides { opacity: 1; }
.jp-gridguides__inner { max-width: var(--container-max); height: 100%; margin: 0 auto; padding-inline: var(--gutter); display: grid; grid-template-columns: repeat(var(--gcols), 1fr); column-gap: var(--col-gap); }
.jp-gridguides__col { background: rgba(239, 19, 103, 0.07); box-shadow: inset 1px 0 0 rgba(176, 18, 78, 0.32), inset -1px 0 0 rgba(176, 18, 78, 0.32); position: relative; }
.jp-gridguides__col span { position: absolute; top: 8px; left: 0; right: 0; text-align: center; font-family: var(--font-body); font-weight: 800; font-size: 10px; line-height: 1; color: var(--pink-deep); }

/* ---- Grid toggle control (bottom-right, clear of the safety controls) ---- */
.jp-gridtoggle { position: fixed; bottom: 18px; right: 18px; z-index: 1600; display: inline-flex; align-items: center; gap: 0.5em;
  background: var(--charcoal); color: var(--white); border: none; cursor: pointer; font-family: var(--font-body); font-weight: 800;
  font-size: 0.75rem; letter-spacing: 0.12em; text-transform: uppercase; padding: 0.6em 0.85em; border-radius: var(--radius-base); box-shadow: var(--shadow-md); }
.jp-gridtoggle .dot { width: 9px; height: 9px; border-radius: 50%; background: #6c6663; }
body.jp-grid-on .jp-gridtoggle { background: var(--pink-bright); }
body.jp-grid-on .jp-gridtoggle .dot { background: var(--white); }

/* ---------- Header ---------- */
.jp-header { background: var(--surface-page); border-bottom: 1px solid var(--line); }
.jp-header__inner { display: flex; align-items: center; gap: 1.5rem; min-height: var(--header-h); }
.jp-logo { display: inline-flex; align-items: center; text-decoration: none; }
.jp-logo__img { display: block; width: auto; height: 68px; }
.jp-nav { display: flex; align-items: center; gap: 1.6rem; margin-left: auto; }
.jp-nav a { color: var(--charcoal); text-decoration: none; font-weight: 600; font-size: 1rem; display: inline-flex; align-items: center; min-height: 44px; padding: 0 0.2rem; }
.jp-nav a:hover { color: var(--pink-deep); text-decoration: underline; text-underline-offset: 0.2em; }
/* Visible "you are here": the semantic aria-current gets a visual state too
   (Krug: location indicators must be seen, not just announced). */
.jp-nav a[aria-current="page"],
.jp-mobnav a[aria-current="page"] { color: var(--pink-deep); font-weight: 800; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 0.35em; }
.jp-burger { display: none; margin-left: auto; align-items: center; gap: 0.5rem; background: none; border: 1.5px solid var(--line-strong); border-radius: var(--radius-base); padding: 0.45rem 0.7rem; min-height: 48px; color: var(--charcoal); cursor: pointer; font-family: var(--font-body); font-weight: 700; font-size: 1rem; }
.jp-burger:hover { border-color: var(--pink-deep); color: var(--pink-deep); }
.jp-burger__label { line-height: 1; }

/* ---------- Hero (asymmetric editorial — on the 12-col grid) ---------- */
/* Double class so this beats .jp-section's later padding-block: the hero owns
   its own rhythm and the panel bleeds up to the header line — no phantom gap. */
.jp-section.jp-hero-section { padding: 0; }
.jp-hero { display: grid; grid-template-columns: repeat(var(--gcols), 1fr); column-gap: var(--col-gap); align-items: stretch; }
.jp-hero__text { grid-column: 1 / 8; padding: 96px 0 72px; max-width: none; }
.jp-hero__h1 { font-size: var(--text-display); line-height: var(--leading-tight); letter-spacing: var(--tracking-tight); margin: 24px 0 0; color: var(--charcoal); }
.jp-hero__lead { font-size: var(--text-lead); color: var(--ink-700); margin: 24px 0 0; max-width: 34rem; }
.jp-hero__cta { display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap; margin-top: 32px; }
.jp-hero__privacy { margin-top: 40px; max-width: 34rem; }

/* Hero reassurance — the low-stakes 'not sure?' on-ramp under the CTAs */
.jp-hero__reassure { margin: 24px 0 0; max-width: 34rem; font-size: 1rem; line-height: var(--leading-normal); color: var(--ink-700); }
.jp-hero__reassure a { color: var(--pink-deep); font-weight: 700; text-decoration: underline; text-underline-offset: 0.15em; }

/* Photo panel — full-bleed image; the photo carries the message on its own
   (the affirmation lines live in the What-happens H2 and the advocacy creed) */
.jp-hero__panel { grid-column: 8 / 13; position: relative; background: var(--pink-mist); overflow: hidden; min-height: 480px; border-left: 1px solid var(--line); }
.jp-hero__sunrise { position: absolute; inset: 0; width: 100%; height: 100%; }
.jp-hero__sunrise picture { display: block; width: 100%; height: 100%; }
.jp-hero__sunrise svg, .jp-hero__sunrise img { width: 100%; height: 100%; object-fit: cover; object-position: 42% 50%; display: block; }
/* Brand-motif variant: the handprint extracted from the logo, shown whole.
   AFTER the base img rule — equal specificity, source order decides. */
.jp-hero__sunrise--motif img { object-fit: contain; padding: clamp(2.5rem, 6vw, 5rem); }
/* Warm sunrise wash rising from the panel's foot: melts the photo into the
   page's pink family so it reads designed-in, not stock-dropped-in. */
.jp-hero__sunrise::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(252, 234, 240, 0.55), rgba(252, 234, 240, 0) 45%);
  pointer-events: none; }

/* ---------- Section scaffold ---------- */
.jp-section { padding-block: clamp(3.5rem, 6vw, 6.5rem); }

/* Anchor offset — when a nav link jumps to a section, keep its heading clear of
   the sticky crisis bar + header. JS (app.js) measures the real pinned height and
   updates this variable exactly; these are the no-JS fallbacks. */
:root { --sticky-offset: 140px; }
/* Universal: ANY anchor target clears the sticky chrome (sections, forms,
   in-page jump targets — present and future). */
[id] { scroll-margin-top: var(--sticky-offset); }
.jp-section__head { max-width: 42rem; margin-bottom: clamp(1.75rem, 3vw, 2.75rem); }
.jp-section__head h2 { font-size: var(--text-h2); line-height: var(--leading-tight); letter-spacing: var(--tracking-tight); margin: 0; text-wrap: balance; }
/* add the gap only when an eyebrow actually precedes the heading */
.jp-section__head .jp-eyebrow + h2 { margin-top: 0.75rem; }
.jp-section__head p { font-size: var(--text-body-lg); color: var(--ink-700); margin: 0.9rem 0 0; }
.jp-page p.jp-eyebrow { color: var(--pink-deep); margin: 0; }

/* Support grid — bordered hairline cards, snapped to 12-col lines (4 x 3 cols) */
.jp-grid { display: grid; grid-template-columns: repeat(var(--gcols), 1fr); column-gap: var(--col-gap); row-gap: var(--col-gap); }
.jp-grid > * { grid-column: span 3; }
/* Row-filling variants — match column count to card count so no row sits
   half-empty (pairs 2-up, trios and sixes 3-up). The tablet/mobile blocks
   further down reset spans, so these are desktop-only by construction. */
.jp-grid--2 > * { grid-column: span 6; }
.jp-grid--3 > * { grid-column: span 4; }

/* ---------- "Where to start" — doorways entry grid (pink-pale field) ---------- */
.jp-doors { background: var(--pink-pale); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.jp-doors__grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(6, 1fr); column-gap: var(--col-gap); row-gap: var(--col-gap); }
/* top row: three cards across (2 cols each of 6); bottom row: two wider cards (3 cols each) */
.jp-doors__grid > li:nth-child(1),
.jp-doors__grid > li:nth-child(2),
.jp-doors__grid > li:nth-child(3) { grid-column: span 2; }
.jp-doors__grid > li:nth-child(4),
.jp-doors__grid > li:nth-child(5) { grid-column: span 3; }
.jp-door { position: relative; display: grid; grid-template-columns: auto 1fr; column-gap: 1.1rem; row-gap: 0.5rem; align-items: start;
  background: var(--white); border-radius: var(--radius-md); padding: 1.6rem 1.8rem; height: 100%;
  text-decoration: none; box-shadow: var(--shadow-sm);
  transition: box-shadow var(--duration-normal) var(--ease-smooth), transform var(--duration-fast) var(--ease-smooth); }
.jp-door:hover { box-shadow: var(--shadow-md), 0 0 0 1px var(--pink-deep); }
.jp-door:active { transform: scale(var(--press-scale)); }
.jp-door__ic { grid-row: 1 / span 2; width: 3rem; height: 3rem; flex: none; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; background: var(--pink-mist); color: var(--pink-bright); }
.jp-door__arrow { position: absolute; top: 1.6rem; right: 1.8rem; color: var(--pink-deep); display: inline-flex; }
.jp-door:hover .jp-door__arrow { color: var(--pink-bright); }
.jp-door__title { font-family: var(--font-heading); font-weight: 700; font-size: 1.5rem; line-height: 1.15; letter-spacing: var(--tracking-tight); color: var(--charcoal); padding-right: 2rem; }
.jp-door__body { grid-column: 2; font-size: 0.9375rem; line-height: var(--leading-snug); color: var(--ink-700); }
.jp-doors__note { display: flex; align-items: center; gap: 0.55rem; flex-wrap: wrap; margin: 2rem 0 0; font-size: var(--text-body-lg); color: var(--ink-700); }
.jp-doors__note-ic { color: var(--pink-bright); flex: none; display: inline-flex; }
.jp-doors__note a { color: var(--pink-deep); font-weight: 700; text-decoration: underline; text-underline-offset: 0.15em; }

/* ---------- "What happens when you reach out" — steps + confidentiality ---------- */
.jp-how__steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(var(--gcols), 1fr); column-gap: var(--col-gap); row-gap: var(--col-gap); counter-reset: step; }
.jp-how__step { grid-column: span 4; display: flex; flex-direction: column; gap: 0.6rem; background: var(--surface-card); border: 1px solid var(--line); border-radius: var(--radius-md); padding: 1.6rem; position: relative; }
.jp-how__num { width: 2.1rem; height: 2.1rem; flex: none; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--pink-deep); color: var(--white); font-family: var(--font-body); font-weight: 800; font-size: 1.0625rem; }
.jp-how__ic { color: var(--pink-bright); display: inline-flex; }
.jp-how__title { display: block; font-family: var(--font-heading); font-weight: 600; font-size: 1.25rem; line-height: 1.2; color: var(--charcoal); }
.jp-how__body { display: block; font-size: 1rem; line-height: var(--leading-normal); color: var(--ink-700); margin-top: 0.15rem; }
.jp-how__safe { display: flex; gap: 1rem; align-items: flex-start; background: var(--pink-pale); border: 1px solid var(--line); border-radius: var(--radius-md); padding: 1.5rem 1.6rem; margin-top: var(--col-gap); }
/* When content continues below a safe/highlight box, keep the same rhythm
   beneath it as above it (it was originally always the last block in a section). */
.jp-how__safe + * { margin-top: var(--col-gap); }
.jp-how__safe-ic { color: var(--pink-bright); flex: none; margin-top: 3px; display: inline-flex; }
.jp-how__safe-title { font-family: var(--font-heading); font-weight: 600; font-size: 1.25rem; color: var(--charcoal); margin: 0 0 0.35rem; }
.jp-how__safe-body { font-size: 1rem; line-height: var(--leading-normal); color: var(--charcoal); margin: 0; max-width: 60ch; }
.jp-how__cta { margin-top: 2rem; }

/* ---------- Third-party logo row (social proof) ----------
   Logo-wall rules, encoded once here for any future logo additions:
   1. Equal visual MASS, not equal height — each mark's height is set optically:
      compact solid blocks sit lowest (--block), tall crests highest (--tall),
      wordmarks between (default). Never give unlike shapes one shared height.
   2. Fixed-height cells centred on one shared midline, so shape differences
      never disturb the row's rhythm.
   3. One treatment for every mark: greyscale + multiply at a single opacity —
      third-party colour never competes with the palette, and any white matte
      in a supplied file melts into the surface behind it.
   4. The row is anchored inside the claim it proves — never left free-floating
      between unrelated blocks.
   5. Assets are trimmed to their content box (no baked-in shadows or padding);
      alt text carries the organisation names. */
.jp-trainedlogos { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 2.75rem; list-style: none; margin: 1.5rem 0 0.25rem; padding: 0; }
.jp-trainedlogos li { display: flex; align-items: center; height: 60px; }
.jp-trainedlogos__mark { display: block; width: auto; height: 29px; filter: grayscale(1); opacity: 0.75; mix-blend-mode: multiply; }
.jp-trainedlogos__mark--block { height: 28px; }
.jp-trainedlogos__mark--tall { height: 56px; }
/* Small screens: step the whole row down together (same mass ratios) so the
   marks hold one line instead of orphaning a lone logo onto a second row. */
@media (max-width: 560px) {
  .jp-trainedlogos { gap: 0.5rem 1.5rem; }
  .jp-trainedlogos li { height: 48px; }
  .jp-trainedlogos__mark { height: 24px; }
  .jp-trainedlogos__mark--block { height: 23px; }
  .jp-trainedlogos__mark--tall { height: 46px; }
}

/* ---------- Language switcher (header) ----------
   Our own accessible menu drives the Google Website Translator (same pattern
   as Project Salama). The switcher is server-rendered but ships with [hidden]:
   translation needs JS either way, so app.js reveals it — no dead control when
   JS is absent. Google's script loads only after a language is chosen, so
   untranslated visits never contact Google. */
.jp-langswitch { position: relative; }
.jp-langswitch__toggle { display: inline-flex; align-items: center; gap: 0.45em; font-family: var(--font-body); font-weight: 700; font-size: 0.9375rem; line-height: 1; color: var(--charcoal); background: none; border: 1.5px solid var(--line); border-radius: var(--radius-base); padding: 0.55em 0.7em; cursor: pointer; transition: color var(--duration-fast) var(--ease-smooth), border-color var(--duration-fast) var(--ease-smooth); }
.jp-langswitch__toggle:hover { color: var(--pink-deep); border-color: var(--pink-deep); }
.jp-langswitch__menu { position: absolute; right: 0; top: calc(100% + 10px); min-width: 230px; max-height: min(60vh, 420px); overflow-y: auto; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-md); box-shadow: var(--shadow-md); list-style: none; margin: 0; padding: 0.4rem; display: none; z-index: 60; }
.jp-langswitch.is-open .jp-langswitch__menu { display: block; }
.jp-langswitch__option { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; width: 100%; text-align: left; background: none; border: 0; padding: 0.55em 0.75em; border-radius: var(--radius-base); font-family: var(--font-body); font-size: 0.9375rem; color: var(--charcoal); cursor: pointer; }
.jp-langswitch__option:hover { background: var(--pink-pale); }
.jp-langswitch__option[aria-current="true"] { font-weight: 800; color: var(--pink-deep); }
.jp-langswitch__en { font-size: 0.8125rem; color: var(--ink-700); }
@media (max-width: 560px) {
  /* Icon-only toggle on phones; the aria-label still names the control. */
  .jp-langswitch__current { display: none; }
}
/* Google Translate chrome suppression: our menu is the only visible UI. The
   body offset Google injects for its banner is neutralised. */
#google_translate_element, iframe.skiptranslate, .goog-te-banner-frame { display: none !important; }
body { top: 0 !important; }

/* ---------- Document prose (policy/legal pages) ----------
   One flowing column for document-style pages (privacy, future terms):
   plain h2 + p + ul, no cards or bands, so the content is trivial to update.
   In the WordPress port this class wraps ordinary rich-text page content. */
.jp-prose { max-width: 70ch; }
.jp-prose h2 { font-family: var(--font-heading); font-weight: 600; font-size: clamp(1.5rem, 1.2rem + 1vw, 1.9rem); line-height: 1.25; color: var(--charcoal); margin: 2.75rem 0 0.85rem; }
.jp-prose h2:first-child { margin-top: 0; }
.jp-prose p, .jp-prose ul { font-size: 1.0625rem; line-height: var(--leading-normal); color: var(--charcoal); margin: 0 0 1.1rem; }
.jp-prose ul { padding-left: 1.3em; }
.jp-prose li { margin-bottom: 0.4rem; }
.jp-prose a { color: var(--pink-deep); font-weight: 700; text-decoration: underline; text-underline-offset: 0.15em; }
.jp-prose .jp-prose__updated { font-size: 0.9375rem; color: var(--ink-700); margin-top: 2.5rem; }

/* ---------- Survivor voice (berry, dark — emotional core) ---------- */
.jp-voice { background: var(--surface-voice); color: var(--white); }
.jp-voice__inner { display: grid; grid-template-columns: repeat(var(--gcols), 1fr); column-gap: var(--col-gap); align-items: center; padding-block: 96px; }
.jp-voice__lead { grid-column: 1 / 8; }
.jp-voice__body { grid-column: 8 / 13; }
.jp-voice__quote { font-family: var(--font-heading); font-size: clamp(2rem, 1rem + 3vw, 3.1rem); line-height: 1.16; color: var(--white); margin: 0.85rem 0 0; text-wrap: balance; }
.jp-voice__quote em { font-style: normal; font-weight: 700; color: var(--pink-soft); }
.jp-voice__body p { color: rgba(255,255,255,0.86); font-size: var(--text-body-lg); margin: 0 0 1.5rem; }

/* ---------- Community & events (warm light) — 3 x 4 cols ---------- */
.jp-community { background: var(--pink-mist); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.jp-events { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(var(--gcols), 1fr); column-gap: var(--col-gap); row-gap: var(--col-gap); }
.jp-events > * { grid-column: span 4; }
.jp-event { display: flex; align-items: flex-start; gap: 0.85rem; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-md); padding: 1.25rem 1.4rem; }
.jp-event__ic { color: var(--pink-bright); flex: none; margin-top: 2px; display: inline-flex; }
.jp-event__text { display: flex; flex-direction: column; gap: 0.25rem; flex: 1; min-width: 0; }
.jp-event__title { display: block; font-family: var(--font-heading); font-weight: 600; font-size: 1.2rem; line-height: 1.25; color: var(--charcoal); overflow-wrap: anywhere; }
.jp-event__when { display: block; font-size: 0.9375rem; color: var(--ink-700); }
.jp-community__cta { margin-top: 2rem; }
/* "More from The Jessica Project" — secondary strip (Crowned With Courage, podcast).
   Kept visually lighter than the event cards so it doesn't pull focus from support. */
.jp-more { list-style: none; margin: 1.25rem 0 0; padding: 0; display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem; }
.jp-more__item { display: flex; align-items: center; gap: 0.85rem; background: transparent; box-shadow: var(--ring-hairline); border-radius: var(--radius-md); padding: 1rem 1.1rem; text-decoration: none;
  transition: box-shadow var(--duration-normal) var(--ease-smooth), background var(--duration-normal) var(--ease-smooth), transform var(--duration-fast) var(--ease-smooth); }
.jp-more__item:hover { box-shadow: 0 0 0 1px var(--pink-deep); background: rgba(255,255,255,0.5); }
.jp-more__item:active { transform: scale(var(--press-scale)); }
.jp-more__ic { color: var(--pink-bright); flex: none; display: inline-flex; }
.jp-more__text { display: flex; flex-direction: column; gap: 0.15rem; flex: 1; }
.jp-more__title { font-family: var(--font-body); font-weight: 800; font-size: 0.9375rem; color: var(--charcoal); }
.jp-more__sub { font-size: 0.875rem; line-height: 1.4; color: var(--ink-700); }
.jp-more__arrow { color: var(--pink-deep); flex: none; display: inline-flex; }

/* ---------- Advocacy & change (pale-pink campaign field) ---------- */
.jp-advocacy { background: var(--surface-campaign); border-top: 1px solid var(--pink-soft); border-bottom: 1px solid var(--pink-soft); }
.jp-advocacy__inner { display: grid; grid-template-columns: repeat(var(--gcols), 1fr); column-gap: var(--col-gap); align-items: center; }
.jp-advocacy__text { grid-column: 1 / 7; }
.jp-pillars { grid-column: 8 / 13; }
.jp-advocacy__text h2 { font-size: var(--text-h2); line-height: var(--leading-tight); letter-spacing: var(--tracking-tight); margin: 0.75rem 0 0; color: var(--plum-deep); text-wrap: balance; }
/* Quoted mission affirmation — a quiet pull-quote, pink accent, wrapped in
   real speech marks (per the brief), with the 'reclaim, rise' refrain kept in
   its italic-Lora treatment per the design system. */
.jp-creed { quotes: "\201C" "\201D"; margin: 1.5rem 0 0; padding: 0 0 0 1.5rem; border-left: 3px solid var(--pink-bright); font-family: var(--font-heading); font-weight: 500; font-size: clamp(1.25rem, 1rem + 1vw, 1.6rem); line-height: 1.35; color: var(--plum-deep); max-width: 34rem; }
.jp-creed::before { content: open-quote; }
.jp-creed::after { content: close-quote; }
.jp-creed em { font-style: italic; font-weight: 500; color: var(--pink-deep); }
.jp-advocacy__text p { font-size: var(--text-body-lg); color: var(--charcoal); margin: 1rem 0 0; max-width: 36rem; }
.jp-advocacy__cta { display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap; margin-top: 1.75rem; }
.jp-advocacy .jp-btn--ghost { color: var(--plum); }
.jp-advocacy .jp-btn--ghost:hover { background: rgba(50,14,34,0.06); }
.jp-pillars { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.85rem; }
.jp-pillars li { display: flex; gap: 0.9rem; align-items: flex-start; background: rgba(255,255,255,0.55); border: 1px solid var(--pink-soft); border-radius: var(--radius-md); padding: 1rem 1.2rem; }
.jp-pillars__ic { color: var(--pink-deep); flex: none; margin-top: 2px; display: inline-flex; }
.jp-pillars b { display: block; font-family: var(--font-body); font-weight: 800; font-size: 1rem; color: var(--plum-deep); margin-bottom: 0.15rem; }
.jp-pillars span { font-size: 0.9375rem; color: var(--ink-700); }

/* ---------- Stand with us / donate (plum-deep, dark) ---------- */
.jp-donate { background: var(--surface-dark); color: var(--white); }
.jp-donate__inner { display: grid; grid-template-columns: repeat(var(--gcols), 1fr); column-gap: var(--col-gap); align-items: center; padding-block: 96px; }
.jp-donate__inner > :first-child { grid-column: 1 / 8; }
.jp-donate__inner > :last-child { grid-column: 8 / 13; }
.jp-donate h2 { color: var(--white); font-size: var(--text-h2); line-height: var(--leading-tight); letter-spacing: var(--tracking-tight); margin: 0.85rem 0 0; text-wrap: balance; }
.jp-donate p { color: rgba(255,255,255,0.84); font-size: var(--text-body-lg); margin: 1rem 0 0; }
.jp-donate__cta { display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap; }
.jp-donate__note { font-size: 0.9375rem; color: rgba(255,255,255,0.62); margin-top: 1.25rem; }

/* ---------- Stats (plum-deep dark, pink figures) ----------
   Large numerals use --pink-bright: sanctioned large-heading pink, and at
   4.06:1 on --plum-deep it clears WCAG AA for large text (needs 3:1). */
.jp-stats { background: var(--surface-dark); color: var(--white); }
.jp-stats .jp-section__head h2 { color: var(--white); }
.jp-stats .jp-section__head p { color: rgba(255,255,255,0.82); }
.jp-stats__grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, 1fr); column-gap: var(--col-gap); row-gap: 2.5rem; }
.jp-stat { display: flex; flex-direction: column; gap: 0.75rem; padding-top: 1.5rem; border-top: 1px solid var(--pink-bright); }
.jp-stat__num { font-family: var(--font-heading); font-weight: 600; font-size: clamp(2.25rem, 1.2rem + 2.4vw, 3rem); line-height: 1.05; color: var(--pink-bright); letter-spacing: -0.02em; white-space: nowrap; }
.jp-stat__label { font-size: var(--text-body-lg); line-height: var(--leading-snug); color: var(--white); }
.jp-stat__src { font-size: 0.875rem; color: rgba(255,255,255,0.55); margin-top: 0.5rem; }

/* ---------- Latest news (paper field, canonical cards) ---------- */
.jp-news { background: var(--surface-page); }
/* Editorial layout: a featured lead story (left, spanning both rows) with two
   secondary stories stacked on the right. Falls back to a single column < md.
   The cards themselves ride the canonical .jp-card family (defined below);
   the variants here add only the news rhythm + the full-bleed lead photo. */
.jp-news__grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 7fr 5fr; column-gap: var(--col-gap); row-gap: var(--col-gap); align-items: stretch; }
.jp-news__grid > li:first-child { grid-row: span 2; }
.jp-news__meta { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
.jp-news__tag, .jp-tag { font-family: var(--font-body); font-weight: 800; font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--pink-deep); background: var(--pink-pale); border-radius: var(--radius-sm); padding: 0.3rem 0.6rem; }
.jp-news__date { font-size: 0.875rem; color: var(--ink-500); }

/* Card-with-photo variant (news/story cards). Double class so these beat the
   canonical .jp-card base (defined LATER in this sheet) regardless of order. */
.jp-card.jp-card--media { --card-pad: 1.75rem; gap: 0.85rem; }

/* Featured lead story — more presence via size + a full-bleed lead photo. */
.jp-card.jp-card--featured { --card-pad: 2.25rem; gap: 1.1rem; }
.jp-card--featured .jp-card__title { font-size: clamp(1.75rem, 1.2rem + 1.6vw, 2.25rem); line-height: 1.15; }
.jp-card--featured .jp-card__body { font-size: var(--text-body-lg); max-width: 46ch; }

/* Reusable media wrapper — fixed ratio, cover-fit, warm placeholder background so
   a slow-loading photo never flashes white. See docs/photography-direction.md. */
.jp-media { display: block; overflow: hidden; background: var(--pink-mist); border-radius: var(--radius-md); }
.jp-media picture { display: block; width: 100%; height: 100%; }
.jp-media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.jp-media svg { display: block; width: 100%; height: 100%; }

/* The photo bleeds to the card's top + side edges (card padding is a token so
   the negative margin matches both standard and featured sizes). */
.jp-card__media { margin: calc(var(--card-pad) * -1) calc(var(--card-pad) * -1) 0;
  border-radius: var(--radius-md) var(--radius-md) 0 0; aspect-ratio: 16 / 10; }
.jp-card--featured .jp-card__media { aspect-ratio: 16 / 9; }
/* Above 960px the featured card spans two grid rows; let the PHOTO absorb the
   spare height (not a void between body and CTA). Scoped so stacked layouts
   below 960px keep the fixed 16/9 ratio box. */
@media (min-width: 961px) {
  .jp-card--featured .jp-card__media { aspect-ratio: auto; flex: 1; min-height: 300px; }
  .jp-card--featured .jp-card__body { flex: 0 0 auto; }
}

/* ---------- Bio split (founder / ambassador / team profiles) ----------
   The standard people-profile pattern: a PORTRAIT photo (4:5 — the formal
   portrait crop) beside the prose on desktop, stacking photo-first on mobile.
   Supply headshots at ~800×1000 (2x display), consistent crop and headroom
   across the team. One .jp-bio per person; text column holds the name (h3),
   role and paragraphs. */
.jp-bio { display: grid; grid-template-columns: minmax(240px, 2fr) 5fr; gap: var(--col-gap); align-items: start; }
.jp-bio + .jp-bio { margin-top: calc(var(--col-gap) * 1.5); }
.jp-bio__media { aspect-ratio: 4 / 5; box-shadow: var(--ring-hairline); }
.jp-bio__text { max-width: 62ch; }
.jp-bio__text > p + p { margin-top: 0.9em; }
.jp-bio__role { font-family: var(--font-body); font-weight: 800; font-size: 0.8125rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--pink-deep); margin: 0.2rem 0 0.9rem; }
@media (max-width: 900px) {
  .jp-bio { grid-template-columns: 1fr; }
  .jp-bio__media { max-width: 300px; }
}

/* ---------- Newsletter sign-up (pink-pale field) ---------- */
.jp-news-signup { background: var(--pink-pale); border-top: 1px solid var(--line); }
.jp-news-signup__inner { display: grid; grid-template-columns: repeat(var(--gcols), 1fr); column-gap: var(--col-gap); align-items: center; row-gap: 2rem; }
.jp-news-signup__text { grid-column: 1 / 7; }
.jp-news-signup__text h2 { margin: 0.75rem 0 0; }
.jp-news-signup__text p { font-size: var(--text-body-lg); color: var(--ink-700); margin: 1rem 0 0; max-width: 36rem; }
.jp-news-signup__form { grid-column: 8 / 13; }
.jp-news-signup__row { display: flex; gap: 0.75rem; align-items: stretch; flex-wrap: wrap; }
.jp-news-signup__row .jp-field__control { flex: 1 1 14rem; min-height: 56px; }
.jp-news-signup__row .jp-btn { min-height: 56px; white-space: nowrap; }
.jp-news-signup__note { display: flex; align-items: flex-start; gap: 0.5rem; margin: 1rem 0 0; font-size: 0.9375rem; color: var(--ink-700); }
/* Post-submit confirmation (JS enhancement; focus lands here for AT users) */
.jp-news-signup__done { margin: 0; font-family: var(--font-body); font-weight: 700; font-size: var(--text-body-lg); color: var(--charcoal); outline: none; }
.jp-news-signup__note-ic { color: var(--pink-bright); flex: none; margin-top: 2px; display: inline-flex; }

/* ===========================================================================
   GET SUPPORT PAGE  (get-support.html)
   Based on the canonical design-system page (ui_kits/website/get-support.html):
   lean, form-first, HTML-first <form-wizard> + <validation-enhancer>. This block
   adds only the page-specific gs-* classes + the "help right now" band; the
   crisis bar, header/nav, .jp-field, .jp-btn, .jp-wizard and footer are reused.
   =========================================================================== */

/* Any in-page jump target clears the sticky crisis bar + header. */

/* Intro + form shell — a single calm column (canonical: max-width 680). */
.gs-intro { max-width: 680px; margin: 0 auto; padding: clamp(2rem, 5vw, 3.5rem) var(--gutter) clamp(1.5rem, 3vw, 2.25rem); }
.gs-eyebrow { color: var(--pink-deep); margin: 0 0 0.75rem; }
.gs-intro h1 { font-family: var(--font-heading); font-weight: 600; font-size: var(--text-h1); line-height: var(--leading-tight); letter-spacing: var(--tracking-tight); color: var(--charcoal); margin: 0; text-wrap: balance; }
.gs-lead { font-size: var(--text-lead); color: var(--ink-700); margin: 1rem 0 0; }
/* Quick-fact strip (inner pages): the scannable who/what/where answer, first
   screen. NN/g: visitors evaluate credibility on About/service pages — give
   them facts before prose. Reused by service pages (Free · Where · Referral). */
.jp-facts { list-style: none; margin: 1.75rem 0 0; padding: 1.25rem 0 0; border-top: 1px solid var(--line); display: flex; flex-wrap: wrap; gap: 1rem 2.5rem; }
/* Fact ribbon: the strip as a full-width band directly under an inner-page hero */
.jp-factbar { background: var(--pink-mist); border-block: 1px solid var(--line); }
.jp-factbar .jp-facts { margin: 0; padding: 1.4rem 0; border-top: 0; justify-content: space-between; }
/* Survivor-voice quote cards: the words in the serif voice, anonymous attribution.
   Attribution NEVER carries a name, age or town — the pattern is the promise.
   3-across on the 12-col grid; the mobile blocks' `.jp-grid > *` reset comes
   later in the sheet, so stacking still wins below 900px. */
.jp-card--quote { grid-column: span 4; }
.jp-card--quote .jp-card__body { font-family: var(--font-heading); font-style: italic; font-size: 1.1875rem; line-height: 1.55; color: var(--charcoal); }
.jp-card--quote figcaption { font-family: var(--font-body); font-size: 0.75rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; color: var(--pink-deep); margin-top: 0.9rem; }
/* Quote cards stay charcoal-on-white even inside dark bands (.jp-donate p etc.
   sets white on descendant paragraphs — this wins it back). */
.jp-on-dark .jp-card--quote p, .jp-donate .jp-card--quote p { color: var(--charcoal); font-size: 1.1875rem; }
/* Editorial pull-quote cue: an oversized opening mark instead of typed quotation
   marks (quote text in the markup carries no literal quote characters). */
.jp-card--quote::before { content: "\201C"; display: block; font-family: var(--font-heading);
  font-size: 3.2rem; line-height: 0.55; color: var(--pink-soft); margin-bottom: 0.5rem; }

/* Masonry flow for quote collections — fixed column width, natural height, so
   short quotes sit compact and longer stories breathe (no equal-height voids). */
.jp-masonry { columns: 3 300px; column-gap: var(--col-gap); }
.jp-masonry > * { break-inside: avoid; margin: 0 0 var(--col-gap); }
.jp-masonry .jp-card { height: auto; }

/* Breadcrumb orientation for pages that live outside the main nav (news,
   myths & facts, staying safe online) — the quiet "you are here" the trunk
   test asks for. One level deep by design. */
.jp-crumbs { list-style: none; display: flex; flex-wrap: wrap; gap: 0.45rem; margin: 0 0 1.1rem; padding: 0;
  font-family: var(--font-body); font-size: 0.875rem; color: var(--ink-700); }
.jp-crumbs a { color: var(--pink-deep); font-weight: 600; }
.jp-crumbs li + li::before { content: "\203A"; margin-right: 0.45rem; color: var(--ink-500); }

/* Attribution line inside the dark voice band (real featured quotes). */
.jp-voice__attr { font-family: var(--font-body); font-size: 0.75rem; font-weight: 800;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--pink-soft); margin: 1.1rem 0 0; }
/* Event list — deliberately shaped like a WordPress events-plugin list view
   (The Events Calendar et al): date badge · category · title · when/where ·
   excerpt. In WP these classes skin the plugin's own markup; recurring groups
   use an icon badge instead of a date. Venues are NEVER precise (safety). */
.jp-eventlist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1rem; }
.jp-eventrow { display: flex; align-items: flex-start; gap: 1.4rem; background: var(--surface-card); border: 1px solid var(--line); border-radius: var(--radius-md); padding: 1.5rem; }
.jp-eventrow__date { flex: none; min-width: 76px; text-align: center; background: var(--pink-pale); border-radius: var(--radius-md); padding: 0.7rem 0.5rem 0.6rem; }
.jp-eventrow__date b { display: block; font-family: var(--font-heading); font-weight: 600; font-size: 1.9rem; line-height: 1; color: var(--pink-deep); }
.jp-eventrow__date span { display: block; margin-top: 0.3rem; font-family: var(--font-body); font-size: 0.75rem; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: var(--pink-deep); }
.jp-eventrow__date .ic { display: inline-flex; color: var(--pink-deep); padding: 0.2rem 0 0.1rem; }
.jp-eventrow__title { font-family: var(--font-heading); font-weight: 600; font-size: 1.25rem; line-height: 1.25; color: var(--charcoal); margin: 0.4rem 0 0; }
.jp-eventrow__when { display: block; margin-top: 0.35rem; font-size: 0.9375rem; color: var(--ink-500); }
.jp-eventrow__desc { margin: 0.5rem 0 0; font-size: 1rem; line-height: var(--leading-normal); color: var(--ink-700); }

/* "You are not alone" in the community's languages (translations pending
   verification by community members before launch — see survivor-voice.html) */
.jp-langs { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 2.25rem 3.5rem; justify-content: center; text-align: center; }
.jp-langs .phrase { display: block; font-family: var(--font-heading), serif; font-size: clamp(1.375rem, 1.1rem + 1vw, 1.75rem); color: var(--white); line-height: 1.5; }
.jp-langs .lang { display: block; margin-top: 0.4rem; font-family: var(--font-body); font-size: 0.75rem; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; color: var(--pink-soft); }
/* Inner-page hero: the homepage split-hero grammar at content-page scale */
.jp-hero--inner .jp-hero__text { padding: 56px 0 60px; }
.jp-hero--inner .jp-hero__panel { min-height: 380px; }
.jp-facts b { display: block; font-family: var(--font-body); font-size: var(--text-eyebrow); font-weight: 800; letter-spacing: var(--tracking-eyebrow); text-transform: uppercase; color: var(--pink-deep); margin: 0 0 0.2rem; }
.jp-facts span { font-family: var(--font-body); font-size: 1rem; font-weight: 600; color: var(--charcoal); }
.gs-main { max-width: 680px; margin: 0 auto; padding: clamp(1.5rem, 3vw, 2.25rem) var(--gutter) 4rem; }

/* Privacy note (canonical jp-privacynote) */
.jp-privacynote { display: flex; gap: 1rem; align-items: flex-start; background: var(--pink-pale); border: 1px solid var(--line); border-radius: var(--radius-md); padding: 1.1rem 1.3rem; margin: 0 0 2.25rem; }
.jp-privacynote .ic { color: var(--pink-bright); flex: none; margin-top: 2px; display: inline-flex; }
.jp-privacynote p { margin: 0; font-size: 0.9375rem; line-height: var(--leading-normal); color: var(--charcoal); }
.jp-privacynote b.t { display: block; font-weight: 800; margin-bottom: 0.2rem; }

/* Form card + steps (canonical gs-*) */
.gs-card { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: clamp(1.5rem, 4vw, 2.5rem); }
.gs-card fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.gs-card legend { padding: 0; }
.gs-steptitle { font-family: var(--font-heading); font-weight: 600; font-size: var(--text-h3); line-height: var(--leading-snug); color: var(--charcoal); margin: 0; }
.gs-fields { display: flex; flex-direction: column; gap: 1.5rem; }
.gs-choice { display: flex; flex-direction: column; gap: 0.6rem; }
.gs-choice__opt { display: flex; align-items: flex-start; gap: 0.7rem; padding: 0.85rem 1rem; border: 1.5px solid var(--line-strong); border-radius: var(--radius-base); cursor: pointer; }
.gs-choice__opt:hover { border-color: var(--ink-500); background: var(--surface-wash); }
.gs-choice__opt input { margin-top: 0.2rem; width: 1.1rem; height: 1.1rem; accent-color: var(--pink-deep); flex: none; }
.gs-choice__opt span { font-size: 1rem; color: var(--charcoal); }

/* Confirmation (shown after a valid submit) */
.gs-done { display: none; }
.gs-done.is-shown { display: block; }
.gs-done .tick { width: 56px; height: 56px; color: var(--pink-bright); margin-bottom: 1rem; }
.gs-done h2 { font-size: var(--text-h2); margin: 0 0 0.75rem; }
.gs-done p { color: var(--ink-700); font-size: var(--text-body-lg); }
.gs-ref { font-weight: 800; color: var(--pink-deep); }

/* Base .jp-btn (the live site sets these inline on the homepage; the form needs
   them in CSS). Hover/active/focus states live in the components block above. */
.gs-card .jp-wizard__nav .jp-btn,
.gs-card .gs-actions .jp-btn,
.gs-intro .jp-btn { font-size: 1.1875rem; padding: 0.72em 1.4em; min-height: 50px; }
/* Action row for non-wizard forms (e.g. the training enquiry) — same spacing
   rhythm as .jp-wizard__nav. */
.gs-actions { display: flex; align-items: center; gap: 1rem; margin-top: 0.5rem; flex-wrap: wrap; }
/* Standalone form card outside .gs-main — same focused column as get-support. */
.gs-card--narrow { max-width: 680px; margin-inline: auto; }
.jp-btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.6em; font-family: var(--font-body); font-weight: 700; line-height: 1; border-radius: var(--radius-base); border: 1.5px solid transparent; cursor: pointer; text-decoration: none; }
.jp-btn--primary { background: var(--action-fill); color: var(--white); border-color: var(--action-fill); }
.jp-btn--secondary { background: transparent; color: var(--pink-deep); border-color: var(--pink-deep); font-weight: 600; }

/* Help right now — sober, high-priority band (same charcoal as the crisis bar) */
.jp-helpnow { background: var(--charcoal); color: var(--white); }
.jp-helpnow__grid { list-style: none; margin: 1.75rem 0 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); column-gap: var(--col-gap); row-gap: var(--col-gap); }
.jp-helpnow__item { display: flex; flex-direction: column; gap: 0.5rem; padding: 1.4rem 1.5rem; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.16); border-radius: var(--radius-md); }
.jp-helpnow__label { display: inline-flex; align-items: center; gap: 0.5rem; font-family: var(--font-body); font-weight: 800; font-size: 0.8125rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--pink-soft); }
.jp-helpnow__big { font-family: var(--font-heading); font-weight: 600; font-size: 1.6rem; line-height: 1.1; color: var(--white); }
.jp-helpnow__big a { color: var(--white); text-decoration: none; }
.jp-helpnow__big a:hover { text-decoration: underline; text-underline-offset: 0.15em; }
.jp-helpnow__sub { font-size: 0.9375rem; color: rgba(255,255,255,0.82); line-height: var(--leading-normal); }
.jp-helpnow .jp-section__head h2 { color: var(--white); }
.jp-helpnow .jp-section__head p { color: rgba(255,255,255,0.82); }

@media (max-width: 900px) { .jp-helpnow__grid { grid-template-columns: 1fr; } }
@media (max-width: 560px) {
  .jp-wizard__steplabel { display: none; }                 /* numbers-only progress */
  .gs-card .jp-wizard__nav .jp-btn { width: 100%; }
  .gs-card .jp-wizard__nav [data-wizard-next], .gs-card .jp-wizard__nav [data-wizard-back] { margin: 0; }
}

/* ---------- Footer (plum-deep) ---------- */
.jp-footer { background: var(--surface-dark); color: var(--white); position: relative; }
/* Brand mark centred where the sunrise crest used to rise (similar size) */
.jp-footer__crest { line-height: 0; height: 200px; display: flex; align-items: center; justify-content: center; }
.jp-footer__crest svg, .jp-footer__crest img { width: auto; height: 152px; display: block; }
.jp-footer__inner { display: grid; grid-template-columns: repeat(var(--gcols), 1fr); column-gap: var(--col-gap); row-gap: var(--baseline-lh); padding-top: 64px; padding-bottom: 48px; }
.jp-footer__inner > * { grid-column: span 3; }
.jp-footer h3 { color: var(--white); font-family: var(--font-body); font-weight: 800; font-size: 0.8125rem; letter-spacing: 0.12em; text-transform: uppercase; margin: 0 0 1rem; }
.jp-footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.15rem; }
.jp-footer a { color: rgba(255,255,255,0.82); text-decoration: none; font-size: 1rem; display: inline-flex; align-items: center; min-height: 44px; }
.jp-footer a:hover { color: var(--white); text-decoration: underline; text-underline-offset: 0.2em; }
.jp-footer__contact li { display: flex; align-items: center; gap: 0.6rem; min-height: 44px; color: rgba(255,255,255,0.82); }
.jp-footer__contact .ic { color: var(--pink-bright); flex: none; margin-top: 1px; }
.jp-footer__bottom { border-top: 1px solid rgba(255,255,255,0.14); padding-block: 1.5rem; display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; font-size: 0.875rem; color: rgba(255,255,255,0.6); }
/* Fine-print links (e.g. Privacy) match the bottom bar's size, underlined for
   discoverability against the muted text. */
.jp-footer__bottom a { font-size: inherit; min-height: 0; text-decoration: underline; text-underline-offset: 0.2em; }

/* ---------- Mobile menu ---------- */
.jp-mobnav { display: none; }

/* ---------- Responsive ---------- */
@media (max-width: 960px) {
  .jp-advocacy__inner { grid-template-columns: 1fr; }
  .jp-advocacy__text, .jp-pillars { grid-column: 1 / -1; }
  .jp-events { grid-template-columns: 1fr; }
  .jp-events > * { grid-column: 1 / -1; }
  .jp-more { grid-template-columns: 1fr; }
  .jp-how__steps { grid-template-columns: 1fr; }
  .jp-how__step { grid-column: 1 / -1; }
  /* Doorways: drop to a 2-column grid at tablet, all cards equal width */
  .jp-doors__grid { grid-template-columns: repeat(2, 1fr); }
  .jp-doors__grid > li { grid-column: auto !important; }
  /* Stats: 2x2 at tablet; news stacks */
  .jp-stats__grid { grid-template-columns: repeat(2, 1fr); }
  .jp-news__grid { grid-template-columns: 1fr; }
  .jp-news__grid > li:first-child { grid-row: auto; }
  /* Newsletter stacks text above the form */
  .jp-news-signup__inner { grid-template-columns: 1fr; }
  .jp-news-signup__text, .jp-news-signup__form { grid-column: 1 / -1; }
}
@media (max-width: 900px) {
  .jp-nav { display: none; }
  .jp-burger { display: inline-flex; }
  /* Compact header on mobile so the pinned crisis-bar + header stack stays short */
  .jp-header { padding-block: 0; }
  .jp-header__inner { min-height: 52px; gap: 1rem; }
  .jp-logo__img { height: 40px !important; }
  /* Compact the crisis bar on mobile: TWO rows, never three. The pinned stack
     must cost as little of the viewport as possible without cutting safety
     content. Row 1: danger line + Quick exit. Row 2: helpline. Divider hidden.
     (At very narrow widths flex-wrap stacks again; app.js re-syncs the offset.) */
  .jp-crisisbar > div { gap: 0.2rem 0.7rem !important; padding-top: 0.45rem !important; padding-bottom: 0.45rem !important; align-items: center !important; line-height: 1.25 !important; }
  .jp-crisisbar > div > span { font-size: 0.875rem !important; }
  .jp-crisisbar > div > span[aria-hidden="true"] { display: none !important; }   /* hide divider */
  .jp-crisisbar > div > span:first-child { order: 1; flex: 0 1 auto; font-size: 0.8125rem !important; } /* danger line, row 1 left (must not grow or oversize, or Quick exit wraps) */
  .jp-crisisbar > div > span:last-child  { order: 2; margin-left: auto !important; } /* Quick exit, row 1 right */
  .jp-crisisbar > div > span:nth-child(3){ order: 3; flex: 1 1 100%; margin-left: 0 !important; } /* helpline, row 2 */
  /* Slimmer Quick exit + helpline row on mobile — tap targets stay ≥44px (button)
     and ≥36px on a full-width row (AA 2.5.8 needs 24px). */
  .jp-crisisbar .jp-quick-exit { font-size: 1rem !important; padding: 0.5em 0.6em !important; }
  .jp-crisisbar > div > span:nth-child(3) a { min-height: 36px; }
  /* Mobile nav scrolls within the viewport if it is taller than the space left
     under the pinned bar, so long menus never trap the user. */
  .jp-mobnav.is-open { max-height: 70vh; overflow-y: auto; }
  .jp-hero { grid-template-columns: 1fr; }
  .jp-hero__text, .jp-hero__panel { grid-column: 1 / -1; }
  .jp-hero__text { padding: 1.25rem 0 2.5rem; max-width: none; }
  /* Responsive type step-down so the message + first CTA fit the first screen */
  .jp-hero__lead { font-size: 1.0625rem; }
  /* No hero image on mobile: the message + CTA are the whole story, and the
     photo panel would cost bytes below the fold for no purpose. The <picture>
     mobile source is a 1px data URI, so the JPEG is never downloaded. */
  .jp-hero__panel { display: none; }
  .jp-grid { grid-template-columns: repeat(2, 1fr); }
  .jp-grid > * { grid-column: auto; }
  .jp-voice__inner, .jp-donate__inner { grid-template-columns: 1fr; }
  .jp-voice__lead, .jp-voice__body,
  .jp-donate__inner > :first-child, .jp-donate__inner > :last-child { grid-column: 1 / -1; }
  .jp-footer__inner { grid-template-columns: repeat(2, 1fr); }
  .jp-footer__inner > * { grid-column: span 1; }
  .jp-mobnav.is-open { display: block; background: var(--surface-page); border-bottom: 1px solid var(--line); }
  .jp-mobnav ul { list-style: none; margin: 0; padding: 0.5rem var(--gutter) 1.25rem; display: flex; flex-direction: column; gap: 0.25rem; max-width: var(--container-max); margin-inline: auto; }
  .jp-mobnav a { display: block; padding: 0.85rem 0; color: var(--charcoal); text-decoration: none; font-weight: 700; font-size: 1.125rem; border-bottom: 1px solid var(--line); }
}
@media (max-width: 560px) {
  .jp-grid { grid-template-columns: 1fr; }
  .jp-doors__grid { grid-template-columns: 1fr; }
  .jp-stats__grid { grid-template-columns: 1fr; }
  .jp-footer__inner { grid-template-columns: 1fr; }
  .jp-footer__inner > * { grid-column: 1 / -1; }
  .jp-hero__cta { gap: 0.75rem; }
  .jp-hero__cta .jp-btn { width: 100%; }
  .jp-how__cta .jp-btn { width: 100%; }
}

/* ===========================================================================
   CRAFT PASS — tactile press, house easing on interactive surfaces, and a
   strict reduced-motion contract. Calm by design: no bounce, no overshoot,
   no entrance animation, nothing on the safety path.
   =========================================================================== */

/* Focus-visible — one consistent, high-contrast ring for keyboard users across
   every interactive element (WCAG 2.4.7). Mouse clicks don't trigger it; only
   keyboard focus does, so it never intrudes on pointer users. */
a:focus-visible,
button:focus-visible,
.jp-btn:focus-visible,
.jp-door:focus-visible,
.jp-more__item:focus-visible,
.jp-card--link:focus-visible,
input:focus-visible,
.jp-burger:focus-visible {
  outline: 3px solid var(--action-outline);
  outline-offset: 2px;
  border-radius: var(--radius-base);
}
/* On dark fields, the ring switches to soft pink so it stays visible on every
   dark surface: 5.0:1 on berry, 7.8:1 on plum-deep/charcoal (≥3:1 non-text).
   (Hot pink would fail on berry at 2.6:1 — soft pink is the light-pink analog
   of the retired gold ring.) */
.jp-voice a:focus-visible, .jp-voice button:focus-visible, .jp-voice .jp-btn:focus-visible,
.jp-donate a:focus-visible, .jp-donate button:focus-visible, .jp-donate .jp-btn:focus-visible,
.jp-stats a:focus-visible, .jp-stats button:focus-visible,
.jp-footer a:focus-visible, .jp-footer button:focus-visible,
.jp-crisisbar a:focus-visible, .jp-quick-exit:focus-visible {
  outline-color: var(--pink-soft);
}
/* Never leave an element with no focus indicator. */
:focus-visible { outline-offset: 2px; }

/* Tactile press — a firm, subtle scale on every clickable surface. */
.jp-btn:active { transform: scale(var(--press-scale)); }
.jp-burger:active,
.jp-event:active { transform: scale(var(--press-scale)); }

/* ---------------------------------------------------------------------------
   Canonical content card — .jp-card
   One reusable card object: an icon-led (Support) or, via --media, a photo-led
   (News) card with a title, body and a trailing arrow link. Deliberately NOT
   used for nav tiles (.jp-door), event rows (.jp-event) or the feature list
   (.jp-pillars) — those are separate components with different jobs.
   --------------------------------------------------------------------------- */
.jp-card { --card-pad: 1.6rem; display: flex; flex-direction: column; gap: 0.75rem; height: 100%;
  background: var(--surface-card); border-radius: var(--radius-md); padding: var(--card-pad);
  font-family: var(--font-body); color: var(--charcoal); box-shadow: var(--shadow-sm);
  transition: box-shadow var(--duration-normal) var(--ease-smooth), transform var(--duration-fast) var(--ease-smooth); }
a.jp-card { text-decoration: none; }
.jp-card--link:hover  { box-shadow: var(--shadow-md), 0 0 0 1px var(--pink-deep); }
.jp-card--link:active { transform: scale(var(--press-scale)); }
.jp-card__ic    { color: var(--pink-bright); display: inline-flex; }
.jp-card__title { font-family: var(--font-heading); font-weight: 600; font-size: 1.375rem; line-height: 1.2; color: var(--charcoal); margin: 0; }
.jp-card__body  { font-size: 1rem; line-height: var(--leading-normal); color: var(--ink-700); margin: 0; flex: 1; }
.jp-card__cta   { display: inline-flex; align-items: center; gap: 0.4em; font-weight: 700; font-size: 0.9375rem; color: var(--pink-deep); text-decoration: underline; text-underline-offset: 0.15em; margin-top: 0.25rem; }
.jp-card--link:hover .jp-card__cta { text-decoration-thickness: 2px; }

/* House easing on the few existing transitions that were using the browser
   default (burger, mobile nav reveal). No NEW motion is introduced. */
.jp-burger { transition: background-color var(--duration-fast) var(--ease-smooth),
  box-shadow var(--duration-fast) var(--ease-smooth), transform var(--duration-fast) var(--ease-smooth); }
.jp-mobnav { transition: max-height var(--duration-normal) var(--ease-smooth); }

/* SAFETY PATH — never animate or transform. The crisis bar, Quick exit, and
   the statistics must always be instantly present and perfectly still. */
.jp-stickytop, .jp-crisisbar, .jp-quick-exit,
.jp-stats, .jp-stat, .jp-stat__num {
  transition: none !important;
  animation: none !important;
}
.jp-quick-exit:active { transform: none !important; }   /* the exit must never feel like a toy */

/* REDUCED MOTION — honour the user's preference and trauma-informed need.
   Everything collapses to instant; nothing moves, scales, or loops. This is
   both a WCAG 2.1 requirement and a duty of care for this audience. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .jp-btn:active, .jp-door:active, .jp-card--link:active,
  .jp-more__item:active, .jp-burger:active, .jp-event:active {
    transform: none !important;
  }
}

/* Hero eyebrow carries the plain "what / who" signal and is a longer string, so
   when it wraps on narrow screens, top-align the sunrise mark and tighten the
   line-height so the multi-line label reads as a tidy block, not a centred sprawl. */
.jp-hero__text .jp-eyebrow { align-items: flex-start; line-height: 1.45; }
.jp-hero__text .jp-eyebrow > span:first-child { margin-top: 1px; }

/* crisis bar tel links: white + a comfortable 44px tap target (from home.html) */
.jp-crisisbar a { color: var(--white); display: inline-flex; align-items: center; min-height: 44px; padding: 0 0.15rem; }

/* ---------- Chrome classes (migrated from inline styles, 2026-07) ---------- */
.jp-crisisbar { background: var(--charcoal); color: var(--white); font-family: var(--font-body); }
.jp-crisisbar__inner { max-width: var(--container-max); margin: 0 auto; min-height: var(--crisis-bar-h); padding: 0.4rem var(--gutter); display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap; }
.jp-crisisbar__item { display: inline-flex; align-items: center; gap: 0.5em; font-size: 0.9375rem; font-weight: 600; }
.jp-crisisbar__item--danger { color: var(--pink-soft); }
.jp-crisisbar__msg { color: var(--white); }
.jp-crisisbar__divider { color: rgba(255,255,255,0.32); }
.jp-crisisbar__org { color: rgba(255,255,255,0.78); }
.jp-crisisbar__exit { margin-left: auto; }
.jp-crisisbar a { text-decoration: none; font-weight: 800; white-space: nowrap; }
.jp-eyebrow > span { display: inline-flex; color: var(--pink-bright); }
.jp-footer__about { color: rgba(255,255,255,0.72); margin-top: 1rem; max-width: 32ch; }
.jp-footer__tagline { color: var(--pink-soft); margin-top: 0.85rem; font-weight: 800; font-size: 0.8125rem; letter-spacing: 0.12em; text-transform: uppercase; }
.jp-footer__notewrap { padding-bottom: 1.5rem; }
.jp-footer .jp-privacynote { margin: 0; }
.jp-privacynote a { color: var(--pink-deep); font-weight: 700; text-decoration: underline; text-underline-offset: 0.15em; }
.jp-privacynote a:hover { color: var(--pink-deep); }


/* ==========================================================================
   WordPress/GeneratePress adapter (WP build only, not part of the design
   system). Pages are composed of full-width section blocks that bring their
   own .jp-wrap containers, so GP's boxed content chrome is neutralised.
   ========================================================================== */
.site-content { padding: 0; display: block; }
.site-content .content-area { width: 100%; }
.grid-container { max-width: none; margin: 0; padding: 0; }
.site-main { margin: 0 !important; }
.separate-containers .inside-article, .one-container .inside-article { padding: 0; }
.separate-containers .site-main > * { margin-bottom: 0; }
.inside-article { background: transparent; }
.page .entry-header { display: none; }
/* InnerBlocks renders an unstyled wrapper div inside jp-section; make it
   layout-neutral so child blocks stack as in the prototype. */
.wp-block-jessica-section .jp-wrap > div:not([class]) { display: contents; }
