/* ==========================================================================
   Grasbloggen — layout
   Header, footer, container, grid layout patterns.
   Ported from design/prototypes/v5/styles.css.
   ========================================================================== */

.container {
	max-width: var(--container);
	margin-inline: auto;
	padding-inline: var(--sp-5);
}
@media (min-width: 720px) {
	.container { padding-inline: var(--sp-7); }
}

/* ==========================================================================
   Header — transparent over photo hero, solid on scroll / non-hero pages
   ========================================================================== */
.site-header {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 50;
	background: transparent;
	color: #fff;
	transition: background 200ms ease-out, box-shadow 200ms ease-out, border-color 200ms ease-out;
	border-bottom: 1px solid transparent;
}
.site-header.is-solid {
	background: var(--color-bg);
	color: var(--color-ink);
	border-bottom: 1px solid var(--hairline);
}
.site-header:not(.has-hero) {
	position: sticky;
	background: var(--color-bg);
	color: var(--color-ink);
	border-bottom: 1px solid var(--hairline);
}
/*
 * WP's own #wpadminbar is fixed and reserves
 * 32px (≥783px) / 46px (≤782px) of vertical space for logged-in users, but
 * core only accounts for that on static body content (`html.wp-toolbar`
 * gets a matching padding-top) — a theme's own `position: fixed`/`sticky`
 * header is never repositioned automatically and sits flush under (behind)
 * the admin bar unless the theme adds this offset itself.
 */
