/*
Theme Name: TYGRtheme
Theme URI: https://example.com/tygrtheme
Author: Tyler Grieve
Author URI: https://itygr.com
Description: A single-page portfolio theme with a floating hero, a macOS-style dock navigation bar, animated skill chips, a work grid, and testimonials. Built as an original theme inspired by modern portfolio design conventions.
Version: 6.6.9
Requires at least: 6.4
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: glasspane
Tags: portfolio, one-page, custom-menu, featured-images, translation-ready

Copyright 2026 Tyler Grieve.

TYGRtheme is distributed under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 2 of the
License, or (at your option) any later version. See license.txt in this
theme's root directory for the full license text, or
https://www.gnu.org/licenses/gpl-2.0.html.

TYGRtheme is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.

NOTE ON THE HEADERS ABOVE: "Requires PHP: 7.4" / "Requires at least: 6.4"
were re-verified directly against this codebase (grepped for every
PHP 8.0+/8.1+ construct — nullsafe ?->, enums, readonly properties, match,
str_contains()/str_starts_with()/str_ends_with(), named arguments — none
are used anywhere in this theme), not carried forward from an earlier,
unverified claim. "Requires at least" is 6.4, not 6.0, specifically
because Revision History restores the _vf_blocks postmeta alongside
post_content via WordPress's native post-meta revisioning, which only
ships from 6.4 onward — on an older WP a restore would revert the
visible content but leave the page builder's own data stale. There is
deliberately no "Tested up to" line: that field
should name a WordPress version this theme has actually been run against,
and as of this build it has only been statically reviewed, never executed
inside a real WordPress install — adding a specific version here would be
a claim this project can't back up yet. Add it once you've verified the
theme against your own WP version.
*/

/* -------------------------------------------------------------------------
   1. Custom properties
   ---------------------------------------------------------------------- */
:root {
	--vf-bg: #f6f5f2;
	--vf-surface: #ffffff;
	--vf-text: #16161a;
	--vf-text-muted: #63636b;
	--vf-border: rgba(22, 22, 26, 0.1);
	--vf-accent: #3b5bfd;
	--vf-accent-ink: #ffffff;
	--vf-chip-1: #ff6b57;
	--vf-chip-2: #35c48b;
	--vf-chip-3: #ffb238;
	--vf-radius-lg: 28px;
	--vf-radius-md: 18px;
	--vf-radius-sm: 12px;
	--vf-shadow-soft: 0 20px 60px rgba(22, 22, 26, 0.08);
	--vf-shadow-dock: 0 12px 40px rgba(22, 22, 26, 0.18);
	--vf-font-display: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Inter", "Helvetica Neue", Arial, sans-serif;
	--vf-font-body: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter", "Helvetica Neue", Arial, sans-serif;
	--vf-container: 1160px;
	--vf-dock-size: 56px;
}

@media (prefers-color-scheme: dark) {
	:root:not(.vf-force-light) {
		--vf-bg: #121214;
		--vf-surface: #1c1c20;
		--vf-text: #f3f3f5;
		--vf-text-muted: #9a9aa3;
		--vf-border: rgba(255, 255, 255, 0.1);
		--vf-shadow-soft: 0 20px 60px rgba(0, 0, 0, 0.35);
		--vf-shadow-dock: 0 12px 40px rgba(0, 0, 0, 0.45);
	}
}

/* -------------------------------------------------------------------------
   2. Reset & base
   ---------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
	margin: 0;
	background: var(--vf-bg);
	color: var(--vf-text);
	font-family: var(--vf-font-body);
	font-size: 16px;
	line-height: 1.6;
	-webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }
ul { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4 { font-family: var(--vf-font-display); margin: 0 0 0.5em; letter-spacing: -0.02em; }
p { margin: 0 0 1em; }
button { font-family: inherit; }
.screen-reader-text {
	position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden;
	clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.vf-container {
	max-width: var(--vf-container);
	margin: 0 auto;
	padding: 0 32px;
}
/* 32px + .vf-shop's own 24px side padding (below) stack to 56px per side —
   30% of a 375px viewport gone to padding alone before content even
   starts. Narrowed here, not removed, since .vf-container is used
   sitewide (including .vf-notes-related), not just the shop. */
@media (max-width: 600px) {
	.vf-container { padding: 0 16px; }
}

/* -------------------------------------------------------------------------
   3. Site header — a full-width glass menu bar (5.1.4), the same material
   as the dock (.vf-dock in style.css §"Dock") so the two read as one
   piece of OS chrome bookending the page, rather than the floating
   centered pill this used to be (which left the space to either side of
   it looking like unused dead air, not a deliberate bar). Still fixed +
   overlaid rather than pushing content down — a section's own top padding
   already clears it, same as before this change.
   ---------------------------------------------------------------------- */
