/**
 * GrantCookie — global styles.
 *
 * Everything block-specific lives in assets/css/blocks/ and is loaded only when
 * that block is on the page. This file holds what is genuinely global: the
 * header behaviour, the footer, typography variations that appear on nearly
 * every page, and the reveal animation.
 */

/* -------------------------------------------------------------------------
   1. Base
   ---------------------------------------------------------------------- */

/* WordPress does not set this globally, and without it any element that
   combines width:100% with horizontal padding — pricing buttons, form fields,
   cards in a grid — renders wider than its container and overlaps its
   neighbours. */

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

html {
	scroll-behavior: smooth;
	/* Keep anchored headings clear of the sticky header. */
	scroll-padding-top: calc( var( --wp--custom--header--height ) + 1rem );
}

@media ( prefers-reduced-motion: reduce ) {
	html {
		scroll-behavior: auto;
	}
}

body {
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	text-rendering: optimizeLegibility;
	overflow-x: clip;
}

/* WordPress inserts the global block gap between every root-level block. The
   root blocks here are full-width painted bands (header wrapper, main, CTA,
   footer) that carry their own spacing — the injected gap shows up as stray
   white lines between bands, and as a white strip above the hero, because the
   fixed header's wrapper is zero-height but the gap after it is not. */

body .wp-site-blocks > * + * {
	margin-block-start: 0;
}

/* The same applies inside the page: a full-bleed section band paints its own
   padding, so the layout gap between two bands is a 20px white line across
   the page. Scoped to alignfull children only — paragraphs, headings and
   ordinary article blocks keep their normal spacing. */

main.wp-block-group > .alignfull,
.wp-block-post-content > .alignfull {
	margin-block-start: 0;
	margin-block-end: 0;
}

:where( a, button, input, select, textarea, summary, [tabindex] ):focus-visible {
	outline: 2px solid var( --wp--preset--color--primary );
	outline-offset: 2px;
	border-radius: 2px;
}

.screen-reader-text {
	border: 0;
	clip-path: inset( 50% );
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	white-space: nowrap;
	width: 1px;
}

.skip-link:focus {
	clip-path: none;
	height: auto;
	width: auto;
	margin: 0;
	top: 0.75rem;
	left: 0.75rem;
	z-index: 999;
	background: var( --wp--preset--color--base );
	border-radius: var( --wp--custom--radius--sm );
	box-shadow: var( --wp--preset--shadow--raised );
	padding: 0.75rem 1.25rem;
}

/* -------------------------------------------------------------------------
   2. Header
   ---------------------------------------------------------------------- */

/* ONE header, two scroll states.
 *
 * At the top of any page it is transparent and the band beneath shows through.
 * As soon as the page scrolls it becomes the solid white bar. It is fixed
 * rather than sticky so the first band can run underneath it — every band
 * therefore carries header-height clearance in its own top padding.
 *
 * The only per-page variation is legibility: over a dark band the logo and
 * links invert. site.js sets .is-over-dark by looking at the first band, so no
 * template or page needs to know anything about it.
 */

.gc-header {
	position: fixed;
	inset-inline: 0;
	top: 0;
	z-index: 100;
	/* Height comes from the bar's own padding and content. A min-height taller
	   than the content left dead white space under the logo row once the bar
	   turned solid, because the content sat at the top of the taller box. */
	display: flex;
	align-items: center;
	background-color: transparent;
	border-bottom: 1px solid transparent;
	transition:
		background-color 220ms cubic-bezier( 0.4, 0, 0.2, 1 ),
		border-color 220ms cubic-bezier( 0.4, 0, 0.2, 1 ),
		box-shadow 220ms cubic-bezier( 0.4, 0, 0.2, 1 );
}

.gc-header.is-scrolled {
	background-color: rgba( 255, 255, 255, 0.92 );
	backdrop-filter: saturate( 180% ) blur( 14px );
	-webkit-backdrop-filter: saturate( 180% ) blur( 14px );
	border-bottom-color: var( --wp--preset--color--line );
	box-shadow: 0 1px 3px rgba( 4, 48, 45, 0.07 ), 0 8px 24px -16px rgba( 4, 48, 45, 0.18 );
}

