/*
 * core.css - the stylesheet every page needs, in cascade order: design tokens, element
 * defaults, layout, components. These were four files and four render-blocking requests
 * until 2026-11-11. Page-specific rules stay in home.css and pages.css, which load after
 * this and are mutually exclusive: anything a template part shares between the home page
 * and an inner page belongs here.
 */

/* ==== tokens ==== */

/**
 * Design tokens — the single source of truth for colour, type, spacing,
 * radius and shadow across the theme. Change values here, not in
 * individual component files. Admin-editable brand colours (primary/
 * secondary/accent) are overridden inline in wp_head by inc/customizer.php
 * — see appiappi_customizer_css_vars().
 */

:root {
	/* ---- Neutrals ---- */
	--color-white: #ffffff;
	--color-neutral-50: #f7f8fa;
	--color-neutral-100: #eef1f5;
	--color-neutral-200: #e2e6ec;
	--color-neutral-300: #cbd2dc;
	--color-neutral-400: #9aa3b2;
	--color-neutral-600: #5b6472;
	--color-neutral-800: #1f2733;
	--color-neutral-900: #10151d;

	/* ---- Brand ---- */
	--color-navy-900: #0b1526;
	--color-navy-800: #10203a;
	--color-navy-700: #16294a;
	--color-primary: #1e5eff;
	--color-primary-dark: #1746c4;
	--color-primary-50: #eaf0ff;
	--color-maple: #d5222b;

	/* ---- Plan accents (admin-editable per plan later; sane defaults now) ---- */
	--color-plan-starter: #0f7a55;
	--color-plan-business: #2563eb;
	--color-plan-professional: #7c3aed;
	--color-plan-growth: #c2410c;
	--color-plan-seo-growth: #0f766e;
	/* 7 additional generic plan-colour choices (bringing the picker to 12 total) */
	--color-plan-red: #dc2626;
	--color-plan-pink: #db2777;
	--color-plan-indigo: #4f46e5;
	--color-plan-amber: #b45309;
	--color-plan-cyan: #0e7490;
	--color-plan-lime: #4d7c0f;
	--color-plan-slate: #475569;

	/* ---- Semantic ---- */
	--color-success: #15803d;
	--color-warning: #f59e0b;
	--color-danger: #b91c1c;

	/* ---- Surface / text aliases ---- */
	--color-bg: var(--color-white);
	--color-bg-subtle: var(--color-neutral-50);
	--color-bg-dark: var(--color-navy-900);
	--color-text: var(--color-neutral-800);
	--color-text-muted: var(--color-neutral-600);
	--color-text-on-dark: var(--color-white);
	--color-text-on-dark-muted: var(--color-neutral-300);
	--color-border: var(--color-neutral-200);
	/* Form controls only. A field's border is the only thing that says it is a field,
	   and SC 1.4.11 puts that at 3:1 against the page; --color-border is 1.25:1 and
	   stays what it is good at - separating cards and rows. */
	--color-border-input: #767f8c;

	/* ---- Typography ---- */
	--font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

	--fs-xs: 0.8125rem;   /* 13px */
	--fs-sm: 0.9375rem;   /* 15px */
	--fs-base: 1rem;      /* 16px */
	--fs-lg: 1.125rem;    /* 18px */
	--fs-xl: 1.375rem;    /* 22px */
	--fs-2xl: 1.75rem;    /* 28px */
	--fs-3xl: 2.125rem;   /* 34px */
	--fs-4xl: 2.75rem;    /* 44px */
	--fs-5xl: 3.375rem;   /* 54px */

	--lh-tight: 1.15;
	--lh-snug: 1.35;
	--lh-normal: 1.6;

	--fw-regular: 400;
	--fw-medium: 500;
	--fw-semibold: 600;
	--fw-bold: 700;

	/* ---- Spacing (4px base scale) ---- */
	--space-1: 0.25rem;
	--space-2: 0.5rem;
	--space-3: 0.75rem;
	--space-4: 1rem;
	--space-5: 1.25rem;
	--space-6: 1.5rem;
	--space-8: 2rem;
	--space-10: 2.5rem;
	--space-12: 3rem;
	--space-16: 4rem;
	--space-20: 5rem;
	--space-24: 6rem;

	/* ---- Radius ---- */
	--radius-sm: 6px;
	--radius-md: 10px;
	--radius-lg: 16px;
	--radius-xl: 22px;
	--radius-full: 999px;

	/* ---- Shadow ---- */
	--shadow-sm: 0 1px 2px rgba(16, 21, 29, 0.06);
	--shadow-md: 0 8px 24px rgba(16, 21, 29, 0.08);
	--shadow-lg: 0 20px 48px rgba(16, 21, 29, 0.14);

	/* ---- Layout ---- */
	--container-max: 1600px;
	--container-pad: var(--space-5);
	--header-height: 76px;
	--transition-base: 180ms ease;

	/* Per-section desktop side padding — overrides the sitewide
	   --container-pad above for specific homepage sections + the
	   sitewide footer, where 10px is too tight. Admin-configurable via
	   Customizer → Layout Spacing (inc/customizer.php); these are the
	   fallback defaults if that section is never touched. Only takes
	   effect at the same ≥768px breakpoint as --container-pad — see
	   home.css/layout.css for where each is actually consumed. */
	--hero-pad-desktop: 30px;
	--pricing-preview-pad-desktop: 20px;
	--templates-preview-pad-desktop: 20px;
	--footer-pad-desktop: 50px;
}

/* Desktop gutter is deliberately tight (~10px, like themeforest.net)
   rather than a wide margin — combined with the wider --container-max
   above, content uses most of the viewport on typical desktop widths
   instead of sitting in a narrow centred column. Per-row item counts
   in grids (pricing cards, template grid, etc.) are controlled by
   their own --cols custom properties, not by container width, so this
   only changes how wide each column/card is, never how many fit per row. */
@media (min-width: 768px) {
	:root {
		--container-pad: 10px;
	}
}

/* ==== base ==== */

/**
 * Reset + base element styles. Mobile-first throughout the theme:
 * unprefixed rules target small screens, min-width media queries add
 * complexity for tablet (768px) / desktop (1024px) / wide (1280px).
 */

*,
*::before,
*::after {
	box-sizing: border-box;
}

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

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}
}

body {
	margin: 0;
	font-family: var(--font-sans);
	font-size: var(--fs-base);
	line-height: var(--lh-normal);
	color: var(--color-text);
	background: var(--color-bg);
	-webkit-font-smoothing: antialiased;
}

img,
picture,
svg,
video {
	display: block;
	max-width: 100%;
	height: auto;
}