.vf-site-header {
	position: fixed;
	top: 0; left: 0; right: 0;
	z-index: 40;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 14px 24px;
	background: color-mix(in srgb, var(--vf-surface) 55%, transparent);
	backdrop-filter: blur(24px) saturate(190%);
	-webkit-backdrop-filter: blur(24px) saturate(190%);
	border-bottom: 1px solid color-mix(in srgb, var(--vf-text) 8%, transparent);
	box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.12);
}
.vf-site-header .vf-brand {
	position: relative;
	font-family: var(--vf-font-display);
	font-weight: 700;
	font-size: 14px;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	display: flex;
	align-items: center;
}
.vf-site-header .vf-brand--logo .custom-logo-link {
	display: flex;
	align-items: center;
}
.vf-site-header .vf-brand--logo .custom-logo {
	display: block;
	height: 26px;
	width: auto;
	max-width: 140px;
	object-fit: contain;
}
#vf-header-cta-wrap:empty { display: none; }
.vf-site-header__end {
	display: flex;
	align-items: center;
	gap: 14px;
}
.vf-header-cta {
	display: inline-flex;
	align-items: center;
	padding: 7px 16px;
	border-radius: 999px;
	font-size: 13px;
	font-weight: 600;
	background: var(--vf-accent);
	color: #fff;
	box-shadow: 0 8px 22px rgba(59, 91, 253, 0.3);
	transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.vf-header-cta:hover { transform: translateY(-2px); box-shadow: 0 12px 28px rgba(59, 91, 253, 0.4); }
@media (max-width: 600px) {
	.vf-header-cta { display: none; }
}
/* Below 600px the CTA is already gone; this only has to protect the brand
   label + search trigger row from a long site title. Without a max-width
   the brand text can push the search trigger past the viewport edge on a
   narrow phone, since .vf-site-header never wraps. */
@media (max-width: 480px) {
	.vf-site-header { padding: 12px 16px; gap: 8px; }
	.vf-site-header .vf-brand {
		font-size: 12px;
		max-width: 50vw;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}
}

/* -------------------------------------------------------------------------
   4. Hero
   ---------------------------------------------------------------------- */
.vf-hero {
	position: relative;
	min-height: 100vh;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	padding: 140px 24px 200px;
	text-align: center;
	isolation: isolate;
}
.vf-hero__bg {
	position: absolute;
	inset: 0;
	z-index: -2;
	background-size: cover;
	background-position: center;
}
.vf-hero__bg::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(10, 10, 12, 0.15) 0%, rgba(10, 10, 12, 0.55) 100%);
}
.vf-hero--no-image .vf-hero__bg {
	background: radial-gradient(circle at 30% 20%, #4a63ff 0%, transparent 55%),
		radial-gradient(circle at 75% 75%, #ff6b57 0%, transparent 50%),
		var(--vf-text);
}
/* A phone rotated to landscape combines a short viewport with the hero's
   min-height:100vh + 340px of fixed top/bottom padding — on, say, a 375px-
   tall landscape viewport that leaves only ~35px for the headline/tagline/
   CTA, which .vf-hero's overflow:hidden would then silently clip. This only
   targets that short-and-narrow combination, not portrait phones (which are
   never this short) or landscape tablets (which have height to spare). */
@media (max-width: 900px) and (max-height: 500px) {
	.vf-hero { min-height: auto; padding: 90px 24px; }
}
.vf-hero__inner {
	position: relative;
	z-index: 1;
	max-width: 820px;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 26px;
	color: #fff;
}
.vf-hero__available {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	padding: 8px 18px;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.14);
	backdrop-filter: blur(10px);
	-webkit-backdrop-filter: blur(10px);
	border: 1px solid rgba(255, 255, 255, 0.25);
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.04em;
}
.vf-hero__available .vf-dot {
	width: 8px; height: 8px; border-radius: 50%;
	background: var(--vf-chip-2);
	box-shadow: 0 0 0 3px rgba(53, 196, 139, 0.25);
}
.vf-hero__headline {
	font-size: clamp(2.4rem, 6vw, 4.6rem);
	font-weight: 800;
	line-height: 1.04;
	margin: 0;
	text-wrap: balance;
}
.vf-hero__tagline {
	font-size: clamp(1rem, 1.6vw, 1.2rem);
	color: rgba(255, 255, 255, 0.85);
	max-width: 520px;
	margin: 0;
}
.vf-hero__cta {
	display: flex;
	gap: 14px;
	margin-top: 8px;
	flex-wrap: wrap;
	justify-content: center;
}
.vf-btn {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 13px 26px;
	border-radius: 999px;
	font-weight: 600;
	font-size: 14px;
	transition: transform 0.25s ease, box-shadow 0.25s ease, background 0.25s ease;
}
.vf-btn--primary {
	background: var(--vf-accent);
	color: var(--vf-accent-ink);
	box-shadow: 0 10px 30px rgba(59, 91, 253, 0.35);
}
.vf-btn--primary:hover { transform: translateY(-2px); box-shadow: 0 16px 36px rgba(59, 91, 253, 0.45); }
.vf-btn--ghost {
	background: rgba(255, 255, 255, 0.12);
	color: #fff;
	border: 1px solid rgba(255, 255, 255, 0.3);
}
.vf-btn--ghost:hover { background: rgba(255, 255, 255, 0.2); transform: translateY(-2px); }

/* Floating skill chips */
.vf-chips {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
}
.vf-chip {
	position: absolute;
	display: inline-flex;
	align-items: center;
	gap: 10px;
	padding: 12px 18px;
	background: var(--vf-surface);
	color: var(--vf-text);
	border-radius: var(--vf-radius-sm);
	box-shadow: var(--vf-shadow-soft);
	font-weight: 600;
	font-size: 14px;
	white-space: nowrap;
	animation: vf-float 7s ease-in-out infinite;
}
.vf-chip__dot { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.vf-chip:nth-child(1) { top: 22%; left: 8%; animation-delay: 0s; }
.vf-chip:nth-child(2) { top: 18%; right: 9%; animation-delay: 1.4s; }
.vf-chip:nth-child(3) { bottom: 24%; left: 12%; animation-delay: 2.8s; }
@keyframes vf-float {
	0%, 100% { transform: translateY(0); }
	50% { transform: translateY(-14px); }
}
@media (max-width: 780px) {
	.vf-chips { display: none; }
}

/* -------------------------------------------------------------------------
   5. Dock navigation (fixed bottom, macOS-style magnification via JS)

   Fidelity notes vs. the real macOS Dock:
   - Icons sit directly on the glass shelf with no per-icon button chrome —
     only the no-custom-icon fallback glyph gets a tinted tile, since a bare
     stroke icon floating on glass reads as "missing" otherwise.
   - The shelf itself carries the glass material (blur+saturation+a top
     specular highlight), not the icons.
   - The "current page" state is a small indicator dot under the icon
     (like a running app), not a recolor — a recolor only makes sense for
     the generic glyph and looks wrong over a real uploaded image.
   - Real SF Symbols / San Francisco font files aren't shipped here — see
     the theme readme's "Apple design assets" note.
   ---------------------------------------------------------------------- */
.vf-dock-wrap {
	position: fixed;
	left: 0; right: 0; bottom: 22px;
	z-index: 50;
	display: flex;
	justify-content: center;
	pointer-events: none;
}
.vf-dock {
	position: relative;
	pointer-events: auto;
	display: flex;
	align-items: flex-end;
	gap: var(--vf-dock-gap, 14px);
	padding: 10px 16px;
	border-radius: 28px;
	background: color-mix(in srgb, var(--vf-surface) 55%, transparent);
	backdrop-filter: blur(28px) saturate(190%);
	-webkit-backdrop-filter: blur(28px) saturate(190%);
	border: 1px solid color-mix(in srgb, var(--vf-text) 8%, transparent);
	box-shadow: var(--vf-shadow-dock), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
.vf-dock::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	pointer-events: none;
	background: linear-gradient(180deg, rgba(255, 255, 255, 0.16) 0%, rgba(255, 255, 255, 0) 40%);
}
.vf-dock__item {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	width: var(--vf-dock-size);
	height: var(--vf-dock-size);
	border-radius: 22%;
	transform-origin: bottom center;
	transition: transform 0.12s ease-out;
	will-change: transform;
	flex: none;
}
.vf-dock__item--fallback {
	background: color-mix(in srgb, var(--vf-text) 8%, transparent);
	border: 1px solid var(--vf-border);
}
.vf-dock__item svg { width: 46%; height: 46%; color: var(--vf-text); }
.vf-dock__item img { width: 100%; height: 100%; object-fit: cover; border-radius: 22%; }
.vf-dock__item .vf-dock__label {
	position: absolute;
	bottom: calc(100% + 14px);
	left: 50%;
	transform: translateX(-50%) translateY(4px);
	padding: 5px 11px;
	border-radius: 8px;
	background: var(--vf-text);
	color: var(--vf-bg);
	font-size: 12px;
	font-weight: 600;
	white-space: nowrap;
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.15s ease, transform 0.15s ease;
}
.vf-dock__item:hover .vf-dock__label,
.vf-dock__item:focus-visible .vf-dock__label {
	opacity: 1;
	transform: translateX(-50%) translateY(0);
}
/* A visible keyboard-focus ring, drawn inward (negative offset) so it never
   overlaps the next icon at the dock's tight 14px gap. The accent color
   also keeps it legible over the dock's blurred, translucent background in
   both light and dark mode, unlike the browser default. */
.vf-dock__item:focus-visible {
	outline: 2px solid var(--vf-accent);
	outline-offset: -4px;
	border-radius: 22%;
}
.vf-dock__item.is-current::after {
	content: "";
	position: absolute;
	bottom: -9px;
	left: 50%;
	transform: translateX(-50%);
	width: 4px;
	height: 4px;
	border-radius: 50%;
	background: var(--vf-text);
	opacity: 0.6;
}
.vf-dock__item.is-launching { animation: vf-dock-bounce 0.42s cubic-bezier(0.28, 0.84, 0.42, 1); }
@keyframes vf-dock-bounce {
	0% { transform: scale(1) translateY(0); }
	30% { transform: scale(1.12) translateY(-18px); }
	55% { transform: scale(0.97) translateY(0); }
	75% { transform: scale(1.04) translateY(-6px); }
	100% { transform: scale(1) translateY(0); }
}

@media (max-width: 600px) {
	:root { --vf-dock-size: 46px; }
	/* A macOS Dock has no answer for "more icons than fit" because it never
	   needs one — a phone viewport does. Rather than shrinking icons
	   indefinitely as items are added to the Dock Navigation menu, the dock
	   caps its own width to the wrap's (see left/right below) and becomes a
	   horizontally scrollable strip once content exceeds that — every icon
	   stays reachable via a swipe instead of silently overflowing off-screen
	   past the viewport edge, which .vf-dock-wrap's centering would otherwise
	   do with no way back. justify-content:flex-start (instead of the base
	   rule's implicit centering behavior) only matters once content actually
	   overflows the max-width below; a dock that still fits stays visually
	   centered by .vf-dock-wrap same as ever. */
	.vf-dock-wrap { left: 12px; right: 12px; }
	.vf-dock {
		gap: 8px;
		padding: 8px 12px;
		max-width: 100%;
		overflow-x: auto;
		overflow-y: hidden;
		justify-content: flex-start;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
	}
	.vf-dock::-webkit-scrollbar { display: none; }
}

/* -------------------------------------------------------------------------
   5b. Windows (assets/js/window.js) — a real macOS window: title bar,
   traffic-light controls, draggable, minimize/zoom/close. Sits BELOW the
   dock and the header pill in stacking order (z-index 30 vs. their 50/40)
   because on the real Dock/menu bar, both always render above app windows.
   ---------------------------------------------------------------------- */
.vf-window {
	position: fixed;
	top: 10%;
	left: 50%;
	transform: translateX(-50%);
	width: min(720px, 92vw);
	max-height: 76vh;
	z-index: 30;
	display: flex;
	flex-direction: column;
	background: var(--vf-surface);
	border-radius: 12px;
	border: 1px solid var(--vf-border);
	box-shadow: 0 30px 80px rgba(0, 0, 0, 0.32);
	overflow: hidden;
}
.vf-window.is-hidden { display: none; }
.vf-window.is-zoomed {
	top: 4%;
	width: min(1200px, 94vw);
	max-height: 92vh;
}
.vf-window__titlebar {
	position: relative;
	display: flex;
	align-items: center;
	padding: 12px 14px;
	background: var(--vf-bg);
	border-bottom: 1px solid var(--vf-border);
	cursor: move;
	user-select: none;
	flex: none;
}
.vf-window__controls { display: flex; gap: 8px; z-index: 1; }
.vf-window__control {
	width: 12px;
	height: 12px;
	border-radius: 50%;
	border: none;
	padding: 0;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	background: color-mix(in srgb, var(--vf-text) 22%, transparent);
}
.vf-window__control svg { width: 7px; height: 7px; opacity: 0; transition: opacity 0.15s ease; }
.vf-window__titlebar:hover .vf-window__control svg { opacity: 1; }
.vf-window.is-focused .vf-window__control--close { background: #ff5f57; }
.vf-window.is-focused .vf-window__control--minimize { background: #febc2e; }
.vf-window.is-focused .vf-window__control--zoom { background: #28c840; }
.vf-window__title {
	position: absolute;
	left: 0;
	right: 0;
	text-align: center;
	font-size: 12.5px;
	font-weight: 600;
	color: var(--vf-text-muted);
	pointer-events: none;
}
.vf-window__body {
	padding: 34px 42px 48px;
	overflow-y: auto;
}
.vf-window__body .vf-window__page-title { font-family: var(--vf-font-display); font-size: clamp(1.5rem, 3vw, 2rem); margin-bottom: 0.6em; }
.vf-window__body > * + * { margin-top: 1.1em; }
.vf-window__loading { color: var(--vf-text-muted); }

@media (max-width: 700px) {
	.vf-window { display: none !important; }
}

/* -------------------------------------------------------------------------
   6. Section shell
   ---------------------------------------------------------------------- */
.vf-section {
	padding: 110px 0;
	position: relative;
}
.vf-section + .vf-section { border-top: 1px solid var(--vf-border); }
.vf-section__head {
	max-width: 640px;
	margin: 0 auto 56px;
	text-align: center;
}
.vf-section__eyebrow {
	display: inline-block;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--vf-accent);
	margin-bottom: 14px;
}
.vf-section__title { font-size: clamp(1.8rem, 3.4vw, 2.6rem); }
.vf-section__desc { color: var(--vf-text-muted); font-size: 17px; }
.vf-reveal { opacity: 0; transform: translateY(24px); transition: opacity 0.7s ease, transform 0.7s ease; }
.vf-reveal.is-visible { opacity: 1; transform: translateY(0); }

/* About / page content beneath hero */
.vf-content {
	max-width: 760px;
	margin: 0 auto;
	font-size: 17px;
	color: var(--vf-text-muted);
}
.vf-content > * + * { margin-top: 1.1em; }
.vf-content--wide { max-width: 1000px; }

/* Button block rendered by the custom Page editor (inc/custom-editor.php)
   — a plain-background-safe pair, distinct from .vf-btn (which is built
   for the hero's photo/gradient backdrop, where a translucent "ghost"
   variant would go invisible on ordinary page content). */
.vf-content-btn {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 12px 24px;
	border-radius: var(--vf-btn-radius, 999px);
	font-weight: 600;
	font-size: 14px;
	text-decoration: none;
	transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease, color 0.25s ease;
}
.vf-content-btn--primary {
	background: var(--vf-accent);
	color: #fff;
	box-shadow: 0 10px 26px rgba(59, 91, 253, 0.25);
}
.vf-content-btn--primary:hover { transform: translateY(-2px); box-shadow: 0 14px 32px rgba(59, 91, 253, 0.35); }
.vf-content-btn--secondary {
	background: transparent;
	color: var(--vf-text);
	border: 1.5px solid var(--vf-border);
}
.vf-content-btn--secondary:hover { border-color: var(--vf-accent); color: var(--vf-accent); transform: translateY(-2px); }

/* Text Styles (5.1) — site-wide named typography presets a Heading,
   Paragraph, or Quote block picks from (see BLOCK_REGISTRY's text_style
   field in assets/js/custom-editor.js). Each var() fallback here IS the
   real default (vf_text_style_defaults() in inc/custom-editor.php) —
   vf_enqueue_assets() only ever emits an override when a saved value
   actually differs from it, the same convention every other Design
   Globals value already follows. line-height/letter-spacing are fixed
   per preset, not independently configurable. */
.vf-text-style--title {
	font-family: var(--vf-ts-title-font, var(--vf-font-display));
	font-size: var(--vf-ts-title-size, 48px);
	font-weight: var(--vf-ts-title-weight, 800);
	line-height: 1.1;
	letter-spacing: -0.02em;
	text-transform: var(--vf-ts-title-transform, none);
	color: var(--vf-ts-title-color, inherit);
}
.vf-text-style--subtitle {
	font-family: var(--vf-ts-subtitle-font, var(--vf-font-body));
	font-size: var(--vf-ts-subtitle-size, 20px);
	font-weight: var(--vf-ts-subtitle-weight, 400);
	line-height: 1.5;
	letter-spacing: 0;
	text-transform: var(--vf-ts-subtitle-transform, none);
	color: var(--vf-ts-subtitle-color, var(--vf-text-muted));
}
.vf-text-style--h1 {
	font-family: var(--vf-ts-h1-font, var(--vf-font-display));
	font-size: var(--vf-ts-h1-size, 40px);
	font-weight: var(--vf-ts-h1-weight, 700);
	line-height: 1.15;
	letter-spacing: -0.01em;
	text-transform: var(--vf-ts-h1-transform, none);
	color: var(--vf-ts-h1-color, inherit);
}
.vf-text-style--h2 {
	font-family: var(--vf-ts-h2-font, var(--vf-font-display));
	font-size: var(--vf-ts-h2-size, 28px);
	font-weight: var(--vf-ts-h2-weight, 700);
	line-height: 1.2;
	letter-spacing: 0;
	text-transform: var(--vf-ts-h2-transform, none);
	color: var(--vf-ts-h2-color, inherit);
}
.vf-text-style--body {
	font-family: var(--vf-ts-body-font, var(--vf-font-body));
	font-size: var(--vf-ts-body-size, 17px);
	font-weight: var(--vf-ts-body-weight, 400);
	line-height: 1.7;
	letter-spacing: 0;
	text-transform: var(--vf-ts-body-transform, none);
	color: var(--vf-ts-body-color, inherit);
}
.vf-text-style--quote {
	font-family: var(--vf-ts-quote-font, var(--vf-font-display));
	font-size: var(--vf-ts-quote-size, 24px);
	font-weight: var(--vf-ts-quote-weight, 500);
	line-height: 1.4;
	letter-spacing: 0;
	font-style: italic;
	text-transform: var(--vf-ts-quote-transform, none);
	color: var(--vf-ts-quote-color, inherit);
}
.vf-text-style--copyright {
	font-family: var(--vf-ts-copyright-font, var(--vf-font-body));
	font-size: var(--vf-ts-copyright-size, 13px);
	font-weight: var(--vf-ts-copyright-weight, 400);
	line-height: 1.5;
	letter-spacing: 0.02em;
	text-transform: var(--vf-ts-copyright-transform, none);
	color: var(--vf-ts-copyright-color, var(--vf-text-muted));
}

/* Quote block (5.1) — a real <blockquote>, distinct from the Paragraph
   block's rich-text HTML: a big accent mark plus an optional citation
   line, defaulting to the "quote" Text Style above. */
.vf-pb-quote {
	position: relative;
	margin: 0;
	padding: 8px 0 8px 28px;
	border-left: 3px solid var(--vf-accent);
}
.vf-pb-quote__text { margin: 0; }
.vf-pb-quote__cite {
	display: block;
	margin-top: 10px;
	font-style: normal;
	font-size: 14px;
	color: var(--vf-text-muted);
}
.vf-pb-quote__cite::before { content: "— "; }

/* -------------------------------------------------------------------------
   6b. Homepage widget row (floating "featured" cards, just under the hero)
   ---------------------------------------------------------------------- */
.vf-widgets-row { padding: 40px 0 0; }
.vf-widgets-scroller {
	display: flex;
	gap: 18px;
	overflow-x: auto;
	padding-bottom: 6px;
	scrollbar-width: thin;
}
.vf-widget-card {
	flex: 0 0 220px;
	background: var(--vf-surface);
	border-radius: var(--vf-radius-md);
	box-shadow: var(--vf-shadow-soft);
	overflow: hidden;
	transition: transform 0.3s ease;
}
.vf-widget-card:hover { transform: translateY(-4px); }
.vf-widget-card__media { aspect-ratio: 4 / 3; background: var(--vf-bg); overflow: hidden; }
.vf-widget-card__media img { width: 100%; height: 100%; object-fit: cover; }
.vf-widget-card__body { padding: 14px 16px 18px; }
.vf-widget-card__kicker { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--vf-accent); }
.vf-widget-card__title { font-size: 15px; margin: 6px 0 0; }

/* -------------------------------------------------------------------------
   7. Work grid
   ---------------------------------------------------------------------- */
.vf-work-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
	gap: 28px;
}
.vf-project-card {
	background: var(--vf-surface);
	border-radius: var(--vf-radius-md);
	overflow: hidden;
	box-shadow: var(--vf-shadow-soft);
	transition: transform 0.35s ease, box-shadow 0.35s ease;
	display: flex;
	flex-direction: column;
}
.vf-project-card:hover { transform: translateY(-6px); }
.vf-project-card__media {
	aspect-ratio: 4 / 3;
	background: var(--vf-bg);
	overflow: hidden;
}
.vf-project-card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; }
.vf-project-card:hover .vf-project-card__media img { transform: scale(1.05); }
.vf-project-card__body { padding: 22px 24px 26px; }
.vf-project-card__tag { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--vf-accent); }
.vf-project-card__title { font-size: 20px; margin: 8px 0 6px; }
.vf-project-card__excerpt { color: var(--vf-text-muted); font-size: 14.5px; margin: 0; }

