/* ==========================================================================
   Vanguard — component layer
   theme.json owns tokens (colour, type scale, spacing). This file owns
   components theme.json cannot express. Every colour here is a token var;
   no raw hex except in the grid motif, which is an alpha wash.
   ========================================================================== */

:root {
	--vg-hairline: var(--wp--preset--color--hairline);
	--vg-radius: 4px;
	--vg-radius-lg: 6px;
	--vg-tap: 44px;
	--vg-ease: cubic-bezier(.2, 0, .2, 1);
	--vg-dur: 150ms;
	--vg-header-h: 60px;
	--vg-rule: rgba(11, 12, 14, .055);
	/* The convergence lines carry their own per-line opacity, so they need the
	   colour at full strength and let the SVG do the fading. */
	--vg-rule-solid: rgba(11, 12, 14, .5);
	--vg-bloom: rgba(59, 73, 245, .07);
	/* Lifted from the logo: the one chevron picked out of the formation. It marks
	   the leading position, so it appears exactly twice, on the brand mark and at
	   the vertex. Do not spend it anywhere else. */
	--vg-coral: #E0574A;
}

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

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

html { scroll-behavior: smooth; }
body { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }

::selection { background: var(--wp--preset--color--accent); color: #fff; }

/* The filter island hides cards with `el.hidden = true`. The UA stylesheet's
   [hidden] { display: none } is beaten by any author display rule, and .vg-card
   sets display:flex, .vg-grid-cards sets display:grid. Without this the library
   search and the domain filters update the count and hide nothing. */
[hidden]:not([hidden="until-found"]) { display: none !important; }

a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, summary:focus-visible, [tabindex]:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
	border-radius: 2px;
}

.vg-skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 999;
	padding: .75rem 1.125rem;
	background: var(--wp--preset--color--ink);
	color: #fff;
	font-size: var(--wp--preset--font-size--small);
	border-radius: 0 0 var(--vg-radius) 0;
}
.vg-skip-link:focus { left: 0; }

/* Monospace machine register — IDs, tags, counts, metadata. */
.vg-mono,
.vg-tag,
.vg-id,
.vg-price,
.vg-stat__value {
	font-family: var(--wp--preset--font-family--mono);
	font-variant-numeric: tabular-nums;
}

/* Page-type label. Sentence case, no tracking, no rule: it names the surface
   you are on and nothing more. */
.vg-eyebrow {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink-faint);
	margin: 0 0 .5rem;
}

/* Page-rules motif.
   Faint horizontal rules, the spacing of lines of type on a page, fading in from
   the top right where no copy sits, under a soft accent bloom. It reads as a
   printed page rather than as engineering graph paper, which suits a publisher.
   Both layers sit on pseudo-elements, so the fade never touches the content. */
.vg-page-motif { position: relative; }
.vg-page-motif > * { position: relative; z-index: 1; }
.vg-page-motif::before,
.vg-page-motif::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
}
.vg-page-motif::before {
	background-image: repeating-linear-gradient(
		to bottom,
		var(--vg-rule) 0, var(--vg-rule) 1px,
		transparent 1px, transparent 30px
	);
	-webkit-mask-image: linear-gradient(112deg, transparent 34%, #000 78%);
	        mask-image: linear-gradient(112deg, transparent 34%, #000 78%);
}
.vg-page-motif::after {
	background: radial-gradient(58% 64% at 86% 6%, var(--vg-bloom), transparent 62%);
}

/* Convergence.
   Rules shorten as they descend and resolve into a single chevron. Scattered
   data narrowing until a decision falls out, which is the product, and the V is
   the initial. The chevron geometry comes from the logo formation. */
.vg-converge { position: relative; overflow: hidden; }
.vg-converge::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	z-index: 0;
	background: radial-gradient(56% 62% at 82% 12%, var(--vg-bloom), transparent 64%);
}
.vg-converge > * { position: relative; z-index: 1; }
.vg-converge__art {
	position: absolute;
	top: 0;
	right: max(2vw, calc((100vw - 1192px) / 2));
	height: 100%;
	width: min(42vw, 520px);
	/* Above .vg-hero__inner, which spans the whole 1240px column and would
	   otherwise swallow every pointer event before the art saw one. Nothing
	   interactive sits under this band: the headline is capped at 15ch and the
	   buttons end well left of it. */
	z-index: 2;
	display: flex;
	align-items: center;
}
.vg-converge__svg { width: 100%; height: auto; max-height: 86%; display: block; }

/* The art is absolutely placed, so the copy has to be told to stay out of its
   column. Below 1100px there is not enough width for both, and the art leaves
   rather than sitting behind the text. */
@media (max-width: 1100px) {
	.vg-converge__art { display: none; }
}
@media (min-width: 1101px) {
	.vg-converge .vg-hero__title { max-width: 15ch; }
	.vg-converge .vg-hero__lede { max-width: 46ch; }
}

/* Brand mark: two chevrons, the lead one coral. The logo in miniature. */
.vg-brand__mark { display: block; flex: none; margin-right: .1rem; }

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

.vg-header {
	position: sticky;
	top: 0;
	z-index: 100;
	background: rgba(255, 255, 255, .86);
	backdrop-filter: saturate(1.6) blur(10px);
	-webkit-backdrop-filter: saturate(1.6) blur(10px);
	border-bottom: 1px solid var(--vg-hairline);
}
.vg-header__inner {
	max-width: 1240px;
	margin-inline: auto;
	padding: 0 var(--wp--preset--spacing--30);
	min-height: var(--vg-header-h);
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--30);
}
.vg-brand {
	display: inline-flex;
	align-items: center;
	gap: .4rem;
	font-weight: 660;
	font-size: 1.0625rem;
	letter-spacing: -.03em;
	color: var(--wp--preset--color--ink);
	text-decoration: none;
	flex: none;
}

.vg-nav { display: flex; align-items: center; gap: .25rem; margin-left: auto; }
.vg-nav__list { display: flex; align-items: center; gap: .25rem; list-style: none; margin: 0; padding: 0; }
.vg-nav__link {
	display: inline-flex;
	align-items: center;
	height: 34px;
	padding: 0 .6875rem;
	border-radius: var(--vg-radius);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	color: var(--wp--preset--color--ink-muted);
	text-decoration: none;
	transition: color var(--vg-dur) var(--vg-ease), background var(--vg-dur) var(--vg-ease);
	white-space: nowrap;
}
.vg-nav__link:hover { color: var(--wp--preset--color--ink); background: var(--wp--preset--color--panel); text-decoration: none; }
.vg-nav__link[aria-current="page"] { color: var(--wp--preset--color--ink); font-weight: 560; }

.vg-header__actions { display: flex; align-items: center; gap: .5rem; flex: none; }

.vg-cart {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px; height: 34px;
	border-radius: var(--vg-radius);
	color: var(--wp--preset--color--ink-muted);
}
.vg-cart:hover { background: var(--wp--preset--color--panel); color: var(--wp--preset--color--ink); }
.vg-cart__count {
	position: absolute; top: 1px; right: 1px;
	min-width: 15px; height: 15px; padding: 0 3px;
	border-radius: 999px;
	background: var(--wp--preset--color--accent);
	color: #fff;
	font-family: var(--wp--preset--font-family--mono);
	font-size: 9px; line-height: 15px; text-align: center;
	font-variant-numeric: tabular-nums;
}

/* On a phone the brand, the menu button and the two actions did not fit, and
   every page scrolled sideways by 17px at 375 and 20px at 320. Measured, not
   guessed. The header keeps all three groups and loses only the Browse button,
   which is the same destination as "Case Library" inside the menu; "Sign in"
   stays, because the menu carries no other route to it. */
@media (max-width: 560px) {
	.vg-header__inner { padding-inline: 1rem; gap: .75rem; }
	.vg-header__actions { gap: .5rem; }
	/* Two classes deep on purpose. `.vg-btn` sets its own display further down
	   this file, and at equal specificity the later rule wins, so a single
	   class here was silently ignored. */
	.vg-header__actions .vg-header__cta { display: none; }
}

/* Mobile nav: a disclosure, no framework. */
.vg-nav-toggle { display: none; }
@media (max-width: 860px) {
	.vg-nav-toggle {
		display: inline-flex; align-items: center; justify-content: center;
		width: 44px; height: 44px; margin-left: auto;
		border: 1px solid var(--vg-hairline); border-radius: var(--vg-radius);
		background: transparent; color: var(--wp--preset--color--ink); cursor: pointer;
	}
	.vg-nav {
		position: fixed;
		inset: var(--vg-header-h) 0 auto 0;
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		margin: 0;
		padding: var(--wp--preset--spacing--20);
		background: var(--wp--preset--color--base);
		border-bottom: 1px solid var(--vg-hairline);
		box-shadow: var(--wp--preset--shadow--lift);
	}
	.vg-nav[hidden] { display: none; }
	.vg-nav__list { flex-direction: column; align-items: stretch; gap: 0; }
	.vg-nav__link { height: var(--vg-tap); padding-inline: .75rem; font-size: var(--wp--preset--font-size--base); }
}

/* ------------------------------------------------------------ buttons --- */

/* Every control here was written with border-box numbers: min-height 38px
   means 38px on the page. The site had no box-sizing reset, so padding and
   border were added on top, and the header's buttons measured 56px against a
   60px header (the large ones 70px). Scoped to the theme's own controls
   rather than a global reset, which would also resize plugin widgets that
   were built the other way. */
.vg-btn,
.vg-cart,
.vg-nav__link,
.vg-nav-toggle,
.vg-filter,
.vg-tag,
.vg-search__input,
.vg-select,
.vg-subnav__link,
.vg-um .um input[type="submit"].um-button,
.vg-um .um a.um-button,
.vg-um .um .um-form input,
.vg-redirector .simple-redirector-form input,
.vg-password .post-password-form input,
.vg-contact__form input,
.vg-contact__form textarea,
.vg-contact__form select { box-sizing: border-box; }

.vg-btn {
	display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
	min-height: 38px;
	padding: .5rem 1.0625rem;
	border: 1px solid var(--wp--preset--color--accent);
	border-radius: var(--vg-radius);
	background: var(--wp--preset--color--accent);
	color: #fff;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 560;
	text-decoration: none;
	cursor: pointer;
	transition: background var(--vg-dur) var(--vg-ease), border-color var(--vg-dur) var(--vg-ease);
}
.vg-btn:hover { background: #2E3AD4; border-color: #2E3AD4; color: #fff; text-decoration: none; }

.vg-btn--ghost {
	background: transparent;
	color: var(--wp--preset--color--ink);
	border-color: var(--vg-hairline);
}
.vg-btn--ghost:hover { background: var(--wp--preset--color--panel); border-color: var(--wp--preset--color--ink-faint); color: var(--wp--preset--color--ink); }

.vg-btn--quiet { background: transparent; border-color: transparent; color: var(--wp--preset--color--ink-muted); }
.vg-btn--quiet:hover { background: var(--wp--preset--color--panel); color: var(--wp--preset--color--ink); border-color: transparent; }

.vg-btn--lg { min-height: 46px; padding: .6875rem 1.375rem; font-size: var(--wp--preset--font-size--base); }
.vg-btn[disabled], .vg-btn[aria-disabled="true"] { opacity: .45; pointer-events: none; }
/* Pointer-sized controls on touch widths. 38px is comfortable with a mouse and
   short of the 44px touch minimum. */
@media (max-width: 860px) {
	.vg-btn { min-height: 44px; }
	a.vg-tag { min-height: 32px; padding-inline: .625rem; }
}

/* --------------------------------------------------------------- tags --- */

.vg-tag {
	display: inline-flex; align-items: center;
	height: 21px; padding: 0 .5rem;
	border: 1px solid var(--vg-hairline);
	border-radius: 3px;
	background: var(--wp--preset--color--base);
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: .015em;
	color: var(--wp--preset--color--ink-muted);
	white-space: nowrap;
	text-decoration: none;
}
a.vg-tag:hover { border-color: var(--wp--preset--color--accent); color: var(--wp--preset--color--accent); text-decoration: none; }
.vg-tag--owned { border-color: transparent; background: var(--wp--preset--color--signal-soft); color: var(--wp--preset--color--signal); }
.vg-tag--accent { border-color: transparent; background: var(--wp--preset--color--accent-soft); color: var(--wp--preset--color--accent); }
.vg-tags { display: flex; flex-wrap: wrap; gap: .3125rem; }

/* -------------------------------------------------- case-study module --- */

.vg-grid-cards {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(258px, 1fr));
	gap: 1px;
	background: var(--vg-hairline);
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius-lg);
	overflow: hidden;
}

/* One hairline lattice: cards sit on a 1px grid background, so every gutter
   is a rule and no card needs its own border. */
.vg-card {
	position: relative;
	display: flex;
	flex-direction: column;
	background: var(--wp--preset--color--base);
	padding: var(--wp--preset--spacing--30);
	min-height: 232px;
	transition: background var(--vg-dur) var(--vg-ease);
}
.vg-card:hover { background: var(--wp--preset--color--panel); }
.vg-card:focus-within { background: var(--wp--preset--color--panel); }

.vg-card__head { display: flex; align-items: center; justify-content: space-between; gap: .75rem; margin-bottom: .875rem; }
.vg-card__id {
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink);
	font-weight: 500;
}
.vg-card__price { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink); font-weight: 500; }
.vg-card__price del { color: var(--wp--preset--color--ink-faint); font-weight: 400; margin-right: .3rem; }
.vg-card__price ins { text-decoration: none; color: var(--wp--preset--color--accent); }

.vg-card__title {
	font-size: var(--wp--preset--font-size--base);
	font-weight: 400;
	line-height: 1.5;
	letter-spacing: -.008em;
	color: var(--wp--preset--color--ink-muted);
	margin: 0 0 auto;
	display: -webkit-box;
	-webkit-line-clamp: 4;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.vg-card__title a { color: inherit; text-decoration: none; }

/* The whole card is the target; the link keeps the accessible name. */
.vg-card__link::after { content: ""; position: absolute; inset: 0; }
.vg-card__link:focus-visible { outline: none; }
.vg-card:has(.vg-card__link:focus-visible) { outline: 2px solid var(--wp--preset--color--accent); outline-offset: -2px; }

.vg-card__foot { display: flex; align-items: center; justify-content: space-between; gap: .75rem; margin-top: 1rem; }
.vg-card__thumb {
	width: 100%; aspect-ratio: 16 / 9;
	object-fit: cover;
	border-radius: var(--vg-radius);
	background: var(--wp--preset--color--panel);
	margin-bottom: .875rem;
	border: 1px solid var(--vg-hairline);
}

/* --------------------------------------------------------- library UI --- */

.vg-toolbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: .625rem;
	padding: var(--wp--preset--spacing--20) 0;
	margin-bottom: var(--wp--preset--spacing--20);
}
.vg-search {
	position: relative;
	flex: 1 1 240px;
	min-width: 0;
}
.vg-search__input {
	width: 100%;
	height: 38px;
	padding: 0 .75rem 0 2.125rem;
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius);
	background: var(--wp--preset--color--base);
	font: inherit;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink);
}
.vg-search__input::placeholder { color: var(--wp--preset--color--ink-faint); }
.vg-search__input:focus { border-color: var(--wp--preset--color--accent); box-shadow: 0 0 0 3px var(--wp--preset--color--accent-soft); }
.vg-search__icon { position: absolute; left: .6875rem; top: 50%; transform: translateY(-50%); color: var(--wp--preset--color--ink-faint); pointer-events: none; }