h1,
h2,
h3,
h4,
h5,
h6 {
	margin: 0 0 var(--space-4);
	line-height: var(--lh-tight);
	font-weight: var(--fw-bold);
	color: var(--color-neutral-900);
}

h1 {
	font-size: var(--fs-4xl);
}

h2 {
	font-size: var(--fs-3xl);
}

h3 {
	font-size: var(--fs-xl);
}

p {
	margin: 0 0 var(--space-4);
	color: var(--color-text-muted);
}

a {
	color: var(--color-primary);
	text-decoration: none;
}

a:hover {
	text-decoration: underline;
}

ul,
ol {
	margin: 0;
	padding: 0;
	list-style: none;
}

button,
input,
select,
textarea {
	font-family: inherit;
	font-size: 100%;
}

button {
	cursor: pointer;
}

/* Focus visibility for keyboard users (accessibility) */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
	outline: 2px solid var(--color-primary);
	outline-offset: 2px;
}

/* Skip link */
.skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 10000;
	background: var(--color-navy-900);
	color: var(--color-white);
	padding: var(--space-3) var(--space-5);
	border-radius: 0 0 var(--radius-sm) 0;
}

.skip-link:focus {
	left: 0;
}

.screen-reader-text {
	border: 0;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	height: 1px;
	width: 1px;
	overflow: hidden;
	position: absolute !important;
	word-wrap: normal !important;
}

@media (min-width: 1024px) {
	h1 {
		font-size: var(--fs-5xl);
	}
	h2 {
		font-size: var(--fs-4xl);
	}
}

/* ==== layout ==== */

/**
 * Structural layout: containers, section rhythm, site header/footer shell.
 * Section-specific visuals (hero, pricing, cards…) live in home.css.
 */

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

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

.section--tight {
	padding-block: var(--space-10);
}

.section--subtle {
	background: var(--color-bg-subtle);
}

.section--dark {
	background: var(--color-navy-900);
	color: var(--color-text-on-dark-muted);
}

.section--dark h2,
.section--dark h3 {
	color: var(--color-text-on-dark);
}

.section-heading {
	max-width: 640px;
	margin-inline: auto;
	text-align: center;
	margin-bottom: var(--space-10);
}

.section-heading__eyebrow {
	display: inline-block;
	font-size: var(--fs-xs);
	font-weight: var(--fw-semibold);
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--color-primary);
	margin-bottom: var(--space-3);
}

.section-heading p {
	margin-top: var(--space-3);
	margin-bottom: 0;
}

/* ---------- Site header ---------- */

.site-header {
	position: sticky;
	top: 0;
	z-index: 100;
	background: var(--color-white);
	border-bottom: 1px solid var(--color-border);
	transition: box-shadow var(--transition-base);
}

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

.site-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-4);
	min-height: var(--header-height);
}

.site-branding {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	color: var(--color-neutral-900);
	flex-shrink: 0;
}

.site-branding:hover {
	text-decoration: none;
}

.site-branding img {
	height: 36px;
	width: auto;
}

/* Fixed 2026-09-13: the star mark + underline (the 'leaf' icon used as
   the fallback logo when no custom logo image is set in Customizer,
   see appiappi_icon('leaf') in inc/template-tags.php) is a 24x24 inline
   SVG sized only by its width/height HTML attributes. base.css's global
   `svg { max-width: 100%; height: auto; }` reset makes that sizing
   depend on the SVG's flex-item box having real width to resolve
   against — on the cramped mobile header row (icon + name only, no
   explicit size floor) that box could shrink to the text's own width
   instead of the icon's, squeezing the mark down to near-nothing.
   Pinning an explicit, non-shrinking box here guarantees the star and
   its underline always render at a fixed, visible size regardless of
   how tight the surrounding flex row gets. */
.site-branding__mark {
	display: inline-flex;
	flex-shrink: 0;
	width: 24px;
	height: 24px;
}

.site-branding__mark svg {
	width: 100%;
	height: 100%;
}

.site-branding__name {
	font-weight: var(--fw-bold);
	font-size: var(--fs-lg);
	line-height: 1.1;
}

.site-branding__tagline {
	display: none;
}

.primary-nav {
	display: none;
}

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

.header-actions .btn-link {
	display: none;
}

/* "Get Started" is hidden entirely below 1024px (revised 2026-09-07) —
   per explicit request, mobile shouldn't show it at all, not even
   inside the slide-out nav (that instance was removed from the markup
   rather than hidden here). */
.header-actions .header-cta {
	display: none;
}

.mobile-nav-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	border: 1px solid var(--color-border);
	border-radius: var(--radius-md);
	background: var(--color-white);
}

.mobile-nav {
	position: fixed;
	inset: var(--header-height) 0 0 0;
	background: var(--color-white);
	transform: translateY(-8px);
	opacity: 0;
	visibility: hidden;
	transition: opacity var(--transition-base), transform var(--transition-base), visibility var(--transition-base);
	overflow-y: auto;
	z-index: 90;
}

.mobile-nav.is-open {
	opacity: 1;
	transform: translateY(0);
	visibility: visible;
}

.mobile-nav__list {
	padding: var(--space-6) var(--container-pad);
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
}

.mobile-nav__list a {
	display: block;
	padding: var(--space-3) 0;
	font-size: var(--fs-lg);
	font-weight: var(--fw-medium);
	color: var(--color-neutral-900);
	border-bottom: 1px solid var(--color-border);
}

.mobile-nav__list a:hover {
	text-decoration: none;
	color: var(--color-primary);
}

/* Current-page highlight, mobile nav (added 2026-09-13) — WordPress adds
   current-menu-item/current_page_item to the <li> itself (and
   current-menu-parent/current-menu-ancestor up the tree) automatically;
   this theme never styled any of them before, so the active page was
   never visually distinguished in the menu. A left accent bar + tinted
   background reads clearly in a stacked list. */
.mobile-nav__list li.current-menu-item > a,
.mobile-nav__list li.current_page_item > a,
.mobile-nav__list li.current-menu-parent > a,
.mobile-nav__list li.current-menu-ancestor > a {
	color: var(--color-primary-dark);
	background: var(--color-primary-50);
	border-radius: var(--radius-md);
	padding-inline: var(--space-3);
	margin-inline: calc(var(--space-3) * -1);
	border-bottom-color: transparent;
	box-shadow: inset 3px 0 0 var(--color-primary);
}

.mobile-nav__actions {
	padding: var(--space-6) var(--container-pad);
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
}

body.mobile-nav-is-open {
	overflow: hidden;
}