/* -------------------------------------------------------------------------
   8. Testimonials
   ---------------------------------------------------------------------- */
.vf-testimonials {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 24px;
}
.vf-testimonial {
	background: var(--vf-surface);
	border-radius: var(--vf-radius-md);
	padding: 30px;
	box-shadow: var(--vf-shadow-soft);
}
.vf-testimonial__quote { font-size: 16.5px; margin-bottom: 20px; }
.vf-testimonial__author { display: flex; align-items: center; gap: 12px; }
.vf-testimonial__avatar { width: 42px; height: 42px; border-radius: 50%; object-fit: cover; background: var(--vf-bg); }
.vf-testimonial__name { font-weight: 700; font-size: 14.5px; }
.vf-testimonial__role { font-size: 13px; color: var(--vf-text-muted); }

/* A standalone Testimonial page (single-vf_testimonial.php) — same card,
   but given room to breathe rather than sitting in a dense grid. */
.vf-testimonial--single {
	max-width: 640px;
	margin: 0 auto 24px;
	padding: 48px;
	text-align: center;
}
.vf-testimonial--single .vf-testimonial__quote { font-size: 22px; font-family: var(--vf-font-display); }
.vf-testimonial--single .vf-testimonial__author { justify-content: center; }
.vf-testimonial--single .vf-testimonial__avatar { width: 56px; height: 56px; }
@media (max-width: 600px) {
	/* .vf-single already contributes 24px of its own side padding, so the
	   card's own 48px was compounding to 72px of dead space per side on a
	   375px phone — over a third of the viewport width gone before any text. */
	.vf-testimonial--single { padding: 32px 24px; }
}

