/* Fits the draft's styles to WordPress block markup, and adds the accessibility and motion fixes
   (pause controls, reduced motion, focus visibility). Kept apart from draft.css so the design stays recognisable. */

/* Block layout. Page content keeps WordPress's own gap between blocks (1.25rem) where the draft sets no margin, and
   the draft's own margins where it does (48px above the notice box; section headings below). */
.wp-site-blocks { padding: 0; }
.wp-site-blocks > * + * { margin-block-start: 0; }
.wp-block-group.hero, .wp-block-group.marquee-strip, .wp-block-group.gallery-section, .wp-block-group.features-section { margin: 0; }
/* Home: the sections below the banner are the Home page's own content; their wrapper adds no gap. */
main > .wp-block-post-content { margin: 0; }
/* Inner pages: the eyebrow, title and intro keep the draft's own spacing, not the block gap. */
.page-shell .container > * { margin-block-start: 0; }
/* The same where a page's own content holds its eyebrow, title and intro: no block gap above the title (the eyebrow's
   16px is the gap) or above the intro (the title's 20px), and the intro's own 56px below it, which the block layout
   cancels when the intro is the last line of its group. */
.page-shell .wp-block-post-content > .page-title, .page-shell .wp-block-post-content > .page-title + * { margin-block-start: 0; }
.page-shell .wp-block-post-content .page-intro { margin-block-end: 56px; }
/* A section heading in a page's content has 24px above it (Derek, 2 Oct 2026), not the draft's 64px. The first one
   after the intro still follows the intro's 56px, because the two margins collapse. This also replaces the draft's
   :first-of-type 0, so a heading that comes first in its own group (after the entries panel on Enter, the Sponsors
   page's tiers) gets the same 24px rather than none. */
.page-shell .wp-block-post-content .section-heading { margin-top: 24px; }
/* The Press page's year headings follow the same rule: 24px above each later one (the draft's CSS says 56px). Written
   at the draft's own weight, so its :first-of-type 0 still lets the first follow the intro's 56px, and the Documents
   rows keep their own margin of 0. */
:where(.page-shell .wp-block-post-content) .year-heading { margin-top: 24px; }
/* A link to a place in a page (such as #documents) brings it to just below the fixed 80px header, not under it: the
   header's height plus the eyebrow's 16px gap. */
.page-shell [id] { scroll-margin-top: 96px; }

/* The draft's page title is an h1 left at the browser's bold, which thickens the single-weight Archivo Black;
   theme.json sets headings to 400. */
.page-title { font-weight: 700; overflow-wrap: anywhere; } /* a long word (a category, a search term) must not push the page sideways on a phone */

/* Core navigation inside the draft's header. Core sets menu links to "color: inherit" with a selector that
   outranks the draft's white .nav-link, so the white comes from the menu itself; the draft's hover and active
   colours still apply. */
.site-nav { color: white; }
/* The draft's menu links are inline, so a pill is as tall as the text itself (about 1.34 times the 12px size) plus
   its padding; core's links are blocks and would use the 1.6 line height, making every pill 3px taller. */
.site-nav .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation-item__content { line-height: 1.34; }
.site-header .wp-block-buttons { margin: 0 0 0 16px; }

/* "Enter a team": the draft's .hero-cta, compact. Core buttons are pill-shaped and let the label break. The hero's
   dates button may wrap, as the draft's does on the narrowest phones (it would be cut off at 320px). */
.hero-cta .wp-block-button__link, .header-cta .wp-block-button__link { border-radius: 0; }
.header-cta .wp-block-button__link { white-space: nowrap; }
.header-cta .wp-block-button__link { padding: 10px 20px; }

/* Six links and the button need about 1105px (the draft's four links needed under 600px), so the menu button
   takes over below 1200px, not 900px. The button moves before the menu button, which stays at the far right as
   in the draft. */
