/**
 * Header + footer structural layout. Nav menu/dropdown visual treatment
 * lives in components/nav.css — this file handles positioning and the
 * header/footer "frame" only.
 */

/* ---------- Header ---------- */

/* The scroll-collapse transition below (.lbm-header.is-scrolled) shrinks
   the header's own height over ~220ms. Without this, the browser's default
   scroll anchoring "corrects" window.scrollY every frame of that shrink to
   keep content visually stable, which re-triggers the scroll threshold in
   nav.js and produces a flicker loop right at the crossing point (verified
   in-browser: ~10 class toggles within 400ms without this rule). This has
   to be set on the scrolling box itself (html), not on .lbm-header — the
   anchoring correction is performed by the scroller, and setting the
   property on the element that merely changes size doesn't suppress it.
   Hysteresis in nav.js (two thresholds instead of one) is a backstop, but
   this removes the feedback source entirely. */
html {
	overflow-anchor: none;
}

.lbm-header {
	position: sticky;
	top: 0;
	z-index: var(--z-sticky);
	background-color: color-mix(in srgb, var(--color-paper) 88%, transparent);
	backdrop-filter: blur(9px);
	-webkit-backdrop-filter: blur(9px);
	border-bottom: 1px solid transparent;
	box-shadow: none;
	transition: border-color var(--duration-hover) var(--ease-standard),
		box-shadow var(--duration-hover) var(--ease-standard);
}

/* Scrolled state — set via JS (nav.js) once the page scrolls past a small
   threshold. Height reduction is done on the inner padding rather than the
   header itself so the transition stays smooth without layout jumps. */
.lbm-header.is-scrolled {
	border-bottom-color: var(--color-border);
	box-shadow: 0 4px 16px -8px color-mix(in srgb, var(--color-ink) 25%, transparent);
}

.lbm-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-6);
	padding-block: var(--space-4);
	transition: padding-block var(--duration-hover) var(--ease-standard);
}

.lbm-header.is-scrolled .lbm-header__inner {
	padding-block: calc(var(--space-4) - 7px);
}

/* ---------- Two-row desktop header (brand row + category-nav row) ----------
 * Below 1024px this collapses to just the brand row — .lbm-nav--primary is
 * already display:none there (nav.css) and the mobile off-canvas drawer
 * (nav-mobile.php) is the real mobile nav, so .lbm-header__row--nav simply
 * never renders on mobile: no separate mobile-specific override needed. */
.lbm-header__row--nav {
	display: none;
}

@media (min-width: 1024px) {
	.lbm-header__row--nav {
		display: block;
		border-top: 1px solid var(--color-border);
		max-height: 72px;
		/* overflow stays visible at rest — dropdown submenus are absolutely
		   positioned descendants that extend below this row on purpose, and
		   overflow:hidden here would clip them regardless of z-index. It's
		   only switched to hidden in the .is-scrolled state below, where the
		   row is actually collapsing away and nothing should be escaping it. */
		overflow: visible;
		opacity: 1;
		visibility: visible;
		transition: max-height var(--duration-hover) var(--ease-standard),
			opacity var(--duration-hover) var(--ease-standard),
			border-color var(--duration-hover) var(--ease-standard),
			visibility 0s linear 0s;
	}

	/* Collapsed on scroll (extends the existing is-scrolled mechanism, see
	   nav.js) so the sticky header only pays its full two-row height at the
	   top of the page — while reading, only the compact brand/utility row
	   stays. visibility flips after the collapse finishes (not before) so
	   the hidden links drop out of tab order without an abrupt cut. */
	.lbm-header.is-scrolled .lbm-header__row--nav {
		max-height: 0;
		overflow: hidden;
		opacity: 0;
		border-top-color: transparent;
		visibility: hidden;
		transition: max-height var(--duration-hover) var(--ease-standard),
			opacity var(--duration-hover) var(--ease-standard),
			border-color var(--duration-hover) var(--ease-standard),
			visibility 0s linear var(--duration-hover);
	}
}

.lbm-header__inner--nav {
	padding-block: var(--space-3);
}

.lbm-header__brand {
	flex-shrink: 1;
	min-width: 0;
}

/* Below 1024px min-width:0 above is the deliberate escape hatch that lets
   the logo shrink instead of overlapping the mobile action icons (see the
   img rule below). At laptop/desktop widths the primary nav is visible
   and content is tight enough that the same flex-shrink was squeezing the
   logo down to a thin sliver well below its designed size — give it a
   floor there instead. */
@media (min-width: 1024px) {
	.lbm-header__brand {
		flex-shrink: 0;
		min-width: auto;
	}
}