/* -------------------------------------------------------------------------
   9. Contact / footer
   ---------------------------------------------------------------------- */
.vf-contact {
	text-align: center;
}
.vf-contact__email {
	font-family: var(--vf-font-display);
	font-size: clamp(1.6rem, 4vw, 2.6rem);
	font-weight: 800;
	display: inline-block;
	margin-top: 10px;
	border-bottom: 3px solid var(--vf-accent);
	padding-bottom: 4px;
}
.vf-social-row {
	display: flex;
	justify-content: center;
	gap: 16px;
	margin-top: 34px;
}
.vf-social-row a {
	width: 44px; height: 44px;
	display: flex; align-items: center; justify-content: center;
	border-radius: 50%;
	background: var(--vf-surface);
	border: 1px solid var(--vf-border);
	box-shadow: var(--vf-shadow-soft);
	transition: transform 0.25s ease, background 0.25s ease;
}
.vf-social-row a:hover { transform: translateY(-4px) scale(1.08); background: var(--vf-accent); color: #fff; }
.vf-social-row svg { width: 18px; height: 18px; }

.vf-site-footer {
	padding: 60px 0 140px;
	text-align: center;
	color: var(--vf-text-muted);
	font-size: 13.5px;
}

/* -------------------------------------------------------------------------
   10. Single project / testimonial templates
   ---------------------------------------------------------------------- */
.vf-single {
	max-width: 820px;
	margin: 0 auto;
	padding: 160px 24px 140px;
}
.vf-single--wide { max-width: 1100px; }
.vf-single__title { font-size: clamp(1.8rem, 4vw, 3rem); }
.vf-single__meta { color: var(--vf-text-muted); font-size: 14px; margin-bottom: 30px; }
.vf-single__media { border-radius: var(--vf-radius-md); overflow: hidden; margin-bottom: 36px; box-shadow: var(--vf-shadow-soft); }
.vf-single__body { font-size: 17px; color: var(--vf-text-muted); }
.vf-single__body > * + * { margin-top: 1.1em; }
.vf-back-link { display: inline-block; margin-top: 40px; font-weight: 600; color: var(--vf-accent); }

/* -------------------------------------------------------------------------
   10b. Field Notes — home.php (archive), archive.php (category/tag), and
   single.php (article), built around one shared card (vf_render_note_card())
   so the archive grid and the "More Field Notes" strip look identical.
   ---------------------------------------------------------------------- */
.vf-notes { padding: 160px 0 140px; }

.vf-notes-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 32px;
	margin-top: 40px;
}

