/*
Theme Name: Dr Jo Prendergast
Theme URI: https://drjoprendergast.com/
Author: Shannon Briggs
Description: Speaker theme for Dr Jo Prendergast, built from the approved static mockups. Design is reproduced pixel-for-pixel; all content is editable via ACF with the original copy as a fallback.
Version: 0.1.0
Requires at least: 6.0
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: drjo
*/

/* ==========================================================================
   FONTS — self-hosted (mockups loaded Metropolis from jsDelivr; self-hosting
   removes the third-party dependency and the render-blocking CDN lookup).
   Albra is Jo's purchased brand font, shipped from assets/fonts/.
   ========================================================================== */
@font-face{ font-family:"Metropolis"; src:url("assets/fonts/metropolis-400.woff2") format("woff2"); font-weight:400; font-style:normal; font-display:swap; }
@font-face{ font-family:"Metropolis"; src:url("assets/fonts/metropolis-500.woff2") format("woff2"); font-weight:500; font-style:normal; font-display:swap; }
@font-face{ font-family:"Metropolis"; src:url("assets/fonts/metropolis-600.woff2") format("woff2"); font-weight:600; font-style:normal; font-display:swap; }
@font-face{ font-family:"Metropolis"; src:url("assets/fonts/metropolis-700.woff2") format("woff2"); font-weight:700; font-style:normal; font-display:swap; }
@font-face{ font-family:"Albra Display"; src:url("assets/fonts/AlbraDisplay-Bold.woff2") format("woff2"); font-weight:700; font-style:normal; font-display:swap; }
@font-face{ font-family:"Albra Display"; src:url("assets/fonts/AlbraDisplay-Regular.woff2") format("woff2"); font-weight:400; font-style:normal; font-display:swap; }
@font-face{ font-family:"Albra"; src:url("assets/fonts/Albra-RegularItalic.woff2") format("woff2"); font-weight:400; font-style:italic; font-display:swap; }

/* ==========================================================================
   BRAND TOKENS — the July 2026 governing brief's exact hex values.
   Read these rather than guessing when styling forms or new components.
   ========================================================================== */
:root{
  /* Round 3: the three navies (header, content blocks, footer) unified to the brand pack's
     #10254D. --navy-deep and --navy-ink are kept only so existing class names below don't
     need renaming; all three are now the same colour. */
  --navy:#10254D;        /* primary background + dark type */
  --navy-deep:#10254D;   /* was #0E1330 */
  --navy-ink:#10254D;    /* was #141A3E */
  --cyan:#13BCE8;        /* accent */
  --cyan-deep:#0F97BD;
  --sky:#8DD9F0;         /* hero gradient / accents */
  --lime:#C4DC4A;        /* CTAs / highlight */
  --lime-bright:#D2E86A; /* CTA hover */
  --mist:#EAF6FB;        /* RETIRED: was body type on navy + pale panels. Jo asked for
                            pure white on navy and bright white panels, so nothing
                            should use this. Kept only to document the old value. */
  --slate:#5E6E88;
  --white:#ffffff;
}

/* ==========================================================================
   RESET / BASE — carried verbatim from the mockups' shared <style> block.
   ========================================================================== */
*{ box-sizing:border-box; margin:0; padding:0; }
html{ scroll-behavior:smooth; }
/* The mockups set the type stack on an inner wrapper div, leaving <body> at the browser
   default. Repeating it here costs nothing visually (the wrapper still wins by proximity)
   but stops anything rendered OUTSIDE that wrapper — admin bar, plugin markup — falling
   back to Times New Roman. */