@media (max-width: 1199px) {
	.site-nav .wp-block-navigation__responsive-container-open { display: block; }
	.site-nav .wp-block-navigation__responsive-container:not(.is-menu-open) { display: none; }
	.site-header .wp-block-buttons { order: -1; margin: 0 8px 0 0; }
}
/* Phones: the draft's header holds only the brand and the menu button, so the header's yellow button is hidden and
   the open menu ends with the same button instead (.nav-enter-cta, added by pvh_navigation_enter_button()). It is
   hidden everywhere else, where the header button shows. */
.nav-enter-cta { display: none; }
@media (max-width: 560px) {
	.site-header .wp-block-buttons { display: none; }
	.site-nav .is-menu-open .nav-enter-cta, html:not(.js) .site-nav .nav-enter-cta { display: list-item; margin-top: 16px; }
}

/* Without JavaScript the menu button can't open anything (core's menu needs it), so the links stay on show at
   every width (the head script adds .js when scripts run). Below 1200px they wrap onto a second row under the
   brand and the "Enter a team" button, so the header grows and joins the page flow instead of covering it. */
html:not(.js) .site-nav .wp-block-navigation__responsive-container-open,
html:not(.js) .site-nav .wp-block-navigation__responsive-container-close { display: none; }
html:not(.js) .site-nav .wp-block-navigation__responsive-container:not(.is-menu-open) { display: block; position: static; }
@media (max-width: 1199px) {
	html:not(.js) .site-header { position: relative; }
	html:not(.js) .header-inner { height: auto; min-height: 80px; flex-wrap: wrap; padding: 14px 0; row-gap: 8px; }
	html:not(.js) .header-inner > .wp-block-group { display: contents; }
	html:not(.js) .site-header .wp-block-buttons { order: 0; margin: 0; }
	html:not(.js) .site-header .site-nav { order: 1; flex-basis: 100%; }
	html:not(.js) .page-shell { padding-top: 40px; }
}

/* The open phone menu: core's full-screen overlay becomes the draft's right-hand panel (.mobile-nav). Core pins
   the overlay to both sides and paints it white with black text, using a long selector; the backdrop shadow
   stands in for the draft's dimmed overlay (.mobile-nav-overlay). */
.site-header .site-nav.wp-block-navigation .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay) {
	left: auto;
	background-color: var(--stone);
	color: white;
	box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.7);
	--navigation-layout-justification-setting: stretch;
}
/* Core adds its own space above the list and lines the links up with the menu (right), via a variable that the
   list sets on itself; the draft's links start under the header and fill the panel. */
.site-header .site-nav.wp-block-navigation .is-menu-open .wp-block-navigation__responsive-container-content { padding-top: 0; }
.site-nav .is-menu-open .wp-block-navigation__container { --navigation-layout-justification-setting: stretch; }
/* The close button sits where the menu button was. */
.site-nav .is-menu-open .wp-block-navigation__responsive-dialog { position: static; }
.site-nav .is-menu-open .wp-block-navigation__responsive-container-close { top: 29px; right: calc(var(--gap) + 8px); }
/* The draft's Lucide menu and close icons are 22px; core's are 24px. */
.site-nav .wp-block-navigation__responsive-container-open svg, .site-nav .wp-block-navigation__responsive-container-close svg { width: 22px; height: 22px; }

/* Footer: nine links instead of the draft's four, so on wide screens they wrap onto right-aligned rows. */
/* The tile PNG is drawn for the header's 34x52; at the footer's 48px height it is 31.4 wide, not the 31 its width
   attribute reserves, so let it keep its own shape (the draft sets only the height). */
.footer-brand img { width: auto; }
.footer-brand { flex-shrink: 0; }
.footer-links a { white-space: nowrap; }
/* The footer links are a navigation block (nav > ul > li > a; core repeats .footer-links on the list, so the draft's
   flex rules lay out the links as before). It follows the brand in a group, whose block gap would push it down.
   Core's "color: inherit" on menu links outranks .footer-links a, so the colour comes from the menu (in the contrast
   fixes below), as in the header, and the draft's hover needs core's specificity. */
