/* ----------------------------------------------------------------
 * theme.css — bridge layer between WordPress and the Design System.
 *
 * Lives between tokens.css and component CSS. Holds:
 *   - Page layout skeleton (.site, .site-content, .site-main)
 *   - WP-specific classes mapped to DS
 *   - Admin-bar offset
 *
 * Component-specific overrides go in dedicated files
 * (prose-overrides.css, etc.), not here.
 * ---------------------------------------------------------------- */

html { background: var(--bg); }
body {
	background: var(--bg);
	color: var(--fg-2);
	font-family: var(--font-sans);
	margin: 0;
	min-height: 100vh;
	display: flex;
	flex-direction: column;
}

.site {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}

/* Site content gutters mirror DS nav/footer geometry exactly:
 * .dh-nav has  left/right: var(--sp-4)   + inner padding var(--nav-h-pad)
 * .dh-footer has margin: 0 var(--sp-4)   + padding: 0 var(--nav-h-pad)
 * So the leftmost content x = sp-4 (16) + nav-h-pad (20) = 36px from viewport.
 * On wide viewports the max-width cap centers the same way as .dh-nav-inner. */
.site-content {
	flex: 1 0 auto;
	width: 100%;
	padding-inline: calc(var(--sp-4) + var(--nav-h-pad, 20px));
}

.site-main {
	display: block;
	width: 100%;
	max-width: var(--max-w);
	margin-inline: auto;
	padding-inline: 0;
	padding-block: var(--sp-12);
}

@media (max-width: 768px) {
	.site-main { padding-block: var(--sp-8); }
	/* On mobile the floating nav card and footer sit 16px from the viewport edge,
	 * but .site-content uses sp-4 + nav-h-pad (36px total), making the article
	 * column 40px narrower than the header/footer cards. Drop nav-h-pad from the
	 * inline padding so content aligns to the same 16px edge as the cards. */
	.site-content { padding-inline: var(--sp-4); }
}

/* WP admin bar offset for FIXED-position elements (nav + reading-progress).
 * WordPress already pushes the document via `html { margin-top: 32px !important }`
 * so body content shifts automatically. Fixed elements need their own top offset. */
body.admin-bar .dh-nav { top: calc(var(--nav-top, 12px) + 32px); }
body.admin-bar .dh-rpb { top: 32px; }
@media (max-width: 782px) {
	body.admin-bar .dh-nav { top: calc(var(--nav-top, 12px) + 46px); }
	body.admin-bar .dh-rpb { top: 46px; }
}
/* Below 600px WP renders the admin bar non-fixed, so the offset must collapse. */
@media (max-width: 600px) {
	body.admin-bar .dh-nav { top: var(--nav-top, 12px); }
	body.admin-bar .dh-rpb { top: 0; }
}

/* Skip link — accessible focus target */
.skip-link {
	position: absolute;
	left: -9999px;
	top: auto;
	width: 1px;
	height: 1px;
	overflow: hidden;
}
.skip-link:focus {
	left: var(--sp-4);
	top: var(--sp-4);
	width: auto;
	height: auto;
	padding: var(--sp-2) var(--sp-4);
	background: var(--bg-card);
	color: var(--fg);
	border: 2px solid var(--accent);
	border-radius: var(--r-sm);
	z-index: 100000;
}

/* WP alignment helpers inside flow content */
.alignwide   { max-width: var(--max-w-wide); margin-inline: auto; }
.alignfull   { max-width: 100%; }
.aligncenter { display: block; margin-inline: auto; }
.alignleft   { float: left;  margin-right: var(--sp-4); }
.alignright  { float: right; margin-left:  var(--sp-4); }

/* Compensate for fixed .dh-nav so the first content does not slide under it */
.site-content {
	padding-top: calc(var(--nav-height, 64px) + var(--nav-top, 12px) + var(--sp-8));
}

/* Lock body scroll while the mobile nav drawer is open */
body.dh-drawer-open {
	overflow: hidden;
}

/* Archive header block (used on home.php, archive.php, search.php) */
.dh-archive-head {
	margin-bottom: var(--sp-8);
	max-width: var(--max-w-narrow);
}
.dh-archive-head .dh-eyebrow { margin-bottom: var(--sp-2); }
.dh-archive-head .dh-h1      { margin: 0 0 var(--sp-3); }
.dh-archive-head .dh-archive-desc { margin: 0; }

/* Slight top spacing for filter-bar inside an archive */
.site-main > .dh-tag-filter { margin-bottom: var(--sp-8); }

/* Pagination spacing */
.site-main > .dh-pagination { margin-top: var(--sp-12); }

/* Breadcrumb spacing inside main */
.site-main > .dh-breadcrumb { margin-bottom: var(--sp-6); }