.vg-select {
	height: 38px;
	padding: 0 2rem 0 .75rem;
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius);
	background: var(--wp--preset--color--base) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5 6 8l3-3.5' fill='none' stroke='%235C626E' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right .625rem center;
	font: inherit;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink);
	appearance: none;
	cursor: pointer;
}

.vg-filters { display: flex; flex-wrap: wrap; gap: .375rem; }
.vg-filter {
	display: inline-flex; align-items: center; gap: .375rem;
	height: 30px; padding: 0 .625rem;
	border: 1px solid var(--vg-hairline);
	border-radius: 999px;
	background: var(--wp--preset--color--base);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: 0;
	color: var(--wp--preset--color--ink-muted);
	cursor: pointer;
	white-space: nowrap;
	transition: all var(--vg-dur) var(--vg-ease);
}
.vg-filter:hover { border-color: var(--wp--preset--color--ink-faint); color: var(--wp--preset--color--ink); }
.vg-filter[aria-pressed="true"] {
	background: var(--wp--preset--color--ink);
	border-color: var(--wp--preset--color--ink);
	color: #fff;
}
.vg-filter__count { opacity: .55; font-variant-numeric: tabular-nums; }

.vg-resultbar {
	display: flex; align-items: center; justify-content: space-between; gap: 1rem;
	padding-bottom: .75rem;
	border-bottom: 1px solid var(--vg-hairline);
	margin-bottom: var(--wp--preset--spacing--30);
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink-faint);
	font-variant-numeric: tabular-nums;
}

.vg-empty {
	padding: var(--wp--preset--spacing--60) var(--wp--preset--spacing--30);
	text-align: center;
	border: 1px dashed var(--vg-hairline);
	border-radius: var(--vg-radius-lg);
	color: var(--wp--preset--color--ink-muted);
}
.vg-empty__title { font-weight: 560; color: var(--wp--preset--color--ink); margin-bottom: .375rem; }

/* --------------------------------------------------- case-study page --- */

.vg-case { max-width: 1240px; margin-inline: auto; padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--30) var(--wp--preset--spacing--60); }
.vg-case__layout { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: var(--wp--preset--spacing--50); align-items: start; }
@media (max-width: 900px) { .vg-case__layout { grid-template-columns: 1fr; } }

.vg-breadcrumb {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink-faint);
	margin-bottom: var(--wp--preset--spacing--30);
}
.vg-breadcrumb a { color: var(--wp--preset--color--ink-faint); text-decoration: none; }
.vg-breadcrumb a:hover { color: var(--wp--preset--color--accent); }
.vg-breadcrumb span { margin: 0 .5rem; opacity: .5; }

.vg-case__title {
	font-size: var(--wp--preset--font-size--xxl);
	line-height: 1.12;
	letter-spacing: -.026em;
	margin: 0 0 var(--wp--preset--spacing--30);
}
.vg-case__lede {
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.5;
	color: var(--wp--preset--color--ink-muted);
	margin: 0 0 var(--wp--preset--spacing--40);
	max-width: 62ch;
}
.vg-case__figure { margin: 0 0 var(--wp--preset--spacing--40); }
.vg-case__figure img {
	width: 100%; height: auto; display: block;
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius-lg);
	background: var(--wp--preset--color--panel);
}

/* The case page on one screen (U95). The image and the details sit side by
   side instead of stacked: a square illustration at the column's full width
   was 854px tall by itself at 1440, so the page ran to 2354px and the details
   began below the fold. The details column holds the spec for a member and
   the sign-in invitation for a guest, so both see the same shape. */
.vg-case__media {
	display: grid;
	grid-template-columns: minmax(0, 17.5rem) minmax(0, 1fr);
	gap: var(--wp--preset--spacing--40);
	align-items: start;
}
.vg-case__media .vg-case__figure { margin: 0; }
.vg-case__media .vg-case__figure img { aspect-ratio: 1 / 1; object-fit: cover; }
.vg-case__media .vg-spec,
.vg-case__media .vg-gate { margin: 0; }
.vg-case__media .vg-spec { border-top: 1px solid var(--vg-hairline); }
.vg-case__media .vg-spec--compact .vg-spec__row { grid-template-columns: 7.5rem minmax(0, 1fr); }
/* No image: the details take the whole row rather than the image's column.
   Two classes, so the width breakpoints below cannot override it. */
.vg-case__media.vg-case__media--bare { grid-template-columns: 1fr; }
/* Tighter above the fold, which is where the height went. Measured with the
   details in place: they end at 630px, so the case and the buy panel fit on
   any common laptop, and the terms end at 853px, inside 1536x864. */
.vg-case { padding-top: var(--wp--preset--spacing--30); }
.vg-case .vg-breadcrumb { margin-bottom: var(--wp--preset--spacing--20); }
.vg-case .vg-case__title { margin-bottom: var(--wp--preset--spacing--20); }
.vg-case .vg-case__lede { margin-bottom: var(--wp--preset--spacing--30); }
.vg-case .vg-prose { margin-top: var(--wp--preset--spacing--40); }
.vg-case .vg-disclaimer { margin-top: var(--wp--preset--spacing--30); padding-top: var(--wp--preset--spacing--20); }
.vg-case .vg-disclaimer p { margin-bottom: .375rem; line-height: 1.5; }
/* Stack again where two columns would crush the details. */
@media (max-width: 1100px) {
	.vg-case__media { grid-template-columns: minmax(0, 13rem) minmax(0, 1fr); }
}
@media (max-width: 640px) {
	.vg-case__media { grid-template-columns: 1fr; }
	.vg-case__media .vg-case__figure { max-width: 20rem; }
}

/* Buy panel — sticky on desktop, inline on mobile. */
.vg-buy {
	position: sticky; top: calc(var(--vg-header-h) + 16px);
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius-lg);
	padding: var(--wp--preset--spacing--30);
	background: var(--wp--preset--color--base);
}
@media (max-width: 900px) { .vg-buy { position: static; } }
.vg-buy__price {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--xl);
	font-variant-numeric: tabular-nums;
	letter-spacing: -.02em;
	color: var(--wp--preset--color--ink);
	line-height: 1;
	margin-bottom: .25rem;
}
.vg-buy__note { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-muted); margin-bottom: var(--wp--preset--spacing--30); }
.vg-buy .vg-btn { width: 100%; }
.vg-buy__meta { margin-top: var(--wp--preset--spacing--30); padding-top: var(--wp--preset--spacing--20); border-top: 1px solid var(--vg-hairline); }

.vg-meta { display: grid; gap: .625rem; }
.vg-meta__row { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; font-size: var(--wp--preset--font-size--small); }
.vg-meta__k {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink-faint);
	flex: none;
}
.vg-meta__v { color: var(--wp--preset--color--ink); text-align: right; }

.vg-prose { max-width: 68ch; }
.vg-prose h2 { margin: var(--wp--preset--spacing--50) 0 var(--wp--preset--spacing--20); }
.vg-prose h3 { margin: var(--wp--preset--spacing--40) 0 var(--wp--preset--spacing--10); }
.vg-prose p { margin: 0 0 var(--wp--preset--spacing--20); color: var(--wp--preset--color--ink-muted); }
.vg-prose ul, .vg-prose ol { margin: 0 0 var(--wp--preset--spacing--20); padding-left: 1.25rem; color: var(--wp--preset--color--ink-muted); }
.vg-prose li { margin-bottom: .375rem; }
.vg-prose li::marker { color: var(--wp--preset--color--ink-faint); }

/* Legal pages. Long, numbered, referred back to rather than read straight
   through, so the headings need to be findable by eye when scrolling. */
.vg-prose--legal { max-width: 74ch; padding-bottom: var(--wp--preset--spacing--50); }
.vg-prose--legal h2 {
	font-size: var(--wp--preset--font-size--large);
	padding-top: var(--wp--preset--spacing--30);
	border-top: 1px solid var(--vg-hairline);
}
.vg-prose--legal h3 { font-size: var(--wp--preset--font-size--medium); }
.vg-prose--legal a { color: var(--wp--preset--color--accent); }
.vg-prose--legal table {
	width: 100%;
	border-collapse: collapse;
	margin: 0 0 var(--wp--preset--spacing--20);
	font-size: var(--wp--preset--font-size--small);
}
.vg-prose--legal th,
.vg-prose--legal td {
	text-align: left;
	padding: .625rem .75rem;
	border-bottom: 1px solid var(--vg-hairline);
	vertical-align: top;
}
.vg-prose--legal th { font-weight: 560; color: var(--wp--preset--color--ink); }

/* Sectioned spec list — the "simulation briefing" register. */
.vg-spec { border-top: 1px solid var(--vg-hairline); margin-top: var(--wp--preset--spacing--50); }
.vg-spec__row { display: grid; grid-template-columns: 180px minmax(0, 1fr); gap: var(--wp--preset--spacing--30); padding: var(--wp--preset--spacing--30) 0; border-bottom: 1px solid var(--vg-hairline); }
@media (max-width: 640px) { .vg-spec__row { grid-template-columns: 1fr; gap: .5rem; } }
/* Labels are words, so the sans in sentence case. They were mono capitals,
   which the design register reserves for codes (DESIGN-PASS.md section 2). */
.vg-spec__k {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	color: var(--wp--preset--color--ink);
	padding-top: .1rem;
}
.vg-spec__v { color: var(--wp--preset--color--ink-muted); }
.vg-spec__v > :last-child { margin-bottom: 0; }

/* ------------------------------------------------------ member library --- */

.vg-lib { display: grid; gap: 1px; background: var(--vg-hairline); border: 1px solid var(--vg-hairline); border-radius: var(--vg-radius-lg); overflow: hidden; }
.vg-lib__row {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto auto;
	align-items: center;
	gap: var(--wp--preset--spacing--30);
	padding: .875rem var(--wp--preset--spacing--30);
	background: var(--wp--preset--color--base);
	transition: background var(--vg-dur) var(--vg-ease);
}
.vg-lib__row:hover { background: var(--wp--preset--color--panel); }
.vg-lib__name { display: flex; flex-direction: column; gap: .25rem; min-width: 0; }
.vg-lib__id { font-family: var(--wp--preset--font-family--mono); font-size: var(--wp--preset--font-size--micro); letter-spacing: .07em; text-transform: uppercase; color: var(--wp--preset--color--ink); }
.vg-lib__sub { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vg-lib__date { font-family: var(--wp--preset--font-family--mono); font-size: var(--wp--preset--font-size--micro); color: var(--wp--preset--color--ink-faint); font-variant-numeric: tabular-nums; }
@media (max-width: 640px) {
	.vg-lib__row { grid-template-columns: 1fr auto; }
	.vg-lib__date { display: none; }
}

/* Retention. Files are kept 30 days from purchase and then removed by hand, so
   a library row outlives its download. The row has to say which it is looking
   at — a Download button pointing at a deleted file is the worst of the three
   possible answers. */
.vg-lib__notice {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink-muted);
	margin: 0 0 var(--wp--preset--spacing--20);
	max-width: 62ch;
}
.vg-lib__row--expired { background: var(--wp--preset--color--panel); }
.vg-lib__row--expired .vg-lib__id,
.vg-lib__row--expired .vg-lib__sub { color: var(--wp--preset--color--ink-faint); }
.vg-lib__gone {
	display: flex;
	align-items: baseline;
	gap: .5rem;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink-faint);
}
.vg-lib__warn {
	display: block;
	margin-top: .2rem;
	color: var(--wp--preset--color--warn);
	font-family: var(--wp--preset--font-family--sans);
	letter-spacing: 0;
	text-transform: none;
}

/* ------------------------------------------------------------- orders --- */

/* Same hairline-and-band device as the library rather than a stack of cards.
   An order is a record, so its identifiers and money are set in mono and its
   status is set in words. */
.vg-orders { display: grid; gap: 1px; background: var(--vg-hairline); border: 1px solid var(--vg-hairline); border-radius: var(--vg-radius-lg); overflow: hidden; }
.vg-order { background: var(--wp--preset--color--base); padding: var(--wp--preset--spacing--30); }
.vg-order__head {
	display: flex;
	align-items: baseline;
	gap: var(--wp--preset--spacing--20);
	flex-wrap: wrap;
}
.vg-order__num {
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: .06em;
	color: var(--wp--preset--color--ink);
	font-variant-numeric: tabular-nums;
}
.vg-order__date { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-faint); }
.vg-order__total {
	margin-left: auto;
	font-size: var(--wp--preset--font-size--small);
	font-variant-numeric: tabular-nums;
	color: var(--wp--preset--color--ink);
}
.vg-order__status { font-size: var(--wp--preset--font-size--micro); }
.vg-order__status--completed { border-color: transparent; background: var(--wp--preset--color--signal-soft); color: var(--wp--preset--color--signal); }
.vg-order__status--failed,
.vg-order__status--failed-payment { border-color: transparent; background: var(--wp--preset--color--warn-soft); color: var(--wp--preset--color--warn); }

.vg-order__items { list-style: none; margin: var(--wp--preset--spacing--20) 0 0; padding: 0; display: grid; gap: .5rem; }
.vg-order__item {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--20);
	padding-top: .5rem;
	border-top: 1px solid var(--vg-hairline);
}
.vg-order__item-name { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink); min-width: 0; }
.vg-order__gone { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-faint); }
.vg-order__note {
	margin: var(--wp--preset--spacing--20) 0 0;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--warn);
}
.vg-btn--sm { padding: .35rem .7rem; font-size: var(--wp--preset--font-size--micro); }

@media (max-width: 640px) {
	.vg-order__total { margin-left: 0; }
	.vg-order__item { flex-wrap: wrap; }
}

/* ------------------------------------------------------------ contact --- */

/* The form used to get a 26rem column and a 120px message box beside a 776px
   introduction, so the thing a visitor came to write was the most cramped thing
   on the page (U103). The form now takes the larger share, in a panel, with a
   message box about twice as tall. The introduction is narrower and does more. */