/* Transparent over a dark band — invert so the bar stays readable. Scoped away
   from the dropdown panels, which are white cards whatever the header is doing. */

.gc-header.is-over-dark:not(.is-scrolled) :where( a, .wp-block-navigation-item__content, .wp-block-navigation__submenu-icon ):not( .wp-block-navigation__submenu-container * ) {
	color: rgba( 255, 255, 255, 0.92 );
}

.gc-header.is-over-dark:not(.is-scrolled) :where( a:hover, .wp-block-navigation-item__content:hover ):not( .wp-block-navigation__submenu-container * ) {
	color: #fff;
}

/* Over a dark band the header swaps to the supplied white lockup, which keeps
   the mark in brand teal — a knock-out filter would have flattened it too. */

.gc-header.is-over-dark:not(.is-scrolled) .wp-block-site-logo img {
	content: url( "../images/Grantcookie-logo-white.png" );
}

.gc-header.is-over-dark:not(.is-scrolled) .wp-block-button:not(.is-style-gc-ghost) .wp-block-button__link {
	background-color: #fff;
	color: var( --wp--preset--color--primary );
	box-shadow: 0 8px 24px -12px rgba( 0, 0, 0, 0.5 );
}

.gc-header.is-over-dark:not(.is-scrolled) .wp-block-button:not(.is-style-gc-ghost) .wp-block-button__link:hover {
	background-color: rgba( 255, 255, 255, 0.9 );
	color: var( --wp--preset--color--primary-hover );
}

@media ( prefers-reduced-motion: reduce ) {
	.gc-header {
		transition: none;
	}
}

.gc-header .wp-block-site-logo img {
	height: 28px;
	width: auto;
}

/* -------------------------------------------------------------------------
   3. Hero decoration
   ---------------------------------------------------------------------- */

.gc-hero {
	position: relative;
	isolation: isolate;
	overflow: hidden;
}

/* The decoration is painted on top of the element's own background, and the
   content is lifted above it — a negative z-index would put these behind the
   gradient the element paints itself, i.e. invisible. */

.gc-hero > * {
	position: relative;
	z-index: 2;
}

/* A soft dot field over the gradient — the same texture the product UI uses. */

.gc-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background-image: radial-gradient( circle, rgba( 255, 255, 255, 0.14 ) 1px, transparent 1px );
	background-size: 26px 26px;
	pointer-events: none;
}

/* Two wide, low-opacity glows so the gradient never reads as a flat
   rectangle: a cool one bottom-left, a brighter one behind the headline. */

.gc-hero::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background:
		radial-gradient( 46rem 34rem at 8% 108%, rgba( 255, 255, 255, 0.16 ) 0%, transparent 60% ),
		radial-gradient( 40rem 28rem at 78% -12%, rgba( 122, 205, 196, 0.30 ) 0%, transparent 62% );
	pointer-events: none;
}

.gc-hero.is-light::before {
	background-image: radial-gradient( circle, rgba( 4, 48, 45, 0.05 ) 1px, transparent 1px );
}

.gc-hero.is-light::after {
	background:
		radial-gradient( 44rem 30rem at 82% -20%, rgba( 11, 95, 88, 0.10 ) 0%, transparent 62% );
}

/* -------------------------------------------------------------------------
   4. Typography variations
   ---------------------------------------------------------------------- */

.is-style-gc-eyebrow {
	font-family: var( --wp--preset--font-family--body );
	font-size: var( --wp--preset--font-size--x-small );
	font-weight: 600;
	letter-spacing: 0.09em;
	text-transform: uppercase;
	color: var( --wp--preset--color--primary );
	margin-bottom: 0.75rem;
}

/* Only ever inverted inside an explicitly dark section — keying off "has a
   background" would also catch the light surface sections, where white text
   disappears. */

.gc-on-dark .is-style-gc-eyebrow:not([class*="has-text-color"]) {
	color: rgba( 255, 255, 255, 0.85 );
}