.lbm-header__brand img {
	/* min() against 100%, not a bare px cap: .lbm-header__brand has
	   flex-shrink + min-width:0 so it can shrink below 190/260px on
	   narrow screens, but an img's max-width is an intrinsic cap, not a
	   response to the parent's actual box — without the 100% term the
	   image held its full 190px and visually overlapped the theme-toggle
	   button once the actions group left it less room than that. */
	max-width: min(260px, 100%);
	width: auto;
	height: auto;
	max-height: 48px;
}

@media (max-width: 480px) {
	.lbm-header__brand img {
		max-width: min(190px, 100%);
		max-height: 40px;
	}
}

.lbm-header__site-title {
	font-family: var(--font-serif);
	font-weight: 700;
	font-size: 1.375rem;
	color: var(--color-ink);
}

.lbm-header__actions {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	flex-shrink: 0;
}

.lbm-header__cta {
	font-size: 0.8125rem;
	padding: var(--space-2) var(--space-4);
	white-space: nowrap;
}

@media (max-width: 700px) {
	/* Specificity bump (not !important): buttons.css enqueues after this
	   file, so plain .lbm-header__cta { display: none } loses the cascade
	   to .lbm-btn's unconditional display: inline-flex at equal
	   specificity — the CTA stayed visible (and oversized) on mobile. */
	.lbm-header__actions .lbm-header__cta {
		display: none;
	}
}

.lbm-mobile-nav__cta {
	display: flex;
	margin: var(--space-5) var(--space-5) 0;
	text-align: center;
	justify-content: center;
}

.lbm-header__search-toggle,
.lbm-header__menu-toggle {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: var(--radius-sm);
	transition: background-color var(--duration-hover) var(--ease-standard);
}

.lbm-header__search-toggle:hover,
.lbm-header__menu-toggle:hover {
	background-color: var(--color-surface);
}

/* ---------- Dark/light toggle ----------
 * Same footprint and hover treatment as the adjacent search/menu buttons
 * (kept as its own rule rather than joining their selector so this feature
 * never has to touch that existing block). Icon swap mirrors the exact
 * light/dark condition structure from tokens.css: system preference by
 * default, [data-theme] attribute overrides it once the visitor has
 * toggled manually. */
.lbm-header__theme-toggle {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: var(--radius-sm);
	transition: background-color var(--duration-hover) var(--ease-standard);
}

.lbm-header__theme-toggle:hover {
	background-color: var(--color-surface);
}

.lbm-header__theme-toggle:focus-visible {
	outline: 2px solid var(--color-accent);
	outline-offset: 2px;
}

.lbm-header__theme-toggle .lbm-icon--sun,
.lbm-header__theme-toggle .lbm-icon--moon {
	display: none;
}

/* Light mode (default): show the Moon — clicking switches to dark. */
.lbm-header__theme-toggle .lbm-icon--moon {
	display: block;
}

/* System dark, no manual override yet: show the Sun. */
@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) .lbm-header__theme-toggle .lbm-icon--moon {
		display: none;
	}

	:root:not([data-theme="light"]) .lbm-header__theme-toggle .lbm-icon--sun {
		display: block;
	}
}

/* Manual override always wins over system preference. */
[data-theme="dark"] .lbm-header__theme-toggle .lbm-icon--moon {
	display: none;
}

[data-theme="dark"] .lbm-header__theme-toggle .lbm-icon--sun {
	display: block;
}

[data-theme="light"] .lbm-header__theme-toggle .lbm-icon--sun {
	display: none;
}

[data-theme="light"] .lbm-header__theme-toggle .lbm-icon--moon {
	display: block;
}

.lbm-header__menu-toggle {
	display: flex;
}

@media (min-width: 1024px) {
	.lbm-header__menu-toggle {
		display: none;
	}
}

/* Search overlay markup/styling lives in components/search-overlay.css
   (P2 roadmap item — replaced the old inline dropdown panel with a
   ⌘K-style centered modal). */

.lbm-search-form__submit {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	flex-shrink: 0;
	border-radius: var(--radius-sm);
	color: var(--color-neutral-600);
	transition: color var(--duration-hover) var(--ease-standard),
		background-color var(--duration-hover) var(--ease-standard);
}

.lbm-search-form__submit:hover {
	color: var(--color-accent);
	background-color: var(--color-surface);
}

/* ---------- Footer — editorial masthead ---------- */

.lbm-footer {
	margin-top: var(--space-10);
	/* A restrained "masthead rule" — the one deliberate accent-color
	   signature moment outside the type system, marking the footer as
	   the publication's closing spread rather than a bare theme footer. */
	border-top: 2px solid var(--color-accent);
	background-color: var(--color-surface);
}