.vg-contact {
	display: grid;
	grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr);
	gap: var(--wp--preset--spacing--60);
	align-items: start;
}
@media (max-width: 1040px) {
	.vg-contact { gap: var(--wp--preset--spacing--40); }
}
@media (max-width: 900px) {
	.vg-contact { grid-template-columns: 1fr; }
}
.vg-contact__title {
	font-size: var(--wp--preset--font-size--xxl);
	letter-spacing: -.03em;
	line-height: 1.05;
	margin: 0;
}
.vg-contact__lede {
	font-size: var(--wp--preset--font-size--medium);
	color: var(--wp--preset--color--ink-muted);
	max-width: 40ch;
	margin: .875rem 0 0;
}
.vg-contact__sub {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 400;
	color: var(--wp--preset--color--ink-faint);
	letter-spacing: 0;
	margin: var(--wp--preset--spacing--40) 0 .75rem;
}
.vg-contact__help { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--vg-hairline); }
.vg-contact__help li {
	display: grid;
	grid-template-columns: 2.25rem minmax(0, 1fr);
	gap: .5rem;
	padding: 1rem 0;
	border-bottom: 1px solid var(--vg-hairline);
}
.vg-contact__n {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: .08em;
	color: var(--wp--preset--color--accent);
	padding-top: .2rem;
}
.vg-contact__k { font-weight: 580; letter-spacing: -.01em; color: var(--wp--preset--color--ink); margin: 0; }
.vg-contact__v { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-muted); line-height: 1.6; margin: .25rem 0 0; }
.vg-contact__checks { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.vg-contact__checks li { display: flex; align-items: flex-start; gap: .625rem; font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink); }
.vg-contact__tick {
	flex: none;
	display: inline-flex; align-items: center; justify-content: center;
	width: 1.25rem; height: 1.25rem;
	border-radius: 50%;
	background: var(--wp--preset--color--accent-soft);
	color: var(--wp--preset--color--accent);
}
.vg-contact__tick svg { width: .75rem; height: .75rem; }

/* The way into the partner page, set as a quiet dark tile so it reads as a
   different door rather than as one more help item. */
.vg-contact__partner {
	position: relative;
	display: grid;
	gap: .375rem;
	margin-top: var(--wp--preset--spacing--40);
	padding: var(--wp--preset--spacing--30);
	border-radius: var(--vg-radius-lg);
	background:
		radial-gradient(120% 140% at 100% 0%, rgba(59, 73, 245, .45), transparent 55%),
		var(--wp--preset--color--ink);
	color: #fff;
	text-decoration: none;
	overflow: hidden;
	transition: transform 220ms var(--vg-ease), box-shadow 220ms var(--vg-ease);
}
.vg-contact__partner:hover { text-decoration: none; color: #fff; transform: translateY(-2px); box-shadow: 0 14px 30px -18px rgba(11, 12, 14, .55); }
.vg-contact__partner-k { font-size: var(--wp--preset--font-size--small); color: rgba(255, 255, 255, .62); }
.vg-contact__partner-v { font-size: var(--wp--preset--font-size--medium); font-weight: 560; letter-spacing: -.012em; line-height: 1.4; max-width: 34ch; }
.vg-contact__partner-go { font-size: var(--wp--preset--font-size--small); font-weight: 560; color: #AEB5FF; margin-top: .25rem; }
.vg-contact__partner-go::after { content: " \2192"; display: inline-block; transition: transform 220ms var(--vg-ease); }
.vg-contact__partner:hover .vg-contact__partner-go::after { transform: translateX(3px); }

.vg-contact__panel {
	background: var(--wp--preset--color--panel);
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius-lg);
	padding: var(--wp--preset--spacing--40);
}
@media (max-width: 600px) {
	.vg-contact__panel { padding: var(--wp--preset--spacing--30) var(--wp--preset--spacing--20); }
}
.vg-contact__panel-title { font-size: var(--wp--preset--font-size--large); letter-spacing: -.018em; margin: 0; }
.vg-contact__panel-note { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-muted); margin: .375rem 0 0; }
.vg-contact__form {
	margin-top: var(--wp--preset--spacing--30);
	padding-top: var(--wp--preset--spacing--30);
	border-top: 1px solid var(--vg-hairline);
}

/* WPForms output. The theme styled WooCommerce's form rows and nothing else,
   so the live contact form arrived unstyled the moment its Elementor wrapper
   stopped rendering. Field markup here is WPForms' own; only the presentation
   is ours.

   WPForms' modern stylesheet draws the form from its own custom properties and
   its selectors are specific enough to beat plain component rules, so the
   theme's field styling never reached the page and the submit button stayed
   WPForms blue. The properties are set on :root by an inline style, so
   restating them on the wrapper is all it takes: every field, label and button
   picks up the site's colours, sizes and radii at their own specificity. Only
   the three things WPForms hard-codes are overridden below. */
.vg-contact__form {
	--wpforms-field-border-radius: var(--vg-radius);
	--wpforms-field-border-color: rgba(11, 12, 14, .16);
	--wpforms-field-border-color-spare: rgba(11, 12, 14, .16);
	--wpforms-field-background-color: var(--wp--preset--color--base);
	--wpforms-field-text-color: var(--wp--preset--color--ink);
	--wpforms-field-size-input-height: 44px;
	--wpforms-field-size-input-spacing: 12px;
	--wpforms-field-size-font-size: 15px;
	--wpforms-field-size-line-height: 22px;
	--wpforms-field-size-padding-h: 12px;
	--wpforms-field-size-sublabel-spacing: 4px;
	--wpforms-label-color: var(--wp--preset--color--ink);
	--wpforms-label-sublabel-color: var(--wp--preset--color--ink-faint);
	--wpforms-label-error-color: var(--wp--preset--color--warn);
	--wpforms-label-size-font-size: 13px;
	--wpforms-label-size-line-height: 18px;
	--wpforms-label-size-sublabel-font-size: 12px;
	--wpforms-label-size-sublabel-line-height: 16px;
	--wpforms-button-background-color: var(--wp--preset--color--accent);
	--wpforms-button-border-color: var(--wp--preset--color--accent);
	--wpforms-button-border-radius: var(--vg-radius);
	--wpforms-button-size-font-size: 15px;
	--wpforms-button-size-height: 46px;
	--wpforms-button-size-padding-h: 22px;
	--wpforms-button-size-margin-top: 4px;
	--wpforms-page-break-color: var(--wp--preset--color--accent);
}
/* WPForms caps a medium field at 60% of its column. That was written for a
   form dropped into a full-width page, not for one that already sits in its
   own panel, and it is what kept the name row at 250px. */
.vg-contact__form .wpforms-container input.wpforms-field-medium,
.vg-contact__form .wpforms-container select.wpforms-field-medium,
.vg-contact__form .wpforms-container textarea.wpforms-field-medium,
.vg-contact__form .wpforms-container .wpforms-field-row.wpforms-field-medium { max-width: 100%; }
/* The message box: 2.8 input heights, which measured 120px. A message is the
   point of the page, so it opens at about twice that and still drags taller. */
.vg-contact__form div.wpforms-container-full .wpforms-form textarea.wpforms-field-medium {
	height: 15rem;
	line-height: 1.6;
	resize: vertical;
}
/* The name row: two blocks, one line, the full width of the panel. */
.vg-contact__form .wpforms-container .wpforms-field-row { display: flex; gap: .875rem; }
.vg-contact__form .wpforms-container .wpforms-field-row-block { flex: 1 1 0; min-width: 0; width: auto; float: none; padding: 0; margin: 0; }
@media (max-width: 480px) {
	.vg-contact__form .wpforms-container .wpforms-field-row { flex-direction: column; gap: .75rem; }
}
/* The submit button, stated outright rather than through WPForms' properties:
   its own rules resolve the colour through a fallback chain, and the site's
   button is not a thing to leave to a fallback. */
.vg-contact__form div.wpforms-container-full button[type="submit"],
.vg-contact__form div.wpforms-container-full input[type="submit"] {
	background-color: var(--wp--preset--color--accent);
	color: #fff;
	height: 46px;
	padding: 0 22px;
	border-radius: var(--vg-radius);
	font-size: 15px;
	font-weight: 560;
}
.vg-contact__form .wpforms-field { padding: 0 0 var(--wp--preset--spacing--20); }
.vg-contact__form .wpforms-field-sublabel { display: block; }
.vg-contact__form .wpforms-required-label { color: var(--wp--preset--color--warn); }
/* Hover is WPForms' own: a dark wash over whatever the button colour is, which
   on the accent lands within a shade of the site's button hover. Left to it,
   rather than fought over. */
.vg-contact__form .wpforms-error { color: var(--wp--preset--color--warn); font-size: var(--wp--preset--font-size--small); }

/* ------------------------------------------------------- terms of use --- */

/* Banded, not boxed, and set quieter than body copy: it is a term of sale that
   has to be present and readable on four pages without competing with the
   thing being bought. */
.vg-disclaimer {
	margin: var(--wp--preset--spacing--50) 0 0;
	padding: var(--wp--preset--spacing--30) 0 0;
	border-top: 1px solid var(--vg-hairline);
	max-width: 68ch;
}
.vg-disclaimer p {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink-muted);
	margin: 0 0 .625rem;
	line-height: 1.6;
}
.vg-disclaimer__title {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 560;
	color: var(--wp--preset--color--ink) !important;
	margin-bottom: .5rem !important;
}
.vg-disclaimer__accept { color: var(--wp--preset--color--ink) !important; }
.vg-disclaimer__accept a { color: var(--wp--preset--color--accent); }

/* ------------------------------------------------------------ landing --- */

/* The hero sits on the same grid as every section below it. It used to put its
   side padding on the outer box and give the inner box the full 1240px, while
   .vg-section puts 1240px on the outer box and its padding inside. The two
   disagreed by 24px a side, so the headline sat left of every heading under it. */
.vg-hero {
	position: relative;
	padding: var(--wp--preset--spacing--70) 0 var(--wp--preset--spacing--60);
	border-bottom: 1px solid var(--vg-hairline);
	overflow: hidden;
}
.vg-hero__inner {
	max-width: 1240px; margin-inline: auto; position: relative;
	padding-inline: var(--wp--preset--spacing--30);
}
.vg-hero__title {
	font-size: var(--wp--preset--font-size--display);
	line-height: 1.04;
	letter-spacing: -.036em;
	margin: 0 0 var(--wp--preset--spacing--30);
	max-width: 17ch;
}
.vg-hero__lede { font-size: var(--wp--preset--font-size--large); color: var(--wp--preset--color--ink-muted); max-width: 56ch; margin: 0 0 var(--wp--preset--spacing--30); }
.vg-hero__lede:last-of-type { margin-bottom: var(--wp--preset--spacing--40); }
.vg-hero__actions { display: flex; flex-wrap: wrap; gap: .625rem; }

/* Full-width rules, content on the 1240px grid. The band used to be a full-bleed
   grid, which put its first value at the viewport edge while every other element
   on the page started at the content edge. */
.vg-stats { border-block: 1px solid var(--vg-hairline); background: var(--wp--preset--color--base); }
.vg-stats__inner {
	max-width: 1240px; margin-inline: auto;
	padding-inline: var(--wp--preset--spacing--30);
	display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.vg-stat { padding-block: var(--wp--preset--spacing--30); }
.vg-stat + .vg-stat { border-left: 1px solid var(--vg-hairline); padding-left: var(--wp--preset--spacing--30); }
.vg-stat:not(:last-child) { padding-right: var(--wp--preset--spacing--30); }
@media (max-width: 700px) {
	.vg-stats__inner { grid-template-columns: 1fr; }
	.vg-stat + .vg-stat { border-left: 0; border-top: 1px solid var(--vg-hairline);
		padding-left: 0; padding-top: var(--wp--preset--spacing--30); }
	.vg-stat:not(:last-child) { padding-right: 0; }
}
/* With four figures only three columns fit between the single-column breakpoint
   and about 900px, which leaves the fourth alone on a second row. Two by two
   reads better there than four cramped ones. The rules above assume a single
   row, so the dividers are restated for a grid that has two. */
@media (min-width: 701px) and (max-width: 900px) {
	.vg-stats__inner { grid-template-columns: 1fr 1fr; }
	.vg-stat:nth-child(odd) { border-left: 0; padding-left: 0; }
	.vg-stat:nth-child(even) { padding-right: 0; }
	.vg-stat:nth-child(n+3) { border-top: 1px solid var(--vg-hairline);
		padding-top: var(--wp--preset--spacing--30); }
}
.vg-stat__value { font-size: var(--wp--preset--font-size--xl); letter-spacing: -.03em; color: var(--wp--preset--color--ink); line-height: 1; }
.vg-stat__label { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-muted); margin-top: .5rem; }

.vg-section { max-width: 1240px; margin-inline: auto; padding: var(--wp--preset--spacing--60) var(--wp--preset--spacing--30); }
.vg-section__head { margin-bottom: var(--wp--preset--spacing--40); }
.vg-section__title { font-size: var(--wp--preset--font-size--xl); letter-spacing: -.024em; margin: .5rem 0 0; }
.vg-section__lede { color: var(--wp--preset--color--ink-muted); max-width: 62ch; margin: .625rem 0 0; }

.vg-steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--wp--preset--spacing--40); counter-reset: step; }
.vg-step { counter-increment: step; }
.vg-step::before {
	content: counter(step, decimal-leading-zero);
	display: block;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: .1em;
	color: var(--wp--preset--color--accent);
	margin-bottom: .625rem;
}
.vg-step__title { font-size: var(--wp--preset--font-size--medium); font-weight: 580; margin: 0 0 .375rem; }
.vg-step__body { color: var(--wp--preset--color--ink-muted); font-size: var(--wp--preset--font-size--small); margin: 0; }

/* --------------------------------------------- repositioning components --- */

/* Level chip — Foundation / Practitioner / Leadership. */
.vg-tag--level { border-color: transparent; background: var(--wp--preset--color--ink); color: #fff; letter-spacing: .015em; }
.vg-card__meta { font-size: var(--wp--preset--font-size--micro); color: var(--wp--preset--color--ink-faint); white-space: nowrap; letter-spacing: .02em; }

/* Audience tiles — one lattice, same as the cards. */
.vg-audiences {
	display: grid;
	grid-template-columns: repeat(6, 1fr);
	gap: 1px;
	background: var(--vg-hairline);
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius-lg);
	overflow: hidden;
}
/* Rank, not sequence: the lead tile takes the full row, the next three take a
   third each, the last two share a row at half height. */
