/**
 * Atlas Labs — Layout System
 *
 * Page-structure primitives: the content container, grid utilities,
 * section spacing wrappers, and the structural (non-content) shell of
 * the header and footer. Grouped in one file because all five are the
 * same underlying concern — page-level structure, not reusable
 * widgets — per DESIGN_SYSTEM.md#section-9-grid-system,
 * #section-13-header-tokens, and #section-14-footer-tokens.
 *
 * The header/footer rules here are structural only: dimensions,
 * background, sticky behavior, and internal flex/grid regions. No
 * navigation markup, menu output, or icon wiring is implied — that is
 * built in the sprint that adds real header.php/footer.php templates
 * and populates them with an actual WordPress nav menu.
 *
 * Known gap: DESIGN_SYSTEM.md defines no z-index scale. The sticky
 * header and floating buttons need one regardless, so a local
 * `--z-sticky-header` / `--z-floating` pair is used below rather than
 * inventing a value inline — flagged for addition to
 * DESIGN_SYSTEM.md's token set in a future documentation pass.
 */

:root {
	--z-sticky-header: 50;
	--z-floating: 40;
}

/* ---------------------------------------------------------------
 * Container
 * ------------------------------------------------------------- */

.al-container {
	width: 100%;
	max-width: var(--container-max-width);
	margin-inline: auto;
	padding-inline: var(--container-gutter-mobile);
}

@media (min-width: 768px) {
	.al-container {
		padding-inline: var(--container-gutter-tablet);
	}
}

@media (min-width: 1024px) {
	.al-container {
		padding-inline: var(--container-gutter-laptop);
	}
}

@media (min-width: 1280px) {
	.al-container {
		padding-inline: var(--container-gutter-desktop);
	}
}

/* ---------------------------------------------------------------
 * Grid utilities
 * Card grid gutter: space-16 (tablet/mobile) / space-24
 * (desktop/laptop), per DESIGN_SYSTEM.md#section-9-grid-system.
 * ------------------------------------------------------------- */

.al-grid {
	display: grid;
	gap: var(--space-16);
}

@media (min-width: 1024px) {
	.al-grid {
		gap: var(--space-24);
	}
}

.al-grid--cols-2 {
	grid-template-columns: repeat(2, 1fr);
}

.al-grid--cols-3 {
	grid-template-columns: repeat(3, 1fr);
}

.al-grid--cols-4 {
	grid-template-columns: repeat(4, 1fr);
}

/* ---------------------------------------------------------------
 * Section wrapper
 * Section spacing: space-48 (mobile) / space-64 (tablet+laptop) /
 * space-96 (desktop+), per DESIGN_SYSTEM.md#section-9-grid-system.
 * ------------------------------------------------------------- */

.al-section {
	padding-block: var(--space-48);
}

@media (min-width: 768px) {
	.al-section {
		padding-block: var(--space-64);
	}
}

@media (min-width: 1280px) {
	.al-section {
		padding-block: var(--space-96);
	}
}

/* Alternating-section treatment per BRAND_GUIDELINES.md's
   Surface/Secondary usage note ("alternating sections, footers"). */
.al-section--secondary {
	background-color: var(--color-bg-secondary);
}

/* Floating-panel treatment: the same alternating Surface/Secondary
   rhythm, expressed as an inset rounded panel on the white page
   background rather than a full-bleed band — the container's gutters
   stay white, so the section reads as a large floating card.
   radius-xl per DESIGN_SYSTEM.md#section-5-border-radius-tokens
   ("large feature imagery containers"); these panels are the largest
   feature containers on the page. No shadow — on the dark palette,
   elevation comes from the panel's LIGHTER fill plus a hairline
   border (surfaces get lighter as they come forward), per
   DESIGN_SYSTEM.md#section-7-shadow-system. */
.al-panel {
	background-color: var(--color-bg-secondary);
	border: var(--border-width-standard) solid var(--color-border-primary);
	border-radius: var(--radius-xl);
	padding: var(--space-48) var(--space-24);
}

@media (min-width: 768px) {
	.al-panel {
		padding: var(--space-64) var(--space-48);
	}
}

@media (min-width: 1280px) {
	.al-panel {
		padding: var(--space-96) var(--space-64);
	}
}

/* A section whose content is an .al-panel carries the section rhythm
   inside the panel itself, so the section wrapper only spaces panels
   apart — roughly half the standard section padding. */
