/*
Theme Name: TechProMaster
Theme URI: https://example.com/techpromaster
Author: TechProMaster Team
Author URI: https://example.com
Description: A production-grade WordPress theme for technology education platforms and digital template marketplaces, featuring full WooCommerce integration, dark mode, dynamic platform statistics, and a complete content publishing system.
Version: 2.1.23
Requires at least: 6.0
Requires PHP: 8.1
Tested up to: 6.6
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: techpromaster
Tags: e-commerce, education, blog, one-column, two-columns, right-sidebar, custom-menu, featured-images, translation-ready, dark-mode, accessibility-ready
*/

/* =========================================================
   1. DESIGN TOKENS (CSS Custom Properties)
   Consumed by: assets/css/components.css, woocommerce.css,
   and assets/js/main.js (customizer preview reads these via
   getComputedStyle where needed).
   ========================================================= */
:root {
	/* Brand */
	--tpm-color-primary: #2563eb;
	--tpm-color-primary-dark: #1d4ed8;
	--tpm-color-primary-light: #60a5fa;

	/* Neutrals (light mode) */
	--tpm-color-bg: #fff;
	--tpm-color-bg-alt: #f8fafc;
	--tpm-color-surface: #fff;
	--tpm-color-border: #e2e8f0;
	--tpm-color-text: #0f172a;
	--tpm-color-text-muted: #64748b;

	/* Status */
	--tpm-color-success: #16a34a;
	--tpm-color-danger: #dc2626;

	/* Hero gradient (per SCREENSHOT_BUILD.md) */
	--tpm-hero-gradient: linear-gradient(180deg, #f8fafc 0%, #fff 100%);

	/* Type */
	--tpm-font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	--tpm-font-heading: var(--tpm-font-body);

	/* Spacing scale */
	--tpm-space-1: 4px;
	--tpm-space-2: 8px;
	--tpm-space-3: 16px;
	--tpm-space-4: 24px;
	--tpm-space-5: 32px;
	--tpm-space-6: 48px;
	--tpm-space-7: 72px;

	/* Radius / shadow */
	--tpm-radius: 8px;
	--tpm-radius-lg: 16px;
	--tpm-shadow: 0 1px 3px rgba(15, 23, 42, 0.08), 0 1px 2px rgba(15, 23, 42, 0.06);

	/* Layout */
	--tpm-container-width: 1200px;
	/*
	 * Wider than --tpm-container-width on purpose — see the
	 * "Root cause of 'menu items truncated'" comment on
	 * .tpm-header .tpm-container below. Only the header uses this; every
	 * other .tpm-container (articles, card grids, footer) keeps the
	 * narrower, shared reading-width constant above.
	 */
	--tpm-header-container-width: 1440px;
	--tpm-header-height: 72px;
}

[data-theme="dark"] {
	--tpm-color-bg: #0f172a;
	--tpm-color-bg-alt: #111827;
	--tpm-color-surface: #1e293b;
	--tpm-color-border: #334155;
	--tpm-color-text: #f1f5f9;
	--tpm-color-text-muted: #94a3b8;
	--tpm-hero-gradient: linear-gradient(180deg, #111827 0%, #0f172a 100%);
}

/* =========================================================
   2. RESET / BASE
   ========================================================= */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
	margin: 0;
	font-family: var(--tpm-font-body);
	font-size: var(--tpm-font-base-size, 16px);
	color: var(--tpm-color-text);
	background: var(--tpm-color-bg);
	line-height: 1.6;
	transition: background-color .2s ease, color .2s ease;
}

img { max-width: 100%; height: auto; display: block; }

a { color: var(--tpm-color-primary); text-decoration: none; }
a:hover, a:focus { text-decoration: underline; }

/*
 * Default link color (--tpm-color-primary, #2563eb) measures ~3.45:1 against
 * the dark-mode background (#0f172a) — below WCAG AA's 4.5:1 for text.
 * --tpm-color-primary-light (#60a5fa) measures ~7.02:1 on the same background.
 * :where() keeps this at the same specificity as the plain `a` rule above, so
 * it only affects links that don't already have their own color (body content,
 * footer nav, social links) — every component class (.tpm-menu-link,
 * .tpm-mega-link, .tpm-card-title a, buttons, etc.) already sets its own
 * explicit color and continues to win the cascade unchanged.
 */
:where([data-theme="dark"]) a {
	color: var(--tpm-color-primary-light);
}

h1, h2, h3, h4, h5, h6 {
	font-family: var(--tpm-font-heading);
	line-height: 1.2;
	margin: 0 0 var(--tpm-space-3);
	color: var(--tpm-color-text);
}

.screen-reader-text {
	position: absolute !important;
	width: 1px; height: 1px;
	overflow: hidden;
	clip: rect(1px, 1px, 1px, 1px);
	white-space: nowrap;
}

.screen-reader-text:focus {
	position: static !important;
	width: auto; height: auto;
	clip: auto;
}

.tpm-container {
	max-width: var(--tpm-container-width);
	margin: 0 auto;
	padding: 0 var(--tpm-space-4);
}

/* =========================================================
   3. BUTTONS
   ========================================================= */
.tpm-btn {
	display: inline-flex;
	align-items: center;
	gap: var(--tpm-space-2);
	padding: var(--tpm-space-2) var(--tpm-space-4);
	border-radius: var(--tpm-radius);
	font-weight: 600;
	border: 1px solid transparent;
	cursor: pointer;
	text-decoration: none;
	transition: transform 0.1s ease;
}

/* Subtle press feedback — previously buttons had hover/focus states but nothing distinguished an active click from a hover. */
.tpm-btn:active {
	transform: scale(0.98);
}

@media (prefers-reduced-motion: reduce) {
	.tpm-btn:active { transform: none; }
}

.tpm-btn-primary {
	background: var(--tpm-color-primary);
	color: #fff;
}

.tpm-btn-primary:hover, .tpm-btn-primary:focus {
	background: var(--tpm-color-primary-dark);
	text-decoration: none;
	color: #fff;
}

.tpm-btn-secondary {
	background: transparent;
	border-color: var(--tpm-color-border);
	color: var(--tpm-color-text);
}

.tpm-btn-secondary:hover, .tpm-btn-secondary:focus {
	border-color: var(--tpm-color-primary);
	text-decoration: none;
}

.tpm-btn-small {
	padding: var(--tpm-space-1) var(--tpm-space-3);
	font-size: 0.8125rem;
}

/* =========================================================
   4. HEADER
   ========================================================= */
.tpm-header {
	height: var(--tpm-header-height);
	display: flex;
	align-items: center;
	border-bottom: 1px solid var(--tpm-color-border);
	position: sticky;
	top: 0;
	z-index: 100;
	transition: box-shadow 0.2s ease;
}

/*
 * Background + blur live on a pseudo-element rather than directly on
 * .tpm-header. backdrop-filter (like transform/filter/will-change)
 * establishes a new CSS containing block for any position:fixed
 * descendant — and .tpm-primary-nav (the mobile off-canvas panel) and
 * #tpm-nav-overlay are both descendants of .tpm-header. With the filter
 * on .tpm-header itself, their `top`/`bottom` offsets resolved against
 * .tpm-header's own 72px box instead of the viewport, collapsing the
 * open mobile menu to zero height. Moving the same background/blur onto
 * ::before (which has no descendants of its own) keeps .tpm-header
 * itself filter-free, so position:fixed children correctly escape to
 * the viewport again. Visual output is unchanged.
 */
.tpm-header::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: rgba(255, 255, 255, 0.8);
	backdrop-filter: saturate(180%) blur(12px);
	-webkit-backdrop-filter: saturate(180%) blur(12px);
}