.vg-audience { grid-column: span 2; }
.vg-audience--lead { grid-column: 1 / -1; }
.vg-audience--min { grid-column: span 3; }
@media (max-width: 900px) {
	.vg-audiences { grid-template-columns: repeat(2, 1fr); }
	.vg-audience { grid-column: span 1; }
	.vg-audience--min { grid-column: span 1; }
	.vg-audience--lead { grid-column: 1 / -1; }
}
@media (max-width: 600px) {
	.vg-audiences { grid-template-columns: 1fr; }
	.vg-audience, .vg-audience--lead, .vg-audience--min { grid-column: 1 / -1; }
}
.vg-audience {
	display: flex; flex-direction: column; gap: .5rem;
	padding: var(--wp--preset--spacing--30);
	background: var(--wp--preset--color--base);
	color: inherit; text-decoration: none;
	transition: background var(--vg-dur) var(--vg-ease);
}
.vg-audience:hover { background: var(--wp--preset--color--panel); text-decoration: none; }
.vg-audience--lead { padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--30); }
.vg-audience--lead .vg-audience__k { font-size: var(--wp--preset--font-size--large); letter-spacing: -.018em; }
.vg-audience--lead .vg-audience__v { font-size: var(--wp--preset--font-size--base); max-width: 62ch; }
.vg-audience--min { gap: .25rem; padding-block: var(--wp--preset--spacing--20); }
.vg-audience--min .vg-audience__k { font-size: var(--wp--preset--font-size--base); }
/* The tile is the link, so this cannot be an anchor. It is the affordance. */
.vg-audience__go { font-size: var(--wp--preset--font-size--small); font-weight: 520; color: var(--wp--preset--color--accent); margin-top: .25rem; }
.vg-audience:hover .vg-audience__go { text-decoration: underline; }
.vg-audience__k { font-weight: 580; font-size: var(--wp--preset--font-size--medium); letter-spacing: -.012em; color: var(--wp--preset--color--ink); }
.vg-audience__v { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-muted); line-height: 1.55; }

/* Library pager. The class, not [hidden], so the pager and the filter island
   never fight over the same attribute: the filter owns `hidden` (does this card
   match) and this owns the class (is it on this page). */
.is-paged-out { display: none !important; }
/* The guest sample (U97): starred cases beyond the eight on show. A class for
   the same reason as the pager's, since the filter island owns `hidden`. */
.is-sampled-out { display: none !important; }
.vg-library__head { margin-bottom: var(--wp--preset--spacing--40); }
.vg-library__title { font-size: var(--wp--preset--font-size--xxl); margin-top: 0; }
.vg-pager {
	margin-top: var(--wp--preset--spacing--40);
	padding-top: var(--wp--preset--spacing--30);
	border-top: 1px solid var(--vg-hairline);
	display: flex; flex-wrap: wrap; align-items: center;
	justify-content: space-between; gap: 1rem;
}
.vg-pager__count { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-muted); margin: 0; }
.vg-pager__list { list-style: none; display: flex; flex-wrap: wrap; gap: .25rem; margin: 0; padding: 0; }
.vg-pager__btn {
	font: inherit; font-size: var(--wp--preset--font-size--small);
	min-width: 2.25rem; padding: .4rem .6rem;
	border: 1px solid var(--vg-hairline); border-radius: var(--vg-radius);
	background: var(--wp--preset--color--base); color: var(--wp--preset--color--ink);
	cursor: pointer; transition: background var(--vg-dur) var(--vg-ease);
}
.vg-pager__btn:hover:not(:disabled) { background: var(--wp--preset--color--panel); }
.vg-pager__btn[aria-current="true"] { background: var(--wp--preset--color--ink); color: #fff; border-color: var(--wp--preset--color--ink); }
.vg-pager__btn:disabled { opacity: .4; cursor: default; }
.vg-pager__gap { padding: .4rem .25rem; color: var(--wp--preset--color--ink-faint); }

/* Levels strip. */
.vg-levels {
	display: grid; grid-template-columns: 1.2fr repeat(3, 1fr); gap: var(--wp--preset--spacing--40);
	padding: var(--wp--preset--spacing--40) 0;
	border-block: 1px solid var(--vg-hairline);
	align-items: start;
}
@media (max-width: 900px) { .vg-levels { grid-template-columns: 1fr 1fr; } .vg-levels__head { grid-column: 1 / -1; } }
@media (max-width: 560px) { .vg-levels { grid-template-columns: 1fr; } }
.vg-level__who { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink); font-weight: 520; margin: .75rem 0 .25rem; }
.vg-level__what { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-muted); margin: 0; }

/* Themed rows. */
.vg-row + .vg-row { margin-top: var(--wp--preset--spacing--40); }
.vg-row__head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-bottom: .875rem; }
.vg-row__title { font-size: var(--wp--preset--font-size--medium); font-weight: 580; letter-spacing: -.012em; margin: 0; display: flex; align-items: baseline; gap: .5rem; }
.vg-row__count { font-size: var(--wp--preset--font-size--micro); color: var(--wp--preset--color--ink-faint); font-weight: 400; }
.vg-row__all { font-size: var(--wp--preset--font-size--small); font-weight: 500; white-space: nowrap; }
.vg-grid-cards--row { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.vg-grid-cards--row .vg-card { min-height: 200px; }

/* Illustrative briefs — "commission a case". */
.vg-briefs { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--wp--preset--spacing--20); }
.vg-brief {
	display: flex; flex-direction: column; gap: .625rem;
	padding: var(--wp--preset--spacing--30);
	border: 1px dashed var(--vg-hairline);
	border-radius: var(--vg-radius-lg);
	background: var(--wp--preset--color--base);
}
.vg-brief__head { display: flex; gap: .3125rem; flex-wrap: wrap; }
.vg-brief__q { font-size: var(--wp--preset--font-size--medium); font-weight: 580; letter-spacing: -.014em; line-height: 1.3; margin: .25rem 0 0; }
.vg-brief__how { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-muted); margin: 0 0 auto; }
.vg-brief__note { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-faint); margin: .5rem 0 0; }

/* Regions + partners. */
.vg-regions { display: grid; grid-template-columns: 1.3fr 1fr; gap: var(--wp--preset--spacing--50); align-items: center; padding: var(--wp--preset--spacing--40) 0; border-top: 1px solid var(--vg-hairline); }
@media (max-width: 800px) { .vg-regions { grid-template-columns: 1fr; } }
.vg-regions__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; background: var(--vg-hairline); border: 1px solid var(--vg-hairline); border-radius: var(--vg-radius-lg); overflow: hidden; }
.vg-regions__list li { display: flex; align-items: center; gap: 1rem; padding: .875rem var(--wp--preset--spacing--30); background: var(--wp--preset--color--base); font-size: var(--wp--preset--font-size--small); }
.vg-regions__year { margin-left: auto; font-family: var(--wp--preset--font-family--mono); font-size: var(--wp--preset--font-size--micro); color: var(--wp--preset--color--ink-faint); }
.vg-regions__k { font-family: var(--wp--preset--font-family--mono); font-size: var(--wp--preset--font-size--micro); letter-spacing: .06em; color: var(--wp--preset--color--ink); width: 3.5ch; flex: none; }
.vg-partners { display: flex; align-items: center; gap: var(--wp--preset--spacing--30); flex-wrap: wrap; padding: var(--wp--preset--spacing--30) 0 0; border-top: 1px solid var(--vg-hairline); margin-top: var(--wp--preset--spacing--40); }
.vg-partners__k { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-faint); margin: 0; }
.vg-partners__list { list-style: none; margin: 0; padding: 0; display: flex; gap: var(--wp--preset--spacing--30); flex-wrap: wrap; font-weight: 560; color: var(--wp--preset--color--ink-muted); letter-spacing: -.01em; }

/* Landing CTA and posts. */
.vg-cta { border: 1px solid var(--vg-hairline); border-radius: var(--vg-radius-lg); padding: var(--wp--preset--spacing--50); display: flex; gap: var(--wp--preset--spacing--40); align-items: center; justify-content: space-between; flex-wrap: wrap; }
.vg-posts .wp-block-post-template { gap: 1px; background: var(--vg-hairline); border: 1px solid var(--vg-hairline); border-radius: var(--vg-radius-lg); overflow: hidden; }
.vg-post { background: var(--wp--preset--color--base); padding: var(--wp--preset--spacing--30); }
.vg-post .wp-block-post-title { margin-top: .5rem; line-height: 1.3; }
.vg-post .wp-block-post-title a { color: var(--wp--preset--color--ink); }


/* ---------------------------------------------------- convergence motion --- */

/* The only thing on the page that moves on its own, and it moves because the
   picture means something: rows of data narrowing to one decision.

   Ambient  a pass of light down the rules. Each lifts from 58% to full and falls
            back, one after the next, so two or three are lit at a time and the
            band travels toward the vertex. Then a pause, then again.
   Hover    the rules run to the vertex top first and the chevron ticks once as
            they arrive.

   A lit rule carries about 3.7 times the ink of a resting one and twice the
   width. That ratio is the whole point: the rules are drawn faint on purpose, so
   the pass has to be a real change against them rather than a nudge. The resting
   picture is within a percentage point of where it always was.

   The delays are positive with a backwards fill, so the rules start dim and the
   first pass sweeps in as the page loads. */
.vg-converge__art { pointer-events: auto; }

/* The pass. It sits on the group with the collapse, but on a different property:
   a CSS animation beats a transition on the same one even while it is paused, so
   `transform` is left to the hover alone. */
.vg-converge__svg line {
	/* In CSS rather than an attribute so the pass can animate it. */
	stroke-width: 1.25;
	animation: vg-scan 7s ease-in-out infinite backwards;
	/* --i is set on the parent group and inherits. */
	animation-delay: calc(var(--i, 0) * 0.42s);
}

.vg-converge__svg g {
	transform-box: view-box;
	transform-origin: 300px 0;
	transition: transform 420ms var(--vg-ease);
	transition-delay: calc(var(--i, 0) * 22ms);
}
.vg-converge__svg g:nth-child(1) { --i: 0; }
.vg-converge__svg g:nth-child(2) { --i: 1; }
.vg-converge__svg g:nth-child(3) { --i: 2; }
.vg-converge__svg g:nth-child(4) { --i: 3; }
.vg-converge__svg g:nth-child(5) { --i: 4; }
.vg-converge__svg g:nth-child(6) { --i: 5; }
.vg-converge__svg g:nth-child(7) { --i: 6; }
.vg-converge__svg g:nth-child(8) { --i: 7; }
.vg-converge__svg g:nth-child(9) { --i: 8; }
.vg-converge__svg g:nth-child(10) { --i: 9; }
.vg-converge__svg g:nth-child(11) { --i: 10; }
.vg-converge__svg g:nth-child(12) { --i: 11; }

@keyframes vg-scan {
	0%   { opacity: .26; stroke-width: 1.25; }
	5%   { opacity: .95; stroke-width: 2.4; }
	18%  { opacity: .26; stroke-width: 1.25; }
	100% { opacity: .26; stroke-width: 1.25; }
}

.vg-converge__svg path {
	transform-box: view-box;
	transform-origin: 300px 345px;
	/* Waits for the rules to arrive before it acknowledges them. */
	transition: transform 200ms var(--vg-ease) 300ms;
}

.vg-converge__art:hover .vg-converge__svg g { transform: scaleX(.05); }
.vg-converge__art:hover .vg-converge__svg path { transform: scale(1.08); }

@media (prefers-reduced-motion: reduce) {
	.vg-converge__svg line,
	.vg-converge__svg g,
	.vg-converge__svg path { animation: none; transition: none; }
	.vg-converge__art { pointer-events: none; }
}

/* ---------------------------------------------------------------- gate --- */

/* A case is for account holders. The gate uses the band device the figures
   already use, a panel between two hairlines, so it reads as part of the page
   rather than as a callout bolted onto it. */
.vg-gate {
	margin: var(--wp--preset--spacing--40) 0;
	padding: var(--wp--preset--spacing--30) 0;
	border-block: 1px solid var(--vg-hairline);
	max-width: 62ch;
}
.vg-gate__title { font-size: var(--wp--preset--font-size--medium); font-weight: 580; margin: 0; }
.vg-gate__body { color: var(--wp--preset--color--ink-muted); margin: .5rem 0 0; }
.vg-gate__actions { display: flex; gap: .625rem; flex-wrap: wrap; margin: var(--wp--preset--spacing--30) 0 0; }
.vg-buy__cta { width: 100%; }
.vg-buy .vg-tag--owned { display: inline-flex; margin-bottom: .5rem; }

/* Fulfilment state.
   On this store the file is prepared before the sale, so a case with nothing
   prepared for you is one you cannot be given. Said here, in the buy box,
   before the click — the add-to-cart refusal is the backstop, not the message.
   Banded like .vg-gate rather than boxed: the site's device is a rule, not a
   card. */
.vg-buy__state {
	padding: var(--wp--preset--spacing--20) 0;
	border-block: 1px solid var(--vg-hairline);
	margin-bottom: var(--wp--preset--spacing--30);
}
.vg-buy__state-title {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 580;
	margin: 0;
	color: var(--wp--preset--color--ink);
}
.vg-buy__state-body {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink-muted);
	margin: .375rem 0 0;
}
/* Pending reads as in-progress, not as a failure: the accent, not the warning
   colour. Unavailable is the one that has to look like a stop. */
.vg-buy__state--pending .vg-buy__state-title { color: var(--wp--preset--color--accent); }
.vg-buy__state--unavailable .vg-buy__state-title { color: var(--wp--preset--color--warn); }

.vg-card__price--pending,
.vg-card__price--unavailable {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: .04em;
	font-weight: 500;
}
.vg-card__price--gated {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: .04em;
	color: var(--wp--preset--color--ink-faint);
	font-weight: 500;
}
.vg-card__price--pending { color: var(--wp--preset--color--accent); }
.vg-card__price--unavailable { color: var(--wp--preset--color--ink-faint); }

/* A case a signed-in student cannot buy yet, because their file is not on the
   server. The class is added only when signed in: a guest is `unavailable` on
   every case by definition, and greying the public catalogue would read as a
   closed shop. Greyed means "not yet", so the card stays readable and still
   opens: the text keeps full contrast and only the image and the chrome drop
   back. Contrast is the one thing not traded away here.

   The background is deliberately left alone: `panel` is a near-white already
   spoken for by :hover, so it would be both invisible and a collision. The
   greyscale image and the "Not open" label carry it. */
.vg-card--unavailable .vg-card__thumb,
.vg-card--pending .vg-card__thumb { filter: grayscale(1); opacity: .5; }
.vg-card--unavailable .vg-tag,
.vg-card--pending .vg-tag { opacity: .65; }
.vg-card--unavailable .vg-card__id { color: var(--wp--preset--color--ink-faint); }
@media (prefers-reduced-motion: no-preference) {
	.vg-card--unavailable .vg-card__thumb,
	.vg-card--pending .vg-card__thumb { transition: filter var(--vg-dur) var(--vg-ease), opacity var(--vg-dur) var(--vg-ease); }
}
.vg-card--unavailable:hover .vg-card__thumb,
.vg-card--pending:hover .vg-card__thumb { filter: grayscale(.4); opacity: .75; }