.lbm-footer__columns {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-8);
	padding-block: var(--space-10);
}

@media (min-width: 768px) {
	.lbm-footer__columns {
		grid-template-columns: 1.75fr 1fr 1fr 1fr;
		gap: var(--space-7);
	}
}

.lbm-footer__brand-col {
	display: flex;
	flex-direction: column;
	gap: var(--space-5);
}

.lbm-footer__site-title {
	font-family: var(--font-serif);
	font-weight: 700;
	font-size: var(--text-h3);
}

.lbm-footer__about {
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	line-height: 1.6;
	color: var(--color-neutral-600);
	max-width: 42ch;
}

.lbm-footer__tagline {
	font-family: var(--font-serif);
	font-style: italic;
	color: var(--color-neutral-700);
	font-size: 1.0625rem;
	max-width: 30ch;
	line-height: 1.5;
}

.lbm-footer__nav-col {
	display: flex;
	flex-direction: column;
}

.lbm-footer__col-title {
	font-family: var(--font-sans);
	font-size: var(--text-kicker);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: var(--tracking-kicker);
	color: var(--color-accent);
	margin-bottom: var(--space-4);
}

.lbm-footer__nav-list {
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
}

.lbm-footer__nav-list a {
	color: var(--color-neutral-700);
	font-size: 0.9375rem;
	transition: color var(--duration-hover) var(--ease-standard);
}

.lbm-footer__nav-list a:hover {
	color: var(--color-accent);
}

.lbm-footer__contact-list a,
.lbm-footer__contact-list .lbm-footer__address {
	display: flex;
	align-items: center;
	gap: var(--space-2);
}

.lbm-footer__address {
	color: var(--color-neutral-600);
	font-size: 0.9375rem;
}

.lbm-footer__contact-list .lbm-icon {
	color: var(--color-neutral-500);
}

/* Left-aligned (not centered) so the icons start flush under the
   Location icon above them, in the same left edge as the Email/Location
   list — centering here was what made them read as "off to the side"
   relative to the rest of the Contact column (2026-08-14). */
.lbm-social-links {
	list-style: none;
	display: flex;
	justify-content: flex-start;
	gap: var(--space-3);
	margin-top: var(--space-4);
}

.lbm-social-links__item a {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border-radius: var(--radius-full);
	border: 1px solid var(--color-border);
	color: var(--color-neutral-600);
	transition: color var(--duration-hover) var(--ease-standard), border-color var(--duration-hover) var(--ease-standard);
}

.lbm-social-links__item a:hover {
	color: var(--color-accent);
	border-color: var(--color-accent);
}

.lbm-footer__bottom {
	border-top: 1px solid var(--color-border);
}

.lbm-footer__bottom-inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: var(--space-2) var(--space-5);
	padding-block: var(--space-4);
}

.lbm-footer__copyright,
.lbm-footer__credit {
	font-size: var(--text-meta);
	color: var(--color-neutral-600);
}

/* Sizing/weight/case approach matches Tech Fixon's TF-Astro footer legal
   row (normal case, no letter-spacing, ~12.5px/400) for visual
   consistency across both properties — colors stay on LBM's own "Quiet
   Authority" tokens rather than TF-Astro's literal hex values.
   Reference: D:\TF-Astro\src\components\Footer.astro, .footer-col-legal a. */
.lbm-footer__legal {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	justify-content: center;
	row-gap: var(--space-1);
	column-gap: var(--space-2);
	font-family: var(--font-sans);
	font-size: 0.78rem;
	font-weight: 400;
	line-height: 1.6;
}

.lbm-footer__legal a {
	color: var(--color-neutral-500);
	text-decoration: none;
	transition: color var(--duration-hover) var(--ease-standard);
}

.lbm-footer__legal a:hover,
.lbm-footer__legal a:focus-visible {
	color: var(--color-accent);
}

.lbm-footer__legal-sep {
	color: var(--color-neutral-400);
	font-size: 0.625rem;
}

.lbm-footer__credit a {
	color: var(--color-neutral-600);
	text-decoration: underline;
	text-decoration-color: var(--color-border);
	text-underline-offset: 2px;
	transition: color var(--duration-hover) var(--ease-standard);
}

.lbm-footer__credit a:hover {
	color: var(--color-accent);
}

/* ---------- Fallback (index.php) — bare, undesigned, Phase 2C territory ---------- */

.lbm-fallback {
	padding-block: var(--space-8);
}

.lbm-fallback__grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
	gap: var(--space-6);
}