@media (min-width: 1024px) {
	.primary-nav {
		display: block;
	}

	.primary-nav ul {
		display: flex;
		align-items: center;
		gap: var(--space-6);
	}

	.primary-nav li {
		position: relative;
	}

	.primary-nav a {
		display: inline-flex;
		align-items: center;
		color: var(--color-neutral-800);
		font-size: var(--fs-sm);
		font-weight: var(--fw-medium);
		padding-block: var(--space-2);
		position: relative;
	}

	.primary-nav a:hover {
		color: var(--color-primary);
		text-decoration: none;
	}

	/* Current-page highlight, desktop nav (added 2026-09-13) — see the
	   mobile-nav note above for why this never existed before. A
	   colour change alone reads as too subtle at this size, so the
	   active item also gets a short animated underline (::after),
	   growing in from the centre — the same "quiet but unmistakable"
	   treatment used for hover states on plenty of production nav bars,
	   just made persistent instead of hover-only for whichever item
	   matches the current page. current-menu-parent/-ancestor (a menu
	   item whose child page is the one currently open) get the same
	   treatment, one shade lighter, so a sub-page still shows *where in
	   the site* the visitor is even though the exact label isn't lit up. */
	.primary-nav a::after {
		content: '';
		position: absolute;
		left: 50%;
		right: 50%;
		bottom: -2px;
		height: 2px;
		border-radius: var(--radius-full, 999px);
		background: var(--color-primary);
		transition: left var(--transition-base), right var(--transition-base);
	}

	.primary-nav li.current-menu-item > a,
	.primary-nav li.current_page_item > a {
		color: var(--color-primary-dark);
		font-weight: var(--fw-semibold);
	}

	.primary-nav li.current-menu-item > a::after,
	.primary-nav li.current_page_item > a::after {
		left: 0;
		right: 0;
	}

	.primary-nav li.current-menu-parent > a,
	.primary-nav li.current-menu-ancestor > a {
		color: var(--color-primary);
	}

	.primary-nav li.current-menu-parent > a::after,
	.primary-nav li.current-menu-ancestor > a::after {
		left: 0;
		right: 0;
		opacity: 0.5;
	}

	.header-actions .btn-link {
		display: inline-flex;
	}

	.header-actions .header-cta {
		display: inline-flex;
	}

	.mobile-nav-toggle,
	.mobile-nav {
		display: none;
	}

	.site-branding__tagline {
		display: block;
		font-size: var(--fs-xs);
		color: var(--color-text-muted);
	}
}

/* ---------- Site footer ---------- */

.site-footer {
	background: var(--color-navy-900);
	color: var(--color-text-on-dark-muted);
	padding-block: var(--space-16) var(--space-8);
}

.site-footer a {
	color: var(--color-text-on-dark-muted);
}

.site-footer a:hover {
	color: var(--color-white);
}

.footer-grid {
	display: grid;
	gap: var(--space-10);
	grid-template-columns: 1fr;
	margin-bottom: var(--space-12);
}

.footer-col__title {
	color: var(--color-white);
	font-size: var(--fs-sm);
	font-weight: var(--fw-semibold);
	text-transform: uppercase;
	letter-spacing: 0.03em;
	margin-bottom: var(--space-4);
}

.footer-col__list li {
	margin-bottom: var(--space-2);
}

.footer-col--brand .site-branding {
	color: var(--color-white);
	margin-bottom: var(--space-4);
}

.footer-contact li {
	display: flex;
	align-items: flex-start;
	gap: var(--space-2);
	margin-bottom: var(--space-3);
}

.footer-social {
	display: flex;
	gap: var(--space-3);
	margin-top: var(--space-4);
}

.footer-social a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border-radius: var(--radius-full);
	background: rgba(255, 255, 255, 0.08);
}

.footer-bottom {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	padding-top: var(--space-6);
	border-top: 1px solid rgba(255, 255, 255, 0.1);
	font-size: var(--fs-xs);
}

.footer-bottom__legal {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-4);
}

/* Mobile only (<640px): Quick Links and Services are dropped to keep
   the footer short on a phone screen (Contact and the brand column
   already cover the essentials), and the copyright/legal row centres
   instead of left-aligning. Both columns come back from 640px up. */
@media (max-width: 639.98px) {
	.footer-col--links,
	.footer-col--services {
		display: none;
	}

	.footer-bottom {
		align-items: center;
		text-align: center;
	}

	.footer-bottom__legal {
		justify-content: center;
	}
}

@media (min-width: 640px) {
	.footer-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1024px) {
	.footer-grid {
		grid-template-columns: 1.6fr 1fr 1fr 1.2fr;
	}

	.footer-bottom {
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
	}
}

/* Footer's own desktop side-padding (configurable via Customizer ->
   Layout Spacing), separate from the sitewide --container-pad — the
   footer's 4-column grid, copyright and legal links all share this
   one .container, so one override covers all of them. */
@media (min-width: 768px) {
	.site-footer .container {
		padding-inline: var(--footer-pad-desktop);
	}
}

/* ==== components ==== */

/**
 * Reusable UI components: buttons, badges, icon chips, cards, forms,
 * pricing cards. Loaded on every page (unlike home.css/pages.css, which
 * are conditional on is_front_page()) — so anything used in more than
 * one template context belongs here, not in one of those two.
 */

/* ---------- Buttons ---------- */

.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	padding: var(--space-3) var(--space-6);
	border-radius: var(--radius-md);
	font-size: var(--fs-sm);
	font-weight: var(--fw-semibold);
	border: 1px solid transparent;
	transition: background var(--transition-base), color var(--transition-base), border-color var(--transition-base), transform var(--transition-base);
	white-space: nowrap;
}

.btn:hover {
	text-decoration: none;
}

.btn:active {
	transform: translateY(1px);
}

.btn-primary {
	background: var(--color-primary);
	color: var(--color-white);
}

.btn-primary:hover {
	background: var(--color-primary-dark);
	color: var(--color-white);
}

.btn-secondary {
	background: var(--color-white);
	color: var(--color-neutral-900);
	border-color: var(--color-border);
}

.btn-secondary:hover {
	border-color: var(--color-neutral-400);
	color: var(--color-neutral-900);
}

.btn-outline-inverse {
	background: transparent;
	color: var(--color-white);
	border-color: rgba(255, 255, 255, 0.4);
}

.btn-outline-inverse:hover {
	background: rgba(255, 255, 255, 0.08);
	color: var(--color-white);
}

.btn-link {
	background: transparent;
	color: var(--color-neutral-800);
	padding-inline: var(--space-2);
}

.btn-link:hover {
	color: var(--color-primary);
}

.btn-block {
	display: flex;
	width: 100%;
}

.btn-sm {
	padding: var(--space-2) var(--space-4);
	font-size: var(--fs-xs);
}

/* ---------- Badges ---------- */