.is-style-gc-lead {
	font-size: var( --wp--preset--font-size--large );
	/* Looser than a heading, tighter than body — a lead only reads as a lead if
	   its leading differs from the paragraphs around it, not just its size. */
	line-height: 1.45;
	font-weight: 450;
	color: var( --wp--preset--color--ink-soft );
}

/* Tracking is scale-dependent: it tightens as type grows and OPENS UP below
   15px. Fine print inheriting the negative display tracking is the detail that
   makes a page feel machine-set — and on a compliance product the fine print is
   the copy buyers read hardest. */

.is-style-gc-note,
.has-x-small-font-size,
.wp-block-post-terms,
figcaption {
	letter-spacing: 0.008em;
}

/* Numbers that sit in columns must not dance as they change. */

.gc-dash__stat b,
.gc-plan__amount,
.gc-log__table td {
	font-variant-numeric: tabular-nums;
	font-feature-settings: "tnum" 1;
}

.is-style-gc-note {
	font-size: var( --wp--preset--font-size--x-small );
	line-height: 1.6;
	color: var( --wp--preset--color--ink-faint );
}

.is-style-gc-gradient {
	background: linear-gradient( 100deg, var( --wp--preset--color--primary ) 0%, #35a89b 55%, var( --wp--preset--color--primary-deep ) 100% );
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	-webkit-text-fill-color: transparent;
}

.is-style-gc-underline {
	position: relative;
	display: inline-block;
}

.is-style-gc-underline::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0.08em;
	height: 0.32em;
	z-index: -1;
	background: var( --wp--preset--color--accent );
	border-radius: 2px;
}

/* -------------------------------------------------------------------------
   5. Sections and grids
   ---------------------------------------------------------------------- */

/* Two section rhythms, and only two. Every band on a page uses one of them,
   so the vertical spacing is consistent as you scroll. Patterns must not set
   their own inline padding — an inline style outranks these classes and is
   how the rhythm drifted in the first place. */

.gc-section {
	padding-block: var( --wp--preset--spacing--70 );
}

.gc-section--tight {
	padding-block: var( --wp--preset--spacing--60 );
}

/* The header is fixed, so whatever opens a page has to clear it. The bands that
   carry a page title do this in their own markup; a page that opens straight
   into a section (the Landing template) is handled here, which works because
   .gc-section sets its padding in CSS rather than inline. */

main > .gc-section:first-child,
main > .gc-section--tight:first-child,
.wp-block-post-content > .gc-section:first-child,
.wp-block-post-content > .gc-section--tight:first-child {
	padding-block-start: calc( var( --wp--custom--header--height ) + var( --wp--preset--spacing--60 ) );
}

/* The page-title bands are full-wide so the title starts on the same grid line
   as the logo. Text still needs a readable measure, so it is capped here rather
   than by centring the container. */

.gc-hero.is-light :where( h1, h2, .wp-block-post-title, .is-style-gc-lead ) {
	max-width: 52rem;
}

/* On the Landing template there is no title band — the opening section's own
   intro IS the page title. It therefore aligns to the logo like every other
   page title, while sections further down stay centred. The selector is long
   enough to beat .has-text-align-center without !important. */

.wp-block-post-content > .gc-section:first-child > .wp-block-group:first-child,
.wp-block-post-content > .gc-section--tight:first-child > .wp-block-group:first-child {
	max-width: var( --wp--style--global--wide-size );
}

.wp-block-post-content > .gc-section:first-child > .wp-block-group:first-child :where( h1, h2, p ),
.wp-block-post-content > .gc-section--tight:first-child > .wp-block-group:first-child :where( h1, h2, p ) {
	text-align: left;
	max-width: 52rem;
	/* !important only because core's constrained layout centres children with
	   `margin-left/right: auto !important` — there is no winning without it. */
	margin-left: 0 !important;
	margin-right: 0 !important;
}