[data-theme="dark"] .tpm-header::before {
	background: rgba(15, 23, 42, 0.75);
}

.tpm-header.is-scrolled {
	box-shadow: 0 4px 24px rgba(15, 23, 42, 0.06);
}

.tpm-header .tpm-container {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: center;
	width: 100%;
	column-gap: var(--tpm-space-4);
	/*
	 * Root cause of "menu items truncated" (verified with a real-browser
	 * layout test, not assumed): .tpm-container's max-width
	 * (--tpm-container-width, 1200px — the site's shared reading-width
	 * constant, used everywhere from articles to card grids) was also
	 * capping the *header's* available width. At 1200px, the six primary
	 * nav items plus the full WooCommerce header actions (search, Login,
	 * Create Account, cart, theme toggle) need more horizontal room than
	 * is left over once the logo and actions are accounted for — so
	 * .tpm-primary-nav's flex-shrink + text-overflow:ellipsis safety net
	 * (added to guarantee zero horizontal overflow/scrollbar, and still
	 * doing its job) was visibly kicking in on real menus, exactly
	 * matching the "Prompt Engineering" / "Guides & Tutorials" truncation
	 * report. This reproduced identically at 1280–1920px browser widths,
	 * because .tpm-container's max-width caps out at 1200px regardless of
	 * viewport — a wider monitor was never going to fix it on its own.
	 *
	 * Fix: give the header's own container more width than the
	 * site's shared reading-width constant, instead of changing
	 * --tpm-container-width itself (which every other .tpm-container on
	 * the site — article content, card grids, footer — deliberately
	 * shares, for consistent reading-width alignment; widening it
	 * globally would be a much bigger, unrelated visual change). This
	 * override only applies where .tpm-container is a direct descendant
	 * of .tpm-header.
	 */
	max-width: var(--tpm-header-container-width);
}