.badge {
	display: inline-flex;
	align-items: center;
	gap: var(--space-1);
	padding: var(--space-1) var(--space-3);
	border-radius: var(--radius-full);
	font-size: var(--fs-xs);
	font-weight: var(--fw-semibold);
}

.badge-primary {
	background: var(--color-primary-50);
	color: var(--color-primary-dark);
}

.badge-dark {
	background: var(--color-navy-900);
	color: var(--color-white);
}

/* ---------- Feature chips (hero) ---------- */

.chip-list {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--space-4);
	margin: var(--space-8) auto;
	max-width: fit-content;
	text-align: left;
}

.chip {
	display: flex;
	align-items: center;
	gap: var(--space-3);
}

.chip__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border-radius: var(--radius-md);
	background: var(--color-primary-50);
	color: var(--color-primary);
	flex-shrink: 0;
}

.chip__label {
	font-size: var(--fs-sm);
	font-weight: var(--fw-medium);
	color: var(--color-neutral-900);
}

/* ---------- Icon tile (trust bar) ---------- */

.icon-tile {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-4);
}

.icon-tile {
	--tile-color: var(--color-primary);
}

.icon-tile__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	border-radius: var(--radius-md);
	background: color-mix(in srgb, var(--tile-color) 14%, white);
	color: var(--tile-color);
	flex-shrink: 0;
}

.icon-tile__title {
	font-size: var(--fs-sm);
	font-weight: var(--fw-semibold);
	color: var(--color-neutral-900);
	margin: 0;
}

/* ---------- Trust bar (moved here from home.css 2026-09-07 — used by
   the homepage AND the About page, but this file was front-page-only,
   so the About page's 4 icons had zero layout CSS and rendered stacked
   on top of each other instead of in a row. Same "shared markup styled
   in a page-conditional file" mistake this project has hit before;
   components.css loads on every page, so this fixes it at the root
   instead of duplicating the rule per page.) ---------- */

.trust-bar {
	background: var(--color-bg-subtle);
}

.trust-bar__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-6);
}

@media (min-width: 640px) {
	.trust-bar__grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1024px) {
	.trust-bar__grid {
		grid-template-columns: repeat(4, 1fr);
	}
}

/* ---------- Card base ---------- */

.card {
	background: var(--color-white);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-sm);
}

/* ---------- Forms ---------- */

.form-field {
	margin-bottom: var(--space-4);
}

.form-field label {
	display: block;
	font-size: var(--fs-sm);
	font-weight: var(--fw-medium);
	color: var(--color-neutral-900);
	margin-bottom: var(--space-2);
}

.form-field input,
.form-field select,
.form-field textarea {
	width: 100%;
	padding: var(--space-3) var(--space-4);
	border: 1px solid var(--color-border-input);
	border-radius: var(--radius-md);
	background: var(--color-white);
	color: var(--color-text);
}

.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
	/* No `outline: none` here: it also beat the theme's :focus-visible rule, and what
	   was left - the border going from #767f8c to #1e5eff (1.26:1 between the two) and
	   a halo at 1.14:1 against white - was not an indicator a keyboard user could see. */
	border-color: var(--color-primary);
	box-shadow: 0 0 0 3px var(--color-primary-50);
}

@media (min-width: 1024px) {
	.chip-list {
		grid-template-columns: repeat(2, 1fr);
		gap: var(--space-5);
	}
}

/**
 * ---------- Pricing cards ----------
 * Lives here (not home.css) because appiappi_render_pricing_cards() is
 * shared between the homepage teaser AND the dedicated /pricing/ page —
 * home.css is only enqueued on is_front_page(), so any of this in that
 * file would silently vanish on the Pricing page. See DEVELOPMENT_LOG.md.
 */

.pricing-grid {
	--cols: 1;
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: stretch;
	gap: var(--space-6);
}

.pricing-card {
	--plan-color: var(--color-primary);
	width: calc((100% - (var(--cols) - 1) * var(--space-6)) / var(--cols));
	display: flex;
	flex-direction: column;
	padding: var(--space-8) var(--space-6);
	border-radius: var(--radius-lg);
	border: 1px solid var(--color-border);
	background: var(--color-white);
	position: relative;
	scroll-margin-top: calc(var(--header-height) + var(--space-6));
}

.pricing-card--featured {
	border-color: var(--plan-color);
	box-shadow: var(--shadow-lg);
}

/* ---------- Pricing tabs (full Pricing page, added 2026-09-07) ---------- */
/* One tab per plan instead of stacking every plan in a group — shown
   only when appiappi_render_pricing_cards() is called with $as_tabs.
   Progressive enhancement: every .pricing-tabs__panel (= .pricing-card)
   is fully present and visible in the raw HTML; main.js adds
   .is-ready to .pricing-tabs once it has picked the initial tab, and
   ONLY THEN does this CSS hide the non-active panels — so a visitor
   (or a crawler) with JS disabled/broken still sees every plan,
   stacked, instead of a blank or broken page. */
.pricing-tabs__list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
	margin-bottom: var(--space-8);
	border-bottom: 1px solid var(--color-border);
}

.pricing-tabs__tab {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	padding: var(--space-3) var(--space-5);
	border: none;
	background: none;
	border-bottom: 3px solid transparent;
	margin-bottom: -1px;
	font-size: var(--fs-sm);
	font-weight: var(--fw-semibold);
	color: var(--color-text-muted);
	cursor: pointer;
}

.pricing-tabs__tab svg {
	width: 20px;
	height: 20px;
	color: var(--plan-color, currentColor);
	flex-shrink: 0;
}

.pricing-tabs__tab-text {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	line-height: 1.2;
}

.pricing-tabs__tab-period {
	font-size: var(--fs-xs);
	font-weight: var(--fw-medium);
	color: var(--color-text-muted);
}

.pricing-tabs__tab:hover {
	color: var(--color-neutral-900);
}

.pricing-tabs__tab.is-active {
	color: var(--plan-color, var(--color-primary));
	border-bottom-color: var(--plan-color, var(--color-primary));
}

.pricing-tabs__tab.is-active .pricing-tabs__tab-period {
	color: inherit;
	opacity: 0.75;
}

/* Marks a billing-group boundary when multiple groups share one tab
   bar (e.g. one-time Launch plans + monthly Growth plans merged into
   one row, 2026-09-07) — inserted only where the group actually
   changes, so it disappears on its own if a page ever shows just one
   group again. */
.pricing-tabs__divider {
	width: 1px;
	flex-shrink: 0;
	align-self: stretch;
	background: var(--color-border);
	margin-inline: var(--space-1);
}