/* page.html deliberately gives the post-content wrapper no top padding, because
   a page that opens with a full-bleed section band gets its spacing from that
   band. Stacking the two produced a ~270px dead gap under the page header.

   Pages that open with ordinary prose instead have nothing to inherit spacing
   from, so they get it here. Additive rather than subtractive on purpose: the
   template carries no inline top padding to fight, and an inline style would
   beat this rule if it did. */

.wp-block-post-content > :first-child:not(.alignfull) {
	margin-block-start: var( --wp--preset--spacing--60 );
}

.gc-card-grid .wp-block-post {
	height: 100%;
}

/* Query loops styled as cards get the card chrome without every post template
   having to opt in block by block. */

.is-style-gc-cards .wp-block-post-template > li {
	display: flex;
}

.is-style-gc-cards .wp-block-post-template > li > .wp-block-group {
	flex: 1;
	background: var( --wp--preset--color--base );
	border: 1px solid var( --wp--preset--color--line );
	border-radius: var( --wp--custom--radius--lg );
	box-shadow: var( --wp--preset--shadow--card );
	transition: transform 180ms cubic-bezier( 0.4, 0, 0.2, 1 ), box-shadow 180ms cubic-bezier( 0.4, 0, 0.2, 1 ), border-color 180ms cubic-bezier( 0.4, 0, 0.2, 1 );
}

.is-style-gc-cards .wp-block-post-template > li > .wp-block-group:hover {
	transform: translateY( -3px );
	border-color: rgba( 11, 95, 88, 0.35 );
	box-shadow: var( --wp--preset--shadow--raised );
}

.is-style-gc-cards .wp-block-post-title a {
	text-decoration: none;
	color: var( --wp--preset--color--contrast );
}

.is-style-gc-cards .wp-block-post-title a:hover {
	color: var( --wp--preset--color--primary );
	text-decoration: none;
}

.is-style-gc-cards .wp-block-post-excerpt__excerpt {
	color: var( --wp--preset--color--ink-soft );
}

/* -------------------------------------------------------------------------
   6. Footer
   ---------------------------------------------------------------------- */

/* One continuous black band. The footer used to paint two separate fills, and
   the layout gap between them showed through as a white line across the page. */

.gc-footer {
	position: relative;
	isolation: isolate;
	overflow: hidden;
	color: var( --wp--preset--color--ink-faint );
}

/* A dot field, fading out towards the bottom so the fine print sits on clean
   black rather than on texture. */

.gc-footer::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	background-image: radial-gradient( circle, rgba( 255, 255, 255, 0.085 ) 1px, transparent 1px );
	background-size: 26px 26px;
	-webkit-mask-image: linear-gradient( 180deg, #000 0%, rgba( 0, 0, 0, 0.4 ) 62%, transparent 94% );
	mask-image: linear-gradient( 180deg, #000 0%, rgba( 0, 0, 0, 0.4 ) 62%, transparent 94% );
}

/* Two wide brand glows, so the black reads as deliberate rather than flat. */

.gc-footer::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	background:
		radial-gradient( 48rem 26rem at 8% -10%, rgba( 11, 95, 88, 0.28 ) 0%, transparent 62% ),
		radial-gradient( 38rem 22rem at 92% 0%, rgba( 143, 224, 74, 0.16 ) 0%, transparent 60% );
}

.gc-footer > * {
	position: relative;
	z-index: 1;
}

/* The bottom bar is separated by a hairline instead of a second fill — that is
   what keeps the band continuous with no seam. */

.gc-footer__bottom {
	border-top: 1px solid rgba( 255, 255, 255, 0.09 );
}

.gc-footer h2,
.gc-footer h3,
.gc-footer h4 {
	color: #fff;
	font-size: var( --wp--preset--font-size--small );
	font-weight: 600;
	letter-spacing: -0.01em;
	margin-bottom: 0.9rem;
}

.gc-footer a {
	color: var( --wp--preset--color--ink-faint );
	text-decoration: none;
	transition: color 160ms cubic-bezier( 0.4, 0, 0.2, 1 );
}

.gc-footer a:hover,
.gc-footer a:focus {
	color: #fff;
	text-decoration: none;
}