/* Home icon: visual centroid sits below geometric center of its 20x20 viewBox.
   Nudge it up so it optically aligns with mono label baseline. */
.dh-breadcrumb .bc-home-icon { transform: translateY(-1px); }

/* Article hero (DS dh-ah2) is a full-width band: cancel the `.site-content`
 * gutters so its own background/border/padding span viewport-to-viewport. */
.site-content > .dh-ah2 {
	margin-inline: calc(-1 * (var(--sp-4) + var(--nav-h-pad, 20px)));
	margin-bottom: var(--sp-12);
}
/* On mobile .site-content padding is reduced to sp-4 (16px), so the negative
 * margin must match. Placed AFTER the non-media rule so mobile wins cascade. */
@media (max-width: 768px) {
	.site-content > .dh-ah2 {
		margin-inline: calc(-1 * var(--sp-4));
	}
}

/* Landing-page mode: page contains datahints/hero or other layout blocks.
 * `.site-main.is-layout-blocks` drops the 1200px max-width / padding so
 * blocks span the full viewport and self-style. The negative margin
 * cancels the `.site-content` gutters too. */
body.page .site-main.is-layout-blocks {
	max-width: none;
	padding: 0;
	margin-inline: calc(-1 * (var(--sp-4) + var(--nav-h-pad, 20px)));
}
@media (max-width: 768px) {
	body.page .site-main.is-layout-blocks {
		margin-inline: calc(-1 * var(--sp-4));
	}
}
.site-main.is-layout-blocks > .dh-hero,
.site-main.is-layout-blocks > .dh-services,
.site-main.is-layout-blocks > .dh-cases,
.site-main.is-layout-blocks > .kpi-bar {
	margin-block: 0;
}

/* Page head (prose mode pages) */
.dh-page-head {
	max-width: var(--max-w-narrow);
	margin: 0 auto var(--sp-10);
}
.dh-page-head .dh-h1 { margin: 0; }

/* Single posts: hero owns its own top padding (sp-24 = 96px) which clears
 * the floating nav, so the page-level top gutter is unnecessary. Drop it
 * so the hero's bg image runs flush to the viewport top. */
body.single .site-content { padding-top: 0; }

/* Component overrides (`.dh-ah2`, `.dh-rpb`, `.dh-post-media`,
 * `.dh-ah2--media-compact`, `.dh-ah2--no-ribbon`) live in
 * `assets/theme/theme-overrides.css` so they load AFTER the
 * context-aware DS components and win the cascade without `!important`. */

/* Useful-links section: center to align with prose column. */
.dh-post-useful { margin-inline: auto; }

/* Single-post layout: 3-column grid on .site-main itself.
 * - All "central" elements (article, pagination) live in column 2 which is
 *   exactly max-w-narrow, centered to viewport. This matches .article-hero-inner
 *   above the fold, so the entire vertical spine is aligned.
 * - TOC sidebar lives in column 3, sticky-positioned, doesn't affect the
 *   center column. On narrow viewports the grid collapses to 1 column. */
body.single .site-main.has-aside {
	display: grid;
	grid-template-columns:
		minmax(0, 1fr)
		min(var(--max-w-narrow), 100%)
		minmax(0, 1fr);
	column-gap: var(--sp-8);
	max-width: var(--max-w-wide);
	margin-inline: auto;
}
body.single .site-main.has-aside > * { grid-column: 2; }
body.single .site-main.has-aside > .dh-post-aside {
	grid-column: 1;
	grid-row: 1;
	justify-self: end;
	/* No align-self: stretch (default) so the aside box matches the
	 * article row height. This gives `.toc-sticky` inside enough scroll
	 * headroom to actually behave as sticky. */
	max-width: 280px;
	width: 100%;
}

/* Sticky TOC clears the fixed nav with breathing room.
 * `--toc-top-gap` aggregates nav clearance, admin-bar (logged-in only),
 * and a comfortable breathing-room gap. */
body.single .site-main {
	--toc-top-gap: calc(var(--nav-height, 64px) + var(--nav-top, 12px) + var(--sp-10));
}
body.admin-bar.single .site-main { --toc-top-gap: calc(var(--nav-height, 64px) + var(--nav-top, 12px) + var(--sp-10) + 32px); }
@media (max-width: 782px) {
	body.admin-bar.single .site-main { --toc-top-gap: calc(var(--nav-height, 64px) + var(--nav-top, 12px) + var(--sp-10) + 46px); }
}
@media (max-width: 600px) {
	body.admin-bar.single .site-main { --toc-top-gap: calc(var(--nav-height, 64px) + var(--nav-top, 12px) + var(--sp-10)); }
}