/* The Growth-tier plans are the real conversion goal once merged into
   the same bar as Launch — a persistent tint (not just on hover/active)
   so they read as the recommended path at a glance, distinct from
   which single plan carries the separate, admin-set "Most Popular"
   badge (.pricing-card__badge). */
.pricing-tabs__tab--highlight {
	background: color-mix(in srgb, var(--plan-color, var(--color-primary)) 10%, transparent);
	border-radius: var(--radius-md) var(--radius-md) 0 0;
}

.pricing-tabs__tab--highlight:hover {
	background: color-mix(in srgb, var(--plan-color, var(--color-primary)) 16%, transparent);
}

.pricing-tabs__tab--highlight.is-active {
	background: color-mix(in srgb, var(--plan-color, var(--color-primary)) 18%, transparent);
}

/* Full tab mode (Pricing page, appiappi_render_pricing_cards( $as_tabs )):
   exactly one plan visible at a time, at every viewport width. Excludes
   .pricing-tabs--mobile-only (homepage teaser) — that variant keeps every
   plan visible side by side at desktop widths and only switches to
   one-at-a-time below 640px, see that rule further down. */
.pricing-tabs.is-ready:not(.pricing-tabs--mobile-only) .pricing-tabs__panel {
	display: none;
}

.pricing-tabs.is-ready:not(.pricing-tabs--mobile-only) .pricing-tabs__panel.is-active {
	display: flex;
}

/* Mobile-only dropdown, replacing the tab row below 640px (2026-09-13) —
   see appiappi_render_pricing_cards() for why the tab buttons AND this
   select both exist in the markup at all times regardless of viewport
   (progressive enhancement / SEO: every plan panel is always fully
   present in the raw HTML either way, this is purely a CSS swap of
   which *control* drives showing one at a time). Hidden by default,
   shown only under the mobile breakpoint below. */
.pricing-tabs__mobile-label,
.pricing-tabs__mobile-select-wrap {
	display: none;
}

@media (max-width: 639.98px) {
	.pricing-tabs__list {
		display: none;
	}

	.pricing-tabs__mobile-label {
		display: block;
		font-size: var(--fs-xs);
		font-weight: var(--fw-semibold);
		text-transform: uppercase;
		letter-spacing: 0.04em;
		color: var(--color-text-muted);
		margin-bottom: var(--space-2);
	}

	.pricing-tabs__mobile-select-wrap {
		position: relative;
		display: block;
		margin-bottom: var(--space-8);
	}

	.pricing-tabs__mobile-select {
		width: 100%;
		appearance: none;
		-webkit-appearance: none;
		background: var(--color-white);
		border: 1px solid var(--color-border);
		border-radius: var(--radius-md);
		padding: var(--space-4) var(--space-10) var(--space-4) var(--space-4);
		font-size: var(--fs-base);
		font-weight: var(--fw-semibold);
		color: var(--color-neutral-900);
		cursor: pointer;
		transition: border-color var(--transition-base), box-shadow var(--transition-base);
	}

	.pricing-tabs__mobile-select:focus {
		border-color: var(--color-primary);
		box-shadow: 0 0 0 3px var(--color-primary-50);
	}

	.pricing-tabs__mobile-select-caret {
		position: absolute;
		top: 50%;
		right: var(--space-4);
		transform: translateY(-50%);
		width: 18px;
		height: 18px;
		color: var(--color-text-muted);
		pointer-events: none;
	}

	/* .pricing-tabs--mobile-only (homepage teaser): every plan is visible
	   side by side above this breakpoint (see the :not() rule above) —
	   only down here does picking one from the <select> actually hide the
	   rest, matching the full-tabs behaviour but confined to mobile. */
	.pricing-tabs--mobile-only.is-ready .pricing-tabs__panel {
		display: none;
	}

	.pricing-tabs--mobile-only.is-ready .pricing-tabs__panel.is-active {
		display: flex;
	}
}

.pricing-card__badge {
	position: absolute;
	top: -14px;
	left: 50%;
	transform: translateX(-50%);
	background: var(--plan-color);
	color: var(--color-white);
	font-size: var(--fs-xs);
	font-weight: var(--fw-semibold);
	padding: var(--space-1) var(--space-4);
	border-radius: var(--radius-full);
	white-space: nowrap;
}

.pricing-card__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: var(--radius-md);
	background: color-mix(in srgb, var(--plan-color) 14%, white);
	color: var(--plan-color);
	margin-bottom: var(--space-4);
}

.pricing-card__name {
	font-size: var(--fs-lg);
	margin-bottom: var(--space-1);
}

.pricing-card__tagline {
	font-size: var(--fs-sm);
	font-weight: var(--fw-semibold);
	color: var(--plan-color);
	margin-bottom: 0;
}

.pricing-card__price {
	display: flex;
	align-items: baseline;
	gap: var(--space-1);
	color: var(--plan-color);
	margin: var(--space-2) 0 var(--space-1);
}

.pricing-card__price-amount {
	font-size: var(--fs-3xl);
	font-weight: var(--fw-bold);
}

.pricing-card__price-period {
	font-size: var(--fs-sm);
	color: var(--color-text-muted);
}

.pricing-card__note {
	font-size: var(--fs-xs);
	color: var(--color-text-muted);
	margin-bottom: var(--space-3);
}

.pricing-card__audience {
	font-size: var(--fs-xs);
	font-style: italic;
	color: var(--color-neutral-600);
	margin-bottom: var(--space-6);
}

.pricing-card__description {
	font-size: var(--fs-sm);
	color: var(--color-neutral-800);
	line-height: var(--lh-normal);
	margin-bottom: var(--space-6);
	padding: var(--space-5);
	background: color-mix(in srgb, var(--plan-color) 8%, white);
	border: 1px solid color-mix(in srgb, var(--plan-color) 22%, white);
	border-radius: var(--radius-lg);
}

.pricing-card__description p:last-child {
	margin-bottom: 0;
}

.pricing-card__description-label {
	font-size: var(--fs-xs);
	font-weight: var(--fw-semibold);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--plan-color);
	margin-bottom: var(--space-2);
}

.pricing-card__features {
	flex: 1;
	margin-bottom: var(--space-6);
}

.pricing-card__features li {
	display: flex;
	align-items: flex-start;
	gap: var(--space-2);
	font-size: var(--fs-sm);
	color: var(--color-neutral-800);
	padding-block: var(--space-2);
	border-top: 1px solid var(--color-border);
}

.pricing-card__features li:first-child {
	border-top: none;
}

.pricing-card__features svg {
	flex-shrink: 0;
	color: var(--plan-color);
	margin-top: 2px;
}

.pricing-card__feature-name {
	display: block;
}

.pricing-card__feature-desc {
	display: block;
	font-size: var(--fs-xs);
	color: var(--color-text-muted);
	margin-top: 2px;
}