.footer-top > * { margin-block-start: 0; }
.footer-links .wp-block-navigation-item__content:hover { color: var(--blaze); }
@media (min-width: 901px) {
	.footer-top { gap: 48px; }
	.footer-links { flex-wrap: wrap; justify-content: flex-end; row-gap: 12px; }
}

/* Footer lines the draft doesn't have: the organiser, the district logo slot (text until the district supplies
   the logo) and the social links. */
.footer-meta { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 16px 32px; margin-bottom: 32px; }
.footer-org { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; font-size: 12px; letter-spacing: 0.5px; color: var(--sand); }
.footer-org__logo-slot { padding: 6px 12px; border: 1px solid var(--rock); font-size: 11px; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; }
.footer-social { display: flex; gap: 24px; }
.footer-social a { display: inline-flex; align-items: center; justify-content: center; min-width: 24px; min-height: 24px; font-size: 12px; font-weight: 600; letter-spacing: 1.5px; text-transform: uppercase; color: var(--sand); transition: color 0.2s; }
.footer-social a:hover { color: var(--blaze); }

/* ─── Home: hero ─── */
/* The draft's spacing inside the hero and gallery comes from its own margins, not the block gap. */
.hero > *, .hero-content > *, .gallery-section > *, .carousel > * { margin-block-start: 0; }
/* The draft's h1 is left at the browser's bold (see .page-title). */
.hero h1 { font-weight: 700; }
/* A blank strapline (Settings → Event facts) leaves nothing behind: no lone yellow rule, no gap above the title. */
.hero-eyebrow:empty { display: none; }
/* Likewise a blank description: no empty paragraph whose margin would widen the gap between the title and the button. */
.hero-desc:empty { display: none; }
/* The header (80px) is fixed over the hero. On short phones the content is taller than the hero's minimum height,
   so the hero grows instead of sliding the strapline under the header. No change where the content fits. */
.hero { padding-top: 80px; }
/* The button block puts .hero-cta on its wrapper as well as the link; only the link is the draft's yellow button. */
.wp-block-button.hero-cta { padding: 0; background: none; overflow: visible; }
.wp-block-button.hero-cta:hover { transform: none; box-shadow: none; }
.wp-block-button.hero-cta::after { content: none; }
/* The draft's arrow after the dates (Lucide ArrowRight, 16px). The bound text replaces the link's contents, so the
   arrow is drawn by the link itself; ::after is the draft's shine. */
.hero-cta .wp-block-button__link::before {
	content: '';
	order: 1;
	flex-shrink: 0;
	width: 16px;
	height: 16px;
	background: currentColor;
	mask: 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' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m12 5 7 7-7 7'/%3E%3C/svg%3E") center / contain no-repeat;
}
/* The draft's entrance (framer-motion): the eyebrow slides in from the left, the rest rises, one after another. */
@keyframes pvh-rise { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
@keyframes pvh-slide { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: none; } }
.hero-content > * { animation: pvh-rise .6s cubic-bezier(.25,.46,.45,.94) backwards; }
.hero-content > :nth-child(1) { animation-name: pvh-slide; }
.hero-content > :nth-child(2) { animation-duration: .7s; animation-delay: .1s; }
.hero-content > :nth-child(3) { animation-delay: .25s; }
.hero-content > :nth-child(n+4) { animation-delay: .4s; }
/* "Supported by": quiet, under the dates, never competing with the title. */
.hero .supported-by { display: flex; align-items: center; gap: 12px; margin-top: 28px; font-size: 13px; color: var(--fog); }
.supported-by__label { font-size: 11px; font-weight: 600; letter-spacing: 1.5px; text-transform: uppercase; }
.supported-by__offer { text-decoration: underline; text-decoration-color: rgba(214, 211, 209, 0.4); text-underline-offset: 3px; transition: color 0.2s; }
.supported-by__offer:hover { color: var(--blaze); }
.supported-by img { width: auto; max-height: 40px; padding: 4px 8px; background: white; }
/* On phones the content spans the hero's width, so it ends above the centred "Scroll" cue (96px tall) instead of
   running into it (in the draft the cue already clips the button there). */