.vf-note-card {
	display: flex;
	flex-direction: column;
	background: var(--vf-surface);
	border-radius: var(--vf-radius-md);
	overflow: hidden;
	box-shadow: var(--vf-shadow-soft);
	transition: transform 0.3s ease;
}
.vf-note-card:hover { transform: translateY(-6px); }
.vf-note-card__media { aspect-ratio: 1.8 / 1; background: var(--vf-bg); overflow: hidden; }
.vf-note-card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; }
.vf-note-card:hover .vf-note-card__media img { transform: scale(1.05); }
.vf-note-card__body { padding: 22px 24px 26px; }
.vf-note-card__meta {
	display: flex;
	align-items: center;
	gap: 7px;
	font-size: 12px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--vf-text-muted);
	margin-bottom: 10px;
	flex-wrap: wrap;
}
.vf-note-card__category { color: var(--vf-accent); }
.vf-note-card__dot { opacity: 0.5; }
.vf-note-card__title { font-size: 18px; margin: 0; }
.vf-note-card__excerpt { color: var(--vf-text-muted); font-size: 15px; margin: 10px 0 0; }

/* The lead story: image-left, text-right on wide screens — the "one big
   story + grid of smaller ones" shape of a typical editorial index. */
.vf-note-card--featured {
	display: grid;
	grid-template-columns: 1.15fr 1fr;
	align-items: stretch;
	gap: 0;
}
.vf-note-card--featured .vf-note-card__media { aspect-ratio: auto; height: 100%; }
.vf-note-card--featured .vf-note-card__body { padding: 36px 40px; display: flex; flex-direction: column; justify-content: center; }
.vf-note-card--featured .vf-note-card__title { font-size: clamp(1.6rem, 3vw, 2.2rem); }
@media (max-width: 780px) {
	.vf-note-card--featured { grid-template-columns: 1fr; }
	.vf-note-card--featured .vf-note-card__media { aspect-ratio: 1.8 / 1; height: auto; }
}

/* Single article */
.vf-note__cover { max-width: 1400px; margin: 0 auto; padding: 0 24px; }
.vf-note__cover img { width: 100%; border-radius: var(--vf-radius-md); box-shadow: var(--vf-shadow-soft); }
.vf-note__head {
	max-width: 760px;
	margin: 0 auto;
	padding: 56px 24px 0;
	text-align: center;
}
.vf-note__meta { justify-content: center; }
.vf-note__title { font-size: clamp(2rem, 4.6vw, 3.2rem); }
.vf-note__byline { color: var(--vf-text-muted); font-size: 14px; margin-top: 10px; }
.vf-note__body {
	max-width: 700px;
	margin: 44px auto 0;
	padding: 0 24px 100px;
	font-size: 18px;
	line-height: 1.75;
	color: var(--vf-text-muted);
}
.vf-note__body > * + * { margin-top: 1.3em; }
.vf-note__body h2, .vf-note__body h3 { color: var(--vf-text); font-family: var(--vf-font-display); }
.vf-note__body blockquote {
	margin: 1.6em 0;
	padding-left: 24px;
	border-left: 3px solid var(--vf-accent);
	font-family: var(--vf-font-display);
	font-size: 1.25em;
	font-style: italic;
	color: var(--vf-text);
}
.vf-note__body img { border-radius: var(--vf-radius-sm); }

.vf-notes-related { padding: 0 0 140px; }
.vf-notes-related .vf-container { max-width: 1160px; }
.vf-notes-related__title { font-size: clamp(1.4rem, 2.4vw, 1.8rem); margin-bottom: 8px; }

/* -------------------------------------------------------------------------
   10c. Small-phone grid safety net — every card grid in the theme uses
   repeat(auto-fit, minmax(Npx, 1fr)), which is fine down to ~480px, but the
   minmax minimum (260–300px depending on the grid) is a hard floor: once a
   phone's content width (viewport minus its container's side padding) drops
   below that floor, the track can't shrink further and the grid overflows
   its container instead of wrapping to one column — a real horizontal-
   scroll trap on the narrowest phones. Forcing a single column below 480px
   sidesteps the floor entirely rather than tuning each minmax value closer
   to the edge.
   ---------------------------------------------------------------------- */
@media (max-width: 480px) {
	.vf-work-grid,
	.vf-testimonials,
	.vf-notes-grid,
	.woocommerce ul.products {
		grid-template-columns: 1fr;
	}
}

/* -------------------------------------------------------------------------
   11. Utility
   ---------------------------------------------------------------------- */
.vf-visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

/* -------------------------------------------------------------------------
   12. WooCommerce skin — restyles WooCommerce's own stable markup/classes
   rather than duplicating its templates, so plugin updates keep working.
   ---------------------------------------------------------------------- */
.vf-shop { padding: 160px 24px 140px; }
@media (max-width: 600px) {
	.vf-shop { padding: 120px 10px 90px; }
}

.woocommerce ul.products {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: 28px;
	list-style: none;
	margin: 0 0 40px;
}
/* WooCommerce core still ships width/margin on li.product per columns-N
   (e.g. ".columns-3 li.product { width: 30.75%; margin: 0 4% 2.992em 0; }")
   from its own float-grid era. That selector out-specifies our plain
   "ul.products li.product" rule below, and a percentage width on a grid
   item resolves against its own column track — so without this reset,
   every card shrinks to ~30% of its track and gets extra margin stacked
   on top of our grid gap. Matched at equal specificity for every
   columns-N value WooCommerce's own customizer control can output. */
