/* ==================================================================
   Kwizzbit base — global resets + utility classes used across patterns.
   Tokens come from theme.json; nothing here should declare colour or
   spacing values directly.
   ================================================================== */

/* The page-loader FOUC guard (html.kwb-loading { ... visibility:hidden }) lives in the
   page-loader segment's own CSS, not here — so it is only active on pages that actually
   include the loader, and is dismissed by the loader's own script. */

/* Dark-mode defensive line: the site is a deliberate light-only design. Declaring
   the light colour-scheme stops browsers from auto-darkening UA-styled controls
   (inputs, selects, textareas, scrollbars) in OS dark mode — which would otherwise
   render dark fields on our cream backdrops. Pairs with the <meta name="theme-color">
   in functions.php. Does NOT touch our explicitly-coloured elements. */
html {
	color-scheme: light;
	/* Paint the page CANVAS cream, matching <body>. iOS Safari draws its
	   dynamic-toolbar / overscroll regions (the strip beneath the floating
	   URL bar, pull-to-refresh, rubber-banding) from the canvas, NOT from
	   body — an unset canvas defaults to white and flashed through as a
	   naff white band at the bottom when the mobile-menu scrim faded in.
	   body still paints cream over the whole page, so this only ever shows
	   where body doesn't reach; the top status area stays as-is (driven by
	   theme-color, already cream). */
	background-color: var(--wp--preset--color--cream);
}

/* ==================================================================
   LOADER GATE — keep animations and reveals suppressed while the
   page-loader is showing (html has the .kwb-loading class).

   Two problems solved:
   1. Run-once CSS animations (e.g. content-rise, ~0.72s) would burn
      through their full duration while hidden behind the 3s loader,
      so the user never sees them. Pausing keeps them at frame 0.
   2. IntersectionObservers fire during load and add .is-visible, so
      when the loader lifts the [data-reveal] lift transition is already
      "done" — nothing moves. Forcing opacity/transform to their start
      state ensures the transition fires fresh when kwb-loading is removed.

   #kwb-loader lives directly in <body> (not in .kwb-segment) so
   the .kwb-segment scope never touches the loader's own animations.
   ================================================================== */
html.kwb-loading .kwb-segment,
html.kwb-loading .kwb-segment *{
	animation-play-state: paused !important;
}
/* Hold [data-reveal] elements at their start state even after
   .is-visible is added by the observer — transition fires on dismiss. */
html.kwb-loading [data-reveal]{
	transition: none !important;
}
html.kwb-loading [data-reveal].is-visible{
	opacity: 0 !important;
	transform: translateY(32px) !important;
}
/* Same guard for the JS-primed hero reveals (.has-scroll-reveal). Unlike scroll
   reveals — which are born hidden in CSS and never "prime" — the hero starts
   visible and only gets its hidden state when hero.js adds .has-scroll-reveal.
   With transitions live, that makes the hero animate INTO the hidden state
   (a priming fade/slide-down) before it lifts. If that priming animation hasn't
   finished when the loader lifts, its tail leaks on-screen: the hero flashes and
   restarts its lift from a slightly lower position. Suppressing transitions while
   the loader is up makes priming SNAP instantly, so the only transition the user
   ever sees is the lift itself (fires cleanly once .kwb-loading is removed).
   This is why ONLY the first, load-triggered block was affected. */
html.kwb-loading .has-scroll-reveal,
html.kwb-loading .has-scroll-reveal *{
	transition: none !important;
}
/* On a cross-PAGE view-transition navigation (NOT reloads — those skip the
   transition and keep the loader + lift) the cross-fade is the entrance. The
   pagereveal hook snaps the in-view reveal elements to .is-visible just before
   the snapshot is captured; suppress their transitions while the transition is
   active so that snap is instant, not a second lift fighting the cross-fade. */
html.kwb-vt-active .has-scroll-reveal,
html.kwb-vt-active .has-scroll-reveal *,
html.kwb-vt-active [data-reveal]{
	transition: none !important;
}