@media (max-width: 600px) { .hero-content { padding-bottom: 112px; } }
/* Phones: the text spans the photo, so the draft's bottom fade (stone 40% at 40% height) leaves it unreadable over a
   bright sky. A stronger fade of the same form, measured from the bottom, where the text block is anchored: at least
   88% stone behind the description (86% gives 4.5:1 for sand over a white photo) and 76% behind the eyebrow (74% for
   blaze), up to just above them at 320 px, where they wrap the most (description top 435 px, eyebrow top 587 px up;
   at 390 px 382 and 534, with the 2027 description, which is longer), then fading out. The draft's left-hand fade stays, so the photo above looks as before.
   Recorded in brand/CHANGES.md. */
@media (max-width: 600px) {
	.hero-bg::after {
		background:
			linear-gradient(0deg, var(--stone) 0, rgba(28,25,23,0.88) 450px, rgba(28,25,23,0.76) 600px, transparent 750px),
			linear-gradient(90deg, rgba(28,25,23,0.6) 0%, transparent 60%);
	}
}

/* ─── Home: scrolling banner ─── */
.marquee-strip { position: relative; }
/* Blank "Scrolling banner items": the whole strip goes, not an empty yellow bar. */
.marquee-strip:has(.marquee-track:empty) { display: none; }
/* Static (no JavaScript, or reduced motion): the text in the draft's type, wrapped and centred. */
.marquee-strip:not(.is-ready) .marquee-track { display: block; animation: none; transform: none; white-space: normal; text-align: center; }
.marquee-strip.is-paused .marquee-track { animation-play-state: paused; }

/* ─── Home: gallery ─── */
.gallery-section .carousel.reveal { transition-delay: .15s; }
.carousel-track > .wp-block-image { margin: 0; flex: 0 0 100%; }
/* Without JavaScript the photos scroll sideways (the draft's transform-driven track needs the script). */
.carousel:not(.is-ready) .carousel-track { overflow-x: auto; scroll-snap-type: x mandatory; transform: none !important; }
.carousel:not(.is-ready) .carousel-track > .wp-block-image { scroll-snap-align: start; }
/* The pause button makes the dots bar about 85px wider than the draft's. On phones the bar would be wider than the
   photo, so the dots narrow to fit (never below the 24px minimum target). */
.carousel-controls { max-width: 100%; }
.carousel-dot { flex: 0 1 44px; min-width: 24px; }

/* ─── Content pages: the draft's inline icons ─── */
/* Page content holds no inline SVG, so each link draws its icon itself, as the hero's arrow does: Lucide's external-link
   (15px) before a link-list link that opens a new tab (the Links page), and mail (14px) before a contact card's address.
   The link list's icon colour is in the contrast fixes below; the mail icon takes the button's text colour. */