.tpm-logo {
	font-size: 1.25rem;
	font-weight: 800;
	color: var(--tpm-color-text);
	justify-self: start;
}
.tpm-logo .tpm-logo-accent { color: var(--tpm-color-primary); }

/*
 * Primary nav: perfectly centered regardless of logo/actions width.
 * The child combinator (>) is deliberate — #primary-menu is the only
 * direct-child <ul> of .tpm-primary-nav. Without it, this descendant
 * selector also matched .tpm-mega-grid and .tpm-mega-col-links (both
 * <ul> elements nested deeper inside), forcing display:flex on them and
 * silently overriding their own display:grid/flex-direction rules in
 * components.css (equal specificity, but this rule's extra type selector
 * gave it (0,1,1) vs. their (0,1,0)) — the CSS-cascade root cause of the
 * squeezed mobile mega-menu columns.
 */

/*
 * Nav dropdown regression fix (this milestone): P1.21's "no-scrollbar fix"
 * put `overflow: hidden` directly on `.tpm-primary-nav`. That container is
 * also the DOM ancestor of every mega-menu dropdown panel
 * (.tpm-mega-panel — a descendant of the <li>, which is a descendant of
 * this element), and an `overflow: hidden` ancestor clips ALL descendant
 * painting/hit-testing that escapes its box — including absolutely
 * positioned descendants. Since `.tpm-primary-nav` itself is only ever as
 * tall as a single line of nav links (~40px), every dropdown panel
 * (top:100%, height ~200px+) was being clipped away below that 40px line:
 * invisible, and — critically — un-hittable by the mouse, so moving the
 * cursor from a trigger down into "the dropdown" actually moved it onto
 * whatever real page content sat behind the (invisible) panel, firing
 * mouseleave on the trigger and closing the menu. This is the confirmed
 * root cause of "dropdown doesn't open reliably" / "closes when the
 * cursor moves into it" (verified with a real-browser hover test: the
 * element under the cursor inside the dropdown's visual area was the page
 * background, not the panel).
 *
 * Fix: remove the clipping. No-scrollbar protection does not actually
 * depend on `overflow: hidden` here — it comes from the flex-shrink +
 * min-width:0 chain below (#primary-menu > li, each .tpm-menu-link's
 * fluid clamp() padding/gap, text-overflow:ellipsis) which was verified,
 * with a real headless-browser layout test, to shrink every item to fit
 * any available width with zero overflow on its own. `overflow: hidden`
 * was never load-bearing for that guarantee and is not reintroduced here;
 * the equivalent protection for the mobile off-canvas drawer (where no
 * dropdown needs to escape the container) is scoped locally to that
 * media query below instead.
 */
.tpm-primary-nav {
	justify-self: center;
	min-width: 0;
	max-width: 100%;
	overflow: visible;
}

.tpm-primary-nav > ul {
	list-style: none;
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	gap: clamp(0px, 1.2vw, var(--tpm-space-1));
	margin: 0;
	padding: 0;
	min-width: 0;
}

.tpm-primary-nav > ul > li {
	min-width: 0;
	flex-shrink: 1;
}