.pricing-card__value-driver {
	display: flex;
	align-items: flex-start;
	gap: var(--space-2);
	font-size: var(--fs-xs);
	font-weight: var(--fw-medium);
	color: var(--color-neutral-800);
	background: color-mix(in srgb, var(--plan-color) 10%, white);
	border-radius: var(--radius-md);
	padding: var(--space-3);
	margin-bottom: var(--space-5);
}

.pricing-card__value-driver svg {
	flex-shrink: 0;
	color: var(--plan-color);
	margin-top: 1px;
}

.pricing-card .btn {
	border-color: var(--plan-color);
}

.pricing-card .btn-primary {
	background: var(--plan-color);
}

.pricing-card .btn-secondary {
	color: var(--plan-color);
}

@media (min-width: 640px) {
	.pricing-grid {
		/* Tablet always caps at 2 regardless of the admin's desktop setting —
		   these cards are too content-heavy to comfortably fit 3+ at this width. */
		--cols: min(var(--pricing-cols, 4), 2);
	}
}

@media (min-width: 1024px) {
	.pricing-grid {
		--cols: var(--pricing-cols, 4);
	}

	.pricing-card--featured {
		transform: translateY(-var(--space-4));
	}
}

/* ---------- Template showcase (homepage preview + /templates/ page) ---------- */

.templates-layout {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-8);
}

/* Holds the search/categories/price card and, since 2026-09-07, the
   shared Account card below it (appiappi_client_login_render_sidebar_account_box(),
   appended in appiappi_render_template_showcase()) — flex column so
   the two stack with a consistent gap instead of touching. */
.templates-sidebar {
	display: flex;
	flex-direction: column;
	gap: var(--space-6);
}

.templates-sidebar__card {
	padding: var(--space-6);
}

.templates-sidebar__search {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-md);
	padding: var(--space-2) var(--space-3);
	margin-bottom: var(--space-6);
	color: var(--color-text-muted);
}

.templates-sidebar__search input {
	/* border: none is deliberate - the wrapper draws the box. outline: none was not: with
	   both gone this field had no focus indicator at all, on the search box of an archive
	   of 12,923 designs. */
	border: none;
	flex: 1;
	font-size: var(--fs-sm);
	background: transparent;
	color: var(--color-text);
}

.templates-sidebar__group {
	margin-bottom: var(--space-6);
}

.templates-sidebar__group:last-child {
	margin-bottom: 0;
}

.templates-sidebar__title {
	font-size: var(--fs-xs);
	font-weight: var(--fw-semibold);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--color-text-muted);
	margin-bottom: var(--space-3);
}

.templates-sidebar__categories li {
	margin-bottom: var(--space-1);
}

.templates-sidebar__categories a {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	padding: var(--space-2) var(--space-3);
	border-radius: var(--radius-md);
	font-size: var(--fs-sm);
	color: var(--color-neutral-800);
}

.templates-sidebar__categories a span:first-of-type {
	flex: 1 1 auto;
}

/* Design-count badge, added 2026-09-12 next to each category/sub-category
   label — see appiappi_showcase_get_category_counts(). */
.templates-sidebar__count {
	flex-shrink: 0;
	font-size: var(--fs-xs);
	font-weight: var(--fw-medium);
	color: var(--color-text-muted);
	background: var(--color-bg-subtle);
	border-radius: var(--radius-full, 999px);
	padding: 1px var(--space-2);
	line-height: 1.6;
}

.templates-sidebar__categories li.is-active .templates-sidebar__count {
	color: var(--color-primary-dark);
	background: #fff;
}

.templates-sidebar__categories a:hover {
	background: var(--color-bg-subtle);
	text-decoration: none;
}

.templates-sidebar__categories svg {
	width: 18px;
	height: 18px;
	flex-shrink: 0;
	color: var(--color-text-muted);
}

.templates-sidebar__categories li.is-active a {
	background: var(--color-primary-50);
	color: var(--color-primary-dark);
	font-weight: var(--fw-semibold);
}

.templates-sidebar__categories li.is-active svg {
	color: var(--color-primary);
}

/* Sub-categories (e.g. Corporate > Business, added 2026-09-11) — indented
   directly under their parent's link, slightly smaller so the hierarchy
   reads clearly without needing an expand/collapse toggle. */
.templates-sidebar__categories--children {
	margin: var(--space-1) 0 var(--space-2) var(--space-5);
}

.templates-sidebar__categories--children a {
	padding: var(--space-1) var(--space-3);
	font-size: var(--fs-xs);
}

.templates-sidebar__categories--children svg {
	width: 15px;
	height: 15px;
}

/* Expand/collapse caret, added 2026-09-12 — a branch's children only
   render in the markup when it's on the active category's path
   (appiappi_showcase_get_categories()'s 'expanded' flag), so the caret
   just hints there's more underneath; clicking the link itself (making
   that term active) is what reveals it on the next page load. */
.templates-sidebar__caret {
	flex-shrink: 0;
	display: inline-flex;
	color: var(--color-text-muted);
	transition: transform 0.15s ease;
}

.templates-sidebar__caret svg {
	width: 14px;
	height: 14px;
}

.templates-sidebar__categories li.is-expanded > a > .templates-sidebar__caret {
	transform: rotate(90deg);
}

/* ---------- Sitewide left sidebar (Categories + Account) ---------- */
/* Added 2026-09-07: appiappi_render_page_sidebar() (inc/template-tags.php)
   on every page except the homepage. Mobile/tablet: the Categories card
   sits in normal document flow directly after the page header (title +
   subtitle) — .page-sidebar is simply the first child of .page-layout
   in markup, so no extra CSS is needed for that placement. The Account
   card is hidden below 1024px entirely (revised 2026-09-07) — the
   header already has its own profile icon there (appiappi-client-login's
   header widget), so repeating it in the sidebar was judged redundant.
   Desktop (≥1024px, same breakpoint as .templates-layout above): a
   280px left column; only .page-sidebar__account (not Categories) is
   pinned via position: sticky, per explicit request — Categories
   scrolls away normally, then Account "catches" and stays in view once
   it reaches the sticky offset. */
.page-layout {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-8);
}

.page-sidebar {
	display: flex;
	flex-direction: column;
	gap: var(--space-6);
}

.page-sidebar__card {
	padding: var(--space-6);
}

.page-sidebar__account {
	display: none;
}

/* Below the desktop breakpoint the two columns become one, and the sidebar is
   first in the markup - so on a phone a reader met sixteen rows of design
   categories before the first sentence of /about/, /contact/ or /faq/. The
   categories are secondary navigation on those pages; the page's own words are
   what the visitor came for. Only the painting order changes, so the markup and
   the desktop layout (where the sidebar is a real left column) stay as they are.
   Measured 2026-10-27 at 375px: no horizontal overflow before or after. */