/* ------------------------------------------------------------- lattice --- */

/* One hairline lattice for every grid that uses one. The rules are drawn by the
   cells, not bled through from the container, so a short row ends where the
   cards end instead of showing a grey block. See DESIGN-PASS.md. */
.vg-audiences,
.vg-grid-cards,
.vg-posts .wp-block-post-template {
	background: var(--wp--preset--color--base);
}
.vg-audience,
.vg-card,
.vg-post {
	box-shadow: -1px 0 0 var(--vg-hairline), 0 -1px 0 var(--vg-hairline);
}

/* Four cards to a row, and every fallback count divides four. */
.vg-grid-cards--row { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1040px) { .vg-grid-cards--row { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .vg-grid-cards--row { grid-template-columns: 1fr; } }

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

.vg-footer { border-top: 1px solid var(--vg-hairline); background: var(--wp--preset--color--panel); margin-top: var(--wp--preset--spacing--60); }
.vg-footer__inner { max-width: 1240px; margin-inline: auto; padding: var(--wp--preset--spacing--50) var(--wp--preset--spacing--30); display: grid; grid-template-columns: 1.4fr repeat(3, 1fr); gap: var(--wp--preset--spacing--40); }
@media (max-width: 860px) { .vg-footer__inner { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px) { .vg-footer__inner { grid-template-columns: 1fr; } }
.vg-footer__title { font-size: var(--wp--preset--font-size--small); font-weight: 560; color: var(--wp--preset--color--ink); margin: 0 0 .875rem; }
.vg-footer__list { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.vg-footer__list a { color: var(--wp--preset--color--ink-muted); font-size: var(--wp--preset--font-size--small); text-decoration: none; }
.vg-footer__list a:hover { color: var(--wp--preset--color--accent); }
.vg-footer__bar { border-top: 1px solid var(--vg-hairline); }
.vg-footer__bar-inner { max-width: 1240px; margin-inline: auto; padding: var(--wp--preset--spacing--20) var(--wp--preset--spacing--30); display: flex; flex-wrap: wrap; gap: .75rem; justify-content: space-between; font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-faint); }

/* DethemeKit prints an empty quick-view modal into wp_footer on every page, and
   its own stylesheet is not enqueued on this theme. The unstyled shell was
   rendering as a 24px white band under the copyright line. No template carries a
   quick-view trigger, so it is never filled. Keyed on the empty body rather than
   on the id alone: if the plugin ever does load a product into it, the modal
   shows. A browser without :has() drops the rule and only the band comes back. */
#htwlquick-viewmodal:has(.htwl-modal-body:empty) { display: none; }

/* ------------------------------------------------- WooCommerce bridging --- */

.woocommerce-message, .woocommerce-info, .woocommerce-error {
	border: 1px solid var(--wp--preset--color--accent);
	border-radius: var(--vg-radius);
	background: var(--wp--preset--color--accent-soft);
	padding: .875rem 1rem;
	font-size: var(--wp--preset--font-size--small);
	list-style: none;
	margin: 0 0 var(--wp--preset--spacing--30);
}
.woocommerce-error { border-color: var(--wp--preset--color--warn); background: var(--wp--preset--color--warn-soft); }
.woocommerce-message { border-color: var(--wp--preset--color--signal); background: var(--wp--preset--color--signal-soft); }

.woocommerce form .form-row input.input-text,
.woocommerce form .form-row textarea,
.woocommerce form .form-row select {
	width: 100%;
	min-height: 40px;
	padding: .5rem .75rem;
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius);
	font: inherit;
	font-size: var(--wp--preset--font-size--small);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--ink);
}
.woocommerce form .form-row label { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-muted); margin-bottom: .3rem; display: block; }
.woocommerce form .form-row input.input-text:focus,
.woocommerce form .form-row select:focus,
.woocommerce form .form-row textarea:focus { border-color: var(--wp--preset--color--accent); box-shadow: 0 0 0 3px var(--wp--preset--color--accent-soft); }

.woocommerce table.shop_table {
	width: 100%;
	border-collapse: collapse;
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius-lg);
	overflow: hidden;
	font-size: var(--wp--preset--font-size--small);
}
.woocommerce table.shop_table th,
.woocommerce table.shop_table td { padding: .875rem 1rem; border-bottom: 1px solid var(--vg-hairline); text-align: left; }
/* Column and row labels are words, so they are set in the sans, sentence case,
   no tracking. This rule used to set every WooCommerce table header in
   uppercase mono — "PRODUCT", "SUBTOTAL", "TOTAL" — which predates the design
   register and breaks it: mono is for values, uppercase for codes only. Caught
   on the cart during its design pass, and fixed here so every WooCommerce
   table on the site follows the register rather than only the two that were
   being looked at. */
.woocommerce table.shop_table th {
	font-family: inherit;
	font-size: var(--wp--preset--font-size--small);
	letter-spacing: 0;
	text-transform: none;
	color: var(--wp--preset--color--ink-muted);
	font-weight: 500;
	background: transparent;
}

/* Hide WooCommerce's default star-rating furniture: no reviews are collected. */
.woocommerce .star-rating, .woocommerce .woocommerce-product-rating { display: none; }

/* ------------------------------------------------------------ utility --- */

.vg-visually-hidden {
	position: absolute !important;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
	white-space: nowrap; border: 0;
}
.vg-stack > * + * { margin-top: var(--wp--preset--spacing--20); }
.vg-hr { height: 1px; background: var(--vg-hairline); border: 0; margin: var(--wp--preset--spacing--50) 0; }

@media print {
	.vg-header, .vg-footer, .vg-buy, .vg-toolbar { display: none !important; }
	body { color: #000; }
}

/* ----------------------------------------------------------- app pages --- */

/* Pages the theme draws in full (inc/app-pages.php): the sign-in pages, the
   member area and the utility pages. One heading block, then the page's own
   body, on the same 1240px grid as every other section. */
.vg-app__head { margin: 0 0 var(--wp--preset--spacing--40); max-width: 62ch; }
.vg-app__title {
	font-size: var(--wp--preset--font-size--xxl);
	line-height: 1.1;
	letter-spacing: -.026em;
	margin: 0;
	text-wrap: balance;
}
.vg-app__lede {
	font-size: var(--wp--preset--font-size--medium);
	color: var(--wp--preset--color--ink-muted);
	margin: .75rem 0 0;
	max-width: 56ch;
}
.vg-app__actions { display: flex; flex-wrap: wrap; gap: .625rem; margin: 0; }
.vg-app__note { color: var(--wp--preset--color--ink-muted); font-size: var(--wp--preset--font-size--small); }
.vg-app__part { margin-top: var(--wp--preset--spacing--50); }

/* The key/value register from the contact page, tightened for a side note. */
.vg-spec--compact { margin-top: 0; }
.vg-spec--compact .vg-spec__row {
	grid-template-columns: 9.5rem minmax(0, 1fr);
	gap: var(--wp--preset--spacing--20);
	padding: var(--wp--preset--spacing--20) 0;
}
.vg-spec--compact .vg-spec__v p { margin: 0; font-size: var(--wp--preset--font-size--small); line-height: 1.55; }
@media (max-width: 640px) {
	.vg-spec--compact .vg-spec__row { grid-template-columns: 1fr; gap: .25rem; }
}

/* ---- sign-in, register, password reset ----------------------------------- */

/* Words left, form right; on a phone, heading, then form, then the notes. */
.vg-auth {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 26rem);
	grid-template-areas:
		"head form"
		"spec form";
	grid-template-rows: auto 1fr;
	column-gap: var(--wp--preset--spacing--60);
	align-items: start;
}
.vg-auth__head { grid-area: head; }
.vg-auth__form { grid-area: form; padding-top: var(--wp--preset--spacing--20); border-top: 1px solid var(--vg-hairline); }
.vg-auth__spec { grid-area: spec; max-width: 36rem; }
@media (max-width: 900px) {
	.vg-auth {
		grid-template-columns: 1fr;
		grid-template-areas: "head" "form" "spec";
		grid-template-rows: auto;
	}
	.vg-auth__spec { margin-top: var(--wp--preset--spacing--40); }
}

/* ---- Ultimate Member forms ------------------------------------------------ */

/* The markup is Ultimate Member's and is left alone: its handlers read the
   field names, the nonce and the honeypot. Only the presentation is ours.
   Its stylesheet sets much of this with !important, so these do too, scoped
   under .vg-um and one class stronger so they win whatever order the two
   stylesheets load in. */
.vg-um .um {
	max-width: none !important;
	margin: 0 !important;
	/* Ultimate Member starts every form at opacity 0 and reveals it from its
	   script. Shown from the first paint instead, so a script that fails to
	   run can never leave a blank sign-in page. */
	opacity: 1 !important;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink-muted);
}
.vg-um .um .um-row { margin: 0 !important; }
.vg-um .um .um-field { padding: 0 0 var(--wp--preset--spacing--20); }
.vg-um .um .um-field-label { margin: 0 0 .375rem; }
.vg-um .um .um-field-label label {
	font-size: var(--wp--preset--font-size--small) !important;
	line-height: 1.4 !important;
	font-weight: 500 !important;
	color: var(--wp--preset--color--ink) !important;
}
.vg-um .um span.um-req { color: var(--wp--preset--color--ink-faint); }

.vg-um .um .um-form input[type="text"],
.vg-um .um .um-form input[type="email"],
.vg-um .um .um-form input[type="password"],
.vg-um .um .um-form input[type="tel"],
.vg-um .um .um-form input[type="url"],
.vg-um .um .um-form input[type="number"],
.vg-um .um .um-form input[type="date"],
.vg-um .um .um-form input[type="search"],
.vg-um .um .um-form select,
.vg-um .um .um-form textarea {
	width: 100%;
	height: 42px !important;
	padding: 0 .75rem !important;
	border: 1px solid var(--vg-hairline) !important;
	border-radius: var(--vg-radius) !important;
	background: var(--wp--preset--color--base) !important;
	color: var(--wp--preset--color--ink) !important;
	font-family: inherit !important;
	font-size: var(--wp--preset--font-size--small) !important;
	line-height: 1.4 !important;
	box-shadow: none !important;
	transition: border-color var(--vg-dur) var(--vg-ease), box-shadow var(--vg-dur) var(--vg-ease);
}
.vg-um .um .um-form textarea { height: auto !important; min-height: 8rem !important; padding: .625rem .75rem !important; }
.vg-um .um .um-form input[type]:focus,
.vg-um .um .um-form select:focus,
.vg-um .um .um-form textarea:focus {
	border-color: var(--wp--preset--color--accent) !important;
	box-shadow: 0 0 0 3px var(--wp--preset--color--accent-soft) !important;
	outline: none !important;
}
.vg-um .um .um-form input[type].um-error { border-color: var(--wp--preset--color--warn) !important; }
.vg-um .um .um-form ::placeholder { color: var(--wp--preset--color--ink-faint) !important; }