.al-section--panel {
	padding-block: var(--space-24);
}

@media (min-width: 768px) {
	.al-section--panel {
		padding-block: var(--space-32);
	}
}

@media (min-width: 1280px) {
	.al-section--panel {
		padding-block: var(--space-48);
	}
}

/* ---------------------------------------------------------------
 * Header framework (structure only)
 * ------------------------------------------------------------- */

.al-site-header {
	position: sticky;
	top: 0;
	z-index: var(--z-sticky-header);
	/* Bumped from 56px (founder feedback, 2026-07-16: the 80px mobile
	   logo was touching the bottom of the header bar). 88px leaves a few
	   px of clearance above and below the logo, verified live at 375px —
	   same containment fix already applied at the >=768px breakpoint
	   below. */
	height: 88px;
	background-color: var(--color-bg-primary);
	border-bottom: var(--border-width-standard) solid var(--color-border-primary);
}

@media (min-width: 768px) {
	.al-site-header {
		/* Bumped from 72px (founder feedback, 2026-07-16: the 112px
		   logo at this breakpoint was bleeding below the header's
		   border-bottom into the hero section — contain it instead of
		   letting it overflow). 120px leaves ~4px of clearance above
		   and below the logo, verified live at 1280px. */
		height: 120px;
	}
}

/* Toggled by a future scroll-listener module; condenses the desktop
   header to the same height mobile uses by default. */
.al-site-header--condensed {
	height: 56px;
	transition: height var(--duration-standard) var(--easing-standard);
}

/* Once the page scrolls, the sticky header genuinely floats over
   content, so it earns an elevation cue (shadow signals elevation,
   per DESIGN_SYSTEM.md#section-7-shadow-system). Toggled by the
   header-scroll module in main.js; without JS the hairline
   border-bottom above still separates the header. */
.al-site-header {
	transition: box-shadow var(--duration-standard) var(--easing-standard);
}

.al-site-header.is-scrolled {
	box-shadow: var(--shadow-sm);
}

/* The header's fixed height (56/72px) must reach the flex row: the
   intermediate .al-container has no height of its own, so without
   this rule .al-site-header__inner's height: 100% resolves against an
   auto-height parent and the row is free to grow past the header bar
   — one of the two root causes of the "logo escapes the header" bug. */
.al-site-header > .al-container {
	height: 100%;
}

/* Brand was originally centered via a real 3-column grid rather than
   absolute positioning (founder decision, 2026-07-12): an earlier
   absolute-position version centered against the header's full width,
   which put the logo flush against the last nav item on this content
   width — verified live. Re-laid-out twice more since (founder
   feedback, 2026-07-16): first to logo-left / nav-right-of-logo, then
   to the current logo-left / nav-centered-in-the-remaining-space /
   utility-right — the middle `minmax(0, 1fr)` track is what nav
   centers itself within via `justify-self: center` below, so it's
   genuinely centered between whatever the logo and utility clusters
   actually measure, not centered against the full header width (which
   is exactly the collision the very first absolute-position attempt
   hit). Still a grid rather than a flex row for the same reason as
   ever: a real reserved column per item, not manual spacing, is what
   keeps them from colliding regardless of content length.

   `grid-row: 1` on all three items below is load-bearing, not
   decoration — found live after two failed alignment-based fixes.
   Root cause: brand is FIRST in DOM order (navigation.php; unchanged
   so screen readers/keyboard focus still hit the home link first) but
   sits in the MIDDLE column (2); nav is second in DOM order but wants
   the FIRST column (1) — a column "behind" where auto-placement's
   cursor already sits after placing brand. Grid auto-placement doesn't
   backfill columns behind its cursor within a row, so nav (and then
   utility, following it) got silently pushed onto an implicit SECOND
   row, each row auto-sized to its own content (56px logo row, 44px
   nav/utility row) — a visually broken two-row header that no amount
   of align-items/align-content could fix, because the real problem was
   never alignment, it was that the items were never in the same row to
   begin with. Explicit `grid-row: 1` forces all three into one row
   regardless of DOM-order-vs-column-order mismatch; nav's grid-column
   has moved twice since with the re-layouts above, but still needs its
   own `grid-row: 1` for the same reason. */
.al-site-header__inner {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: center;
	column-gap: var(--space-8);
	height: 100%;
}