.woocommerce ul.products.columns-1 li.product,
.woocommerce ul.products.columns-2 li.product,
.woocommerce ul.products.columns-3 li.product,
.woocommerce ul.products.columns-4 li.product,
.woocommerce ul.products.columns-5 li.product,
.woocommerce ul.products.columns-6 li.product,
.woocommerce ul.products li.product {
	width: auto;
	margin: 0;
	background: var(--vf-surface);
	border-radius: var(--vf-radius-md);
	overflow: hidden;
	box-shadow: var(--vf-shadow-soft);
	padding: 0 0 20px;
	transition: transform 0.3s ease;
}
.woocommerce ul.products li.product:hover { transform: translateY(-6px); }
.woocommerce ul.products li.product a { text-decoration: none; color: inherit; display: block; }
.woocommerce ul.products li.product img {
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	margin: 0 0 16px;
	border-radius: 0;
}
.woocommerce ul.products li.product .woocommerce-loop-product__title {
	font-size: 16px;
	font-weight: 700;
	padding: 0 20px;
	margin: 0 0 6px;
}
.woocommerce ul.products li.product .price { padding: 0 20px; color: var(--vf-accent); font-weight: 700; }
.woocommerce span.onsale {
	background: var(--vf-accent);
	color: #fff;
	border-radius: 999px;
	font-weight: 700;
	min-height: auto;
	padding: 4px 12px;
}

.woocommerce div.product .woocommerce-product-gallery { border-radius: var(--vf-radius-md); overflow: hidden; }
.woocommerce div.product p.price, .woocommerce div.product span.price { color: var(--vf-accent); font-size: 22px; font-weight: 700; }
.woocommerce div.product .summary h1.product_title { font-family: var(--vf-font-display); font-size: clamp(1.6rem, 3vw, 2.2rem); }
.woocommerce div.product form.cart { margin-top: 20px; }

.woocommerce a.button, .woocommerce button.button, .woocommerce #respond input#submit, .woocommerce input.button {
	background: var(--vf-accent);
	color: #fff;
	border-radius: 999px;
	padding: 12px 26px;
	font-weight: 600;
	border: none;
	transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.woocommerce a.button:hover, .woocommerce button.button:hover, .woocommerce input.button:hover {
	background: var(--vf-accent);
	color: #fff;
	transform: translateY(-2px);
	box-shadow: 0 10px 26px rgba(59, 91, 253, 0.3);
}

.woocommerce table.shop_table {
	border-radius: var(--vf-radius-md);
	overflow: hidden;
	border: 1px solid var(--vf-border);
	border-collapse: separate;
}
.woocommerce table.shop_table th { background: var(--vf-bg); }
.woocommerce #order_review, .woocommerce-checkout-review-order {
	background: var(--vf-surface);
	border-radius: var(--vf-radius-md);
	padding: 24px;
	box-shadow: var(--vf-shadow-soft);
}
.woocommerce form .form-row input.input-text,
.woocommerce form .form-row textarea,
.woocommerce-checkout select {
	border-radius: var(--vf-radius-sm);
	border: 1px solid var(--vf-border);
	padding: 10px 14px;
	background: var(--vf-surface);
	color: var(--vf-text);
}
.woocommerce-message, .woocommerce-info, .woocommerce-error {
	border-top-color: var(--vf-accent);
	border-radius: var(--vf-radius-sm);
	background: var(--vf-surface);
	box-shadow: var(--vf-shadow-soft);
}

/* -------------------------------------------------------------------------
   13. Digital vs. physical — product badges + shop filter pills
   (inc/woocommerce.php, assets/js/shop-filter.js)
   ---------------------------------------------------------------------- */
.vf-product-badge {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 5px 12px 5px 10px;
	border-radius: 999px;
	font-size: 12px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	margin: 4px 20px 6px;
}
.woocommerce div.product .vf-product-badge { margin-left: 0; }
.vf-product-badge svg { width: 13px; height: 13px; flex: none; }
.vf-product-badge--digital { background: color-mix(in srgb, var(--vf-accent) 14%, transparent); color: var(--vf-accent); }
.vf-product-badge--physical { background: color-mix(in srgb, var(--vf-text) 8%, transparent); color: var(--vf-text-muted); }

.vf-product-type-info { margin-bottom: 18px; }
.vf-product-type-note { color: var(--vf-text-muted); font-size: 14px; margin: 0; }

.vf-shop-filter {
	display: inline-flex;
	gap: 6px;
	padding: 4px;
	background: var(--vf-surface);
	border: 1px solid var(--vf-border);
	border-radius: 999px;
	margin-bottom: 32px;
}
.vf-shop-filter__pill {
	border: none;
	background: transparent;
	color: var(--vf-text-muted);
	font-size: 13.5px;
	font-weight: 600;
	padding: 8px 18px;
	border-radius: 999px;
	cursor: pointer;
	transition: background 0.2s ease, color 0.2s ease;
}
.vf-shop-filter__pill.is-active { background: var(--vf-accent); color: #fff; }
@media (max-width: 480px) {
	.vf-shop-filter { flex-wrap: wrap; }
	.vf-shop-filter__pill { padding: 11px 16px; }
}

/* -------------------------------------------------------------------------
   14. Skip-to-content link (accessibility)
   ---------------------------------------------------------------------- */
.vf-skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 100;
	background: var(--vf-accent);
	color: #fff;
	padding: 12px 20px;
	border-radius: 0 0 8px 0;
	font-weight: 600;
	font-size: 14px;
}
.vf-skip-link:focus { left: 0; }

/* -------------------------------------------------------------------------
   15. Pagination — WordPress core's own the_posts_pagination()/
   the_comments_pagination() markup (.pagination .nav-links .page-numbers),
   skinned to match the theme rather than duplicated.
   ---------------------------------------------------------------------- */
.pagination { margin-top: 48px; text-align: center; }
.pagination .nav-links { display: inline-flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 40px;
	height: 40px;
	padding: 0 14px;
	border-radius: 999px;
	background: var(--vf-surface);
	border: 1px solid var(--vf-border);
	color: var(--vf-text);
	font-weight: 600;
	font-size: 14px;
	text-decoration: none;
	transition: transform 0.2s ease, border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}