.gc-footer .wp-block-list {
	list-style: none;
	padding-left: 0;
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: 0.6rem;
	font-size: var( --wp--preset--font-size--small );
}

.gc-footer .wp-block-site-logo img {
	content: url( "../images/Grantcookie-logo-white.png" );
	height: 24px;
	width: auto;
}

.gc-footer__badge {
	display: inline-block;
	margin-inline-start: 0.5rem;
	padding: 0.1rem 0.5rem;
	border-radius: var( --wp--custom--radius--pill );
	background: var( --wp--preset--color--primary );
	color: #fff;
	font-size: 0.6875rem;
	font-weight: 500;
	letter-spacing: 0;
	text-transform: none;
	vertical-align: 2px;
}

/* -------------------------------------------------------------------------
   7. Reveal on scroll
   ---------------------------------------------------------------------- */

/* The hidden state is applied only once site.js has confirmed it is running,
   so a script failure can never leave a section invisible. */

.gc-js .gc-reveal {
	opacity: 0;
	transform: translateY( 18px );
	transition: opacity 620ms cubic-bezier( 0.16, 1, 0.3, 1 ), transform 620ms cubic-bezier( 0.16, 1, 0.3, 1 );
	will-change: opacity, transform;
}

.gc-reveal.is-revealed {
	opacity: 1;
	transform: none;
	will-change: auto;
}

@media ( prefers-reduced-motion: reduce ) {
	.gc-js .gc-reveal {
		opacity: 1;
		transform: none;
		transition: none;
	}
}

/* -------------------------------------------------------------------------
   8. Compliance badge row
   ---------------------------------------------------------------------- */