.al-site-header__brand {
	grid-column: 1;
	grid-row: 1;
	justify-self: start;
	flex-shrink: 0;
	display: flex;
	align-items: center;
	height: 100%;
}

.al-site-header__nav {
	grid-column: 2;
	grid-row: 1;
	justify-self: center;
	display: flex;
	align-items: center;
	min-width: 0;
	overflow: hidden;
}

.al-site-header__utility {
	grid-column: 3;
	grid-row: 1;
	justify-self: end;
	display: flex;
	align-items: center;
	gap: var(--space-16);
}

/* The inline search field only fits alongside a full 6-item nav once
   the container is wide enough — verified live: at 1024px (this
   layout's minimum, matched to the breakpoint below) nav + search +
   account + cart genuinely don't fit even at zero gap (a 24px real
   overlap), while nav + account + cart alone clears with 96px to
   spare. Hiding search through 1199px and restoring it at 1200px
   (comfortable margin above the 1024 pinch point, verified live at
   1024/1100/1280px) avoids the collision without shrinking anything
   else. Search remains reachable via its page URL in this range, same
   trade already made for mobile in the phone-width rule below. */
@media (min-width: 1024px) and (max-width: 1199px) {
	.al-site-header__search {
		display: none;
	}
}

/* Below 1024px, .al-site-header__nav is display: none (see the
   nav-hiding rule further down this file) — but an empty grid item
   still reserves its own track, so this collapses the base's 3-column
   (brand | nav | utility) layout down to 2 (brand | utility) rather
   than leaving a dead middle column. Below 768px this is also the
   point where the enlarged logo needs the room nav would otherwise
   have reserved (verified live — see the img sizing comment further
   down). Brand and utility's grid-column/justify-self here match the
   base values already; only the column count changes. */
@media (max-width: 1023px) {
	.al-site-header__inner {
		grid-template-columns: auto minmax(0, 1fr);
	}

	.al-site-header__brand {
		grid-column: 1;
		justify-self: start;
	}

	.al-site-header__utility {
		grid-column: 2;
	}
}

.al-site-header__announcement {
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: var(--color-bg-secondary);
	padding-block: var(--space-8);
}

/* Header content added in Sprint 3 (logo, nav list, cart count) —
 * the structural rules above are from Sprint 2 and unchanged.
 */

/* Logo sizing — height-locked to the header bar, and deliberately
   covering WordPress's own the_custom_logo() output
   (a.custom-logo-link > img.custom-logo), which is what
   navigation.php actually emits when a logo is set in the Customizer.
   Bumped by one element (html body …) because Kadence ships its own
   .custom-logo-link/.custom-logo rules at tying specificity in its
   later-loaded stylesheets — the second root cause of the "logo not
   staying in the header, moving around" bug: if these constraints
   lose the cascade, the multi-thousand-pixel logo PNG renders at
   max-width: 100% and sprawls out of the 56px bar. max-height caps it
   against the header even if the fixed height ever loses. */
html body .al-site-header .custom-logo-link {
	display: flex;
	align-items: center;
	height: 100%;
}

/* Enlarged from 28/32px (founder feedback, 2026-07-12: "still really
   small... make it large enough for customers to easily see"), then
   doubled again to 80/112px (founder feedback, 2026-07-16: keep the
   56/72px header bar itself unchanged, just make the mark bigger).
   Fixed px, not a percentage: the image's immediate parent (.custom-
   logo-link) has no explicit height of its own — a percentage height
   has no containing block to resolve against there and is ignored per
   spec, verified live wasn't worth risking. max-height is deliberately
   `none` here, not `100%`.
   Originally the 80px mobile logo was left to overflow the 56px bar
   vertically on purpose (no ancestor in the header chain sets
   overflow: hidden, so nothing clipped it). Founder feedback the same
   day: that overflow read as broken on both mobile and >=768px, so
   both breakpoints now grow the header bar itself to contain the logo
   instead (88px mobile, 120px >=768px — both above). */
html body .al-site-header__brand img,
html body .al-site-header__brand svg,
html body .al-site-header img.custom-logo {
	display: block;
	height: 80px;
	max-height: none;
	width: auto;
	max-width: none;
}

@media (min-width: 768px) {
	html body .al-site-header__brand img,
	html body .al-site-header__brand svg,
	html body .al-site-header img.custom-logo {
		height: 112px;
	}
}