body.single .site-main .toc-sticky {
	position: sticky;
	top: var(--toc-top-gap);
	max-height: calc(100vh - var(--toc-top-gap) - var(--sp-6));
	overflow-y: auto;
}

@media (max-width: 1023px) {
	body.single .site-main.has-aside {
		grid-template-columns: minmax(0, 1fr);
		column-gap: 0;
	}
	/* Reset all children from grid-column:2 (desktop) to column 1.
	 * Without this, article/pagination fall into an implicit column 2
	 * and overflow off-screen on mobile. */
	body.single .site-main.has-aside > * {
		grid-column: 1;
	}
	body.single .site-main.has-aside > .dh-post-aside {
		grid-row: auto;
		max-width: var(--max-w-narrow);
		margin-inline: auto;
	}
	body.single .site-main.has-aside {
		padding-top: var(--sp-5);
	}
	body.single .site-main .toc-sticky {
		position: static;
		max-height: none;
		overflow-y: visible;
		margin-bottom: var(--sp-8);
	}
}

/* Anchor scroll offset: when user clicks a TOC link or follows a #anchor
 * URL, the target scrolls under the fixed nav. Add scroll-margin-top so
 * the heading lands just below the nav. This also makes IntersectionObserver
 * scroll-spy report the correct active section. */
.dh-prose :is(h2, h3, h4),
.dh-section-anchor {
	scroll-margin-top: calc(var(--nav-height, 64px) + var(--nav-top, 12px) + var(--sp-4));
}
body.admin-bar .dh-prose :is(h2, h3, h4),
body.admin-bar .dh-section-anchor {
	scroll-margin-top: calc(var(--nav-height, 64px) + var(--nav-top, 12px) + var(--sp-4) + 32px);
}
@media (max-width: 782px) {
	body.admin-bar .dh-prose :is(h2, h3, h4),
	body.admin-bar .dh-section-anchor {
		scroll-margin-top: calc(var(--nav-height, 64px) + var(--nav-top, 12px) + var(--sp-4) + 46px);
	}
}
@media (max-width: 600px) {
	body.admin-bar .dh-prose :is(h2, h3, h4),
	body.admin-bar .dh-section-anchor {
		scroll-margin-top: calc(var(--nav-height, 64px) + var(--nav-top, 12px) + var(--sp-4));
	}
}

/* Inline share-bar at the end of the article: cap to prose width and
 * separate from preceding content. */
.dh-post .dh-share-bar.share-bar-inline {
	max-width: var(--max-w-narrow);
	margin: var(--sp-12) auto 0;
	padding-top: var(--sp-6);
	border-top: 1px solid var(--border);
}

/* Single-post head and byline (Phase 5.2 placeholder until article-hero lands) */
.dh-post-head {
	max-width: var(--max-w-narrow);
	margin: 0 0 var(--sp-10);
}
.dh-post-head .dh-eyebrow { margin-bottom: var(--sp-2); }
.dh-post-head .dh-h1      { margin: 0 0 var(--sp-4); }
.dh-post-head .dh-subtitle { margin: 0 0 var(--sp-6); }
.dh-post-head .dh-post-format-tag { margin: 0 0 var(--sp-4); }

.dh-post-byline {
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	flex-wrap: wrap;
	font-family: var(--font-mono);
	font-size: 0.75rem;
	color: var(--fg-3);
	margin-top: var(--sp-4);
}
.dh-post-byline .dh-author-card { margin: 0; }
.dh-meta-sep  { opacity: 0.5; }
.dh-meta-item { white-space: nowrap; }

/* Article body width — narrow column for prose readability,
 * centered to align with .article-hero-inner above the fold. */
.dh-prose { max-width: var(--max-w-narrow); margin-inline: auto; }

/* Useful-links section spacing */
.dh-post-useful {
	max-width: var(--max-w-narrow);
	margin-top: var(--sp-12);
}
.dh-post-useful .dh-h3 { margin: 0 0 var(--sp-4); }

/* Prev/next post navigation: constrain to article-body width and let DS
 * `space-between + max-width: 340px` keep both buttons compact and balanced.
 * `min-width: 0` on the inline-flex button is required so the child title
 * actually picks up DS's `text-overflow: ellipsis` instead of overflowing. */
.site-main > .dh-pagination-simple {
	width: 100%;
	max-width: var(--max-w-narrow);
	margin-inline: auto;
	margin-top: var(--sp-16);
}
/* DS caps each button at 340px which leaves a wide gap and makes the
 * pair look narrower than the article column. Remove the cap so each
 * button grows to fill its half of the article column. */