@media (max-width: 1023.98px) {
	.page-layout__main {
		order: 1;
	}

	.page-sidebar {
		order: 2;
	}
}

@media (min-width: 1024px) {
	.page-layout {
		grid-template-columns: 280px 1fr;
		align-items: start;
	}

	.page-sidebar__account {
		display: block;
		position: sticky;
		top: calc(var(--header-height) + var(--space-4));
	}

	/* Fixed 2026-09-13: a CSS Grid row is always exactly as tall as its
	   tallest column — with no in-flow way around that — so on any page
	   whose own main content is short (e.g. Contact, FAQ, About) but whose
	   category tree is long (several top-level categories, each with
	   sub-categories), the *sidebar's* height was silently dictating the
	   whole section's height, leaving a large empty gap under the short
	   main column before the next section could start. Capping the
	   category list's own height and letting it scroll internally once it
	   would exceed a sensible chunk of the viewport keeps this sidebar
	   from ever dwarfing genuinely short page content — scoped to this
	   sitewide sidebar only (appiappi_render_page_sidebar()), not the
	   Website Designs archive's own richer .templates-sidebar, whose main
	   column (the design grid) is essentially always the taller one. */
	.page-sidebar__card .templates-sidebar__categories {
		max-height: 60vh;
		overflow-y: auto;
		overflow-x: hidden;
	}
}

/* The 404 page's list of ways on. Narrow, like the FAQ list, so the lines do
   not run the full width of a desktop container. */
.error-404 {
	max-width: 760px;
}

.error-404 ul {
	margin-block: var(--space-5);
	padding-inline-start: var(--space-6);
	list-style: disc;
}

.error-404 li {
	margin-block: var(--space-3);
}

.templates-intro {
	max-width: 760px;
	color: var(--color-text-muted);
}

.templates-intro p:last-child {
	margin-bottom: 0;
}

/* ---------- Price range filter (sidebar) ---------- */

.templates-price-filter__row {
	display: flex;
	gap: var(--space-3);
	margin-bottom: var(--space-3);
}

.templates-price-filter__field {
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	font-size: var(--fs-xs);
	color: var(--color-text-muted);
	flex: 1;
	min-width: 0;
}

.templates-price-filter__field input {
	width: 100%;
	border: 1px solid var(--color-border);
	border-radius: var(--radius-md);
	padding: var(--space-2) var(--space-3);
	font-size: var(--fs-sm);
	color: var(--color-text);
}

.templates-price-filter__hint {
	font-size: var(--fs-xs);
	color: var(--color-text-muted);
	margin-bottom: var(--space-3);
}

/* Category breadcrumb above the toolbar, shown only when a category
   filter is active — see appiappi_showcase_get_breadcrumb(). */
.templates-breadcrumb {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-1, 4px);
	font-size: var(--fs-sm);
	color: var(--color-text-muted);
	margin-bottom: var(--space-3);
}

.templates-breadcrumb__link {
	color: var(--color-text-muted);
	text-decoration: none;
}

.templates-breadcrumb__link:hover {
	color: var(--color-primary);
	text-decoration: underline;
}

.templates-breadcrumb__current {
	color: var(--color-text);
	font-weight: var(--fw-medium);
}

.templates-breadcrumb__sep {
	color: var(--color-border);
}

/* Pagination now renders inside .templates-main itself (right after the
   design grid), instead of below the whole sidebar+main layout — with a
   long sidebar (19+ categories) that flex row is taller than the grid,
   which used to push the page-number links far below the actual
   designs. See appiappi_render_template_showcase(). */
.templates-main__pagination {
	margin-top: var(--space-6);
}

.templates-main__toolbar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	margin-bottom: var(--space-5);
	gap: var(--space-3);
}

.templates-main__count {
	font-size: var(--fs-sm);
	color: var(--color-text-muted);
	margin: 0;
}

.templates-main__count-total {
	color: var(--color-text-muted);
	font-weight: normal;
}

/* ---------- Sort controls (toolbar) ---------- */

.templates-main__sort {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	flex-shrink: 0;
}

.templates-sort-form select {
	border: 1px solid var(--color-border);
	border-radius: var(--radius-md);
	padding: var(--space-2) var(--space-3);
	font-size: var(--fs-sm);
	color: var(--color-text);
	background: var(--color-white);
}

/* Flexbox (not CSS Grid) so a short last row centres on the page instead
   of leaving a lopsided gap on the right — same reasoning as .pricing-grid. */
.template-grid {
	--cols: 1;
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--space-6);
}

.template-card {
	width: calc((100% - (var(--cols) - 1) * var(--space-6)) / var(--cols));
	overflow: hidden;
	display: flex;
	flex-direction: column;
}

/* Exact aspect ratio of the source marketplace preview images
   (590×300 — confirmed across every downloaded design so far) so
   object-fit: cover never actually crops anything, while every card's
   media box still comes out the same height for a tidy, uniform grid
   regardless of the source image's exact pixel size. */
.template-card__media {
	position: relative;
	aspect-ratio: 590 / 300;
	background: var(--color-neutral-100);
	overflow: hidden;
}

.template-card__image {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0;
	transition: opacity 300ms ease;
}

.template-card__image.is-active {
	opacity: 1;
}

.template-card__category {
	position: absolute;
	top: var(--space-3);
	left: var(--space-3);
	z-index: 2;
}

/* Carousel prev/next — only rendered at all when a design has more
   than one image (gallery, in addition to the Featured Image). */
.template-card__nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 2;
	width: 28px;
	height: 28px;
	border-radius: var(--radius-full);
	border: none;
	background: rgba(16, 21, 29, 0.55);
	color: var(--color-white);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	opacity: 0;
	transition: opacity 150ms ease, background 150ms ease;
}

.template-card__nav svg {
	width: 16px;
	height: 16px;
}

.template-card__media:hover .template-card__nav {
	opacity: 1;
}

.template-card__nav:hover {
	background: rgba(16, 21, 29, 0.8);
}

.template-card__nav--prev {
	left: var(--space-2);
}

.template-card__nav--next {
	right: var(--space-2);
}

.template-card__body {
	padding: var(--space-5);
	display: flex;
	flex-direction: column;
	gap: var(--space-1);
	flex: 1;
}

.template-card__name {
	font-size: var(--fs-lg);
	margin-bottom: 0;
}

.template-card__name a {
	color: inherit;
	text-decoration: none;
}

.template-card__name a:hover {
	color: var(--color-primary);
	text-decoration: underline;
}