/* Buttons: primary in the accent, the alternative as the ghost button. */
.vg-um .um input[type="submit"].um-button,
.vg-um .um a.um-button {
	display: block;
	width: 100%;
	min-height: 44px;
	padding: .6875rem 1.125rem !important;
	border: 1px solid var(--wp--preset--color--accent) !important;
	border-radius: var(--vg-radius) !important;
	background: var(--wp--preset--color--accent) !important;
	color: #fff !important;
	font-family: inherit !important;
	font-size: var(--wp--preset--font-size--small) !important;
	font-weight: 560 !important;
	line-height: 1.4 !important;
	text-align: center;
	box-shadow: none !important;
	transition: background var(--vg-dur) var(--vg-ease), border-color var(--vg-dur) var(--vg-ease);
}
.vg-um .um input[type="submit"].um-button:hover,
.vg-um .um a.um-button:hover { background: #2E3AD4 !important; border-color: #2E3AD4 !important; color: #fff !important; }
.vg-um .um a.um-button.um-alt,
.vg-um .um input[type="submit"].um-button.um-alt {
	background: transparent !important;
	color: var(--wp--preset--color--ink) !important;
	border-color: var(--vg-hairline) !important;
}
.vg-um .um a.um-button.um-alt:hover,
.vg-um .um input[type="submit"].um-button.um-alt:hover {
	background: var(--wp--preset--color--panel) !important;
	border-color: var(--wp--preset--color--ink-faint) !important;
	color: var(--wp--preset--color--ink) !important;
}
.vg-um .um .um-col-alt { margin: var(--wp--preset--spacing--20) 0 0; }
.vg-um .um .um-col-alt-b { padding-top: var(--wp--preset--spacing--20); }
.vg-um .um .um-half { width: calc(50% - .3125rem); }
/* The register button is centred at a fixed 250px by default. */
.vg-um .um .um-center { text-align: left; }
.vg-um .um .um-center .um-button { display: block !important; width: 100% !important; min-width: 0 !important; }

.vg-um .um a.um-link-alt {
	display: inline-block !important;
	text-align: left;
	color: var(--wp--preset--color--accent) !important;
	font-size: var(--wp--preset--font-size--small);
}
.vg-um .um a.um-link-alt:hover { text-decoration: underline !important; }
.vg-um .um a.um-link { color: var(--wp--preset--color--accent); }

/* "Keep me signed in". The box is Ultimate Member's icon font. */
.vg-um .um .um-field-checkbox { margin-bottom: 0 !important; }
.vg-um .um .um-field-checkbox .um-field-checkbox-state i { color: var(--wp--preset--color--ink-faint); }
.vg-um .um .um-field-checkbox.active .um-field-checkbox-state i { color: var(--wp--preset--color--accent); }
.vg-um .um .um-field-checkbox-option {
	color: var(--wp--preset--color--ink-muted) !important;
	font-size: var(--wp--preset--font-size--small);
}

/* Messages. Tinted bands in the site's own warning, success and accent tones,
   in place of Ultimate Member's red, green and blue blocks with arrows. */
.vg-um .um .um-field-error,
.vg-um .um .um-error-block {
	background: var(--wp--preset--color--warn-soft);
	color: var(--wp--preset--color--warn);
	border: 1px solid rgba(194, 65, 12, .22);
	border-radius: var(--vg-radius);
	padding: .5rem .75rem;
	margin-top: .5rem;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.45 !important;
}
.vg-um .um .um-field-error a { color: var(--wp--preset--color--warn) !important; }
.vg-um .um .um-field-notice,
.vg-um .um .um-notice-block {
	background: var(--wp--preset--color--accent-soft);
	color: var(--wp--preset--color--ink);
	border-radius: var(--vg-radius);
	padding: .5rem .75rem;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.45 !important;
}
.vg-um .um .um-field-notice a { color: var(--wp--preset--color--accent) !important; }
.vg-um .um .um-field-arrow { display: none; }
.vg-um .um p.um-notice {
	border-radius: var(--vg-radius);
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.5;
	padding: .75rem 2.75rem .75rem 1rem !important;
	margin: 0 0 var(--wp--preset--spacing--20) !important;
	color: var(--wp--preset--color--ink);
}
.vg-um .um p.um-notice.err { background: var(--wp--preset--color--warn-soft); color: var(--wp--preset--color--warn); border: 1px solid rgba(194, 65, 12, .22); }
.vg-um .um p.um-notice.success { background: var(--wp--preset--color--signal-soft); color: var(--wp--preset--color--ink); border: 1px solid rgba(0, 179, 122, .25); }
.vg-um .um p.um-notice.warning { background: var(--wp--preset--color--panel); color: var(--wp--preset--color--ink); border: 1px solid var(--vg-hairline); }
.vg-um .um p.um-notice i { font-size: 1.5rem; top: .45rem; }

/* The password-reset page's status line: set as text, not centred in grey. */
.vg-um .um .um-field-type_block { padding-top: 0; }
.vg-um .um .um-field-block,
.vg-um .um .um-field-block > div {
	text-align: left !important;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.6;
	color: var(--wp--preset--color--ink-muted);
}

/* Ultimate Member hides this already. Said again so a change on its side can
   never put "Only fill in if you are not human" on the page. */
.vg-um .um_request_name { display: none !important; }

/* Account. Ultimate Member's side menu and tabs, recoloured and set in the
   site's type: a list with a rule between items, not grey bars. */
.vg-um .um-account-side ul { border-top: 1px solid var(--vg-hairline); }
.vg-um .um-account-side li { background: transparent !important; margin: 0 !important; border-bottom: 1px solid var(--vg-hairline); }
.vg-um .um-account-side li a {
	display: flex !important;
	align-items: center;
	gap: .75rem;
	height: auto !important;
	padding: .75rem .5rem !important;
	font-size: var(--wp--preset--font-size--small) !important;
	line-height: 1.4 !important;
	color: var(--wp--preset--color--ink-muted) !important;
	text-decoration: none !important;
}
.vg-um .um-account-side li a:hover { background: var(--wp--preset--color--panel) !important; color: var(--wp--preset--color--ink) !important; }
.vg-um .um-account-side li a span.um-account-icon {
	float: none !important;
	width: 18px !important;
	height: auto !important;
	padding: 0 !important;
	border: 0 !important;
	font-size: 16px !important;
	color: var(--wp--preset--color--ink-faint) !important;
}
.vg-um .um-account-side li a span.um-account-icon i { height: auto !important; line-height: 1 !important; }
.vg-um .um-account-side li a span.um-account-title { float: none !important; padding: 0 !important; height: auto !important; line-height: 1.4 !important; color: inherit !important; }
.vg-um .um-account-side li a span.um-account-arrow { position: static !important; margin-left: auto; font-size: 18px !important; }
.vg-um .um-account-side li a.current,
.vg-um .um-account-side li a.current:hover { color: var(--wp--preset--color--ink) !important; font-weight: 560 !important; background: transparent !important; }
.vg-um .um-account-side li a.current span.um-account-icon { color: var(--wp--preset--color--accent) !important; }
.vg-um .um-account-name a { color: var(--wp--preset--color--ink) !important; font-size: var(--wp--preset--font-size--medium) !important; font-weight: 580 !important; }
.vg-um .um-account-name .um-account-profile-link a { color: var(--wp--preset--color--accent) !important; font-size: var(--wp--preset--font-size--small) !important; font-weight: 400 !important; }
.vg-um .um-account-main div.um-account-heading {
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.3;
	font-weight: 580;
	color: var(--wp--preset--color--ink);
	margin: 0 0 var(--wp--preset--spacing--20) !important;
}
.vg-um .um-account-nav a { color: var(--wp--preset--color--ink-muted) !important; border-bottom-color: var(--vg-hairline) !important; }
.vg-um .um-account-nav a.current { color: var(--wp--preset--color--ink) !important; }
.vg-um div.uimob800 .um-account-side li a.current,
.vg-um div.uimob800 .um-account-side li a.current:hover { background: var(--wp--preset--color--panel) !important; }

/* Profile and directory: the handful of places Ultimate Member paints its
   own blue. */
.vg-um .um .um-profile-nav-item.active a,
.vg-um .um .um-profile-nav-item.active a:hover,
.vg-um .um .um-members-pagi span.current,
.vg-um .um .um-members-pagi span.current:hover { background: var(--wp--preset--color--ink) !important; }
.vg-um .um .um-member-name a,
.vg-um .um-profile.um .um-name a { color: var(--wp--preset--color--ink) !important; }
.vg-um .um .um-member-name a:hover,
.vg-um .um .um-members-pagi a:hover,
.vg-um .um .um-profile-subnav a.active,
.vg-um .um .um-item-meta a { color: var(--wp--preset--color--accent) !important; }

/* ---- member area ------------------------------------------------------------ */

.vg-app--member { padding-top: var(--wp--preset--spacing--40); }

/* Section tabs for the member area. Words, so the sans; the page you are on is
   marked by an ink rule, the same device as the header's current link. */
/* The rules are drawn with inset shadows, not borders: a 2px bottom border
   pulled over the container's 1px line overflowed the scrolling list by a
   pixel, and the browser drew a scrollbar for it. */
.vg-subnav {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--20);
	box-shadow: inset 0 -1px 0 var(--vg-hairline);
	margin: 0 0 var(--wp--preset--spacing--40);
}
.vg-subnav__list { display: flex; gap: .25rem; list-style: none; margin: 0; padding: 0; overflow-x: auto; scrollbar-width: none; }
.vg-subnav__list::-webkit-scrollbar { display: none; }
.vg-subnav__link {
	display: inline-flex;
	align-items: center;
	height: 42px;
	padding: 0 .75rem;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	color: var(--wp--preset--color--ink-muted);
	text-decoration: none;
	white-space: nowrap;
}
.vg-subnav__link:hover { color: var(--wp--preset--color--ink); text-decoration: none; }
.vg-subnav__link[aria-current="page"] { color: var(--wp--preset--color--ink); box-shadow: inset 0 -2px 0 var(--wp--preset--color--ink); }
.vg-subnav__out { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-muted); white-space: nowrap; flex: none; }
.vg-subnav__out:hover { color: var(--wp--preset--color--accent); }
@media (max-width: 640px) {
	.vg-subnav { flex-wrap: wrap; }
	.vg-subnav__out { padding-bottom: .5rem; }
}

/* Overview: three ways in, as one hairline lattice like the audience tiles. */
.vg-hub {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	background: var(--wp--preset--color--base);
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius-lg);
	overflow: hidden;
}
.vg-hub__tile {
	display: flex;
	flex-direction: column;
	gap: .375rem;
	padding: var(--wp--preset--spacing--30);
	color: inherit;
	text-decoration: none;
	box-shadow: -1px 0 0 var(--vg-hairline), 0 -1px 0 var(--vg-hairline);
	transition: background var(--vg-dur) var(--vg-ease);
}
.vg-hub__tile:hover { background: var(--wp--preset--color--panel); text-decoration: none; }
.vg-hub__title { font-size: var(--wp--preset--font-size--medium); font-weight: 580; letter-spacing: -.012em; color: var(--wp--preset--color--ink); }
.vg-hub__value { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--accent); }
.vg-hub__body { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-muted); line-height: 1.55; }
@media (max-width: 760px) { .vg-hub { grid-template-columns: 1fr; } }

/* ---- small forms: the redirector and password-protected pages ----------- */

.vg-redirector .simple-redirector-form,
.vg-password .post-password-form {
	text-align: left;
	margin: 0;
	width: 100%;
	max-width: 26rem;
	padding-top: var(--wp--preset--spacing--20);
	border-top: 1px solid var(--vg-hairline);
}
.vg-password .post-password-form p { color: var(--wp--preset--color--ink-muted); font-size: var(--wp--preset--font-size--small); margin: 0 0 var(--wp--preset--spacing--20); }
.vg-password .post-password-form label { display: grid; gap: .375rem; font-size: var(--wp--preset--font-size--small); font-weight: 500; color: var(--wp--preset--color--ink); }
.vg-redirector .simple-redirector-form input[type="email"],
.vg-password .post-password-form input[type="password"] {
	display: block;
	width: 100%;
	height: 42px;
	margin: 0;
	padding: 0 .75rem;
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--ink);
	font: inherit;
	font-size: var(--wp--preset--font-size--small);
}
.vg-redirector .simple-redirector-form input[type="email"]:focus,
.vg-password .post-password-form input[type="password"]:focus {
	border-color: var(--wp--preset--color--accent);
	box-shadow: 0 0 0 3px var(--wp--preset--color--accent-soft);
	outline: none;
}
.vg-redirector .simple-redirector-form input[type="submit"],
.vg-password .post-password-form input[type="submit"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: auto;
	min-height: 42px;
	margin: .75rem 0 0;
	padding: .5rem 1.125rem;
	border: 1px solid var(--wp--preset--color--accent);
	border-radius: var(--vg-radius);
	background: var(--wp--preset--color--accent);
	color: #fff;
	font: inherit;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 560;
	cursor: pointer;
}
.vg-redirector .simple-redirector-form input[type="submit"]:hover,
.vg-password .post-password-form input[type="submit"]:hover { background: #2E3AD4; border-color: #2E3AD4; color: #fff; }
.vg-redirector #simple-redirector-message { margin-top: var(--wp--preset--spacing--20); font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-muted); }

/* The two internal tools keep their own markup and script; this only sets
   their controls in the site's type. */
.vg-tool { max-width: 62rem; }
.vg-tool label { display: block; font-size: var(--wp--preset--font-size--small); font-weight: 500; color: var(--wp--preset--color--ink); margin: var(--wp--preset--spacing--20) 0 .375rem; }
.vg-tool textarea,
.vg-tool input[type="text"],
.vg-tool input[type="email"] {
	width: 100%;
	padding: .625rem .75rem;
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--small);
}
.vg-tool button,
.vg-tool input[type="button"],
.vg-tool input[type="submit"] {
	min-height: 38px;
	margin: .5rem .5rem 0 0;
	padding: .5rem 1rem;
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--ink);
	font: inherit;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	cursor: pointer;
}
.vg-tool button:hover,
.vg-tool input[type="button"]:hover,
.vg-tool input[type="submit"]:hover { border-color: var(--wp--preset--color--ink); }

/* The header is sticky, but WordPress wraps the header part in a div exactly
   as tall as the header, so position: sticky had nothing to stick within and
   the header scrolled away on every page (measured 2026-09-10). The wrapper
   takes the stickiness instead. Below the admin bar when it is there. */
.wp-block-template-part:has(> .vg-header) { position: sticky; top: 0; z-index: 100; }
body.admin-bar .wp-block-template-part:has(> .vg-header) { top: var(--wp-admin--admin-bar--height, 32px); }

/* Posts: the article lines up with the title and image instead of being
   centred inside them. Core's constrained layout sets auto margins with
   !important, so this has to as well. */
.wp-block-post-content.is-layout-constrained > .vg-prose--article { margin-left: 0 !important; margin-right: 0 !important; }

/* ------------------------------------------------------- cookie banner --- */

/* Complianz. Its colours are plugin settings, printed as custom properties on
   :root, and the banner was still on the plugin's defaults: WordPress blue
   (#1E73BE) buttons and links and an orange switch. Declared again on the
   banner itself, which shadows the :root values for it and nothing else. */
#cmplz-cookiebanner-container .cmplz-cookiebanner {
	--cmplz_banner_background_color: var(--wp--preset--color--base);
	--cmplz_banner_border_color: var(--wp--preset--color--hairline);
	--cmplz_banner_border_width: 1px;
	--cmplz_banner_border_radius: 6px;
	--cmplz_text_color: var(--wp--preset--color--ink-muted);
	--cmplz_hyperlink_color: var(--wp--preset--color--accent);
	--cmplz_button_accept_background_color: var(--wp--preset--color--accent);
	--cmplz_button_accept_border_color: var(--wp--preset--color--accent);
	--cmplz_button_accept_text_color: #fff;
	--cmplz_button_deny_background_color: var(--wp--preset--color--base);
	--cmplz_button_deny_border_color: var(--wp--preset--color--hairline);
	--cmplz_button_deny_text_color: var(--wp--preset--color--ink);
	--cmplz_button_settings_background_color: var(--wp--preset--color--base);
	--cmplz_button_settings_border_color: var(--wp--preset--color--hairline);
	--cmplz_button_settings_text_color: var(--wp--preset--color--ink);
	--cmplz_button_border_radius: 4px;
	--cmplz_button_font_size: 13px;
	--cmplz_slider_active_color: var(--wp--preset--color--accent);
	--cmplz_slider_inactive_color: #C9CDD4;
	--cmplz_category_header_always_active_color: var(--wp--preset--color--signal);
	font-family: var(--wp--preset--font-family--sans);
	box-shadow: var(--wp--preset--shadow--lift);
}
#cmplz-cookiebanner-container .cmplz-cookiebanner .cmplz-title {
	font-weight: 580;
	color: var(--wp--preset--color--ink);
}
#cmplz-cookiebanner-container .cmplz-cookiebanner .cmplz-btn { font-weight: 560; }

/* ---------------------------------------------------------- blog posts --- */

/* inc/posts.php. The article from each post's Elementor data, set as prose
   under the template's title. Date in mono (a value), author in the sans. */
.vg-post-meta { gap: .75rem; margin-bottom: .75rem; }
.vg-post-meta > * { margin: 0; }
.vg-prose--article { max-width: 68ch; }
.vg-prose--article > p:first-child {
	font-size: var(--wp--preset--font-size--medium);
	color: var(--wp--preset--color--ink);
	line-height: 1.6;
}
.vg-prose--article h2 {
	font-size: var(--wp--preset--font-size--large);
	letter-spacing: -.016em;
	margin: var(--wp--preset--spacing--40) 0 var(--wp--preset--spacing--10);
}
.vg-prose--article b,
.vg-prose--article strong { color: var(--wp--preset--color--ink); font-weight: 580; }
.vg-prose--article table { width: 100%; border-collapse: collapse; margin: 0 0 var(--wp--preset--spacing--20); font-size: var(--wp--preset--font-size--small); }
.vg-prose--article td,
.vg-prose--article th { padding: .625rem .75rem; border-bottom: 1px solid var(--vg-hairline); text-align: left; vertical-align: top; color: var(--wp--preset--color--ink-muted); }