.dh-pagination-simple .pg-simple-btn { min-width: 0; max-width: none; }
/* Text block must fill the button so right-aligned content in pg-next sits
 * at the right edge, not the left. Without flex:1 the block shrinks to
 * content width and the button looks empty on short titles. */
.dh-pagination-simple .pg-simple-text { flex: 1; }
/* `pg-simple-text--right` uses `align-items: flex-end`, which shrinks
 * children to intrinsic width and breaks `text-overflow: ellipsis` on the
 * title. Stretch the title back to fill its parent so truncation works. */
.dh-pagination-simple .pg-simple-title { align-self: stretch; }

/* Mobile: stack prev/next buttons vertically, full width.
 * flex-direction:column + flex-wrap:wrap (DS) makes buttons size by content.
 * flex-basis:100% forces each button to its own row in the existing row layout. */
@media (max-width: 600px) {
	.site-main > .dh-pagination-simple .pg-simple-btn {
		flex-basis: 100%;
	}
	/* Cancel DS margin-left:auto that right-aligns a lone next button. */
	.site-main > .dh-pagination-simple .pg-simple-btn.pg-next:only-child {
		margin-left: 0;
	}
}

/* Mobile share bar: move label to its own row so all 3 action buttons
 * fit on a single line below it. */
@media (max-width: 600px) {
	.dh-post .dh-share-bar.share-bar-inline {
		width: 100%;
	}
	.dh-post .dh-share-bar.share-bar-inline .share-label {
		flex: 0 0 100%;
		margin-bottom: var(--sp-1);
	}
	.dh-post .dh-share-bar.share-bar-inline .share-divider {
		display: none;
	}
}

/* ── Footer nav: mobile accordion ──────────────────────────────────
 * Trigger is a real <button> (`.dh-footer-col-toggle`) — keyboard, focus
 * ring, and aria-expanded come for free. The collapse animation uses the
 * `grid-template-rows: 0fr → 1fr` pattern so any number of links fits
 * without the brittle `max-height: 400px` hack. */

/* Toggle is mobile-only by default. */
.dh-footer-col-toggle {
	display: none;
}

/* Desktop / tablet: panel is always rendered, no transition needed. */
.dh-footer-panel { display: contents; }

@media (max-width: 599px) {
	.dh-footer-nav {
		grid-template-columns: 1fr;
		gap: 0;
		border-top: 1px solid var(--border-s);
	}
	.dh-footer-col-title {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: var(--sp-3);
		padding: var(--sp-4) 0;
		border-bottom: 1px solid var(--border-s);
		margin-bottom: 0;
	}
	.dh-footer-col-toggle {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		width: 36px;
		height: 36px;
		margin: calc(var(--sp-2) * -1) calc(var(--sp-2) * -1) calc(var(--sp-2) * -1) auto;
		padding: 0;
		background: none;
		border: none;
		color: var(--fg-3);
		cursor: pointer;
		border-radius: var(--r-sm);
	}
	.dh-footer-col-toggle:focus-visible {
		outline: 2px solid var(--accent);
		outline-offset: 2px;
	}
	.dh-footer-col-toggle svg {
		transition: transform 0.2s ease;
	}
	.dh-footer-col.is-open > .dh-footer-col-title .dh-footer-col-toggle svg {
		transform: rotate(180deg);
	}
	@media (prefers-reduced-motion: reduce) {
		.dh-footer-col-toggle svg { transition: none; }
	}

	/* Collapse via `grid-template-rows: 0fr → 1fr`. Inner element absorbs
	 * the row with `min-height: 0; overflow: hidden`. Replaces the previous
	 * `max-height: 400px` which silently truncated long columns.
	 *
	 * IMPORTANT: padding on the grid item (`.dh-footer-links`) MUST be 0 in
	 * the collapsed state. Even with `min-height: 0`, padding contributes to
	 * the box height and the row track does not shrink past `padding-top + padding-bottom`,
	 * which leaves the first link peeking through the next column's title. */
	.dh-footer-panel {
		display: grid;
		grid-template-rows: 0fr;
		transition: grid-template-rows 0.3s ease;
	}
	.dh-footer-col.is-open > .dh-footer-panel {
		grid-template-rows: 1fr;
	}
	.dh-footer-panel > .dh-footer-links {
		min-height: 0;
		overflow: hidden;
		padding-top: 0;
		padding-bottom: 0;
		transition: padding 0.3s ease;
	}
	.dh-footer-col.is-open > .dh-footer-panel > .dh-footer-links {
		padding-top: var(--sp-2);
		padding-bottom: var(--sp-4);
	}
	@media (prefers-reduced-motion: reduce) {
		.dh-footer-panel,
		.dh-footer-panel > .dh-footer-links { transition: none; }
	}
}