.tpm-menu-link {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 4px;
	max-width: 100%;
	overflow: hidden;
	color: var(--tpm-color-text);
	font-weight: 500;
	font-size: 0.9375rem;
	letter-spacing: -0.006em;
	padding: 8px clamp(8px, 1.4vw, var(--tpm-space-3));
	border-radius: var(--tpm-radius);
	white-space: nowrap;
	text-overflow: ellipsis;
	transition: background-color 0.2s cubic-bezier(0.4, 0, 0.2, 1),
		color 0.2s cubic-bezier(0.4, 0, 0.2, 1),
		transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.tpm-menu-link:hover,
.tpm-menu-link:focus-visible {
	background: var(--tpm-color-bg-alt);
	color: var(--tpm-color-primary);
	text-decoration: none;
	transform: translateY(-1px);
}

.tpm-menu-link:focus-visible {
	outline: 2px solid var(--tpm-color-primary);
	outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
	.tpm-menu-link:hover,
	.tpm-menu-link:focus-visible {
		transform: none;
	}
}

/*
 * Active/current-page indicator (P1.19): previously a flat bg-alt fill
 * identical to the plain :hover state, so "you are here" was only ever
 * visible by coincidence of the mouse being over it. Replaced with a
 * lightweight underline accent — visible at rest without a filled block,
 * the "obvious without looking heavy" premium-nav pattern (Stripe docs,
 * Linear, GitHub tabs). Color contrast is unchanged from before: same
 * --tpm-color-primary text on --tpm-color-bg, which is a lighter
 * background than the bg-alt fill previously used at rest, so contrast
 * can only be equal or better.
 */
.tpm-menu-link[aria-current="page"] {
	color: var(--tpm-color-primary);
}

.tpm-menu-link[aria-current="page"]::after {
	content: '';
	position: absolute;
	left: var(--tpm-space-3);
	right: var(--tpm-space-3);
	bottom: 4px;
	height: 2px;
	border-radius: 1px;
	background: var(--tpm-color-primary);
}

/*
 * Dark-mode text-contrast fix (P1.20): computed via real WCAG relative-
 * luminance math (not estimated) that --tpm-color-primary (#2563eb) on the
 * dark-mode background (#0f172a) measures 3.45:1 — clears the 3:1 non-text/
 * UI-component threshold (so the ::after underline above is compliant as
 * decorative UI, unchanged), but fails the 4.5:1 threshold that applies to
 * this element's own text. P1.16 already found and fixed this exact
 * token/background combination for the generic `a` selector but explicitly
 * excluded .tpm-menu-link (and by extension the P1.19 tpm-nav-primary
 * treatment, which reuses the same token) — that gap is closed here using
 * the same --tpm-color-primary-light substitution already proven at
 * ~7.02:1 for the generic-link fix.
 */
[data-theme="dark"] .tpm-menu-link[aria-current="page"] {
	color: var(--tpm-color-primary-light);
}

[data-theme="dark"] .tpm-menu-link[aria-current="page"]::after {
	background: var(--tpm-color-primary-light);
}

/*
 * Marketplace / primary destination emphasis (P1.19): no menu IDs or
 * titles are hardcoded here. WordPress already exposes a native, admin-only
 * opt-in mechanism — the "CSS Classes" field on a menu item in
 * Appearance > Menus (Screen Options > CSS Classes) — and
 * TechProMaster_Nav_Walker (inc/walkers.php) already passes $item->classes
 * straight through onto the top-level <li> unmodified (verified: no walker
 * change was needed for this). An admin adds the class `tpm-nav-primary`
 * to whichever top-level item should read as the site's main destination
 * (e.g. "Marketplace") and gets this treatment automatically; nothing here
 * assumes a specific label, language, or menu structure. Deliberately a
 * soft tinted pill rather than a solid filled button, so it reads as "the
 * primary link" rather than an ad/CTA block competing with real content.
 */
.tpm-menu-item.tpm-nav-primary .tpm-menu-link {
	color: var(--tpm-color-primary);

	/* rgba(37,99,235,...) is --tpm-color-primary (#2563eb) decomposed to an
	   rgb triplet — matches this file's existing convention for translucent
	   color effects (see --tpm-shadow above and .tpm-search-panel etc.),
	   which uses plain rgba() throughout rather than color-mix(). If
	   --tpm-color-primary's hex value ever changes, this triplet needs
	   updating alongside it. */
	background: rgba(37, 99, 235, 0.08);
	font-weight: 600;
}

.tpm-menu-item.tpm-nav-primary .tpm-menu-link:hover,
.tpm-menu-item.tpm-nav-primary .tpm-menu-link:focus-visible {
	background: rgba(37, 99, 235, 0.14);
}

.tpm-menu-item.tpm-nav-primary .tpm-menu-link[aria-current="page"]::after {
	background: var(--tpm-color-primary);
}

/*
 * Dark-mode text-contrast fix (P1.20), continued from above: the light-mode
 * .tpm-nav-primary rules directly above this comment are all higher
 * specificity than a same-depth [data-theme="dark"] rule would be (each is
 * already 3-4 classes deep), so each override here repeats the full
 * selector chain with [data-theme="dark"] prepended rather than a shorter
 * one — a shorter override would silently lose to the light-mode rule above
 * it and this fix would appear to do nothing in dark mode.
 */
[data-theme="dark"] .tpm-menu-item.tpm-nav-primary .tpm-menu-link {
	color: var(--tpm-color-primary-light);
	background: rgba(96, 165, 250, 0.1);
}

[data-theme="dark"] .tpm-menu-item.tpm-nav-primary .tpm-menu-link:hover,
[data-theme="dark"] .tpm-menu-item.tpm-nav-primary .tpm-menu-link:focus-visible {
	background: rgba(96, 165, 250, 0.16);
}

[data-theme="dark"] .tpm-menu-item.tpm-nav-primary .tpm-menu-link[aria-current="page"]::after {
	background: var(--tpm-color-primary-light);
}

.tpm-menu-chevron {
	width: 14px;
	height: 14px;
	transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.tpm-menu-item--has-children.is-open .tpm-menu-chevron,
.tpm-menu-link[aria-expanded="true"] .tpm-menu-chevron {
	transform: rotate(180deg);
}

.tpm-header-actions {
	display: flex;
	align-items: center;
	gap: var(--tpm-space-3);
	justify-self: end;
}

.tpm-icon-btn {
	background: none;
	border: none;
	cursor: pointer;
	color: var(--tpm-color-text);
	padding: var(--tpm-space-1);
	display: inline-flex;
	border-radius: var(--tpm-radius);
	transition: background-color 0.15s ease;
}

/*
 * Icon-button hover color (P1.21 / Issue 7): light mode previously only
 * changed the background on hover — color stayed at --tpm-color-text — so
 * the search and day/night-toggle icon buttons gave no color feedback at
 * all in light mode, reading as visually "off"/inconsistent next to every
 * other hoverable control in the header (.tpm-menu-link, .tpm-topic-pill,
 * etc.), which all switch to --tpm-color-primary on hover. Dark mode's
 * existing look is preserved exactly via the override directly below —
 * only light mode gains the blue hover color.
 */
.tpm-icon-btn:hover,
.tpm-icon-btn:focus-visible {
	background: var(--tpm-color-bg-alt);
	color: var(--tpm-color-primary);
}

[data-theme="dark"] .tpm-icon-btn:hover,
[data-theme="dark"] .tpm-icon-btn:focus-visible {
	/* Unchanged from before this fix: dark mode keeps its current (correct, per spec) hover behavior — background swap only, no color change. */
	color: var(--tpm-color-text);
}

.tpm-icon-btn:focus-visible {
	outline: 2px solid var(--tpm-color-primary);
	outline-offset: 2px;
}

/*
 * Theme toggle: show only the icon for the *other* mode (sun while in
 * dark mode = "switch to light", moon while in light mode = "switch to
 * dark"). Previously nothing hid either icon, so both rendered
 * side-by-side at once, silently doubling the button's width.
 */
.tpm-icon-moon { display: none; }
[data-theme="dark"] .tpm-icon-sun { display: none; }
[data-theme="dark"] .tpm-icon-moon { display: block; }

/* Animated hamburger — hidden on desktop/tablet, shown on mobile (media query below). */
.tpm-hamburger {
	display: none;
	flex-direction: column;
	justify-content: center;
	gap: 5px;
	width: 40px;
	height: 40px;
	background: none;
	border: none;
	cursor: pointer;
	padding: 0;
	border-radius: var(--tpm-radius);
}

.tpm-hamburger:focus-visible {
	outline: 2px solid var(--tpm-color-primary);
	outline-offset: 2px;
}

.tpm-hamburger-line {
	display: block;
	width: 20px;
	height: 2px;
	margin: 0 auto;
	background: var(--tpm-color-text);
	border-radius: 2px;
	transition: transform 0.25s ease, opacity 0.25s ease;
}

.tpm-hamburger[aria-expanded="true"] .tpm-hamburger-line:nth-child(1) {
	transform: translateY(7px) rotate(45deg);
}

.tpm-hamburger[aria-expanded="true"] .tpm-hamburger-line:nth-child(2) {
	opacity: 0;
}

.tpm-hamburger[aria-expanded="true"] .tpm-hamburger-line:nth-child(3) {
	transform: translateY(-7px) rotate(-45deg);
}

/*
 * Header — Login/Account + Cart (RC Priority 1 & 4).
 * Lives in style.css (loaded on every page, not just WooCommerce ones)
 * since the header itself is global — see inc/enqueue.php.
 */
.tpm-header-account {
	position: relative;
	display: flex;
	align-items: center;
	gap: var(--tpm-space-2);
}

.tpm-header-login,
.tpm-header-signup,
.tpm-header-account-trigger {
	display: inline-flex;
	align-items: center;
	gap: var(--tpm-space-1);
	background: none;
	border: none;
	cursor: pointer;
	color: var(--tpm-color-text);
	padding: var(--tpm-space-1) var(--tpm-space-2);
	border-radius: var(--tpm-radius);
	font: inherit;
	font-weight: 600;
	font-size: 0.9rem;
	text-decoration: none;
	transition: background-color 0.15s ease, color 0.15s ease;
}

.tpm-header-signup {
	color: var(--tpm-color-primary);
}

.tpm-header-login:hover,
.tpm-header-login:focus-visible,
.tpm-header-signup:hover,
.tpm-header-signup:focus-visible,
.tpm-header-account-trigger:hover,
.tpm-header-account-trigger:focus-visible {
	background: var(--tpm-color-bg-alt);
	color: var(--tpm-color-primary);
}

.tpm-header-login:focus-visible,
.tpm-header-signup:focus-visible,
.tpm-header-account-trigger:focus-visible,
.tpm-header-cart:focus-visible {
	outline: 2px solid var(--tpm-color-primary);
	outline-offset: 2px;
}

.tpm-header-avatar {
	width: 28px;
	height: 28px;
	border-radius: 50%;
	display: block;
}

.tpm-header-account-caret {
	width: 14px;
	height: 14px;
	transition: transform 0.15s ease;
}

.tpm-header-account-trigger[aria-expanded="true"] .tpm-header-account-caret {
	transform: rotate(180deg);
}

.tpm-account-dropdown {
	position: absolute;
	top: calc(100% + var(--tpm-space-2));
	right: 0;
	min-width: 220px;
	background: var(--tpm-color-surface);
	border: 1px solid var(--tpm-color-border);
	border-radius: var(--tpm-radius);
	box-shadow: var(--tpm-shadow);
	padding: var(--tpm-space-2);
	display: flex;
	flex-direction: column;
	gap: 2px;
	z-index: 100;
}

.tpm-account-dropdown[hidden] {
	display: none;
}

.tpm-account-dropdown a {
	display: block;
	padding: var(--tpm-space-2) var(--tpm-space-3);
	border-radius: var(--tpm-radius);
	color: var(--tpm-color-text);
	text-decoration: none;
	font-size: 0.9rem;
	white-space: nowrap;
}

.tpm-account-dropdown a:hover,
.tpm-account-dropdown a:focus-visible {
	background: var(--tpm-color-bg-alt);
	color: var(--tpm-color-primary);
}

.tpm-header-cart {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	color: var(--tpm-color-text);
	border-radius: var(--tpm-radius);
	transition: background-color 0.15s ease, color 0.15s ease;
}

.tpm-header-cart:hover,
.tpm-header-cart:focus-visible {
	background: var(--tpm-color-bg-alt);
	color: var(--tpm-color-primary);
}

.tpm-header-cart-icon {
	width: 22px;
	height: 22px;
}

.tpm-cart-count {
	position: absolute;
	top: 2px;
	right: 2px;
	min-width: 16px;
	height: 16px;
	padding: 0 3px;
	border-radius: 999px;
	background: var(--tpm-color-danger);
	color: #fff;
	font-size: 0.65rem;
	font-weight: 700;
	line-height: 16px;
	text-align: center;
}

.tpm-cart-count.is-empty {
	display: none;
}

.tpm-nav-overlay {
	position: fixed;
	inset: 0;
	background: rgba(15, 23, 42, 0.4);
	z-index: 99;
	opacity: 0;
	transition: opacity 0.2s ease;
}
.tpm-nav-overlay[hidden] { display: none; }
.tpm-nav-overlay.is-visible { opacity: 1; }

/* =========================================================
   5. HERO
   ========================================================= */
.tpm-hero {
	background: var(--tpm-hero-gradient);
	padding: clamp(48px, 10vw, var(--tpm-space-7)) 0;
	text-align: center;
}

.tpm-hero-eyebrow {
	color: var(--tpm-color-primary);
	font-weight: 700;
	font-size: 0.875rem;
	text-transform: uppercase;
	letter-spacing: 0.05em;
}

.tpm-hero h1 {
	font-size: clamp(1.75rem, 4vw, 3.25rem);
	max-width: 720px;
	margin: var(--tpm-space-3) auto;
}

.tpm-hero p {
	color: var(--tpm-color-text-muted);
	max-width: 560px;
	margin: 0 auto var(--tpm-space-4);
}

.tpm-hero-ctas {
	display: flex;
	gap: var(--tpm-space-3);
	justify-content: center;
	margin-bottom: var(--tpm-space-5);
}

.tpm-hero-stats {
	display: flex;
	flex-wrap: wrap;
	gap: var(--tpm-space-5);
	justify-content: center;
	color: var(--tpm-color-text-muted);
	font-weight: 600;
}
.tpm-hero-stats strong { color: var(--tpm-color-text); }

/* =========================================================
   6. FOOTER
   ========================================================= */
.tpm-footer {
	background: var(--tpm-color-bg-alt);
	border-top: 1px solid var(--tpm-color-border);
	padding: var(--tpm-space-6) 0 var(--tpm-space-4);
	margin-top: var(--tpm-space-7);
}

.tpm-footer-grid {
	display: grid;
	grid-template-columns: 2fr repeat(3, 1fr);
	gap: var(--tpm-space-5);
}

.tpm-footer-col h3 {
	font-size: 0.875rem;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: var(--tpm-color-text-muted);
}
.tpm-footer-col ul { list-style: none; margin: 0; padding: 0; }
.tpm-footer-col li { margin-bottom: var(--tpm-space-2); }

.tpm-footer-widgets {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--tpm-space-5);
	margin-top: var(--tpm-space-6);
	padding-top: var(--tpm-space-5);
	border-top: 1px solid var(--tpm-color-border);
}

.tpm-footer-bottom {
	margin-top: var(--tpm-space-5);
	padding-top: var(--tpm-space-4);
	border-top: 1px solid var(--tpm-color-border);
	display: flex;
	flex-wrap: wrap;
	gap: var(--tpm-space-2);
	justify-content: space-between;
	color: var(--tpm-color-text-muted);
	font-size: 0.875rem;
}

/*
 * Icon-button touch-target padding intentionally stays at the wider 1024px
 * threshold — it benefits touch users on tablets regardless of which nav
 * mode is active there, and isn't part of the hamburger/drawer mismatch
 * being fixed below. Left untouched (P1.12 Phase 2 scope: breakpoint fix
 * and overflow safety only, no incidental spacing changes).
 */
@media (max-width: 1024px) {
	.tpm-icon-btn { padding: var(--tpm-space-3); }
}

/*
 * Narrow-desktop nav headroom: the .tpm-header-container-width fix above
 * (see the "Root cause of 'menu items truncated'" comment on
 * .tpm-header .tpm-container) removes the truncation entirely from
 * ~1366px up, but at 1366px the header's own max-width already exceeds
 * the viewport, so it's just rendering at the viewport's full width with
 * no further slack to give. A stress-test menu (6 items, including the
 * two from the bug report) combined with the full WooCommerce header
 * actions (search, Login, Create Account, cart) was still ~13px short of
 * fitting without shrinking right at the 1280px floor named in the
 * requirement ("fully readable from 1280px upwards") — confirmed with a
 * real-browser layout test, not assumed. Trimming the header's own side
 * padding by 8px each side in just this range recovers 16px, comfortably
 * closing that gap without touching spacing anywhere else on the site.
 */
@media (min-width: 1025px) and (max-width: 1365px) {
	.tpm-header .tpm-container { padding-left: var(--tpm-space-3); padding-right: var(--tpm-space-3); }
}

/*
 * Unified mobile-nav breakpoint (P1.12 Phase 2): the hamburger's visibility
 * previously switched on at max-width:1024px while every rule that makes it
 * functional — the off-canvas .tpm-primary-nav position/transform, the
 * #tpm-nav-overlay show/hide, the whole drawer — only existed inside this
 * same max-width:782px block. Between 783px and 1024px the hamburger was
 * visible and clickable, and its JS correctly toggled `is-open` + the
 * overlay, but nothing here made the drawer itself appear, so tapping it
 * visibly did nothing to the nav. Moving `.tpm-hamburger`'s display rule
 * into this block — the same breakpoint as the drawer/overlay it controls —
 * closes that dead zone. Tablet widths (783-1024px) now correctly keep the
 * inline desktop-style nav (protected by the new overflow safety net above)
 * with its own trigger-anchored single-column dropdown already defined in
 * assets/css/components.css's existing 783-1024px tablet block — that CSS
 * was already correct and is unchanged; it simply wasn't reachable before
 * because the hamburger was intercepting that width range.
 */
@media (max-width: 782px) {
	.tpm-hamburger { display: flex; width: 44px; height: 44px; }

	.tpm-footer-grid { grid-template-columns: 1fr 1fr; }
	.tpm-footer-widgets { grid-template-columns: 1fr; }

	.tpm-header .tpm-container {
		grid-template-columns: auto auto;
	}
	.tpm-header-actions { order: 2; gap: var(--tpm-space-1); }

	/*
	 * Collapse Login / Create Account / the account name to icon-only
	 * compact buttons (Priority 4: "Mobile should automatically collapse
	 * Login and Cart into compact icon buttons while preserving
	 * usability"). The Login icon still links straight to the My Account
	 * page, which shows WooCommerce's native login *and* register form
	 * together, so Create Account stays reachable in one tap even though
	 * its separate text link is hidden here to save header width.
	 */
	.tpm-header-signup { display: none; }
	.tpm-header-account-label { display: none; }
	.tpm-header-login,
	.tpm-header-account-trigger {
		width: 40px;
		height: 40px;
		padding: 0;
		justify-content: center;
	}
	.tpm-header-account-icon { width: 22px; height: 22px; }
	.tpm-header-account-caret { display: none; }

	/* Keep the dropdown panel fully on-screen at narrow widths. */
	.tpm-account-dropdown {
		right: -8px;
		min-width: 200px;
	}

	/* Off-canvas panel: reuses the same <nav>/<ul> markup, no duplication. */
	.tpm-primary-nav {
		position: fixed;
		top: var(--tpm-header-height);
		left: 0;
		bottom: 0;
		width: min(320px, 85vw);
		background: var(--tpm-color-bg);
		border-right: 1px solid var(--tpm-color-border);
		overflow-y: auto;

		/*
		 * Safe here (unlike desktop/tablet, see the base .tpm-primary-nav
		 * rule above): the mobile mega panel is position:static and part of
		 * normal document flow inside this same element (an inline
		 * expandable accordion section), not an absolutely positioned
		 * escapee, so clipping the horizontal axis can never cut off a
		 * dropdown here.
		 */
		overflow-x: hidden;
		transform: translateX(-100%);
		transition: transform 0.25s ease;
		z-index: 100;
		justify-self: auto;
	}

	.tpm-primary-nav.is-open {
		transform: translateX(0);
	}

	.tpm-primary-nav ul#primary-menu {
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		padding: var(--tpm-space-3);
	}

	.tpm-menu-link {
		width: 100%;
		min-height: 44px;
		padding: 12px 14px;
	}
}