.template-card__group {
	font-size: var(--fs-xs);
	font-style: italic;
	color: var(--color-text-muted);
	margin: 0;
}

.template-card__subgroup {
	margin-left: var(--space-1);
}

.template-card__desc {
	font-size: var(--fs-sm);
	margin-bottom: var(--space-3);
}

.template-card__meta {
	display: flex;
	align-items: center;
	justify-content: space-between;
	font-size: var(--fs-sm);
	margin-bottom: var(--space-4);
}

/* The card's heading level changes with where the grid is (h2 on the archive, h3 on the
   home page), so the element must carry no size or spacing of its own. */
.template-card__name {
	font-size: var(--fs-base);
	font-weight: var(--fw-semibold);
	line-height: var(--lh-snug);
	margin: 0 0 var(--space-2);
}

.template-card__price {
	font-weight: var(--fw-semibold);
	color: var(--color-neutral-900);
}

/* The amount is the theme's marketplace licence, not the price of a website, and it used
   to sit there unlabelled next to a design (2026-10-28). */
.template-card__price-label {
	display: block;
	font-size: var(--fs-xs);
	font-weight: var(--fw-medium);
	color: var(--color-text-muted);
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

.template-card__rating {
	display: inline-flex;
	align-items: center;
	gap: var(--space-1);
	color: var(--color-text-muted);
}

.template-card__rating-count {
	color: var(--color-text-muted);
}

/* Standard gold star rating (appiappi_render_star_rating()) — filled
   count reflects the real numeric rating instead of always showing 5
   gold stars regardless of the value. */
.star-rating {
	display: inline-flex;
	line-height: 1;
	letter-spacing: 1px;
}

.star-rating__star {
	color: var(--color-neutral-300);
}

.star-rating__star--filled {
	color: var(--color-warning);
}

.template-card__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
	margin-top: auto;
}

/* Fixed 2026-09-13, then revised same day: flex items default to
   min-width: auto ("never shrink narrower than my own unwrapped
   content"), so between the fixed breakpoints that step
   .template-grid's column count up (640px, 1024px, 1400px, or
   whatever an admin sets via Website Designs → Display Settings), a
   card's rendered width can land anywhere continuously — and once
   "View Details" + "Live Demo" + the square cart button's combined
   natural width exceeded the card's actual width, this row used to
   silently overflow past .template-card's own overflow: hidden (kept
   for the media carousel's sake), clipping whichever button didn't
   fit clean out of view. The first fix (min-width: 0 + text-overflow:
   ellipsis) stopped that overflow but traded it for a different
   visible problem — the button LABELS themselves getting truncated
   ("View Deta…") once things got tight, when the actual ask is for
   the row to react before either failure mode ever shows: once
   "View Details"/"Live Demo" can't both keep their full label at a
   sensible width, flex-wrap here lets them drop onto their own line(s)
   instead, at their natural, fully-readable width — text is never
   clipped and never overflows, at any width, continuously, with no
   fixed breakpoint to "arrive late" the way the column-count steps do.
   flex-basis: 120px is a floor, not a fixed size — each button still
   grows to share the row 50/50 whenever there's room for both. */
.template-card__actions .btn:not(.template-card__cart) {
	flex: 1 1 120px;
}

/* The "Add to Cart" (Choose This Design) button: square, icon-only,
   sitting beside the two equal-width text buttons. aspect-ratio: 1
   (rather than a guessed fixed px size) combined with the row's
   default align-items: stretch means it's always exactly as tall —
   and therefore exactly as wide — as its two sibling buttons. */
.template-card__cart {
	flex: 0 0 auto;
	aspect-ratio: 1;
	/* aspect-ratio alone let a narrow card squeeze it to 20px wide on a phone (2026-11-11). */
	min-width: 2.5rem;
	padding: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

.template-card__cart svg {
	width: 18px;
	height: 18px;
}

.templates-empty-state {
	text-align: center;
	color: var(--color-text-muted);
	padding-block: var(--space-10);
}

.templates-preview__footer {
	text-align: center;
	margin-top: var(--space-10);
}

@media (min-width: 640px) {
	.template-grid {
		--cols: 2;
	}
}

@media (min-width: 1024px) {
	.templates-layout {
		grid-template-columns: 280px 1fr;
		align-items: start;
	}

	.templates-layout--no-sidebar {
		grid-template-columns: 1fr;
	}

	/* Only the Account card (.page-sidebar__account, sticky rule with the
	   rest of the sitewide sidebar above) pins while scrolling — the
	   search/categories/price card above it now scrolls away normally,
	   matching every other page's sidebar (revised 2026-09-07; this card
	   used to be the sticky one on its own, before the Account card
	   existed here to take over that role — two independently-sticky
	   siblings at the same `top` would otherwise overlap instead of
	   stacking). */

	/* The /templates/ page (with sidebar): admin-configurable via
	   Website Designs → Display Settings, default 3. The homepage
	   teaser (no-sidebar) keeps its own fixed step below instead. */
	.templates-layout:not(.templates-layout--no-sidebar) .template-grid {
		--cols: var(--template-cols, 3);
	}
}

@media (min-width: 1400px) {
	.templates-layout--no-sidebar .template-grid {
		--cols: 4;
	}
}

/* ---------- Final CTA (get_template_part()'d on every page) ---------- */

.final-cta {
	text-align: center;
}

.final-cta h2 {
	margin-bottom: var(--space-3);
}

.final-cta p {
	max-width: 52ch;
	margin-inline: auto;
	margin-bottom: var(--space-8);
}

.final-cta__actions {
	display: flex;
	flex-direction: column;
	gap: var(--space-3);
	align-items: center;
}

@media (min-width: 640px) {
	.final-cta__actions {
		flex-direction: row;
		justify-content: center;
	}
}

/* Final CTA + site footer share one desktop side-padding value
   (configurable via Customizer → Layout Spacing) since visually they
   form one closing "footer area" on every page. */
@media (min-width: 768px) {
	.final-cta {
		padding-inline: var(--footer-pad-desktop);
	}
}

/* ---------- Action button rows (get_template_part()'d/reused off the homepage) ---------- */

/* Same bug as .final-cta and .template-card__* before it: this class
   is used by the homepage hero AND the Website Design detail page's
   button row, but its styles lived in home.css (front-page-only) —
   without them the row degrades to unstyled stacked/overlapping
   inline links, which is almost certainly why the single design
   page's "Back" button reportedly didn't respond to clicks reliably. */
.hero__actions {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-3);
}

.hero__actions .btn {
	width: 100%;
}

@media (min-width: 1024px) {
	.hero__actions {
		flex-direction: row;
		justify-content: center;
	}

	.hero__actions .btn {
		width: auto;
	}
}