/* Takeaways: a list with a rule between points and the tick in the accent. */
.vg-takeaways {
	list-style: none;
	margin: var(--wp--preset--spacing--40) 0 0;
	padding: 0;
	border-top: 1px solid var(--vg-hairline);
}
.vg-takeaways li {
	position: relative;
	margin: 0;
	padding: .875rem 0 .875rem 1.75rem;
	border-bottom: 1px solid var(--vg-hairline);
	color: var(--wp--preset--color--ink);
	line-height: 1.55;
}
.vg-takeaways li::before {
	content: "\2713";
	position: absolute;
	left: .125rem;
	top: .875rem;
	color: var(--wp--preset--color--accent);
	font-weight: 600;
}

/* The cart and checkout section sits last in the file on purpose.
   Its rules are page-scoped overrides of the site-wide WooCommerce rules
   above, and several of them tie those rules on specificity — for example
   `body.woocommerce-cart td.product-price` and `.woocommerce
   table.shop_table td` are both (0,2,2). On a tie, source order wins. With
   this section earlier in the file the global rule won silently: the price
   columns stayed left-aligned and the actions row lost its padding. Keep it
   below the global WooCommerce block. */

/* ---------------------------------------------------- cart & checkout --- */

/* CSS only, on purpose. These two pages take money, and every other change
   made to the site today changed how a page renders. Here the rendering is
   left exactly as it is — Ultimate Member's login gate, WooCommerce's cart and
   checkout templates, the Stripe gateway and the Checkout Field Editor all run
   unchanged — and only the presentation of WooCommerce's classic markup moves.

   Class names below were read from the live WooCommerce 11.1 templates on
   2026-09-10 (cart/cart.php, cart-totals.php, checkout/form-checkout.php,
   review-order.php, payment.php), not written from memory.

   Scoped with the body classes WooCommerce adds to these two pages, so none of
   this can leak onto any other page.

   Values — prices, quantities, totals, order numbers — are set in mono with
   tabular figures. Words are set in the sans. */

/* The page content is an old Elementor layout wrapped around the WooCommerce
   shortcode: a heading repeating the page title, a divider, and an icon-list
   nav bar — the same embedded chrome the legal pages carried (U60). The theme
   prints the real title, header and footer, so the copies go. The WooCommerce
   output is not an Elementor widget and is untouched by this. */
body.woocommerce-cart .elementor-widget-heading,
body.woocommerce-cart .elementor-widget-divider,
body.woocommerce-cart .elementor-widget-icon-list,
body.woocommerce-checkout .elementor-widget-heading,
body.woocommerce-checkout .elementor-widget-divider,
body.woocommerce-checkout .elementor-widget-icon-list { display: none !important; }

/* The rule above hid the widgets and left their boxes standing (U96). Read
   from _elementor_data rather than guessed: both pages were built from the
   same old template, so the same three blocks wrap the WooCommerce widget on
   each. 6c5537a is the old in-page header, a coloured background with a 1px
   bottom border, which is the teal bar under the page title and the dark line
   beneath it; it also holds an old "vp-header" nav on checkout and an old
   ElementsKit menu on cart. 3cb1acc9 and fcab8b5 are old footer bands with
   coloured backgrounds, whose headings were hidden but whose colour was not.
   Targeted by Elementor element ID, never by a broad selector, because the
   block between them is the checkout: a wrong ID can only leave a bar
   standing, it cannot hide the payment form. Not scoped to cart and checkout,
   so any page that still renders this old template loses it too. */
.elementor-element-6c5537a,
.elementor-element-3cb1acc9,
.elementor-element-fcab8b5 { display: none !important; }

/* Every Elementor divider on the site is the old design. The theme draws its
   own hairlines and never emits one, so this can only remove leftovers. */
.elementor-widget-divider { display: none !important; }

/* Cart and checkout run the page's width, 1240px like every other page,
   instead of the 720px reading measure (U96). The templates dropped their
   "constrained" layout for that; this stops Elementor's own boxed container,
   which caps at the kit's content width, from narrowing it again. Articles and
   the legal pages keep 720px on purpose: that is a reading width, and these
   two are forms and tables. */
.vg-section--commerce .e-con,
.vg-section--commerce .e-con-inner {
	--content-width: 100%;
	max-width: 100%;
}

body.woocommerce-cart .vg-main,
body.woocommerce-checkout .vg-main { padding-bottom: var(--wp--preset--spacing--60); }

/* ---- shared: tables and buttons ------------------------------------------ */

body.woocommerce-cart table.shop_table,
body.woocommerce-checkout table.shop_table {
	width: 100%;
	border: 0;
	border-collapse: collapse;
	border-top: 1px solid var(--vg-hairline);
	border-radius: 0;
	margin: 0 0 var(--wp--preset--spacing--30);
	font-size: var(--wp--preset--font-size--small);
}
body.woocommerce-cart table.shop_table th,
body.woocommerce-checkout table.shop_table th {
	font-weight: 500;
	color: var(--wp--preset--color--ink-muted);
	text-align: left;
	padding: .875rem .75rem;
	border-bottom: 1px solid var(--vg-hairline);
	background: transparent;
}
body.woocommerce-cart table.shop_table td,
body.woocommerce-checkout table.shop_table td {
	padding: 1rem .75rem;
	border-bottom: 1px solid var(--vg-hairline);
	border-top: 0;
	vertical-align: middle;
	color: var(--wp--preset--color--ink);
	background: transparent;
}

/* Every figure on these pages is a value, so every figure is mono. */
body.woocommerce-cart .woocommerce-Price-amount,
body.woocommerce-checkout .woocommerce-Price-amount,
body.woocommerce-cart .product-quantity,
body.woocommerce-checkout .product-quantity {
	font-family: var(--wp--preset--font-family--mono);
	font-variant-numeric: tabular-nums;
}

/* The primary action on each page: proceed, then pay. Full-strength accent,
   full width in its column, a 44px floor for a thumb. */
body.woocommerce-cart .wc-proceed-to-checkout .checkout-button,
body.woocommerce-checkout #place_order {
	display: block;
	width: 100%;
	min-height: var(--vg-tap);
	padding: .875rem 1.25rem;
	font: inherit;
	font-size: var(--wp--preset--font-size--base);
	font-weight: 560;
	text-align: center;
	color: #fff;
	background: var(--wp--preset--color--accent);
	border: 1px solid var(--wp--preset--color--accent);
	border-radius: var(--vg-radius);
	cursor: pointer;
	transition: background var(--vg-dur) var(--vg-ease), border-color var(--vg-dur) var(--vg-ease);
}
body.woocommerce-cart .wc-proceed-to-checkout .checkout-button:hover,
body.woocommerce-checkout #place_order:hover {
	background: var(--wp--preset--color--ink);
	border-color: var(--wp--preset--color--ink);
	color: #fff;
}

/* Secondary buttons — apply coupon, update cart — as the ghost style. */
body.woocommerce-cart .actions .button,
body.woocommerce-checkout .checkout_coupon .button {
	font: inherit;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	color: var(--wp--preset--color--ink);
	background: var(--wp--preset--color--base);
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius);
	padding: .5rem .875rem;
	min-height: 38px;
	cursor: pointer;
}
body.woocommerce-cart .actions .button:hover,
body.woocommerce-checkout .checkout_coupon .button:hover { border-color: var(--wp--preset--color--ink); }
body.woocommerce-cart .actions .button:disabled { opacity: .45; cursor: default; }

/* ---- cart ----------------------------------------------------------------- */

body.woocommerce-cart table.shop_table.cart th.product-thumbnail,
body.woocommerce-cart table.shop_table.cart td.product-thumbnail { width: 72px; }
body.woocommerce-cart td.product-thumbnail img {
	width: 56px;
	height: 56px;
	object-fit: cover;
	border-radius: var(--vg-radius);
	border: 1px solid var(--vg-hairline);
	display: block;
}
body.woocommerce-cart td.product-name a {
	font-weight: 560;
	color: var(--wp--preset--color--ink);
	text-decoration: none;
}
body.woocommerce-cart td.product-name a:hover { color: var(--wp--preset--color--accent); }
/* Figures right-aligned, and their headers with them so each label sits over
   its column. `table.shop_table` is in these selectors for specificity: the
   shared header rule above is (0,2,3) and sets text-align: left, so a bare
   `body.woocommerce-cart th.product-price` (0,2,2) lost to it and the headers
   stayed left over right-aligned figures. */
body.woocommerce-cart table.shop_table td.product-price,
body.woocommerce-cart table.shop_table td.product-subtotal,
body.woocommerce-cart table.shop_table td.product-quantity,
body.woocommerce-cart table.shop_table th.product-price,
body.woocommerce-cart table.shop_table th.product-subtotal,
body.woocommerce-cart table.shop_table th.product-quantity { text-align: right; }

/* The remove control: a quiet × that turns to the warning colour on intent,
   not a red disc shouting from every row. */
body.woocommerce-cart td.product-remove { width: 40px; }
body.woocommerce-cart td.product-remove a.remove {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	border-radius: 50%;
	font-size: 1.125rem;
	line-height: 1;
	color: var(--wp--preset--color--ink-faint) !important;
	background: transparent;
	text-decoration: none;
	transition: color var(--vg-dur) var(--vg-ease), background var(--vg-dur) var(--vg-ease);
}
body.woocommerce-cart td.product-remove a.remove:hover {
	color: var(--wp--preset--color--warn) !important;
	background: var(--wp--preset--color--warn-soft);
}

/* Quantity. Every case is sold one at a time (U56), so this is normally a
   plain "1"; when WooCommerce does render an input, it matches the fields. */
body.woocommerce-cart td.product-quantity input.qty {
	width: 4.25rem;
	text-align: right;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--small);
	padding: .45rem .5rem;
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius);
	background: var(--wp--preset--color--base);
}

/* Actions row: coupon on the left, update on the right. */
body.woocommerce-cart td.actions { padding-top: var(--wp--preset--spacing--20); }
body.woocommerce-cart td.actions .coupon {
	display: inline-flex;
	gap: .5rem;
	align-items: center;
	float: none;
}
body.woocommerce-cart td.actions .coupon label { position: absolute; left: -9999px; }
body.woocommerce-cart td.actions .coupon #coupon_code {
	width: 12rem;
	font: inherit;
	font-size: var(--wp--preset--font-size--small);
	padding: .5rem .75rem;
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius);
	min-height: 38px;
}
body.woocommerce-cart td.actions > .button { float: right; }

/* Totals sit under the table on the right, as a column that ends in the
   proceed button, so the eye runs down to the one thing to do next. */
body.woocommerce-cart .cart-collaterals {
	display: flex;
	justify-content: flex-end;
	margin-top: var(--wp--preset--spacing--30);
}
body.woocommerce-cart .cart-collaterals .cart_totals {
	width: 100%;
	max-width: 24rem;
	float: none;
}
body.woocommerce-cart .cart_totals h2 {
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 580;
	margin: 0 0 var(--wp--preset--spacing--20);
}
body.woocommerce-cart .cart_totals table.shop_table td { text-align: right; }
body.woocommerce-cart .cart_totals .order-total th,
body.woocommerce-cart .cart_totals .order-total td {
	font-size: var(--wp--preset--font-size--base);
	font-weight: 600;
	color: var(--wp--preset--color--ink);
	border-bottom: 0;
}
body.woocommerce-cart .wc-proceed-to-checkout { padding: var(--wp--preset--spacing--20) 0 0; }

/* Empty cart. A member lands here after removing their only item, so it
   points straight back to the library rather than at an empty table. */
body.woocommerce-cart .cart-empty {
	font-size: var(--wp--preset--font-size--medium);
	color: var(--wp--preset--color--ink);
	border: 0;
	background: transparent;
	padding: 0;
	margin: 0 0 var(--wp--preset--spacing--20);
}
body.woocommerce-cart .cart-empty::before { display: none; }
body.woocommerce-cart .return-to-shop .button {
	display: inline-block;
	font: inherit;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 560;
	color: #fff;
	background: var(--wp--preset--color--accent);
	border-radius: var(--vg-radius);
	padding: .75rem 1.25rem;
	text-decoration: none;
}

/* ---- checkout ------------------------------------------------------------- */

/* Details on the left, the order and payment on the right. Grid areas are
   named so WooCommerce's AJAX refresh of #order_review, which replaces its
   contents, never disturbs the layout: the container keeps its place. */
body.woocommerce-checkout form.checkout {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 27rem);
	grid-template-areas:
		"details heading"
		"details review";
	column-gap: var(--wp--preset--spacing--50);
	align-items: start;
}
body.woocommerce-checkout form.checkout > * { grid-column: 1 / -1; }
body.woocommerce-checkout #customer_details { grid-area: details; }
body.woocommerce-checkout #order_review_heading { grid-area: heading; }
body.woocommerce-checkout #order_review { grid-area: review; }

@media (max-width: 900px) {
	body.woocommerce-checkout form.checkout {
		grid-template-columns: 1fr;
		grid-template-areas: "details" "heading" "review";
	}
}

/* Case studies are virtual, so there is no shipping column. The two-column
   field set WooCommerce reserves for billing and shipping collapses to one. */
body.woocommerce-checkout #customer_details.col2-set { display: block; width: 100%; }
body.woocommerce-checkout #customer_details .col-1,
body.woocommerce-checkout #customer_details .col-2 { width: 100%; float: none; }

body.woocommerce-checkout .woocommerce-billing-fields h3,
body.woocommerce-checkout .woocommerce-additional-fields h3,
body.woocommerce-checkout #order_review_heading {
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 580;
	margin: 0 0 var(--wp--preset--spacing--20);
	padding-top: var(--wp--preset--spacing--20);
	border-top: 1px solid var(--vg-hairline);
}

body.woocommerce-checkout .form-row { margin: 0 0 var(--wp--preset--spacing--20); padding: 0; }
body.woocommerce-checkout .form-row-first,
body.woocommerce-checkout .form-row-last { width: calc(50% - .5rem); }
body.woocommerce-checkout .form-row-first { float: left; }
body.woocommerce-checkout .form-row-last { float: right; }
body.woocommerce-checkout .form-row-wide { clear: both; }
@media (max-width: 640px) {
	body.woocommerce-checkout .form-row-first,
	body.woocommerce-checkout .form-row-last { width: 100%; float: none; }
}
/* The required asterisk is hidden, and that is WooCommerce's choice, not a
   bug: its stylesheet sets `.form-row .required { visibility: hidden }` and
   `.optional { visibility: visible }`, so fields are required by default and
   the exceptions are the ones labelled "(optional)". Required inputs still
   carry `aria-required`. Do not make the asterisk visible without also
   dropping the "(optional)" labels, or every field gets marked twice. */
body.woocommerce-checkout .form-row .required {
	color: var(--wp--preset--color--warn);
	text-decoration: none;
	border: 0;
}
body.woocommerce-checkout .woocommerce-input-wrapper { display: block; }