/* ==================================================================
   CONTENT-RISE — shared entry lift for load-gated section reveals
   (blog/FAQ header stagger, article + legal "window" lift). Held at
   frame 0 by the html.kwb-loading animation pause above, so it only
   plays once the page-loader clears — exactly like the rest of the
   site's entry choreography. `backwards` fill keeps the start state
   through any stagger delay and leaves NO lingering transform after,
   so it never creates a containing block for fixed/sticky children.
   ================================================================== */
@keyframes kwb-content-rise {
	from { opacity: 0; transform: translateY(28px); }
	to   { opacity: 1; transform: translateY(0); }
}

/* Universal reset — every source segment was authored against
   "* { box-sizing: border-box; margin: 0; padding: 0 }". The per-segment slices rely on it
   (e.g. footer/nav <ul> have list-style:none but no padding:0, so without this they inherit
   the browser's 40px list indent). Specificity 0 — WordPress block styles + theme.json
   spacing override it cleanly. */
*, *::before, *::after{
	box-sizing: border-box;
}
:where(*){
	margin: 0;
	padding: 0;
}

body{
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	/* clip (not hidden): hidden forces overflow-y to `auto`, making <body> a
	   scroll container — which breaks `position: sticky` on the header relative
	   to the viewport. `clip` leaves overflow-y visible, so the sticky header
	   (and the Get started button within it) stays pinned while still trimming
	   the full-bleed .kwb-segment horizontal overflow. */
	overflow-x: clip;
	touch-action: pan-y;
}

/* Kill any bottom gap WP's layout system adds between the <main> and the
   footer template part. Target every wrapper layer individually to ensure
   no padding, margin or min-height sneaks through. */
.wp-site-blocks,
.wp-site-blocks > *{
	margin-bottom: 0 !important;
}
.wp-block-template-part[class]{
	display: block;
	margin-top: 0 !important;
	margin-bottom: 0 !important;
}
/* Collapse padding on the main group + post-content wrappers.
   WP's constrained layout and flow-root display can silently add
   bottom space that shows as a cream strip before the footer. */
main.wp-block-group,
.wp-block-post-content,
.entry-content{
	padding-bottom: 0 !important;
	margin-bottom: 0 !important;
}
/* The cookie-modal pattern sits as a bare wp:html block inside the footer
   template part. WP renders it as a div.wp-block-html which has no visual
   content (the <aside> is `hidden`) but still takes up layout space, creating
   a white strip under the footer. Collapse it to zero so it's invisible. */
footer.wp-block-template-part .wp-block-html:has(#cookie-modal){
	display: contents;
}

#kwb-page-wrap{
	position: relative;
	overflow-x: clip; /* clip, not hidden — preserves sticky (see body note above) */
	touch-action: pan-y;
}

.sr-only{
	position: absolute;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip: rect(0,0,0,0);
	white-space: nowrap;
	border: 0;
}

:focus-visible{
	outline: 2px solid var(--wp--preset--color--coral);
	outline-offset: 3px;
}

.container{
	max-width: var(--wp--custom--layout--page-max);
	margin-inline: auto;
	padding-inline: var(--wp--custom--layout--gutter);
}

/* ------------------------------------------------------------------
   Segment full-bleed. Every pattern wraps its markup in
   <div class="wp-block-group alignfull kwb-segment kwb-segment--NAME">.
   `alignfull` only LIFTS WordPress's max-width clamp inside a constrained
   content column — it does NOT guarantee full-viewport width (it just fills
   whatever the content container is). This forces true 100vw regardless of
   the container, centred on the viewport (margin:calc(50% - 50vw)).
   body{overflow-x:hidden} clips the 100vw so there's no horizontal scrollbar.
   Each segment's own inner element re-centres its content via its own max-width.
   ------------------------------------------------------------------ */
.kwb-segment{
	width: 100vw;
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
	/* WP's is-layout-flow adds margin-block-start to direct children of the
	   post-content wrapper. Force 0 here so kwb-segments always butt flush. */
	margin-block: 0;
}