.link-list a[target="_blank"]::before {
	content: '';
	flex-shrink: 0;
	width: 15px;
	height: 15px;
	mask: 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' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 3h6v6'/%3E%3Cpath d='M10 14 21 3'/%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/%3E%3C/svg%3E") center / contain no-repeat;
}
.link-list a[target="_blank"]:hover::before { background: var(--blaze); }
.email-btn::before {
	content: '';
	flex-shrink: 0;
	width: 14px;
	height: 14px;
	background: currentColor;
	mask: 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' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7'/%3E%3Crect x='2' y='4' width='20' height='16' rx='2'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Contrast fixes (WCAG 2.2 AA, 4.5:1 for this text), each recorded in brand/CHANGES.md. The palette is unchanged.
   - Footer text: the draft's earth on stone is 1.70:1; sand, already the muted text on dark sections, is 6.93:1.
   - Eyebrows and intro links: the draft's blaze-dim on snow is 2.30:1; this darker shade of it (67%) is 4.76:1.
     The eyebrow's rule stays blaze.
   - The gallery's "Gallery" (large text, 3:1): blaze-dim on mist is 2.21:1; blaze-dim at 82% is 3.20:1. The same
     shade marks the home page's "Since 2002" (3.34:1 on snow).
   - The hero's "Scroll" cue: white at 30% over stone is 2.71:1; white at 48% is 4.89:1. The line stays as drawn.
   - Muted text on the white cards: the draft's sand is 2.52:1 on white and 2.31:1 on the sponsor card's mist hover;
     sand at 66% is 5.28:1 and 4.84:1.
   - The contact card's label: blaze-dim on white is 2.41:1; the eyebrows' shade is 4.98:1.
   - The link list's icons (graphics, 3:1): blaze-dim on white is 2.41:1; the large-text shade is 3.49:1. */
:root { --blaze-dim-text: #876d07; --blaze-dim-large: #a58608; --sand-text: #6f6b68; }
.footer-brand-sub, .footer-links, .footer-bottom { color: var(--sand); }
.page-eyebrow, .is-style-eyebrow, .page-intro a { color: var(--blaze-dim-text); }
.gallery-section .section-label span, .impact-section .section-label span { color: var(--blaze-dim-large); }
.hero-scroll { color: rgba(255, 255, 255, 0.48); }
.sponsor-info span, .contact-card .role, .comment-source { color: var(--sand-text); }
.contact-card .label { color: var(--blaze-dim-text); }
.link-list a[target="_blank"]::before { background: var(--blaze-dim-large); }

/* Visible keyboard focus everywhere (WCAG 2.4.7, 1.4.11): a stone ring inside a blaze one. Blaze alone is 1.55:1 on
   the light pages; the stone ring carries it there (16.7:1 on snow, 17.5:1 on white, 16.0:1 on mist, 10.8:1
   against a blaze button), and the blaze ring carries it on stone and rock (10.8:1, 9.4:1). */
a:focus-visible, button:focus-visible, .wp-element-button:focus-visible, .site-nav .wp-block-navigation-item__content:focus-visible {
	outline: 2px solid var(--wp--preset--color--blaze);
	outline-offset: 3px;
	box-shadow: 0 0 0 4px var(--wp--preset--color--stone);
}
/* A home page challenge card is one link (its title's, stretched over the card): the ring goes round the card. A rule
   of its own, so a browser without :has() drops only this and keeps the ring on the title link. */
.challenge-card:has(a:focus-visible) {
	outline: 2px solid var(--wp--preset--color--blaze);
	outline-offset: 3px;
	box-shadow: 0 0 0 4px var(--wp--preset--color--stone);
}
.challenge-card:has(a:focus-visible) a:focus-visible { outline: none; box-shadow: none; }

/* Reveal on scroll: hidden only once site.js is running (never without JavaScript). */
.js-reveal .reveal:not(.is-visible) { opacity: 0; transform: translateY(20px); }
.reveal { transition: opacity .6s cubic-bezier(.25,.46,.45,.94), transform .6s cubic-bezier(.25,.46,.45,.94); }

/* Motion toggles (marquee and carousel pause buttons). */
.motion-toggle { font: 600 12px/1 var(--font-body); letter-spacing: .08em; text-transform: uppercase; padding: 6px 10px; border: 1px solid currentColor; background: transparent; color: inherit; cursor: pointer; }
/* After the base rule, which they override. The banner's sits at the right end of the strip, over the text. The
   slideshow's sits in the dots bar, centred on it. */
.marquee-toggle { position: absolute; right: 12px; top: 50%; margin: 0; transform: translateY(-50%); background: var(--wp--preset--color--blaze); color: var(--wp--preset--color--stone); }
.carousel-toggle { align-self: center; margin: 0 12px; color: #fff; }

@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
	.js-reveal .reveal:not(.is-visible) { opacity: 1; transform: none; }
	/* No entrance at all: with only the duration cut, each line would still wait out its delay, invisible. */
	.hero-content > * { animation: none; }
	/* Also stops the banner if reduced motion is switched on after the page has loaded. */
	.marquee-track { animation: none !important; }
}