.al-site-header__site-title {
	font-family: var(--font-family-base);
	font-size: var(--type-h4-size);
	font-weight: var(--type-h4-weight);
	color: var(--color-text-primary);
}

.al-site-header__nav-list {
	display: flex;
	align-items: center;
	/* Trimmed from space-24 down to space-16, space-12, then space-8
	   across three rounds (founder feedback, 2026-07-12 and
	   2026-07-16) while the header used a centered-logo or logo-left
	   layout — each cramped nav's own reserved column against a fixed
	   neighbor (the logo). Restored to space-24 (founder feedback,
	   same day) once nav moved to its own centered `minmax(0, 1fr)`
	   track between logo and utility: that track's width now floats
	   with the header's actual free space instead of a fixed
	   neighbor-collision budget, so the wider gap is safe again —
	   verified live with 28px of clearance on both sides at 1024px,
	   this layout's tightest width. */
	gap: var(--space-24);
	list-style: none;
	margin: 0;
	padding: 0;
}

.al-site-header__nav-list a {
	font-family: var(--font-family-base);
	font-size: var(--type-nav-size);
	font-weight: var(--type-nav-weight);
	color: var(--color-text-primary);
	padding-block: var(--space-4);
	border-bottom: var(--border-width-standard) solid transparent;
	transition: border-color var(--duration-fast) var(--easing-standard);
	white-space: nowrap;
}

.al-site-header__nav-list a:hover,
.al-site-header__nav-list .current-menu-item > a {
	border-bottom-color: var(--color-accent-primary);
}

/* Per DESIGN_SYSTEM.md#section-13-header-tokens: "40×40px tap target,
   with a color-accent-primary count badge (12px, color-bg-primary
   text)". Positioned absolutely against .al-button's own
   position: relative (see buttons.css). */
.al-site-header__cart-count {
	position: absolute;
	top: -2px;
	right: -2px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 12px;
	height: 12px;
	border-radius: var(--radius-full);
	background-color: var(--color-accent-primary);
	color: var(--color-bg-primary);
	font-size: 8px;
	font-weight: var(--weight-semibold);
	line-height: 1;
}

/* ---------------------------------------------------------------
 * Mobile menu drawer
 * ------------------------------------------------------------- */

.al-mobile-menu {
	position: fixed;
	inset: 0;
	z-index: var(--z-sticky-header);
	visibility: hidden;
}

.al-mobile-menu.is-open {
	visibility: visible;
}

.al-mobile-menu__overlay {
	position: absolute;
	inset: 0;
	background-color: var(--color-overlay-scrim);
	opacity: 0;
	transition: opacity var(--duration-standard) var(--easing-standard);
}

.al-mobile-menu.is-open .al-mobile-menu__overlay {
	opacity: 1;
}

.al-mobile-menu__panel {
	position: absolute;
	top: 0;
	right: 0;
	height: 100%;
	width: 100%;
	max-width: 360px;
	background-color: var(--color-bg-primary);
	padding: var(--space-24);
	overflow-y: auto;
	transform: translateX(100%);
	transition: transform var(--duration-standard) var(--easing-standard);
}

.al-mobile-menu.is-open .al-mobile-menu__panel {
	transform: translateX(0);
}

.al-mobile-menu-close {
	margin-inline-start: auto;
	display: flex;
}

.al-mobile-menu__nav {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
	margin-top: var(--space-24);
}

.al-mobile-menu__nav a {
	display: block;
	padding-block: var(--space-12);
	font-family: var(--font-family-base);
	font-size: var(--type-nav-size);
	font-weight: var(--type-nav-weight);
	color: var(--color-text-primary);
	border-bottom: var(--border-width-standard) solid var(--color-divider-default);
}

.al-mobile-menu__divider {
	margin-block: var(--space-16);
	border: none;
	border-top: var(--border-width-standard) solid var(--color-divider-default);
}

@media (min-width: 1024px) {
	.al-mobile-menu {
		display: none;
	}

	/* html body bump (see CLAUDE.md's Kadence-tie gotcha — same failure
	   mode, different source): buttons.css's `.al-button { display:
	   inline-flex }` is equal specificity (0,1,0) and loads after this
	   file, so it silently won the tie and the toggle never actually
	   hid at any width — confirmed live via computed style, matchMedia
	   true but display still flex. Found while re-laying-out the header
	   for the 2026-07-16 nav redesign, not introduced by it. */
	html body .al-mobile-menu-toggle {
		display: none;
	}
}