/* ------------------------------------------------------------------
   Off-screen animation pause (driven by assets/js/perf.js). When a
   segment scrolls well out of view, perf.js adds .kwb-anim-paused;
   freezing animation-play-state stops the compositor doing per-frame
   work for sections nobody is looking at, which keeps long pages
   smooth. Only affects the segment and its descendants; on-screen
   segments are untouched. (No effect in the editor — perf.js is a
   front-end-only script.)
   ------------------------------------------------------------------ */
.kwb-segment.kwb-anim-paused,
.kwb-segment.kwb-anim-paused *,
.kwb-segment.kwb-anim-paused *::before,
.kwb-segment.kwb-anim-paused *::after{
	animation-play-state: paused !important;
}

/* ------------------------------------------------------------------
   Editor-only scroll-reveal override. Scroll-reveal segments hide their
   content (opacity:0) until front-end JS adds .is-visible — but that JS
   doesn't run in the block-editor canvas, so patterns would show blank/faded
   while editing. In the editor the canvas is wrapped in .editor-styles-wrapper
   (absent on the front end), so this reveals reveal-elements ONLY in the editor
   and is completely inert on the published page. Covers [data-reveal] and any
   class containing "reveal" (.js-reveal, .scroll-reveal, …).
   ------------------------------------------------------------------ */
.editor-styles-wrapper [data-reveal],
.editor-styles-wrapper [class*="reveal"],
.editor-styles-wrapper .hiw-step,            /* how-it-works steps */
.editor-styles-wrapper .ready-made__header,  /* ready-made reveal targets */
.editor-styles-wrapper .ready-made__formats,
.editor-styles-wrapper .features__header,    /* features-9 reveal targets */
.editor-styles-wrapper .feature-panel,       /* (these gate on .is-visible, no "reveal" in the class) */
.editor-styles-wrapper .feature-tour__row [class*="feature-tour__"],  /* features-tour: rows reveal their children on .is-visible */
.editor-styles-wrapper .testimonials__header,   /* testimonials reveal targets */
.editor-styles-wrapper .testimonial-card,
.editor-styles-wrapper .impact-2__mic,          /* impact (GSAP-revealed, JS-gated) */
.editor-styles-wrapper .impact-2__headline,
.editor-styles-wrapper .impact-2__this,
.editor-styles-wrapper .impact-2__cta-wrap,
.editor-styles-wrapper .player-experience__copy,  /* player-experience reveal targets */
.editor-styles-wrapper .player-experience__photo,
.editor-styles-wrapper .beliefs__eyebrow,         /* beliefs reveal targets (no "reveal" in class) */
.editor-styles-wrapper .beliefs__statement-wrap,
.editor-styles-wrapper .beliefs__tags,
.editor-styles-wrapper .cc-offer__inner{          /* offer reveal target */
	opacity: 1 !important;
	transform: none !important;
}
.editor-styles-wrapper .impact-2__char{ visibility: visible !important; }  /* impact "This." chars */
/* Exception: layered "echo" headlines have a DESIGNED resting opacity below 1 (they sit behind
   the primary line). They're also .js-reveal, so the broad rule above would force them to full
   opacity in the editor. Restore their intended opacity here. Add new low-opacity reveal
   elements to this list if future segments introduce them. */
.editor-styles-wrapper .mantra__row--echo-1{ opacity: 0.28 !important; }
.editor-styles-wrapper .mantra__row--echo-2{ opacity: 0.12 !important; }

/* ------------------------------------------------------------------
   Flashing coral period — the blinking "." used at the end of titles
   (how-it-works steps, features-9 headline; mirrors the features-tour
   title accent). Shared utility so any title can borrow it.
   ------------------------------------------------------------------ */
.kwb-flash-period{
	color: var(--wp--preset--color--coral);
	animation: kwb-period-blink 1.1s step-end infinite;
	display: inline-block;
}
@keyframes kwb-period-blink{ 0%, 100%{ opacity: 1; } 50%{ opacity: 0; } }
@media (prefers-reduced-motion: reduce){
	.kwb-flash-period{ animation: none; }
}