body.admin-bar .site-header {
	top: 32px;
}
@media screen and (max-width: 782px) {
	body.admin-bar .site-header {
		top: 46px;
	}
}
.site-header__bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding-block: var(--sp-4);
	gap: var(--sp-4);
	/* Locks the bar's real
	   rendered height to the --header-h token (tokens.css) so
	   compare.css's sticky filter bar (and anything else anchored to the
	   header's height) can never silently drift out of sync with it. */
	min-height: var(--header-h);
	box-sizing: border-box;
}
.logo {
	font-family: var(--font-serif);
	font-size: 1.4rem;
	font-weight: 600;
	color: inherit;
	text-decoration: none;
	letter-spacing: -0.01em;
	white-space: nowrap;
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	/* A11y fix (WCAG 2.2 SC 2.5.8 target size, a11y/perf audit this session):
	   padding on all sides (invisible — no background/border on this link)
	   grows the real click/tap box past the 24x24px minimum and away from
	   the sticky header's neighboring elements, without changing the
	   visible logo mark/wordmark at all. */
	padding: 6px 4px;
	margin: -6px -4px;
}
.logo em { font-style: normal; color: #9fd3b5; }
.site-header.is-solid .logo em,
.site-header:not(.has-hero) .logo em { color: var(--color-accent); }
.logo-mark { width: 26px; height: 26px; flex-shrink: 0; }
.logo-mark .blade { stroke: currentColor; }
.custom-logo-wrap img { max-height: 40px; width: auto; }

.nav-toggle {
	font-family: var(--font-mono);
	font-size: var(--step--1);
	background: none;
	border: 1px solid currentColor;
	opacity: 0.8;
	color: inherit;
	padding: 0.4em 0.8em;
	cursor: pointer;
	/* A11y fix (WCAG 2.2 SC 2.5.8): measured ~62×34px —
	   below the 44×44px minimum target size. min-width/min-height plus
	   flex-centering grow the real tap target without changing the visual
	   label. */
	min-width: 44px;
	min-height: 44px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}
@media (min-width: 1040px) {
	.nav-toggle { display: none; }
}

.primary-nav { display: none; }
.primary-nav.is-open {
	display: block;
	position: absolute;
	top: 100%;
	left: 0;
	right: 0;
	background: var(--color-band-deep);
	border-top: 1px solid var(--color-band-line);
}
/* A11y fix: the sitewide :focus-visible outline
   (--color-action, a mid-green) measured ~3.1:1 against this panel's
   near-black --color-band-deep background — under the 3:1 AA minimum for
   a non-text UI indicator once anti-aliasing/rounding is accounted for.
   The same on-dark mint tint already used for .kicker--on-dark and other
   dark-band text (verified ~9.7:1 against --color-band-deep) is used here
   instead. */
.primary-nav.is-open :focus-visible {
	outline-color: #9fd3b5;
}
.primary-nav ul {
	list-style: none;
	margin: 0;
	padding: var(--sp-3) var(--sp-5);
	display: flex;
	flex-direction: column;
	gap: 0;
}
.primary-nav a {
	display: block;
	padding: var(--sp-3) 0;
	color: #fff;
	text-decoration: none;
	font-size: var(--step--1);
	letter-spacing: 0.02em;
	border-bottom: 1px solid var(--color-band-line);
}
/*
 * Nothing in the nav ever indicated the current
 * page. wp_nav_menu() already adds .current-menu-item/.current-menu-ancestor
 * (and, per WP core since 5.5, aria-current="page" on the link) — this only
 * supplies the missing visual treatment: bold weight plus a permanent
 * underline in the mobile panel, and the same permanent underline (the
 * hover state made visible at rest) on desktop. Uses currentColor so it
 * reads correctly on both the transparent-over-photo and solid header
 * states without a second color token.
 */
.primary-nav .current-menu-item > a,
.primary-nav .current-menu-ancestor > a,
.primary-nav .current_page_item > a,
.primary-nav .current_page_ancestor > a,
.primary-nav .current_page_parent > a {
	font-weight: 700;
}
/*
 * IH3: search entry point. The search form (assets/css/components.css
 * .search-form) is rendered as the nav's own last item so it appears in
 * both the mobile menu panel and the desktop bar with zero markup
 * duplication. Below 960px the toggle button stays hidden and the panel
 * renders inline exactly as before (already inside the vertical mobile
 * menu, so there's no "second row" problem to solve there).
 */
.primary-nav .nav-search { border-bottom: none; padding-top: var(--sp-2); }
.primary-nav .nav-search .search-form { margin: var(--sp-2) 0 0; max-width: none; }
.nav-search__toggle { display: none; }
@media (min-width: 1040px) {
	.primary-nav { display: block; position: static; background: none; border: none; }
	.primary-nav ul { flex-direction: row; flex-wrap: wrap; align-items: center; row-gap: var(--sp-3); gap: var(--sp-5); padding: 0; }
	.primary-nav a {
		padding: 8px 0;
		border-bottom: none;
		font-size: var(--step--1);
		position: relative;
		color: inherit;
	}
	.primary-nav a::after {
		content: "";
		position: absolute;
		left: 0;
		right: 0;
		bottom: 4px;
		height: 1px;
		background: currentColor;
		transform: scaleX(0);
		transform-origin: left;
		transition: transform 250ms ease-out;
	}
	.primary-nav a:hover::after { transform: scaleX(1); }
	.primary-nav .current-menu-item > a::after,
	.primary-nav .current-menu-ancestor > a::after,
	.primary-nav .current_page_item > a::after,
	.primary-nav .current_page_ancestor > a::after,
	.primary-nav .current_page_parent > a::after {
		transform: scaleX(1);
	}

	/*
	 * The search field used to
	 * render inline in the nav row at a fixed 200px, which pushed the row
	 * wide enough to wrap onto a loose second line over the hero at
	 * ordinary desktop widths. It's now a compact icon button in the nav
	 * row (same visual weight as any other nav item) that opens a small
	 * anchored dropdown panel on demand — see initNavSearch() in main.js.
	 */
	.primary-nav .nav-search {
		position: relative;
		margin-left: auto;
		border-bottom: none;
		padding: 0;
		display: flex;
		align-items: center;
	}
	.nav-search__toggle {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		width: 44px;
		height: 44px;
		padding: 0;
		border: 1px solid currentColor;
		opacity: 0.8;
		background: none;
		color: inherit;
		cursor: pointer;
	}
	.nav-search__toggle:hover,
	.nav-search__toggle:focus-visible,
	.nav-search.is-open .nav-search__toggle { opacity: 1; }
	.nav-search__panel {
		display: none;
		position: absolute;
		top: calc(100% + var(--sp-2));
		right: 0;
		z-index: 20;
		background: var(--color-bg);
		border: 1px solid var(--hairline-strong);
		border-radius: var(--radius, 4px);
		padding: var(--sp-3);
		box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14);
	}
	.nav-search.is-open .nav-search__panel { display: block; }
	.primary-nav .nav-search .nav-search__panel .search-form { margin: 0; max-width: 240px; }
}

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer {
	padding-block: var(--sp-7);
	background: var(--color-band-deep);
	color: #fff;
}
.site-footer a { color: #fff; opacity: 0.85; }
.site-footer a:hover { opacity: 1; }
.footer-grid {
	display: grid;
	gap: var(--sp-6);
}
@media (min-width: 700px) {
	.footer-grid { grid-template-columns: 2fr 1fr; }
}
.footer-search { grid-column: 1 / -1; border-top: 1px solid var(--color-band-line); padding-top: var(--sp-5); }
.footer-search .search-form { margin-block: 0; }
.footer-grid nav ul {
	list-style: none;
	padding: 0;
	margin: 0;
	display: grid;
	gap: var(--sp-2);
	font-size: var(--step--1);
}
.footer-logo { font-family: var(--font-serif); font-size: 1.3rem; margin: 0 0 0.5em; }
.footer-fine {
	font-family: var(--font-mono);
	font-size: 0.7rem;
	opacity: 0.65;
	margin-top: var(--sp-6);
}

/* ==========================================================================
   Article layout grid (single.php)
   ========================================================================== */
.article-layout { padding-block: var(--sp-7); }
/*
 * grid-template-columns: minmax(0, 1fr) below 1080px is required, not
 * decorative: without it the single implicit grid column has the default
 * `min-width: auto`, so a wide child (e.g. a spec/compare table inside its
 * own .grasbloggen-table-scroll overflow-x:auto wrapper) grows the grid
 * track — and the whole page — instead of scrolling internally. Found via
 * visual QA on husqvarna-automower-nera at 390px (Snabbfakta table forced
 * ~230px of horizontal page overflow instead of scrolling in place).
 */
.article-layout__grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-7); }
@media (min-width: 1080px) {
	.article-layout__grid { grid-template-columns: 220px minmax(0, var(--measure)) 260px; }
}

/*
 * Third grid track (260px, ≥1080px only). Design review
 * found this column reserved by the grid but never filled — no theme
 * template placed a third child in article-layout__grid, so it rendered as
 * a large empty strip. grasbloggen_render_article_aside() now fills it with
 * real content only (tool CTA / jump links / a compact meta line) — see
 * inc/template-tags.php. Below 1080px this becomes a normal full-width
 * block after the article (no separate rule needed: it just follows grid
 * auto-flow in the single 1fr column).
 */
.article-layout__aside { min-width: 0; }
@media (min-width: 1080px) {
	.article-layout__aside { position: sticky; top: calc(var(--header-h) + var(--sp-5)); align-self: start; }
}
.aside-jump { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-5); font-family: var(--font-mono); font-size: var(--step--1); }
.aside-jump a { color: var(--color-accent); text-decoration: none; }
.aside-jump a:hover { text-decoration: underline; }
.aside-meta { font-family: var(--font-mono); font-size: var(--step--1); color: var(--color-accent-dim); }