.pagination .page-numbers:hover { transform: translateY(-2px); border-color: var(--vf-accent); }
.pagination .page-numbers.current { background: var(--vf-accent); color: #fff; border-color: var(--vf-accent); }
.pagination .page-numbers.dots { background: transparent; border: none; }
@media (max-width: 480px) {
	.pagination .page-numbers { min-width: 44px; height: 44px; }
}

/* -------------------------------------------------------------------------
   16. Shared form styling — the contact form and the comment form
   (comments.php) both use .vf-form for inputs/labels/rows, so they read
   as one consistent system rather than two different-looking forms.
   ---------------------------------------------------------------------- */
.vf-form .vf-form__row,
.vf-form p.comment-form-author,
.vf-form p.comment-form-email,
.vf-form p.comment-form-url,
.vf-form p.comment-form-comment,
.vf-form p.comment-form-cookies-consent {
	margin: 0 0 16px;
}
.vf-form label {
	display: block;
	font-size: 13px;
	font-weight: 600;
	color: var(--vf-text-muted);
	margin-bottom: 6px;
}
.vf-form input[type="text"],
.vf-form input[type="email"],
.vf-form input[type="url"],
.vf-form textarea {
	width: 100%;
	box-sizing: border-box;
	padding: 12px 16px;
	border-radius: var(--vf-radius-sm);
	border: 1px solid var(--vf-border);
	background: var(--vf-surface);
	color: var(--vf-text);
	font-family: inherit;
	/* 16px, not 15px: iOS Safari auto-zooms the whole page on focus for any
	   text input under 16px, which is a jarring, very mobile-specific bug
	   on the theme's own contact/comment/search forms. */
	font-size: 16px;
}
.vf-form input:focus,
.vf-form textarea:focus {
	outline: none;
	border-color: var(--vf-accent);
}
.vf-form textarea { resize: vertical; }
.vf-form .vf-contact-form__hp { position: absolute; left: -9999px; }

.vf-contact-form-wrap { max-width: 480px; margin: 40px auto 0; text-align: left; }
.vf-contact-form__notice {
	padding: 12px 18px;
	border-radius: var(--vf-radius-sm);
	font-size: 14px;
	margin-bottom: 20px;
	text-align: center;
}
.vf-contact-form__notice--success { background: color-mix(in srgb, #35c48b 16%, transparent); color: #1d7a56; }
.vf-contact-form__notice--error { background: color-mix(in srgb, #ff6b57 16%, transparent); color: #a8332a; }

/* -------------------------------------------------------------------------
   17. Comments (comments.php, vf_render_comment())
   ---------------------------------------------------------------------- */
.vf-note__comments { max-width: 700px; margin: 0 auto; padding: 0 24px 80px; }
.vf-comments__title { font-size: 1.4rem; margin-bottom: 24px; }
.vf-comments__list { list-style: none; margin: 0 0 32px; padding: 0; }
.vf-comment {
	padding: 20px 0;
	border-top: 1px solid var(--vf-border);
}
.vf-comments__list .vf-comment .vf-comments__list { margin: 20px 0 0 30px; padding: 0; }
.vf-comment__meta { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.vf-comment__avatar { border-radius: 50%; flex: none; }
.vf-comment__byline { display: flex; flex-direction: column; }
.vf-comment__author { font-weight: 700; font-size: 14.5px; }
.vf-comment__date { font-size: 12.5px; color: var(--vf-text-muted); text-decoration: none; }
.vf-comment__pending { font-size: 13px; color: var(--vf-accent); font-style: italic; margin: 0 0 8px; }
.vf-comment__text { font-size: 15.5px; color: var(--vf-text-muted); }
.vf-comment__text > * + * { margin-top: 0.9em; }
.vf-comment__reply { margin-top: 10px; }
.vf-comment__reply a { font-size: 13px; font-weight: 600; color: var(--vf-accent); }
.vf-comments__closed { color: var(--vf-text-muted); font-size: 14px; }

/* -------------------------------------------------------------------------
   18. Spotlight search (header.php's trigger, footer.php's overlay,
   assets/js/search.js) — a floating glass panel, deliberately not the
   .vf-window component: a Window shows page content, Spotlight finds it —
   the same distinction real macOS keeps between Finder windows and
   Spotlight itself.
   ---------------------------------------------------------------------- */
.vf-spotlight-trigger {
	pointer-events: auto;
	width: 36px;
	height: 36px;
	border-radius: 50%;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: color-mix(in srgb, var(--vf-surface) 55%, transparent);
	backdrop-filter: blur(24px) saturate(190%);
	-webkit-backdrop-filter: blur(24px) saturate(190%);
	border: 1px solid color-mix(in srgb, var(--vf-text) 8%, transparent);
	color: var(--vf-text);
	cursor: pointer;
	flex: none;
}
.vf-spotlight-trigger svg { width: 16px; height: 16px; }
.vf-spotlight-trigger:hover { color: var(--vf-accent); }

.vf-spotlight-overlay {
	position: fixed;
	inset: 0;
	z-index: 60;
	display: none;
	align-items: flex-start;
	justify-content: center;
	padding-top: 12vh;
	background: rgba(10, 10, 12, 0.35);
}
.vf-spotlight-overlay.is-open { display: flex; }
.vf-spotlight {
	width: min(560px, 92vw);
	max-height: 70vh;
	display: flex;
	flex-direction: column;
	background: color-mix(in srgb, var(--vf-surface) 90%, transparent);
	backdrop-filter: blur(32px) saturate(190%);
	-webkit-backdrop-filter: blur(32px) saturate(190%);
	border-radius: 18px;
	border: 1px solid var(--vf-border);
	box-shadow: 0 40px 100px rgba(0, 0, 0, 0.4);
	overflow: hidden;
}
.vf-spotlight__input-row {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 18px 20px;
	border-bottom: 1px solid var(--vf-border);
	flex: none;
}
.vf-spotlight__input-row svg { width: 20px; height: 20px; color: var(--vf-text-muted); flex: none; }
.vf-spotlight__input {
	flex: 1;
	border: none;
	background: transparent;
	font-size: 17px;
	color: var(--vf-text);
	outline: none;
	font-family: inherit;
}
.vf-spotlight__results { overflow-y: auto; }
.vf-spotlight__result {
	display: flex;
	flex-direction: column;
	gap: 2px;
	padding: 12px 20px;
	text-decoration: none;
}
.vf-spotlight__result:hover,
.vf-spotlight__result.is-active { background: color-mix(in srgb, var(--vf-accent) 10%, transparent); }
.vf-spotlight__result-title { font-weight: 600; color: var(--vf-text); font-size: 14.5px; }
.vf-spotlight__result-type { font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--vf-text-muted); }
.vf-spotlight__empty { padding: 24px 20px; color: var(--vf-text-muted); font-size: 14px; text-align: center; }
.vf-spotlight__footer {
	flex: none;
	padding: 10px 20px;
	border-top: 1px solid var(--vf-border);
	font-size: 12px;
	color: var(--vf-text-muted);
	display: flex;
	justify-content: space-between;
}

@media (max-width: 600px) {
	.vf-spotlight-overlay { padding-top: 6vh; }
	/* Phones have no ⌘K — this trigger is the entire mobile path to search,
	   so its 36px desktop size (a mouse-precision target) is bumped to the
	   ~44px comfortable minimum for a fingertip. */
	.vf-spotlight-trigger { width: 44px; height: 44px; }
	.vf-spotlight-trigger svg { width: 18px; height: 18px; }
}

/* -------------------------------------------------------------------------
   19. Discount popup (inc/promo-popup.php, assets/js/promo-popup.js)
   ---------------------------------------------------------------------- */
.vf-promo-overlay {
	position: fixed;
	inset: 0;
	z-index: 65;
	display: none;
	align-items: center;
	justify-content: center;
	padding: 24px;
	background: rgba(10, 10, 12, 0.5);
}
.vf-promo-overlay.is-open { display: flex; }
.vf-promo-modal {
	position: relative;
	width: min(440px, 100%);
	background: var(--vf-surface);
	border-radius: var(--vf-radius-lg);
	box-shadow: 0 40px 100px rgba(0, 0, 0, 0.4);
	padding: 40px 32px 32px;
	text-align: center;
}
.vf-promo-modal__close {
	position: absolute;
	top: 14px;
	right: 14px;
	width: 30px;
	height: 30px;
	border-radius: 50%;
	border: none;
	background: var(--vf-bg);
	color: var(--vf-text-muted);
	font-size: 18px;
	line-height: 1;
	cursor: pointer;
}
.vf-promo-modal__title { font-size: clamp(1.4rem, 3vw, 1.8rem); margin-bottom: 8px; }
.vf-promo-modal__subtitle { color: var(--vf-text-muted); font-size: 14.5px; margin-bottom: 24px; }
.vf-promo-modal__actions { display: flex; flex-direction: column; gap: 10px; margin-bottom: 20px; text-align: left; }
.vf-promo-action {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	padding: 13px 16px;
	border-radius: var(--vf-radius-sm);
	border: 1.5px solid var(--vf-border);
	background: var(--vf-bg);
	font-family: inherit;
	font-size: 14.5px;
	font-weight: 600;
	color: var(--vf-text);
	cursor: pointer;
	transition: border-color 0.2s ease, background 0.2s ease;
}
.vf-promo-action input[type="checkbox"] { margin: 0; accent-color: var(--vf-accent); }
.vf-promo-action.is-done,
.vf-promo-action:has(input:checked) {
	border-color: var(--vf-accent);
	background: color-mix(in srgb, var(--vf-accent) 8%, var(--vf-bg));
}
.vf-promo-action__badge {
	font-size: 12px;
	font-weight: 700;
	color: var(--vf-accent);
	flex: none;
}
.vf-promo-modal__percent { font-size: 15px; margin-bottom: 16px; }
.vf-promo-modal__percent strong { color: var(--vf-accent); font-size: 20px; }
.vf-promo-modal__email {
	width: 100%;
	box-sizing: border-box;
	padding: 12px 16px;
	border-radius: var(--vf-radius-sm);
	border: 1px solid var(--vf-border);
	background: var(--vf-surface);
	color: var(--vf-text);
	font-family: inherit;
	font-size: 16px; /* not 15px — avoids iOS Safari's auto-zoom-on-focus */
	margin-bottom: 12px;
}
.vf-promo-modal__email:focus { outline: none; border-color: var(--vf-accent); }
#vf-promo-claim { width: 100%; justify-content: center; }
.vf-promo-modal__status { min-height: 1.4em; font-size: 13.5px; color: var(--vf-accent); margin: 10px 0 0; }
.vf-promo-modal__note { font-size: 12px; color: var(--vf-text-muted); margin: 14px 0 0; }
@media (max-width: 480px) {
	.vf-promo-overlay { padding: 16px; }
	.vf-promo-modal { padding: 32px 20px 24px; }
	/* 30px is under the ~44px minimum comfortable touch target; this is the
	   one control in the modal a visitor needs to hit accurately on a phone
	   with no pointer precision to fall back on. */
	.vf-promo-modal__close { width: 40px; height: 40px; }
}

/* -------------------------------------------------------------------------
   20. WooCommerce My Account — was previously unstyled (page.php only
   widened Cart/Checkout, not Account or order-received), so the login/
   register form, order history, addresses, and account details all
   rendered with WooCommerce's bare defaults. Targets its stable class
   names, same approach as the rest of the WooCommerce skin.
   ---------------------------------------------------------------------- */
.woocommerce-account .woocommerce-MyAccount-navigation {
	float: none;
	width: auto;
	margin-bottom: 32px;
}
.woocommerce-MyAccount-navigation ul { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; margin: 0; padding: 0; }
.woocommerce-MyAccount-navigation li { margin: 0; }
.woocommerce-MyAccount-navigation li a {
	display: inline-block;
	padding: 9px 18px;
	border-radius: 999px;
	background: var(--vf-surface);
	border: 1px solid var(--vf-border);
	font-size: 13.5px;
	font-weight: 600;
	text-decoration: none;
	color: var(--vf-text);
}
.woocommerce-MyAccount-navigation li.is-active a { background: var(--vf-accent); border-color: var(--vf-accent); color: #fff; }
.woocommerce-MyAccount-content { float: none; width: auto; }
.woocommerce table.shop_table_responsive th,
.woocommerce table.my_account_orders th { background: var(--vf-bg); }
.woocommerce-MyAccount-content mark.order-status { color: var(--vf-accent); font-weight: 600; }
.woocommerce-address-fields fieldset,
.woocommerce-EditAccountForm fieldset {
	border: 1px solid var(--vf-border);
	border-radius: var(--vf-radius-sm);
	padding: 20px;
	margin-bottom: 20px;
}
.woocommerce-address-fields legend,
.woocommerce-EditAccountForm legend { font-weight: 700; padding: 0 6px; }
.woocommerce-form-row label { display: block; font-size: 13px; font-weight: 600; color: var(--vf-text-muted); margin-bottom: 6px; }
.woocommerce-form-row input.input-text,
.woocommerce-form-row select {
	width: 100%;
	box-sizing: border-box;
	padding: 10px 14px;
	border-radius: var(--vf-radius-sm);
	border: 1px solid var(--vf-border);
	background: var(--vf-surface);
	color: var(--vf-text);
}

/* -------------------------------------------------------------------------
   21. WPMU DEV plugin compatibility — a Forminator form embedded via
   [forminator_form id="X"] (in an HTML/Paragraph block, a shortcode, or
   Forminator's own block) reskinned onto the theme's own tokens instead of
   Forminator's plain defaults, targeting its stable, documented markup.
   Hustle's own popups/embeds are meant to be color-matched from Hustle's
   own design settings (see readme.txt) rather than fought with theme CSS,
   but the font-family reset below is a safe, generic touch-up for any
   WPMU DEV embed so it doesn't default to the browser's serif fallback
   inside a page built on the theme's own type.
   ---------------------------------------------------------------------- */
.forminator-custom-form { font-family: inherit; }
.forminator-custom-form .forminator-label {
	font-size: 13px;
	font-weight: 600;
	color: var(--vf-text-muted);
	margin-bottom: 6px;
}
.forminator-custom-form .forminator-input,
.forminator-custom-form .forminator-textarea-input,
.forminator-custom-form select.forminator-select,
.forminator-custom-form .forminator-select2-container {
	width: 100%;
	box-sizing: border-box;
	padding: 10px 14px;
	border-radius: var(--vf-radius-sm);
	border: 1px solid var(--vf-border);
	background: var(--vf-surface);
	color: var(--vf-text);
	font-family: inherit;
	font-size: 16px; /* not 15px — avoids iOS Safari's auto-zoom-on-focus */
}
.forminator-custom-form .forminator-input:focus,
.forminator-custom-form .forminator-textarea-input:focus {
	outline: none;
	border-color: var(--vf-accent);
}
.forminator-custom-form .forminator-button-submit,
.forminator-custom-form .forminator-button {
	font-family: inherit;
	font-weight: 600;
	border-radius: 999px;
	background: var(--vf-accent);
	color: #fff;
	border: none;
	padding: 11px 22px;
	cursor: pointer;
}
[class*="hustle"], [class*="wpmudev-hustle"] { font-family: inherit; }

/* -------------------------------------------------------------------------
   22. Reduced motion — a single, universal backstop so every animation and
   transition in the theme respects prefers-reduced-motion, not just the
   ones that happened to get an explicit check. assets/js/dock.js already
   skips its own JS-driven magnify/bounce logic under this preference (see
   its `reduceMotion` check), but that only covers what JS controls — this
   rule additionally neutralizes the floating hero chips' infinite
   vf-float animation, the dock's vf-dock-bounce keyframes (belt-and-
   suspenders, in case anything ever adds .is-launching outside dock.js's
   own guard), every hover/focus transition (cards, buttons, the dock
   magnify transform), .vf-reveal's scroll-triggered fade-in, and html's
   scroll-behavior:smooth anchor jumps (#work, #contact, etc.) — collapsing
   every duration to effectively zero rather than auditing each one
   individually, so nothing animated purely in CSS is missed.
   ---------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}
}

/* Page Builder section rendering (.vf-pb-section*, .vf-pb-spacer*) lives in
   assets/css/page-builder.css, enqueued separately — see functions.php. */