/* The order summary. */
body.woocommerce-checkout .woocommerce-checkout-review-order-table td.product-total,
body.woocommerce-checkout .woocommerce-checkout-review-order-table th.product-total,
body.woocommerce-checkout .woocommerce-checkout-review-order-table tfoot td { text-align: right; }
body.woocommerce-checkout .woocommerce-checkout-review-order-table .product-name { font-weight: 500; }
body.woocommerce-checkout .woocommerce-checkout-review-order-table .product-quantity {
	color: var(--wp--preset--color--ink-faint);
	font-weight: 400;
}
body.woocommerce-checkout .woocommerce-checkout-review-order-table .order-total th,
body.woocommerce-checkout .woocommerce-checkout-review-order-table .order-total td {
	font-size: var(--wp--preset--font-size--base);
	font-weight: 600;
	color: var(--wp--preset--color--ink);
	border-bottom: 0;
}

/* Payment. A band, not a boxed panel: the methods are a list with a hairline
   between them, and the place-order button closes the column. */
body.woocommerce-checkout #payment {
	background: transparent;
	border-radius: 0;
	border-top: 1px solid var(--vg-hairline);
	padding-top: var(--wp--preset--spacing--20);
}
body.woocommerce-checkout #payment ul.payment_methods {
	list-style: none;
	margin: 0;
	padding: 0;
	border: 0;
}
body.woocommerce-checkout #payment ul.payment_methods li {
	padding: .875rem 0;
	border-bottom: 1px solid var(--vg-hairline);
	font-size: var(--wp--preset--font-size--small);
}
body.woocommerce-checkout #payment ul.payment_methods li > label {
	font-weight: 560;
	color: var(--wp--preset--color--ink);
	cursor: pointer;
}
body.woocommerce-checkout #payment ul.payment_methods li img { max-height: 22px; vertical-align: middle; margin-left: .35rem; }
body.woocommerce-checkout #payment div.payment_box {
	background: var(--wp--preset--color--panel);
	color: var(--wp--preset--color--ink-muted);
	font-size: var(--wp--preset--font-size--small);
	border-radius: var(--vg-radius);
	padding: .875rem 1rem;
	margin: .75rem 0 0;
}
/* WooCommerce draws a speech-bubble arrow on the payment box. */
body.woocommerce-checkout #payment div.payment_box::before { display: none; }

/* The Stripe card fields are iframes Stripe controls. Only the container is
   ours, and it is given the same frame as every other input so the card
   number does not look like a different form. */
body.woocommerce-checkout #payment .wc-stripe-elements-field,
body.woocommerce-checkout #payment .wc-stripe-iban-element-field,
body.woocommerce-checkout #payment .stripe-card-group > div {
	background: var(--wp--preset--color--base);
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius);
	padding: .7rem .75rem;
}

body.woocommerce-checkout .place-order { padding: var(--wp--preset--spacing--20) 0 0; }
body.woocommerce-checkout .woocommerce-terms-and-conditions-wrapper {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink-muted);
	margin-bottom: var(--wp--preset--spacing--20);
}
body.woocommerce-checkout .woocommerce-privacy-policy-text p { margin: 0 0 .5rem; }

/* Coupon and returning-customer toggles above the form. */
body.woocommerce-checkout .woocommerce-form-coupon-toggle .woocommerce-info,
body.woocommerce-checkout .woocommerce-form-login-toggle .woocommerce-info { margin-bottom: var(--wp--preset--spacing--20); }
body.woocommerce-checkout form.checkout_coupon {
	display: flex;
	gap: .5rem;
	align-items: center;
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius);
	padding: .875rem;
	margin: 0 0 var(--wp--preset--spacing--30);
}
body.woocommerce-checkout form.checkout_coupon .form-row { margin: 0; float: none; width: auto; }

/* Leftovers of the old page inside cart and checkout, found in the audit of
   2026-09-10: the 2014–2023/2025 copyright line (the only text widget on
   either page) and, on checkout, the old "Library Account MyOrders Contact"
   bar (an HTML widget printing <nav class="vp-header"> with its own styles).
   The other HTML widget on both pages loads Stripe's script and prints
   nothing, so it is left alone. Still CSS only: no template, hook or payment
   code changes. */
body.woocommerce-cart .elementor-widget-text-editor,
body.woocommerce-checkout .elementor-widget-text-editor,
body.woocommerce-checkout .elementor-widget-html:has(.vp-header),
body.woocommerce-checkout .vp-header { display: none !important; }

/* ---- order received ------------------------------------------------------- */

/* The thank-you view is the checkout page at its order-received endpoint, in
   WooCommerce's classic markup. WooCommerce's own stylesheet sets the order
   overview in small capitals with dashed dividers; here it is a row of
   figures between two rules, words in the sans and values in mono. */
body.woocommerce-order-received .woocommerce-thankyou-order-received {
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 560;
	color: var(--wp--preset--color--ink);
	margin: 0 0 var(--wp--preset--spacing--30);
}
body.woocommerce-order-received ul.woocommerce-order-overview {
	list-style: none;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
	gap: 0 var(--wp--preset--spacing--30);
	margin: 0 0 var(--wp--preset--spacing--40);
	padding: 0;
	border-block: 1px solid var(--vg-hairline);
}
body.woocommerce-order-received ul.woocommerce-order-overview li {
	float: none;
	margin: 0;
	padding: var(--wp--preset--spacing--20) 0;
	border: 0 !important;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.4;
	text-transform: none;
	color: var(--wp--preset--color--ink-faint);
}
body.woocommerce-order-received ul.woocommerce-order-overview li strong {
	display: block;
	margin-top: .25rem;
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--base);
	font-weight: 500;
	color: var(--wp--preset--color--ink);
	font-variant-numeric: tabular-nums;
	text-transform: none;
}
body.woocommerce-order-received .woocommerce-order-details__title,
body.woocommerce-order-received .woocommerce-column__title {
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 580;
	margin: var(--wp--preset--spacing--40) 0 var(--wp--preset--spacing--20);
}
body.woocommerce-order-received .woocommerce-customer-details address {
	font-style: normal;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.6;
	color: var(--wp--preset--color--ink-muted);
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius);
	padding: var(--wp--preset--spacing--20);
}
body.woocommerce-order-received .woocommerce-table--order-details td.product-total,
body.woocommerce-order-received .woocommerce-table--order-details tfoot td { text-align: right; }

/* ------------------------------------------------------------ partner --- */

/* The one page that moves with the pointer. The site's device everywhere else
   is a hairline and a still page, so the motion is kept to the background:
   light behind the words, a field of points that answers the cursor and a soft
   edge on the card under it. Nothing moves that carries meaning, and nothing
   here is needed to read the page.

   The pointer arrives as two custom properties. --mx and --my are the eased
   position in the hero; --x and --y are the raw position inside a card, with
   --on as the switch the pointer turns off on its way out. */

.vg-pt-hero {
	--mx: 50%;
	--my: 38%;
	position: relative;
	overflow: hidden;
	isolation: isolate;
	background: var(--wp--preset--color--ink);
	color: #fff;
	padding: var(--wp--preset--spacing--70) 0 var(--wp--preset--spacing--60);
	border-bottom: 1px solid var(--wp--preset--color--ink);
}
@media (max-width: 780px) {
	.vg-pt-hero { padding: var(--wp--preset--spacing--50) 0 var(--wp--preset--spacing--40); }
}
.vg-pt-hero__field,
.vg-pt-hero__light {
	position: absolute;
	inset: 0;
	pointer-events: none;
	z-index: 0;
}
/* Two washes. The fixed one puts weight in the top right the way the page
   motif does; the moving one is the pointer. */
.vg-pt-hero__light {
	background:
		radial-gradient(34rem 26rem at var(--mx) var(--my), rgba(59, 73, 245, .38), transparent 66%),
		radial-gradient(48rem 32rem at 88% -8%, rgba(59, 73, 245, .16), transparent 62%);
}
.vg-pt-hero__inner {
	position: relative;
	z-index: 1;
	max-width: 1240px;
	margin-inline: auto;
	padding-inline: var(--wp--preset--spacing--30);
}
.vg-pt-hero__eyebrow { color: rgba(255, 255, 255, .56); }
.vg-pt-hero__title {
	font-size: var(--wp--preset--font-size--display);
	line-height: 1.04;
	letter-spacing: -.036em;
	color: #fff;
	max-width: 16ch;
	margin: 0 0 var(--wp--preset--spacing--30);
}
.vg-pt-hero__lede {
	font-size: var(--wp--preset--font-size--medium);
	line-height: 1.6;
	color: rgba(255, 255, 255, .68);
	max-width: 60ch;
	margin: 0 0 var(--wp--preset--spacing--20);
}
.vg-pt-hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: .625rem;
	margin-top: var(--wp--preset--spacing--30);
}
/* Scoped, so the ghost button on a dark ground beats the light one it inherits
   from without either rule having to come later in the file than the other. */
.vg-pt-hero .vg-btn--ghost {
	color: #fff;
	border-color: rgba(255, 255, 255, .3);
	background: transparent;
}
.vg-pt-hero .vg-btn--ghost:hover {
	color: #fff;
	background: rgba(255, 255, 255, .1);
	border-color: rgba(255, 255, 255, .55);
}

.vg-pt-stats { border-top: 0; }

.vg-pt-section .vg-section__head .vg-eyebrow { margin-bottom: .25rem; }

/* Why it works. */
.vg-pt-cards {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
	gap: var(--wp--preset--spacing--20);
}
.vg-pt-card,
.vg-pt-way,
.vg-pt-cta {
	--on: 0;
	position: relative;
	isolation: isolate;
	overflow: hidden;
}
/* The pointer's edge. A wash under the content, switched by --on, so a card
   that never sees the pointer is exactly the card it was. */
.vg-pt-card::before,
.vg-pt-way::before,
.vg-pt-cta::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	opacity: var(--on);
	transition: opacity 240ms var(--vg-ease);
	background: radial-gradient(16rem 16rem at var(--x, 50%) var(--y, 50%), rgba(59, 73, 245, .09), transparent 70%);
}
.vg-pt-card {
	display: flex;
	flex-direction: column;
	gap: .5rem;
	padding: var(--wp--preset--spacing--30);
	background: var(--wp--preset--color--base);
	border: 1px solid var(--vg-hairline);
	border-radius: var(--vg-radius-lg);
	transition: border-color 240ms var(--vg-ease), transform 240ms var(--vg-ease);
}
.vg-pt-card:hover { border-color: rgba(59, 73, 245, .38); transform: translateY(-2px); }
.vg-pt-card__n {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: .1em;
	color: var(--wp--preset--color--accent);
}
.vg-pt-card__k { font-size: var(--wp--preset--font-size--medium); font-weight: 580; letter-spacing: -.014em; margin: 0; }
.vg-pt-card__v { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-muted); line-height: 1.6; margin: 0; }

/* Ways to partner. Three across, then two: the same lattice the landing page
   uses for audiences, so a visitor who saw that grid recognizes this one. */
.vg-pt-ways {
	display: grid;
	grid-template-columns: repeat(6, 1fr);
	gap: 1px;
	background: var(--wp--preset--color--base);
	border-radius: var(--vg-radius-lg);
	overflow: hidden;
}
.vg-pt-way { grid-column: span 2; }
.vg-pt-way:nth-child(4),
.vg-pt-way:nth-child(5) { grid-column: span 3; }
@media (max-width: 900px) {
	.vg-pt-ways { grid-template-columns: 1fr 1fr; }
	.vg-pt-way,
	.vg-pt-way:nth-child(4),
	.vg-pt-way:nth-child(5) { grid-column: span 1; }
}
@media (max-width: 600px) {
	.vg-pt-ways { grid-template-columns: 1fr; }
	.vg-pt-way,
	.vg-pt-way:nth-child(4),
	.vg-pt-way:nth-child(5) { grid-column: 1 / -1; }
}
.vg-pt-way {
	display: flex;
	flex-direction: column;
	gap: .5rem;
	padding: var(--wp--preset--spacing--30);
	background: var(--wp--preset--color--base);
	box-shadow: -1px 0 0 var(--vg-hairline), 0 -1px 0 var(--vg-hairline);
	color: inherit;
	text-decoration: none;
	transition: background var(--vg-dur) var(--vg-ease);
}
.vg-pt-way:hover { background: var(--wp--preset--color--panel); text-decoration: none; }
.vg-pt-way__m {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: .08em;
	color: var(--wp--preset--color--ink-faint);
}
.vg-pt-way__k { font-size: var(--wp--preset--font-size--medium); font-weight: 580; letter-spacing: -.014em; color: var(--wp--preset--color--ink); }
.vg-pt-way__v { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-muted); line-height: 1.6; margin-bottom: auto; }
.vg-pt-way__go { font-size: var(--wp--preset--font-size--small); font-weight: 520; color: var(--wp--preset--color--accent); margin-top: .5rem; }
.vg-pt-way__go::after { content: " \2192"; display: inline-block; transition: transform var(--vg-dur) var(--vg-ease); }
.vg-pt-way:hover .vg-pt-way__go::after { transform: translateX(3px); }

/* In practice. */
.vg-pt-shapes {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--wp--preset--spacing--40);
	border-top: 1px solid var(--vg-hairline);
	padding-top: var(--wp--preset--spacing--40);
}
@media (max-width: 760px) { .vg-pt-shapes { grid-template-columns: 1fr; gap: var(--wp--preset--spacing--30); } }
.vg-pt-shape { display: grid; grid-template-columns: 2.5rem minmax(0, 1fr); }
.vg-pt-shape__n {
	font-family: var(--wp--preset--font-family--mono);
	font-size: var(--wp--preset--font-size--micro);
	letter-spacing: .1em;
	color: var(--wp--preset--color--accent);
	padding-top: .35rem;
}
.vg-pt-shape__k { font-size: var(--wp--preset--font-size--medium); font-weight: 580; letter-spacing: -.014em; margin: 0; }
.vg-pt-shape__v { font-size: var(--wp--preset--font-size--small); color: var(--wp--preset--color--ink-muted); line-height: 1.6; margin: .375rem 0 0; }

/* The reveal. The stylesheet never hides a section on its own: the script adds
   has-motion once it is running, so a page with no JavaScript and a page that
   asked for less motion both get the whole thing, drawn and still. */
.vg-partner.has-motion [data-vg-reveal] {
	opacity: 0;
	transform: translateY(12px);
	transition: opacity 620ms var(--vg-ease), transform 620ms var(--vg-ease);
}
.vg-partner.has-motion [data-vg-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
	.vg-partner [data-vg-reveal] { opacity: 1; transform: none; }
	.vg-pt-card:hover { transform: none; }
}