/* Desktop nav and utility icons are Sprint 3 additions; hide the
   mobile-only affordances above that breakpoint and show the
   desktop nav only from that breakpoint down. */
@media (max-width: 1023px) {
	.al-site-header__nav {
		display: none;
	}
}

/* Phone-width header budget (iPhone 375/390px): logo + 160px search +
   account + cart + menu toggle + gaps overflows the viewport and
   forces horizontal scroll — the inline search form and account icon
   are hidden below tablet width so the bar is logo + cart + menu.
   Search and account remain reachable through their WordPress URLs;
   adding both entry points to the mobile drawer is flagged as
   follow-up work in ROADMAP terms, not silently dropped. */
@media (max-width: 767px) {
	.al-site-header__search,
	.al-site-header__account {
		display: none;
	}
}

/* Touch targets: WCAG/Apple 44px minimum on coarse pointers — a
   deliberate v1.1 override of DESIGN_SYSTEM.md's 40×40 icon-button
   spec, applied only where fingers are the input device. */
@media (pointer: coarse) {
	.al-site-header .al-button--icon,
	.al-mobile-menu .al-button--icon {
		width: 44px;
		height: 44px;
	}
}

/* ---------------------------------------------------------------
 * Footer framework (structure only)
 * ------------------------------------------------------------- */

.al-site-footer {
	background-color: var(--color-bg-secondary);
	padding-block-start: var(--space-64);
	padding-block-end: var(--space-24);
}

@media (min-width: 1280px) {
	.al-site-footer {
		padding-block-start: var(--space-96);
	}
}

.al-site-footer__columns {
	display: grid;
	gap: var(--space-48);
	grid-template-columns: repeat(4, 1fr);
}

.al-site-footer__columns--3 {
	grid-template-columns: repeat(3, 1fr);
}

@media (max-width: 1023px) {
	.al-site-footer__columns,
	.al-site-footer__columns--3 {
		grid-template-columns: 1fr;
	}
}

.al-site-footer__column {
	display: flex;
	flex-direction: column;
}

.al-site-footer__column-heading {
	font-family: var(--font-family-base);
	font-size: var(--type-label-size);
	font-weight: var(--type-label-weight);
	letter-spacing: var(--type-label-letter-spacing);
	text-transform: var(--type-label-transform);
	color: var(--color-text-secondary);
	margin-bottom: var(--space-16);
}

.al-site-footer__menu {
	list-style: none;
	margin: 0;
	padding: 0;
}

.al-site-footer__column a {
	display: block;
	padding-block: var(--space-8);
	font-family: var(--font-family-base);
	font-size: var(--type-body-small-size);
	color: var(--color-text-primary);
}

.al-site-footer__column a:hover {
	color: var(--color-text-secondary);
}

.al-site-footer__newsletter {
	margin-top: var(--space-48);
	max-width: 400px;
}

.al-site-footer__newsletter-form {
	display: flex;
	gap: var(--space-8);
	margin-top: var(--space-12);
}

.al-site-footer__newsletter-form .al-input {
	flex: 1;
}

.al-site-footer__legal-section {
	margin-top: var(--space-48);
}

.al-site-footer__legal {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-16);
	padding-top: var(--space-24);
	border-top: var(--border-width-standard) solid var(--color-divider-default);
}

.al-site-footer__legal-menu {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-16);
	list-style: none;
	margin: 0;
	padding: 0;
}

.al-site-footer__legal a {
	font-family: var(--font-family-base);
	font-size: var(--type-caption-size);
	color: var(--color-text-muted);
}

.al-site-footer__legal a:hover {
	color: var(--color-text-secondary);
}

.al-site-footer__social {
	display: flex;
	gap: var(--space-16);
	padding-top: var(--space-16);
}

.al-site-footer__social-link {
	font-family: var(--font-family-base);
	font-size: var(--type-caption-size);
	color: var(--color-text-muted);
}

.al-site-footer__social-link:hover {
	color: var(--color-text-secondary);
}

.al-site-footer__copyright {
	font-family: var(--font-family-base);
	font-size: var(--type-caption-size);
	color: var(--color-text-muted);
	padding-top: var(--space-24);
}