body{ background:#10254D; font-family:'Metropolis','Hanken Grotesk',system-ui,sans-serif; }

/* Lazy-loading note: only put loading="lazy" on an <img> that reserves height (an explicit
   height in its style, or width/height attributes). A lazy image with height:auto and no
   intrinsic size collapses to 0px, never intersects the viewport, and so never loads. */
a{ color:#C4DC4A; }
a:hover{ color:#D2E86A; }
::selection{ background:#C4DC4A; color:#10254D; }
img{ max-width:100%; }
div[style*="scrollbar-width:none"]::-webkit-scrollbar{ display:none; }

/* ==========================================================================
   HOVER / FOCUS UTILITIES
   The mockups expressed interaction states as style-hover="" / style-focus=""
   attributes, which are a Design-Component runtime feature and are INERT in a
   real browser. Each distinct value from the mockups becomes a class here, so
   the built theme actually has the hover states the design intended.
   ========================================================================== */
.hv-lime:hover{ color:#C4DC4A; }
.hv-bg-lime:hover{ background:#D2E86A; }
.hv-bd-navy:hover{ border-color:#10254D; }
.hv-bd-lime:hover{ border-color:#C4DC4A; }
/* !important because these sit on elements whose navy text (and sometimes transparent
   background) is an inline style, which beats a class - without it the box turned navy
   but the text stayed navy too, e.g. the Resources pagination. */
.hv-navy-white:hover{ background:#10254D !important; color:#fff !important; }
.hv-navy-lime:hover{ background:#10254D !important; color:#C4DC4A !important; }
.hv-navy-sky:hover{ background:#10254D !important; color:#8DD9F0 !important; }
.hv-bg-deep:hover{ background:#10254D; }
.hv-bg-ink:hover{ background:#10254D; }
.hv-underline:hover{ text-decoration:underline; }
/* .hv-bg-cyan retired \u2014 its only user (the "Buy the book" button) is lime now. */
.fc-navy:focus{ border-color:#10254D; }

/* Keyboard focus should never be invisible (WCAG 2.4.7 — the brief asks for AA). */
a:focus-visible, button:focus-visible, input:focus-visible,
textarea:focus-visible, select:focus-visible{
  outline:3px solid #C4DC4A; outline-offset:2px;
}

/* Screen-reader-only, for the skip link and form labels the design hides. */
.screen-reader-text{
  position:absolute !important; width:1px; height:1px; overflow:hidden;
  clip:rect(1px,1px,1px,1px); clip-path:inset(50%); white-space:nowrap;
}
.skip-link:focus{
  position:fixed; top:10px; left:10px; z-index:1000; width:auto; height:auto;
  clip:auto; clip-path:none; background:#C4DC4A; color:#10254D;
  padding:12px 18px; border-radius:999px; font:700 13px/1 'Metropolis',sans-serif;
  text-decoration:none;
}

/* ==========================================================================
   MOBILE NAV
   The mockups have no mobile menu: the 8 nav items simply wrap, leaving a
   STICKY header 146px tall on a 375px screen — 18% of the viewport, permanently,
   pushing the hero down. Below 900px the links collapse behind a toggle instead.
   Desktop (>900px) is untouched and renders exactly as mocked.
   ========================================================================== */
.drjo-nav-toggle{ display:none; }

@media (max-width:900px){
  #site-header nav{ position:relative; }

  /* Collapsing the links is only half the job: at 375px the logo (192px) + CTA (~110px)
     + toggle (44px) + two 26px gaps still overflow and wrap to a second row, leaving the
     sticky header as tall as before. Tightening these three brings the bar to one row. */
  #site-header nav{ gap:12px !important; padding-top:12px !important; padding-bottom:12px !important; }
  #site-header nav > a:first-child img{ height:44px !important; width:auto !important; }
  #site-header nav .hv-bg-lime{ font-size:11px !important; padding:9px 14px !important; letter-spacing:.08em !important; }

  .drjo-nav-toggle{
    display:inline-flex; align-items:center; justify-content:center;
    width:44px; height:44px;            /* 44px: minimum comfortable touch target */
    padding:0; border:none; border-radius:999px;
    background:transparent; cursor:pointer; flex:0 0 auto;
  }
  .drjo-nav-toggle-bars,
  .drjo-nav-toggle-bars::before,
  .drjo-nav-toggle-bars::after{
    display:block; width:22px; height:2px; border-radius:2px;
    background:#C4DC4A; transition:transform .22s ease, opacity .22s ease;
  }
  .drjo-nav-toggle-bars{ position:relative; }
  .drjo-nav-toggle-bars::before,
  .drjo-nav-toggle-bars::after{ content:""; position:absolute; left:0; }
  .drjo-nav-toggle-bars::before{ top:-7px; }
  .drjo-nav-toggle-bars::after{ top:7px; }

  /* Bars morph into a cross while the panel is open. */
  .drjo-nav-toggle[aria-expanded="true"] .drjo-nav-toggle-bars{ background:transparent; }
  .drjo-nav-toggle[aria-expanded="true"] .drjo-nav-toggle-bars::before{ top:0; transform:rotate(45deg); }
  .drjo-nav-toggle[aria-expanded="true"] .drjo-nav-toggle-bars::after{ top:0; transform:rotate(-45deg); }

  .drjo-nav-links{
    display:none !important;
    position:absolute; top:100%; left:0; right:0;
    flex-direction:column; align-items:stretch; gap:0 !important;
    background:#10254D;
    border-top:1px solid rgba(155,214,239,.14);
    border-bottom:1px solid rgba(155,214,239,.14);
    padding:6px 22px 14px;
    box-shadow:0 18px 40px rgba(0,0,0,.35);
    max-height:calc(100vh - 100%); overflow-y:auto;
  }
  .drjo-nav-links.is-open{ display:flex !important; }
  .drjo-nav-links > a{
    padding:14px 0; font-size:15.5px !important;
    border-bottom:1px solid rgba(155,214,239,.10);
  }
  .drjo-nav-links > a:last-child{ border-bottom:none; }
}

@media (prefers-reduced-motion:reduce){
  .drjo-nav-toggle-bars,
  .drjo-nav-toggle-bars::before,
  .drjo-nav-toggle-bars::after{ transition:none; }
}

/* ==========================================================================
   WIDGETS — the two pieces of behaviour carried over from the mockups'
   Design-Component logic. Behaviour lives in assets/site.js; these are the
   styles that make the markup work as a slider / rail.
   ========================================================================== */
/* overflow:hidden belongs on the inner viewport, NOT on [data-slider]: the design's
   arrows are absolutely positioned at left/right:-6px, outside the track, and would be
   clipped away if the outer element hid its overflow. */
[data-slider]{ position:relative; }
[data-slider-viewport]{ overflow:hidden; }
[data-slider-track]{ display:flex; transition:transform .6s cubic-bezier(.4,0,.2,1); will-change:transform; }
[data-slider-track] > *{ flex:0 0 100%; min-width:100%; }
[data-slider-dot]{ cursor:pointer; border:none; padding:0; }
@media (prefers-reduced-motion:reduce){ [data-slider-track]{ transition:none; } }

[data-rail-track]{ display:flex; overflow-x:auto; scroll-snap-type:x mandatory; scrollbar-width:none; -ms-overflow-style:none; }
[data-rail-track]::-webkit-scrollbar{ display:none; }
[data-rail-track] > *{ scroll-snap-align:start; flex:0 0 auto; }
[data-rail-prev][disabled], [data-rail-next][disabled]{ cursor:default; }

/* Video modal — opened by [data-video-trigger] (comedy page video grid). The iframe is
   built in JS and inserted only while open, so a closed modal never keeps a YouTube
   player loaded/playing in the background. */
.drjo-video-modal{ position:fixed; inset:0; z-index:1000; display:flex; align-items:center; justify-content:center; padding:24px; }
.drjo-video-modal[hidden]{ display:none; }
.drjo-video-modal-backdrop{ position:absolute; inset:0; background:rgba(16,37,77,.86); }
.drjo-video-modal-frame{ position:relative; z-index:1; width:100%; max-width:960px; }
.drjo-video-modal-embed{ position:relative; width:100%; aspect-ratio:16/9; border-radius:14px; overflow:hidden; background:#000; box-shadow:0 30px 70px rgba(0,0,0,.5); }
.drjo-video-modal-embed iframe{ position:absolute; inset:0; width:100%; height:100%; border:0; }
.drjo-video-modal-close{
  position:absolute; top:-44px; right:0; width:36px; height:36px; border-radius:50%;
  border:1.5px solid rgba(255,255,255,.5); background:transparent; color:#fff;
  font-size:22px; line-height:1; cursor:pointer; display:flex; align-items:center; justify-content:center;
}
.drjo-video-modal-close:hover{ background:#10254D; border-color:#10254D; }

/* Background video (drjo_background_video(), e.g. the About hero's Banner video). Fills its
   positioned parent like background-size:cover: the media is sized to whichever of
   "full width" or "full height" is larger for a 16:9 frame, then centred and cropped.
   Container query units measure the wrapper itself, so it covers at every screen size.
   A light sky-blue wash from the left keeps the navy heading readable over any footage.
   Reduced-motion visitors get the section's own gradient instead. */
.drjo-bg-video{ position:absolute; inset:0; overflow:hidden; pointer-events:none; container-type:size; }
.drjo-bg-video iframe,.drjo-bg-video video{
  position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); border:0;
  width:max(100cqw, 177.78cqh); height:max(100cqh, 56.25cqw); object-fit:cover;
}
.drjo-bg-video::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(90deg, rgba(197,236,248,.82) 0%, rgba(197,236,248,.55) 45%, rgba(197,236,248,0) 75%);
}
@media (max-width:900px){
  .drjo-bg-video::after{ background:rgba(197,236,248,.6); }
}
/* Banner "Text light": white text needs a navy wash behind it, not the pale one. */
.banner-light .drjo-bg-video::after{
  background:linear-gradient(90deg, rgba(16,37,77,.72) 0%, rgba(16,37,77,.45) 45%, rgba(16,37,77,0) 75%);
}
@media (max-width:900px){
  .banner-light .drjo-bg-video::after{ background:rgba(16,37,77,.5); }
}
@media (prefers-reduced-motion:reduce){
  .drjo-bg-video{ display:none; }
}

/* ==========================================================================
   SCROLL REVEAL — one site-wide motion, the same on every page and screen size.
   Section content (eyebrows, headings, paragraphs, buttons, images and each card
   in a grid) fades and rises into view once, with a short stagger between
   siblings. [data-reveal] in the markup marks cards up front; everything else is
   tagged .drjo-anim by site.js (initAutoReveal), which also sets --drjo-delay for
   the stagger and removes both markers once an element has arrived, so hover
   styles and sticky columns behave normally afterwards. Carousels, the header
   and form fields are never animated.
   ========================================================================== */
[data-reveal],.drjo-anim{
  opacity:0; transform:translateY(18px);
  transition:opacity .6s cubic-bezier(.2,.7,.2,1) var(--drjo-delay,0ms), transform .6s cubic-bezier(.2,.7,.2,1) var(--drjo-delay,0ms);
}
[data-reveal].is-visible,.drjo-anim.is-visible{ opacity:1; transform:none; }
@media (prefers-reduced-motion:reduce){
  [data-reveal],.drjo-anim{ opacity:1; transform:none; transition:none; }
}
/* No-JS / JS-not-yet-run safety net: never leave content invisible if the observer
   hasn't run (e.g. JS blocked). Belt-and-braces with the .no-js class set in header.php. */
.no-js [data-reveal]{ opacity:1; transform:none; }

/* ==========================================================================
   HEADLINE LOAD-IN — round 4: every page's H1 animates in on page arrival, one
   line at a time where the heading actually has more than one line (e.g. the
   About hero's stacked credentials). site.js wraps each line (split on <br>)
   in a .drjo-line span with a staggered animation-delay; a single-line heading
   still gets one clean fade-and-rise as the page loads. Every .drjo-line
   starts invisible via inline style (set by the same JS pass) so there's no
   flash of the joined text before the split runs.
   ========================================================================== */
.drjo-line{ display:block; opacity:0; transform:translateY(18px); animation:drjoLineIn .6s cubic-bezier(.2,.7,.2,1) forwards; }
@keyframes drjoLineIn{ to{ opacity:1; transform:translateY(0); } }
@media (prefers-reduced-motion:reduce){
  .drjo-line{ opacity:1; transform:none; animation:none; }
}
/* No-JS / JS-not-yet-run safety net, same pattern as [data-reveal] above. */
.no-js [data-line-reveal]{ opacity:1; }
.no-js .drjo-line{ opacity:1; transform:none; animation:none; }

/* Marker on a form still rendering the mockup's static markup rather than a real
   Ninja Form. Unstyled by design — it exists so un-wired forms are greppable and
   findable in the DOM during the forms phase. */
.drjo-static-form{ /* intentionally no declarations */ }

/* ==========================================================================
   PROSE — long-form body copy (single posts, and any editor-written page
   rendered through page.php: Privacy Policy, Terms, form confirmations).
   Without this, the_content() renders with headings jammed against text.
   ========================================================================== */
.prose{ font-family:'Metropolis','Hanken Grotesk',sans-serif; font-size:17px; line-height:1.72; color:#FFFFFF; }
.prose > * + *{ margin-top:22px; }
.prose h2{ font-family:'Metropolis',Georgia,serif; font-weight:700; font-size:32px; line-height:1.15; color:#fff; margin-top:44px; }
.prose h3{ font-family:'Metropolis',Georgia,serif; font-weight:700; font-size:24px; line-height:1.2; color:#fff; margin-top:34px; }
.prose h4{ font-family:'Metropolis','Hanken Grotesk',sans-serif; font-weight:700; font-size:18px; color:#fff; margin-top:28px; }
.prose ul, .prose ol{ padding-left:24px; }
.prose li + li{ margin-top:9px; }
.prose blockquote{
  border-left:3px solid #C4DC4A; padding:6px 0 6px 22px; margin-left:0;
  font-family:'Albra',Georgia,serif; font-style:italic; font-size:20px; color:#fff;
}
.prose em{ font-family:'Albra',Georgia,serif; font-style:italic; }
.prose a{ color:#C4DC4A; text-decoration:underline; text-underline-offset:3px; }
.prose a:hover{ color:#D2E86A; }
.prose img{ height:auto; border-radius:14px; }
.prose code{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:.9em; background:rgba(141,217,240,.12); padding:2px 6px; border-radius:5px; }
.prose hr{ border:0; border-top:1px solid rgba(141,217,240,.18); }

/* ==========================================================================
   NINJA FORMS — restyled to the mockups' own form controls.

   Ninja Forms builds its markup CLIENT-SIDE: the server HTML is only a spinner
   <div id="nf-form-N-cont">, so none of these classes exist in a curl of the page.
   Every selector and value below was verified against the live rendered DOM in a
   browser, and the computed styles read back to confirm they beat NF's defaults.

   Two traps, both hit while writing this:
   - The submit is input[type=submit], NOT [type=button]. Targeting [type=button]
     leaves the button completely unstyled.
   - The base field rule carries four :not() clauses, which makes it specificity
     (0,6,1). A variant override written the obvious way — say
     .drjo-nf-newsletter .nf-field-element input[type=email] at (0,3,1) — LOSES to it
     and silently does nothing. Variant overrides therefore repeat the same selector
     shape so specificity ties and source order decides. Keep them below the base.

   Two-column pairing comes from Ninja Forms' own .one-half / .first classes (set at
   field-create time), so there are no float hacks or per-field-id rules here.
   ========================================================================== */
.drjo-nf .nf-form-title,
.drjo-nf .nf-form-fields-required{ display:none; }
.drjo-nf .nf-field-container{ margin-bottom:14px; }
.drjo-nf .nf-field-label label{
  display:block; font-family:'Metropolis','Hanken Grotesk',sans-serif;
  font-size:12px; font-weight:600; color:#5E6E88; margin:0 0 6px;
}
.drjo-nf .nf-field-element input:not([type=submit]):not([type=button]):not([type=checkbox]):not([type=radio]),
.drjo-nf .nf-field-element select,
.drjo-nf .nf-field-element textarea{
  width:100%; height:46px; border-radius:10px; border:1px solid rgba(26,34,80,.18);
  background:#FFFFFF; padding:0 14px; font-family:'Metropolis','Hanken Grotesk',sans-serif;
  font-size:15px; color:#10254D; outline:none; box-shadow:none;
}
.drjo-nf .nf-field-element textarea{
  height:auto; min-height:118px; padding:12px 14px; resize:vertical; line-height:1.5;
}
.drjo-nf .nf-field-element input:not([type=submit]):not([type=button]):not([type=checkbox]):not([type=radio]):focus,
.drjo-nf .nf-field-element select:focus,
.drjo-nf .nf-field-element textarea:focus{ border-color:#10254D; }
.drjo-nf .submit-container input[type=submit]{
  width:auto; height:auto; border:none; cursor:pointer;
  font-family:'Metropolis','Hanken Grotesk',sans-serif; font-size:13px; font-weight:700;
  letter-spacing:.13em; text-transform:uppercase; color:#10254D; background:#C4DC4A;
  padding:14px 28px; border-radius:999px;
}
.drjo-nf .submit-container input[type=submit]:hover{ background:#D2E86A; }
/* The "Your details" / "The event" section headers on the enquiry form. */
.drjo-nf .html-container p{
  font-family:'Metropolis','Hanken Grotesk',sans-serif; font-size:11px; font-weight:700;
  letter-spacing:.02em; color:#10254D; margin:22px 0 12px;
}
.drjo-nf .nf-error-msg, .drjo-nf .ninja-forms-req-symbol{
  font-family:'Metropolis','Hanken Grotesk',sans-serif; font-size:12.5px; color:#B3261E;
}
.drjo-nf .nf-error .nf-field-element input,
.drjo-nf .nf-error .nf-field-element textarea{ border-color:#B3261E; }

/* Ninja Forms' .one-half is a plain float with NO breakpoint of its own, so the paired
   fields stay side by side all the way down and the inputs end up ~131px wide on a phone -
   too narrow to type a name into. Stack them at the same 900px the nav collapses at.

   The selector needs .nf-form-cont in it. NF's display-structure.css declares
   `.nf-form-cont .one-half{ width:48.7179% }` at specificity (0,2,0) — exactly the same as
   a plain `.drjo-nf .one-half` — and NF's stylesheet is enqueued AFTER the theme's, so on a
   tie it wins. Including .nf-form-cont takes this to (0,3,0) and settles it outright.
   (Testing this by injecting a <style> into the page gives a false pass: injected CSS lands
   last in <head>, so it wins the tie that the real stylesheet loses.) */
@media (max-width:900px){
  /* NF's own two-column CSS also puts margin-left:2.5641% on the non-first half (Organisation,
     Phone here) to gap it from its pair. Stacking width/float alone leaves that margin in
     place, so every second field sits a few px right of the others — reset it too. */
  .drjo-nf .nf-form-cont .one-half{ width:100%; float:none; margin-left:0; margin-right:0; }
}

/* Footer newsletter — the same NF markup laid out as one pill. */
.drjo-nf-newsletter .nf-field-label{ display:none; }
.drjo-nf-newsletter nf-fields-wrap{ display:flex; align-items:center; gap:8px; }
.drjo-nf-newsletter .nf-field-container{ margin-bottom:0; }
.drjo-nf-newsletter nf-field:first-child{ flex:1; min-width:0; }
.drjo-nf-newsletter .nf-field-element input:not([type=submit]):not([type=button]):not([type=checkbox]):not([type=radio]){
  height:40px; border-radius:999px; border:1.5px solid rgba(155,214,239,.22);
  font-size:13px; padding:0 16px;
}
.drjo-nf-newsletter .submit-container input[type=submit]{
  height:40px; padding:0 16px; font-size:11px; letter-spacing:.1em; white-space:nowrap;
}

/* Lead-magnet opt-in — the same pill, larger, on the sky-gradient band. */
.drjo-nf-leadmagnet .nf-field-label{ display:none; }
.drjo-nf-leadmagnet nf-fields-wrap{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
.drjo-nf-leadmagnet .nf-field-container{ margin-bottom:0; }
.drjo-nf-leadmagnet nf-field:first-child{ flex:1; min-width:180px; }
.drjo-nf-leadmagnet .nf-field-element input:not([type=submit]):not([type=button]):not([type=checkbox]):not([type=radio]){
  height:52px; border-radius:999px; border:none; font-size:15px; padding:0 22px;
}
.drjo-nf-leadmagnet .submit-container input[type=submit]{
  height:52px; padding:0 28px; font-size:13px; letter-spacing:.12em; white-space:nowrap;
}

/* Light variant — single posts put the article body on the bright white band, so the base
   .prose colours (tuned for the navy sections) would be near-invisible. Values are the
   Blog Post mockup's own article typography. */
.prose-light{ font-size:17px; line-height:1.75; color:#3A4A63; }
.prose-light > * + *{ margin-top:18px; }
.prose-light h2{ font-size:26px; line-height:1.2; color:#10254D; margin-top:30px; margin-bottom:12px; }
.prose-light h3{ font-size:21px; color:#10254D; margin-top:26px; }
.prose-light h4{ color:#10254D; margin-top:22px; }
.prose-light blockquote{ border-left-color:#C4DC4A; color:#10254D; }
.prose-light a{ color:#10254D; }
.prose-light a:hover{ color:#10254D; }
.prose-light code{ background:rgba(26,34,80,.08); }
.prose-light hr{ border-top-color:rgba(26,34,80,.14); }
/* Cap the measure on the INNER element — putting max-width on the .wrap
   container would re-centre it and pull the body out of line with the hero. */
.prose{ max-width:74ch; }

/* ==========================================================================
   RESPONSIVE — carried verbatim from the mockups. These attribute selectors
   are how the mockups made an inline-styled design responsive; they must stay
   because the templates keep the design's inline styles.
   ========================================================================== */
@media (max-width:900px){
  [style*="grid-template-columns"]{ grid-template-columns:1fr !important; }
  [style*="font-size: 74px"],[style*="font-size:74px"]{ font-size:36px !important; white-space:normal !important; line-height:1.06 !important; }
  [style*="font-size: 56px"],[style*="font-size:56px"]{ font-size:34px !important; line-height:1.06 !important; }
  [style*="font-size:54px"]{ font-size:33px !important; line-height:1.07 !important; }
  [style*="font-size:52px"]{ font-size:32px !important; line-height:1.07 !important; }
  [style*="font-size:44px"]{ font-size:30px !important; }
  [style*="font-size:42px"]{ font-size:29px !important; }
  [style*="font-size:40px"]{ font-size:28px !important; }
  [style*="font-size:38px"]{ font-size:27px !important; }
  [style*="font-size:36px"]{ font-size:26px !important; }
  [style*="font-size:34px"]{ font-size:25px !important; }
  [style*="padding: 96px 40px"],[style*="padding:96px 40px"],[style*="padding:88px 40px"],[style*="padding:84px 40px"],[style*="padding:80px 40px"],[style*="padding:78px 40px"],[style*="padding:74px 40px"],[style*="padding:72px 40px"],[style*="padding:70px 40px"],[style*="padding:60px 40px"],[style*="padding:56px 40px 40px"]{ padding-left:22px !important; padding-right:22px !important; }
  nav[style*="padding:16px 40px"]{ padding-left:20px !important; padding-right:20px !important; gap:14px !important; }
  [style*="columns:3"],[style*="columns:4"]{ columns:1 !important; }
  /* Round 4: this used to be scoped to `section [style*="min-height:620px"]`, but the
     Home and About heroes' min-height actually sits on the inner grid <div>, not the
     <section> itself — the old selector never matched either, so the min-height stayed
     in force on mobile and left a large empty gap below the stacked hero content once
     the grid no longer needed that much height for one column. Matching the div directly
     (and adding About's own 560px value) fixes both. */
  [style*="min-height:620px"],[style*="min-height:560px"]{ min-height:0 !important; }
  img[style*="770px"]{ position:static !important; height:auto !important; width:88% !important; max-width:360px !important; right:auto !important; bottom:auto !important; margin:24px auto 0 !important; display:block !important; }

  /* The generic grid-template-columns:1fr rule above stacks #global-lead's cover, heading/body
     and signup form into three full-width rows - the small cover then sits alone on its row
     with a large gap of empty band colour beside it (Jo flagged this directly). Rebuilt as its
     own 2-column grid: cover beside the eyebrow+heading (kept together as one unit, in their
     own .global-lead-heading wrapper - see footer.php), paragraph on a full-width row below
     both, form full-width below that. Earlier attempts split the eyebrow and heading into
     separate grid rows via display:contents on the whole text block, which forced the cover to
     SPAN two auto-sized rows - a spanning item inflates every track it spans to fit its own
     height, which is what was actually causing the oversized gap between the eyebrow and
     heading. Keeping them in one wrapper avoids spanning entirely: the cover only ever occupies
     row 1, sized to plain max(cover, heading-wrapper) with no distribution ambiguity. */
  .global-lead-grid{ grid-template-columns:96px 1fr !important; align-items:start !important; gap:20px 16px !important; }
  .global-lead-cover{ max-width:96px; margin:0; }
  .global-lead-grid > div:nth-child(2){ display:contents; }
  .global-lead-grid > div:nth-child(2) > *:nth-child(1){ grid-column:2; grid-row:1; }
  .global-lead-grid > div:nth-child(2) > *:nth-child(2){ grid-column:1 / -1; grid-row:2; }
  .global-lead-grid > *:nth-child(3){ grid-column:1 / -1; grid-row:3; }

  /* The lead-magnet signup button (real Ninja Form and its no-JS fallback both render inside
     .drjo-nf-leadmagnet) wraps onto its own line once the email field takes the full row width
     on a narrow screen; centre it there rather than leaving it flush left. */
  .drjo-nf-leadmagnet nf-fields-wrap,
  .drjo-nf-leadmagnet .drjo-static-form{ justify-content:center; }
}
@media (max-width:560px){
  [style*="font-size: 74px"],[style*="font-size:74px"]{ font-size:30px !important; }
  [style*="padding: 66px 20px 66px 62px"]{ padding:44px 22px !important; }
}

/* Home page H1 only: two 25% steps up from the generic 74px step-down above, on tablet
   (36px -> 45px -> 56.25px) and phone (30px -> 37.5px -> 46.875px). Desktop keeps the inline
   74px. h1.class outranks the attribute selectors above, so source order is not what makes
   these win. */
@media (max-width:900px){
  h1.home-hero-title{ font-size:56.25px !important; }
}
@media (max-width:560px){
  h1.home-hero-title{ font-size:46.875px !important; }
}

/* Home hero photo on tablet/phone: a head-and-shoulders crop, as on desktop, instead of
   the whole wide cut-out shrunk to fit (which showed Jo to the waist).
   The zoom comes from a scale basis S = min(column width, 420px): the image is drawn
   1.6*S wide, top-aligned, centred on Jo (she sits at ~53% across the file), and a
   negative bottom margin trims it to 0.875*S tall - ending just below the shoulders.
   (1.6x rather than 2x: 2x cropped too tight; this shows ~25% more of the photo.)
   The window itself spans the full column, so on a wide tablet column Jo's arms are
   never clipped at the sides (a 420px-wide window cut them off); the crop is still no
   taller than 368px there. cqw = the photo column's width (it is the query container).
   Tuned to the current hero image (isolated-extended.png, 1418x1109) - a replacement
   with a different framing may need the 1.6 / 0.848 / 0.376 values adjusting.
   The text column's bottom padding is cut back too: it, not the image, was most of the
   gap between the showreel button and the photo. */
@media (max-width:900px){
  #home-hero .home-hero-text{ padding-bottom:12px !important; }
  #home-hero .home-hero-photo{ overflow:hidden; container-type:inline-size; }
  #home-hero .home-hero-photo img{
    position:static !important; display:block !important;
    width:calc(1.6 * min(100cqw, 420px)) !important; max-width:none !important; height:auto !important;
    margin:0 0 calc(-0.376 * min(100cqw, 420px)) calc(50cqw - 0.848 * min(100cqw, 420px)) !important;
  }
}

/* Line the burnout CTA up under the lead-magnet form above it on desktop, closing the gap
   left by justify-content:space-between when the heading is short. Match #global-lead's own
   3-column proportions so the button starts exactly where that form's column starts.
   Mobile keeps the original flex/wrap stacking untouched. */
@media (min-width:901px){
  .global-burnout-row{
    display:grid !important;
    grid-template-columns:120px 1.15fr .85fr !important;
    gap:36px !important;
  }
  .global-burnout-row h2{ grid-column:1 / 3; }
  .global-burnout-row .global-burnout-cta{ justify-self:start; }
}

/* The keynote "Other keynotes" rail's cards are a fixed flex:0 0 300px, wider than a phone
   screen minus its side padding — so the second card always shows a cut-off sliver. Show
   exactly one full card at a time on mobile instead. */
@media (max-width:560px){
  .topic-related-card{ flex-basis:100% !important; }
}

/* wpautop()'s <p> tags for the keynote description used to be nested inside the template's
   own <p> wrapper — invalid HTML that browsers silently "fix" by closing the outer <p> at
   the first inner one, so every paragraph lost its styling AND its gap. Now wrapped in a
   div instead; give the inner paragraphs their spacing back here. */
.topic-desc p{ margin:0 0 14px; }
.topic-desc p:last-child{ margin-bottom:0; }

/* Resources article rows are a fixed-width thumbnail beside flexible text — on a phone the
   220px thumbnail eats most of the width, squeezing the text into a 3-4 word column. Stack
   instead of squeeze. */
@media (max-width:560px){
  .drjo-card{ flex-direction:column; }
  .drjo-card-thumb{ width:100% !important; aspect-ratio:1.91/1; }
}

/* Respect reduced-motion for the smooth scrolling and any carousel. */
@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{ animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; }
}