/* =========================================================
   7. SMALL PHONE (~480px and below)
   Nested inside the existing mobile experience above — only
   tightens spacing and stacks a couple of rows that stay
   side-by-side down to 782px but are too cramped below ~480px.
   Nothing here changes desktop or tablet layout.
   ========================================================= */
@media (max-width: 480px) {
	.tpm-container { padding: 0 var(--tpm-space-3); }

	.tpm-hero-ctas {
		flex-direction: column;
		align-items: stretch;
	}
	.tpm-hero-ctas .tpm-btn { justify-content: center; }
	.tpm-hero-stats { gap: var(--tpm-space-4); }

	.tpm-footer-grid { grid-template-columns: 1fr; }
	.tpm-footer-bottom { flex-direction: column; align-items: flex-start; }

	/*
	 * Header actions overflow fix (RC Priority 1).
	 * Verified via DOM measurement: at 320-375px, the ≤782px sizing for
	 * search + login/account + cart + theme-toggle + hamburger needed
	 * ~224px next to a 143px logo, inside a content area of only
	 * ~288-343px — a real, measured overflow (document.documentElement
	 * .scrollWidth exceeded window.innerWidth), not a guess. All sizes
	 * below stay at/above the WCAG 2.5.8 24x24px minimum target size.
	 */
	.tpm-logo { font-size: 1rem; }
	.tpm-header .tpm-container { column-gap: var(--tpm-space-2); }
	.tpm-header-actions { gap: 2px; }
	.tpm-icon-btn { padding: 2px; }
	.tpm-header-login,
	.tpm-header-account-trigger,
	.tpm-header-cart {
		width: 28px;
		height: 28px;
	}
	.tpm-header-account-icon,
	.tpm-header-cart-icon {
		width: 16px;
		height: 16px;
	}
	.tpm-cart-count { top: 0; right: 0; }
}