.gc-badges {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

.gc-badges .wp-block-button__link,
.gc-badge {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	padding: 0.35rem 0.85rem;
	border: 1px solid var( --wp--preset--color--line );
	border-radius: var( --wp--custom--radius--pill );
	background: var( --wp--preset--color--base );
	color: var( --wp--preset--color--ink-soft );
	font-size: var( --wp--preset--font-size--x-small );
	font-weight: 500;
	box-shadow: none;
}

.gc-on-dark .gc-badge {
	background: rgba( 255, 255, 255, 0.12 );
	border-color: rgba( 255, 255, 255, 0.28 );
	color: #fff;
}

/* -------------------------------------------------------------------------
   9. Plain forms
   ---------------------------------------------------------------------- */

/* Styling for hand-written forms in Custom HTML blocks, so a contact or
   newsletter form looks native before a form plugin is installed. */

.gc-contact-form p {
	margin: 0 0 1rem;
}

.gc-contact-form label {
	display: block;
	margin-bottom: 0.35rem;
	font-size: var( --wp--preset--font-size--x-small );
	font-weight: 500;
	color: var( --wp--preset--color--contrast );
}

.gc-contact-form input,
.gc-contact-form textarea,
.gc-contact-form select {
	width: 100%;
	padding: 0.7rem 0.95rem;
	border: 1px solid var( --wp--preset--color--line );
	border-radius: var( --wp--custom--radius--md );
	background: var( --wp--preset--color--base );
	color: var( --wp--preset--color--contrast );
	font-family: var( --wp--preset--font-family--body );
	font-size: var( --wp--preset--font-size--small );
	line-height: 1.5;
	transition: border-color 180ms cubic-bezier( 0.4, 0, 0.2, 1 ), box-shadow 180ms cubic-bezier( 0.4, 0, 0.2, 1 );
}

.gc-contact-form input:focus,
.gc-contact-form textarea:focus,
.gc-contact-form select:focus {
	outline: none;
	border-color: var( --wp--preset--color--primary );
	box-shadow: 0 0 0 4px rgba( 11, 95, 88, 0.14 );
}

.gc-contact-form textarea {
	resize: vertical;
	min-height: 8rem;
}

/* -------------------------------------------------------------------------
   10. Separator
   ---------------------------------------------------------------------- */

.wp-block-separator.is-style-gc-gradient {
	height: 1px;
	border: 0;
	background: linear-gradient( 90deg, var( --wp--preset--color--line ) 0%, var( --wp--preset--color--line ) 45%, transparent 100% );
	opacity: 1;
}

.gc-on-dark .wp-block-separator.is-style-gc-gradient {
	background: linear-gradient( 90deg, rgba( 255, 255, 255, 0.28 ) 0%, transparent 100% );
}

/* -------------------------------------------------------------------------
   11. Utilities
   ---------------------------------------------------------------------- */

.gc-on-dark,
.gc-on-dark :where( h1, h2, h3, h4, h5, h6, p, li ) {
	color: #fff;
}

.gc-on-dark :where( p, li ):not(.is-style-gc-eyebrow):not([class*="has-text-color"]) {
	color: rgba( 255, 255, 255, 0.82 );
}

.gc-on-dark a:not(.wp-block-button__link) {
	color: #fff;
	text-decoration-color: rgba( 255, 255, 255, 0.5 );
}

.gc-stack-tight > * + * {
	margin-block-start: 0.5rem;
}

.gc-text-balance {
	text-wrap: balance;
}

/* Anything that should never be clipped by the overflow guard on body. */

.gc-allow-overflow {
	overflow: visible;
}

.gc-header > * {
	width: 100%;
}

/* -------------------------------------------------------------------------
   Inner-page body alignment
   ---------------------------------------------------------------------- */

/* Inner pages put the title in the 78rem column, so it starts on the same grid
   line as the logo. The body underneath sat in a NARROWER constrained column
   that core centres, so it started further in again — 275px for the title and
   510px for the prose at a desktop width.
   *
   * The fix is only to stop the centring of the narrow column, never to widen
   * it: anything carrying a wide or full alignment must keep its auto margins,
   * or the body runs to the page edge while the title stays in the column. */

.gc-page-body:not(.alignwide):not(.alignfull),
.gc-page-body > :not(.alignwide):not(.alignfull),
.gc-page-body .is-layout-constrained > :not(.alignwide):not(.alignfull) {
	margin-left: 0 !important;
	margin-right: 0 !important;
}

/* A wide group inside the body column repeats the inset the column already
   applies, which put hub headings 40px right of the title. Scoped to wide
   groups only: full-bleed section bands need their inset to pull their own
   content back off the page edge. */

.gc-page-body > .alignwide.has-global-padding {
	padding-left: 0;
	padding-right: 0;
}

/* Centred text is an explicit choice — a section intro, a panel, a call to
   action — so its box stays centred too. Last, so it wins the tie. */

.gc-page-body :where( .has-text-align-center ) {
	margin-inline: auto !important;
}

/* Inner-page bodies: prose keeps the readable measure, structure uses the
   column. Left-aligning the body fixed the grid line but left every block at
   46rem inside a 78rem column — 512px of dead space down the right, and card
   grids stuck at two cramped columns. Running text still wraps at 46rem;
   panels, grids, tables and media now use the width that is there. */

.gc-page-body .alignwide > .is-layout-grid,
.gc-page-body .alignwide > .wp-block-columns,
.gc-page-body .alignwide > .wp-block-table,
.gc-page-body .alignwide > .wp-block-image,
.gc-page-body .alignwide > figure,
.gc-page-body .alignwide > .is-style-gc-panel,
.gc-page-body .alignwide > .is-style-gc-card,
.gc-page-body .alignwide > .is-style-gc-outline,
.gc-page-body .alignwide > .wp-block-query {
	max-width: none !important;
}

/* A fixed column count was chosen for a 46rem box. Across the full column that
   leaves cards oversized, so they reflow on their own minimum instead — three
   up on a desktop, matching the card grids on the archives. */

.gc-page-body .alignwide > .is-layout-grid {
	grid-template-columns: repeat( auto-fit, minmax( 17rem, 1fr ) );
}

/* WordPress puts a block gap above the first child of the body column, on top
   of the band's own top padding — 160px of empty white between a page's lead
   paragraph and its first block, on every hub page. The band supplies the
   rhythm; the first child should not add to it. */

.gc-page-body > :first-child {
	margin-block-start: 0 !important;
}
