/*
 * CORE — minimal white design in four brand colors, set in Global → Brand:
 * canvas (page background), primary (dark bands: top bar, footer, hero,
 * page banners), mute (light bands) and accent (links and buttons).
 * Tokens first; every color, font and size below comes from them.
 */

:root {
	--vef-canvas: #ffffff;
	--vef-primary: #111111;
	--vef-mute: #f6f6f6;
	--vef-accent: #c8102e;
	--vef-accent-dark: #a00d25;
	--vef-ink: #111111;
	--vef-text: #2b2b2b;
	/* Body text lightened toward the page: for a line that labels something
	   rather than says it — the word under a figure, a caption's byline. Mixed
	   from the text colour so it follows a site's palette instead of being a
	   grey somebody picked once. */
	--vef-text-soft: color-mix(in srgb, var(--vef-text) 72%, var(--vef-canvas, #fff));
	--vef-line: #e6e6e6;
	/* How far a card that is a link rises under the pointer. One number for
	   every card on the site; the click overlays extend by the same amount,
	   so they cannot drift apart from it. */
	--vef-card-lift: 6px;
	/* How heavy every shadow on the site is. Each keeps its own geometry and
	   its own share of the weight -- a hairline under a chip stays a hairline
	   while a video keeps its deep one -- because the dial multiplies the
	   alpha rather than replacing the shadow. 0 makes them all invisible
	   without removing anything, so nothing that uses box-shadow as a border
	   (the outline buttons, the contact chips) or as a focus ring is touched.
	   An alpha over 1 clamps on its own, which is what keeps Strong safe. */
	--vef-shade: 1;
	/* The shadow a card raises under the pointer. One value: the cards had
	   drifted to two, and nothing explained which card got which. */
	--vef-card-shadow: 0 14px 34px -16px rgba(0, 0, 0, calc(.25 * var(--vef-shade)));
	--vef-on-primary: rgba(255, 255, 255, .78);
	--vef-line-primary: rgba(255, 255, 255, .14);
	/* Type and washes on the primary. White on a dark primary (the default);
	   CORE writes charcoal versions when the primary is light enough that
	   white fails (vef_core_on_primary_css). */
	--vef-on-primary-strong: #fff;
	--vef-wash-primary: rgba(255, 255, 255, .06);
	--vef-wash-primary-strong: rgba(255, 255, 255, .15);
	--vef-font-display: "Raleway", system-ui, -apple-system, "Segoe UI", sans-serif;
	--vef-font-body: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
	/* --vef-font is the body face. Kept as the name the rest of the sheet
	   uses, so a site that overrides only one thing still works. */
	--vef-font: var(--vef-font-body);
	/* The eyebrow's size and the gap under it, as tokens because other things
	   line up against them — a hero's media aligns to the big line by
	   clearing exactly this much, and gets it wrong the moment the two
	   disagree. A site changing the eyebrow changes --vef-eyebrow-block too. */
	/* The hero's breathing room, top and bottom. The floor matters more than
	   the ceiling: 10vw of a phone is 37px, so the old 72px floor was a fixed
	   inch of nothing under a header that already takes 105px — a fifth of
	   the screen gone before the first word. Desktop is untouched; 10vw
	   passes 120px at 1200 and the ceiling holds from there. */
	--vef-hero-pad: clamp(40px, 10vw, 120px);
	/* The air above and below a home section. The note band borrows it so
	   its own spacing cannot drift away from the sections either side. */
	--vef-section-pad: clamp(64px, 8vw, 112px);
	/* What the results note gets at each end. A section's own rhythm by
	   default; a site that wants the note held closer to the figures it
	   qualifies sets this one value and both ends follow. */
	--vef-note-gap: var(--vef-section-pad);
	--vef-eyebrow-size: 14px;
	--vef-eyebrow-gap: 20px;
	--vef-eyebrow-block: calc(var(--vef-eyebrow-size) * 1.65 + var(--vef-eyebrow-gap));
	--vef-rail: 1240px;
	--vef-rail-narrow: 760px;
	--vef-gutter: clamp(20px, 4vw, 40px);
	--vef-header-h: 88px;
	/* Corner radius, as one brand dial and a scale derived from it, because a
	   single radius cannot serve a 4px input and a 12px card: the two are
	   proportional to the thing they sit on, not the same decision. Set
	   --vef-round alone and the whole site follows -- 0 squares it, 1.6 takes
	   cards to about 20px and inputs to about 6px. A brand that needs one
	   exception overrides that step instead.

	   Pills follow the dial too, which in practice means they square off at 0
	   and stay pills everywhere else: a pill's radius only has to clear half
	   its own height, so there is no middle. Circles keep 50% whatever the
	   dial says -- a round avatar is a shape, not a corner treatment. */
	--vef-round: 1;
	--vef-radius-xs: calc(4px * var(--vef-round));   /* inputs, buttons, search */
	--vef-radius-sm: calc(8px * var(--vef-round));   /* chips and small boxes */
	--vef-radius-md: calc(12px * var(--vef-round));  /* cards: the workhorse */
	--vef-radius-lg: calc(16px * var(--vef-round));  /* panels, maps, big media */
	--vef-radius-pill: calc(999px * var(--vef-round));
	/* The name the control radius has always had, and what Gravity Forms is
	   handed below. Kept as an alias so a site that set it by hand still works. */
	--vef-radius: var(--vef-radius-xs);
}

/* [hidden] always wins. Any rule here that sets a display — a button, a card
   wrapper, a grid item — would otherwise beat the browser's own
   [hidden] { display: none }, and anything the scripts hide (a filter, load
   more) would stay on screen. Learned twice in one afternoon. */
[hidden] { display: none !important; }

/* Base ------------------------------------------------------------------ */

*, *::before, *::after { box-sizing: border-box; }
/* One offset for every in-page link: targets stop 24px under the sticky header. */
html { -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--vef-chrome, 88px) + 24px); }
/* In-page links glide; instant for visitors who prefer less motion. */
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body {
	margin: 0;
	background: var(--vef-canvas);
	color: var(--vef-text);
	font-family: var(--vef-font);
	font-size: 16px;
	font-weight: 400;
	line-height: 1.65;
	-webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4, h5, h6 {
	color: var(--vef-ink);
	font-family: var(--vef-font-display);
	font-weight: 600;
	line-height: 1.2;
	margin: 0 0 .6em;
}
/* Links take the accent darkened enough to be READ on a light ground
   (--vef-accent-text, computed in PHP). The accent that looks right filling
   a button is 2.3:1 as a word on white. Dark sections set the property back
   to the accent below, so the bright one returns where it is legible. */
a { color: var(--vef-accent-text, var(--vef-accent)); }
a:hover { color: var(--vef-accent-text-dark, var(--vef-accent-dark)); }
/* <mark>: no highlight at all. The marker stroke this used to draw — a gold
   bar under the words — was taken out on 2026-10-18 at Gary's request, for
   every site rather than one.

   The rule stays because deleting it is not the same as removing the
   highlight: with no rule, <mark> falls back to the browser's black-on-yellow
   block, which is further from the design than the bar was. So the element
   stays legal in content and simply reads as the text around it.

   A colour picked in the editor's Highlight control still lands as an inline
   background-color and still wins over this, which is the one way a highlight
   can come back — on purpose, on one phrase, chosen by the person writing. */
mark {
	background: none;
	color: inherit;
}

/* Anything sitting ON the accent takes --vef-on-accent for its label, never
   a literal: white reads 5.9:1 on a red accent and 2.3:1 on a gold one, so a
   colour picked against one palette fails on the next. The token is computed
   per site against the accent and its hover (inc/setup.php). */
/* On a dark ground the bright accent IS the readable one, so these hand the
   property back. It inherits, so one line per section covers every link,
   eyebrow and icon inside it — rather than hunting them down one by one. */
.vef-topbar, .vef-hero, .vef-banner, .vef-contact, .vef-footer,
.vef-features, .vef-home--stats, .vef-callbar, .vef-quote-band, .vef-cta-panel {
	--vef-accent-text: var(--vef-accent);
	--vef-accent-text-dark: var(--vef-accent);
	--vef-button-line: var(--vef-on-primary-strong);
}

/* A link inside muted copy on a dark ground — the caption card, an interior
   banner's lede. The accent handback above would make it a second colour in
   a sentence that is already a colour down from white, so these take it back
   again: the link sits at the copy's own colour, marked only by its
   underline, and hovering lights the text to full white while the underline
   clears. One gesture, carried by the text rather than by the decoration.

   This is the standard for the case. A new context joins the list rather
   than inventing a colour of its own. The underline is the sole affordance
   at rest, so check it clears 3:1 on the site's --vef-primary; at 39% white
   it is 3.7:1 on CORE's near-black and 3.6:1 on a navy. The clearing is done
   in the decoration's colour, not text-decoration: none, because only the
   colour can be transitioned. */
:is(
	.vef-figure__caption,
	.vef-prose figure:not(.wp-block-pullquote) > figcaption,
	.vef-banner__lede
) a {
	color: inherit; text-decoration: underline;
	text-decoration-color: color-mix(in srgb, currentColor 50%, transparent);
	text-decoration-thickness: 1px; text-underline-offset: 3px;
	transition: color .18s ease, text-decoration-color .18s ease;
}
:is(
	.vef-figure__caption,
	.vef-prose figure:not(.wp-block-pullquote) > figcaption,
	.vef-banner__lede
) a:hover,
:is(
	.vef-figure__caption,
	.vef-prose figure:not(.wp-block-pullquote) > figcaption,
	.vef-banner__lede
) a:focus-visible {
	color: var(--vef-on-primary-strong); text-decoration-color: transparent;
}

img { max-width: 100%; height: auto; }
/* Shown to editors only, over content that visitors don't get (sample reviews). */
.vef-sample-note { margin: 0 0 24px; padding: 10px 14px; border: 1px dashed currentColor; border-radius: var(--vef-radius); font-size: 14px; opacity: .8; }
/* No field under 16px on a touch screen. iOS zooms the whole page in on any
   field set smaller and leaves it zoomed, so the page scrolls sideways. This
   wins over a plugin's own sizes (Gravity Forms, a search box set at 15px);
   a form inside another site's frame (Jobber) is out of CSS's reach, which
   is what core.js's viewport line is for. */
@media (pointer: coarse) {
	input:not([type="checkbox"], [type="radio"], [type="range"], [type="file"], [type="submit"], [type="button"], [type="reset"], [type="image"]),
	select,
	textarea { font-size: max(16px, 1em) !important; }
}
:focus-visible { outline: 2px solid var(--vef-accent); outline-offset: 3px; }
[tabindex="-1"]:focus { outline: none; }

.screen-reader-text {
	position: absolute; width: 1px; height: 1px; overflow: hidden;
	clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.vef-skip {
	position: absolute; left: 12px; top: -48px; z-index: 100;
	padding: 10px 16px; background: var(--vef-ink); color: #fff;
}
.vef-skip:focus { top: 12px; color: #fff; }

.vef-rail {
	width: 100%;
	max-width: calc(var(--vef-rail) + 2 * var(--vef-gutter));
	margin-inline: auto;
	padding-inline: var(--vef-gutter);
}
.vef-rail--narrow { max-width: calc(var(--vef-rail-narrow) + 2 * var(--vef-gutter)); }

/* --vef-on-accent is computed from the accent in PHP (vef_core_on_accent_css):
   white where white can be read on it, else the site's own primary, else
   near-black. It is not #fff because #fff is only right for a DARK accent,
   and a gold one shipped this button at 2.3:1. The fallback keeps the old
   behaviour on a site with no accent set at all. */
.vef-button {
	display: inline-flex; align-items: center; justify-content: center;
	padding: 14px 28px;
	border: 0; border-radius: var(--vef-radius);
	background: var(--vef-accent); color: var(--vef-on-accent, #fff);
	font: 700 16px/1.2 var(--vef-font);
	text-decoration: none; white-space: nowrap;
	position: relative; overflow: hidden;
	transition: background-color .15s ease, transform .15s ease;
}
/* A glare crossing the button on a slow loop, from Gary's design, and faster
   while the pointer is on it.

   Always white. It was mixed from --vef-on-accent at first, on the reasoning
   that it should follow the label and so stay visible on a light button --
   which is wrong about what the thing IS. A glare is light catching a
   surface; there is no such thing as a dark one. On Montagna the accent is
   gold, so --vef-on-accent computes to navy and the band swept across as a
   dark smudge. It read as correct on CORE only because red takes a white
   label.

   The variants switch it off: a pale band sweeping a transparent outline
   button reads as a rendering fault. */
.vef-button::after {
	content: ""; position: absolute; top: -20%; bottom: -20%; left: -45%; width: 34%;
	background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .38), transparent);
	transform: skewX(-22deg) translateX(0);
	animation: vef-sheen 4.8s ease-in-out infinite;
	pointer-events: none;
}
@keyframes vef-sheen {
	0%, 62% { transform: skewX(-22deg) translateX(0); }
	86%, 100% { transform: skewX(-22deg) translateX(480%); }
}
.vef-button:hover::after { animation-duration: 1.6s; }
.vef-button--outline::after, .vef-button--light::after, .vef-button--outline-light::after { display: none; }
/* Gary lifts the button; CORE scales it, on Carlos's call -- a lift inside a
   card that is itself lifting reads as two things moving at once. */
.vef-button:hover, .vef-button:focus-visible { background: var(--vef-accent-dark); color: var(--vef-on-accent, #fff); transform: scale(1.03); }
.vef-button { gap: 10px; }
.vef-button--outline { background: transparent; color: var(--vef-ink); box-shadow: inset 0 0 0 2px var(--vef-ink); }
.vef-button--outline:hover, .vef-button--outline:focus-visible { background: var(--vef-ink); color: #fff; }

/* An outline, filling white on hover. It used to be a white fill with no
   edge at all, which on a near-white band is a rectangle you have to hunt
   for — WCAG wants 3:1 on a control's boundary. The line is the primary on
   a light ground; dark sections hand it white below, where the primary
   would vanish instead. */
.vef-button--light {
	background: transparent;
	color: var(--vef-button-line, var(--vef-primary));
	box-shadow: inset 0 0 0 2px var(--vef-button-line, var(--vef-primary));
}
.vef-button--outline-light { background: transparent; color: var(--vef-on-primary-strong); box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--vef-on-primary-strong) 55%, transparent); }
.vef-button--outline-light:hover, .vef-button--outline-light:focus-visible { background: #fff; color: var(--vef-ink); box-shadow: inset 0 0 0 2px #fff; }
/* Filling on hover, not emptying: the label goes back to ink because the
   fill is white on either ground — which is also why the resting label
   takes --vef-button-line rather than ink. Over a dark section that
   property is white, and ink on a transparent dark ground would be a
   button nobody can read. */
.vef-button--light:hover, .vef-button--light:focus-visible { background: #fff; color: var(--vef-ink); }

.vef-eyebrow {
	margin: 0 0 var(--vef-eyebrow-gap);
	color: var(--vef-eyebrow-color, var(--vef-accent-text, var(--vef-accent))); font-family: var(--vef-font);
	font-size: var(--vef-eyebrow-size); font-weight: var(--vef-eyebrow-weight, 600);
	line-height: 1.65; letter-spacing: .2em; text-transform: uppercase;
}
/* Either line can carry the H1 (Home hero / Banner fields), and this is what
   makes the swap invisible: the eyebrow states its own line-height instead of
   inheriting one from the h1 rule, and the big line keeps the display face it
   was getting from that rule. */
p.vef-hero__title, p.vef-banner__title { font-family: var(--vef-font-display); font-weight: 600; }

.vef-icon { display: block; flex: none; }

/* Header ---------------------------------------------------------------- */

.vef-site-header { position: sticky; top: 0; z-index: 50; background: var(--vef-canvas); }
.admin-bar .vef-site-header { top: 32px; }

.vef-topbar { background: var(--vef-primary); color: var(--vef-on-primary-strong); font-size: 14px; text-align: center; }
.vef-topbar .vef-rail { padding-block: 8px; }
.vef-topbar p { margin: 0; }
.vef-topbar a { color: var(--vef-on-primary-strong); text-decoration: none; }
.vef-topbar a:hover { text-decoration: underline; }
/* Three layouts, chosen in Global → Header → Top bar rather than inferred
   from which fields happen to be filled.
   --message centres one line; --links puts the row hard against the right;
   --both gives the row two ends. The old rule claimed the two-ended version
   but set justify-content: flex-end, which pushed the message right along
   with everything else — it was never exercised, because no site had a
   message and a menu at the same time. */
:is(.vef-topbar--links, .vef-topbar--both) { text-align: left; }
:is(.vef-topbar--links, .vef-topbar--both) .vef-rail {
	display: flex; align-items: center;
	gap: 12px clamp(14px, 2vw, 26px); flex-wrap: wrap;
}
.vef-topbar--links .vef-rail { justify-content: flex-end; }
.vef-topbar--both .vef-rail { justify-content: space-between; }
.vef-topbar__note { display: inline-flex; align-items: center; gap: 8px; }
/* Global → Top bar text on phones: the short line swaps in at 640px. */
.vef-topbar__short { display: none; }
@media (max-width: 640px) {
	.vef-topbar__note .vef-topbar__long { display: none; }
	.vef-topbar__note .vef-topbar__short { display: inline; }
}
/* A linked message ends in an arrow, so the line reads as a way in rather
   than a slogan; it nudges on hover, the way the cards' links do. */
.vef-topbar .vef-topbar__note .vef-icon--arrow { width: 14px; height: 14px; color: currentColor; transition: transform .15s ease; }
.vef-topbar .vef-topbar__note:hover .vef-icon--arrow { transform: translateX(3px); }
@media (prefers-reduced-motion: reduce) { .vef-topbar__note .vef-icon--arrow { transition: none; } }
.vef-topbar__links { display: flex; align-items: center; gap: clamp(14px, 2vw, 26px); }
.vef-topbar__links a { display: inline-flex; align-items: center; gap: 7px; }
/* Every icon in the bar is the accent: they are the only colour on a dark
   row, and one of them being different read as an accident. */
.vef-topbar .vef-icon { width: 16px; height: 16px; flex: none; color: var(--vef-accent); }
.vef-topbar__tel { font-weight: 600; }
/* On a phone the bar keeps the icons and drops the words, bar the number. */
@media (max-width: 640px) {
	:is(.vef-topbar--links, .vef-topbar--both) .vef-rail { justify-content: flex-end; }
	/* Icons only, the number included: the row has to fit a narrow screen. */
	/* The message keeps its words in the message layout: it IS the bar
	   there. Hiding it left a linked message as a lone arrow. */
	.vef-topbar__links a span,
	:is(.vef-topbar--links, .vef-topbar--both) .vef-topbar__note span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
	.vef-topbar__note { display: inline-flex; }
	/* A message that wraps to two lines carries its arrow after the last
	   word, not floating beside the block. */
	.vef-topbar--message .vef-topbar__note { display: inline; }
	.vef-topbar--message .vef-topbar__note .vef-icon--arrow { display: inline-block; margin-left: 6px; vertical-align: -2px; }
}

.vef-header { border-bottom: 1px solid var(--vef-line); }
.vef-header__in {
	display: flex; align-items: center; gap: 32px;
	min-height: var(--vef-header-h);
}

.vef-brand { display: flex; align-items: center; margin-right: auto; color: var(--vef-ink); text-decoration: none; flex: 0 0 auto; }
.vef-brand:hover { color: var(--vef-ink); }
/* flex: 0 0 auto — without it the logo is the flexible item in the header
   row, so a cramped header squashes it instead of folding the menu. */
.vef-brand__logo { display: block; width: auto; max-height: 64px; flex: 0 0 auto; }
.vef-brand__name { font-size: 22px; font-weight: 600; letter-spacing: -.01em; }

.vef-nav { flex: none; }
.vef-nav__list { display: flex; gap: clamp(20px, 2.4vw, 36px); margin: 0; padding: 0; list-style: none; }
.vef-nav__list a {
	position: relative; display: inline-flex; align-items: center; gap: 8px; padding-block: 8px;
	color: var(--vef-ink); font-weight: 600; font-size: 16px; text-decoration: none; white-space: nowrap;
}
.vef-nav__list .vef-icon { flex: none; }
/* Every top-level link as tall as the row, so the underlines sit on one line:
   an icon-only item (the home house) is a 20px icon against a line of text,
   and its underline used to ride a few pixels higher than its neighbours'.
   Out in the header only; the folded menu lays its items out itself. */
.vef-site-header:not(.is-folded) .vef-nav__list > li { display: flex; }
.vef-nav__list a:hover { color: var(--vef-accent); }
.vef-nav__list .current-menu-item > a,
.vef-nav__list .current_page_item > a,
.vef-nav__list .current-menu-ancestor > a { color: var(--vef-accent); }
/* The underline belongs to every top-level item, not only the current one:
   it is simply held at scaleX(0) until the item is hovered or is the page
   you are on. Wiping from the left and then beating twice is Gary's, and the
   beat is what stops it reading as a plain CSS underline.

   Top level only (> li > a), so a dropdown's items do not grow one. The
   current-item rule below still matches a submenu item, but with no ::after
   content generated there it has nothing to transform. */
.vef-nav__list > li > a::after {
	content: ""; position: absolute; left: 0; right: 0; bottom: 0;
	height: 3px; border-radius: var(--vef-radius-xs); background: var(--vef-accent);
	transform: scaleX(0); transform-origin: left;
	transition: transform .28s ease;
}
.vef-nav__list > li > a:hover::after,
.vef-nav__list > li > a:focus-visible::after { transform: scaleX(1); animation: vef-navbeat 1.1s ease .3s 2; }
@keyframes vef-navbeat { 0%, 100% { transform: scaleX(1); } 45% { transform: scaleX(.86); } }
.vef-nav__list .current-menu-item > a::after,
.vef-nav__list .current_page_item > a::after { transform: scaleX(1); }
/*
 * Dropdowns, one level deep. CORE hid every sub-menu outright, so a menu
 * with children had them nowhere: not on hover, not folded, not on a phone.
 * No mega menu: a panel of thirty links in columns is more of the site than a
 * menu should try to be, and the group pages list them properly. header.php
 * renders two levels, so a third never reaches this stylesheet. They open on hover
 * and on focus-within, so the keyboard reaches them without script, and they
 * are hidden with visibility rather than display so the transition works and
 * the panel stays in the accessibility tree's reading order.
 */
.vef-nav__list > li { position: relative; }
/* The panel stands off the item rather than touching it, so the underline
   has air under it instead of being the panel's top edge. */
.vef-nav__list .sub-menu {
	--vef-nav-gap: 10px;
	position: absolute;
	top: calc(100% + var(--vef-nav-gap));
	left: -12px;
	z-index: 60;
	min-width: 230px;
	margin: 0;
	padding: 8px;
	list-style: none;
	border: 1px solid var(--vef-line);
	border-radius: var(--vef-radius);
	background: var(--vef-canvas);
	box-shadow: 0 20px 40px -16px rgba(0, 0, 0, calc(.3 * var(--vef-shade)));
	opacity: 0;
	visibility: hidden;
	transform: translateY(6px);
	transition: opacity .15s ease, transform .15s ease, visibility 0s linear .15s;
}
/* That gap would be dead ground: the pointer leaves the item on its way to
   the panel, li:hover goes false and the menu shuts under the cursor. This
   bridges it. It belongs to the panel, and hovering a descendant keeps the
   ancestor hovered, so the item stays open the whole way down. */
.vef-nav__list .sub-menu::before {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: calc(var(--vef-nav-gap) * -1);
	height: var(--vef-nav-gap);
}
.vef-nav__list > li:hover > .sub-menu,
.vef-nav__list > li:focus-within > .sub-menu {
	opacity: 1;
	visibility: visible;
	transform: none;
	transition-delay: 0s;
}
.vef-nav__list .sub-menu a {
	display: block;
	padding: 9px 12px;
	border-radius: var(--vef-radius-sm);
	font-size: 15px;
	font-weight: 600;
	white-space: normal;
}
.vef-nav__list .sub-menu a:hover { background: var(--vef-mute); }
.vef-nav__list .sub-menu .current-menu-item > a { color: var(--vef-accent); }
/* The underline is the top level's marker; inside a panel it reads as a rule. */
.vef-nav__list .sub-menu .current-menu-item > a::after,
.vef-nav__list .sub-menu .current_page_item > a::after { display: none; }

.vef-header__actions { display: flex; flex: none; align-items: center; gap: 24px; }
.vef-phone {
	display: flex; align-items: center; gap: 10px;
	color: var(--vef-ink); font-weight: 600; text-decoration: none; white-space: nowrap;
}
.vef-phone .vef-icon { color: var(--vef-accent); }
.vef-phone:hover { color: var(--vef-accent); }

.vef-nav-toggle {
	display: none; align-items: center; justify-content: center;
	width: 44px; height: 44px; padding: 0;
	border: 1px solid var(--vef-line); border-radius: var(--vef-radius);
	background: var(--vef-canvas); color: var(--vef-ink); cursor: pointer;
}
.vef-nav-toggle .vef-icon--close { display: none; }
.vef-site-header.is-open .vef-nav-toggle .vef-icon--menu { display: none; }
.vef-site-header.is-open .vef-nav-toggle .vef-icon--close { display: block; }

/*
 * Folded menu: core.js adds .is-folded under 1024px and whenever the menu
 * doesn't fit on one line, so it never wraps. Tablets get a dark card under
 * the toggle; phones the full-width panel (below). Without JavaScript the
 * menu stays out in the header.
 */
.vef-site-header.is-folded .vef-header__in { gap: 16px; }
.vef-site-header.is-folded .vef-nav-toggle { display: flex; }
/* The panel is closed to nothing and opened by core.js, which animates the
   height it measures. CSS cannot transition to height:auto, and the grid
   0fr-to-1fr trick that gets around that did not interpolate reliably here —
   it either jumped or stuck at zero, and a menu that sticks shut is worse
   than one that does not animate. The vertical padding sits on the list
   inside so the panel's height is exactly its content. */
.vef-site-header.is-folded .vef-nav {
	position: absolute; right: var(--vef-gutter); top: calc(100% - 4px); z-index: 2;
	width: min(320px, calc(100vw - 2 * var(--vef-gutter)));
	padding-inline: 24px;
	border-radius: var(--vef-radius-lg);
	border: 1px solid var(--vef-line-primary);
	background: var(--vef-primary);
	box-shadow: 0 20px 40px -16px rgba(0, 0, 0, calc(.45 * var(--vef-shade)));
	height: 0;
	overflow: hidden;
	visibility: hidden;
}
.vef-site-header.is-folded .vef-nav > .vef-nav__list { padding-block: 8px; }
.vef-site-header.is-folded.is-open .vef-nav {
	height: auto;
	/* Never taller than the screen below the header: open two or three
	   submenus and the list outgrows the viewport, and a menu you cannot
	   reach the bottom of is a menu with items nobody can tap. */
	max-height: calc(100svh - var(--vef-chrome, 88px) - 24px);
	overflow-y: auto;
	overscroll-behavior: contain;
	visibility: visible;
}
.vef-site-header.is-folded .vef-nav__list { flex-direction: column; gap: 0; }
/* Block, not the inline-flex the top level uses: an inline link is only as
   wide as its words, so the rule under it stopped short — Service Areas and
   Case Results had a border half the width of the ones above them. */
.vef-site-header.is-folded .vef-nav__list a { display: block; padding-block: 16px; border-bottom: 1px solid var(--vef-line-primary); color: var(--vef-on-primary-strong); font-size: 18px; }
/* Except the home icon, which keeps its short rule: it is an icon, not a
   word, and a full-width border under it reads as an empty row. */
.vef-site-header.is-folded .vef-nav__list .icon-only > a { display: inline-flex; }
.vef-site-header.is-folded .vef-nav__list a:hover,
.vef-site-header.is-folded .vef-nav__list .current-menu-item > a,
.vef-site-header.is-folded .vef-nav__list .current_page_item > a { color: var(--vef-accent); }
/* The last row closes the panel, so nothing draws a line under it — the
   chevron included, which kept its own and left a stub of rule floating to
   the right of the last item. */
.vef-site-header.is-folded .vef-nav__list li:last-child > a,
.vef-site-header.is-folded .vef-nav__list li:last-child > .vef-nav__sub { border-bottom: 0; }
/* Desktop: a parent says so with a small chevron. It is a mark, not a control
   — hover and focus-within do the opening — so it is drawn on the item rather
   than shown as the button, which would add a tab stop that does nothing.
   The li carries the link's colour so currentColor is right in every state:
   inherit alone would take the body ink and go near-invisible on a
   transparent header, which is how the folded chevron went wrong. */
.vef-site-header:not(.is-folded) .vef-nav__list > li { color: var(--vef-ink); }
.vef-site-header:not(.is-folded) .vef-nav__list > li:hover,
.vef-site-header:not(.is-folded) .vef-nav__list > li:focus-within,
.vef-site-header:not(.is-folded) .vef-nav__list > li.current-menu-item,
.vef-site-header:not(.is-folded) .vef-nav__list > li.current-menu-ancestor { color: var(--vef-accent); }
.vef-header-over .vef-site-header:not(.is-solid):not(.is-folded) .vef-nav__list > li { color: #fff; }
.vef-header-over .vef-site-header:not(.is-solid):not(.is-folded) .vef-nav__list > li:hover,
.vef-header-over .vef-site-header:not(.is-solid):not(.is-folded) .vef-nav__list > li:focus-within { color: var(--vef-accent); }
.vef-site-header:not(.is-folded) .vef-nav__list > .menu-item-has-children {
	display: flex;
	align-items: center;
	gap: 5px;
}
.vef-site-header:not(.is-folded) .vef-nav__list > .menu-item-has-children::after {
	content: "";
	flex: none;
	width: 6px;
	height: 6px;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: translateY(-2px) rotate(45deg);
	transition: transform .18s ease;
}
.vef-site-header:not(.is-folded) .vef-nav__list > .menu-item-has-children:hover::after,
.vef-site-header:not(.is-folded) .vef-nav__list > .menu-item-has-children:focus-within::after {
	transform: translateY(1px) rotate(-135deg);
}

/* The chevron beside a parent, folded. Hover opens a dropdown at full width,
   so the button is only wanted once the menu folds. */
.vef-nav__sub { display: none; }
.vef-site-header.is-folded .vef-nav__list .menu-item-has-children {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: center;
}
.vef-site-header.is-folded .vef-nav__sub {
	display: flex;
	align-items: center;
	justify-content: center;
	align-self: stretch;
	width: 48px;
	padding: 0;
	border: 0;
	border-bottom: 1px solid var(--vef-line-primary);
	background: none;
	/* The links in the folded card are white; the button inherits from its li,
	   which nothing colours, so it came out near-black on the navy card and
	   the only control for opening a submenu was invisible on a tablet. It
	   follows the links. */
	color: var(--vef-on-primary-strong);
	cursor: pointer;
}
.vef-site-header.is-folded .vef-nav__sub .vef-icon { transition: transform .18s ease; }
.vef-site-header.is-folded .menu-item-has-children.is-open > .vef-nav__sub .vef-icon { transform: rotate(180deg); }

/* Folded, the children are closed until the chevron opens them: Attorneys and
   Resources alone would otherwise push the rest of the menu off the screen.
   Clipped by the row above rather than removed, so it can slide; visibility
   keeps a closed list off the tab order, and waits for the slide to finish. */
.vef-site-header.is-folded .vef-nav__list .menu-item-has-children > .sub-menu {
	grid-column: 1 / -1;
	position: static;
	display: block;
	width: auto;
	min-width: 0;
	max-width: none;
	margin: 0;
	padding: 0 0 0 16px;
	border: 0;
	border-radius: 0;
	background: none;
	box-shadow: none;
	opacity: 1;
	transform: none;
	height: 0;
	overflow: hidden;
	visibility: hidden;
}
.vef-site-header.is-folded .vef-nav__list .menu-item-has-children > .sub-menu::before { display: none; }
.vef-site-header.is-folded .vef-nav__list .menu-item-has-children.is-open > .sub-menu {
	height: auto;
	overflow: visible;
	visibility: visible;
}
.vef-site-header.is-folded .vef-nav__list .sub-menu a {
	padding-block: 12px;
	border-radius: 0;
	font-size: 16px;
	font-weight: 500;
}
.vef-site-header.is-folded .vef-nav__list .sub-menu a:hover { background: none; }
.vef-site-header.is-folded .vef-nav__list .current-menu-item > a::after,
.vef-site-header.is-folded .vef-nav__list .current_page_item > a::after { display: none; }
/* Someone who has asked for less motion gets the menu without the slide. */
@media (prefers-reduced-motion: reduce) {
	.vef-site-header.is-folded .vef-nav,
	.vef-site-header.is-folded .vef-nav__list .menu-item-has-children,
	.vef-site-header.is-folded .vef-nav__list .menu-item-has-children > .sub-menu,
	.vef-site-header.is-folded .vef-nav__sub .vef-icon { transition-duration: 0s; }
	/* The delay too, or the bar stays focusable for a quarter second after
	   it has already gone. */
	.vef-callbar,
	.vef-site-header.is-open ~ .vef-callbar { transition-duration: 0s; transition-delay: 0s; }
}
.vef-header { position: relative; }

@media (max-width: 640px) {
	:root { --vef-header-h: 72px; }
	/* Phones: the menu opens as a full-width panel under the header. */
	.vef-site-header.is-folded .vef-nav {
		left: 0; right: 0; top: 100%; width: auto;
		padding-inline: var(--vef-gutter); border: 0; border-radius: 0;
		background: var(--vef-canvas); border-bottom: 1px solid var(--vef-line);
		box-shadow: 0 12px 24px -16px rgba(0, 0, 0, calc(.25 * var(--vef-shade)));
	}
	.vef-site-header.is-folded.is-open .vef-nav { padding-block: 8px 16px; }
	.vef-site-header.is-folded .vef-nav__list a { padding-block: 14px; border-color: var(--vef-line); color: var(--vef-ink); font-size: 16px; }
	/* The phone panel is the canvas, and its links are ink; so is the chevron. */
	.vef-site-header.is-folded .vef-nav__sub { border-bottom-color: var(--vef-line); color: var(--vef-ink); }
	.vef-header__actions { gap: 8px; }
	.vef-button { padding: 12px 16px; font-size: 15px; }
	.vef-brand__logo { max-height: 48px; }
	.vef-brand__name { font-size: 18px; }
}
/* Call bar ---------------------------------------------------------------

   Two buttons fixed to the bottom of a phone screen (Global → Contact). A
   visitor halfway down a page on a phone is a long way from the header's
   button and the number in the top bar went off the screen a long time ago;
   this puts both back under their thumb.

   The two colours are the site's own: primary for Call, the colour Global
   calls "the dark bands" and gives the top bar, the footer, the hero and
   every page banner — a bar fixed to the screen is furniture of that kind —
   and accent for the second button, the same as the header's.

   Phone only: on anything wider the header is still there and a bar would be
   covering content to say what the header already says. It leaves while the
   folded menu is open, because the menu scrolls and its last item would
   otherwise end up underneath this — sliding out the way the menu itself
   slides in, since a fixed bar that blinks out reads as a glitch rather than
   as something moving aside. */
.vef-callbar { display: none; }
@media (max-width: 640px) {
	.vef-callbar {
		position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
		display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
		/* The home indicator on a phone without a physical button sits over
		   the last few pixels; without this the labels are under it. */
		padding-bottom: env(safe-area-inset-bottom, 0px);
		background: var(--vef-primary);
		box-shadow: 0 -8px 24px -18px rgba(0, 0, 0, calc(.6 * var(--vef-shade)));
		/* Visibility goes the moment it is back, and only once it has
		   finished leaving, so the buttons are never a tab stop off the
		   bottom of the screen. */
		transition: transform .24s ease, visibility 0s;
	}
	.vef-callbar__button {
		display: flex; align-items: center; justify-content: center; gap: 8px;
		min-height: 56px; padding: 12px 16px;
		font-size: 16px; font-weight: 600; line-height: 1.2; text-align: center;
		text-decoration: none;
	}
	.vef-callbar__button--call { background: var(--vef-primary); color: var(--vef-on-primary-strong); }
	.vef-callbar__button--call .vef-icon { color: var(--vef-accent); }
	/* The label is computed, not chosen: --vef-ink reads 3.2:1 on CORE's red
	   and 8.2:1 on Montagna's gold, so hand-picking it passes on one palette
	   and fails on the next. */
	.vef-callbar__button--message { background: var(--vef-accent); color: var(--vef-on-accent, #fff); }
	/* Each button names its own hover colours. "inherit" took them from the
	   bar, which has no colour of its own, so Call fell back to the ink the
	   page sets on body and went dark-on-dark the moment a thumb rested on
	   it — the same trap the nav chevron fell into. */
	.vef-callbar__button--call:hover,
	.vef-callbar__button--call:focus-visible { background: color-mix(in srgb, var(--vef-primary) 84%, #fff); color: var(--vef-on-primary-strong); }
	.vef-callbar__button--message:hover,
	.vef-callbar__button--message:focus-visible { background: var(--vef-accent-dark); color: var(--vef-on-accent, #fff); }
	.vef-has-callbar { padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px)); }
	.vef-site-header.is-open ~ .vef-callbar {
		visibility: hidden; transform: translateY(100%);
		transition: transform .24s ease, visibility 0s linear .24s;
	}
}

/* The Text us bubble (Global → Contact; vef_core_text_bubble()): fixed to
   the bottom right, a pill with its label on larger screens and a round
   button on a phone, where it sits just above the call bar. On a computer
   it opens a small card with the number (core.js). */
.vef-text-bubble { position: fixed; right: 24px; bottom: 24px; z-index: 55; transition: opacity .2s ease, visibility 0s; }
.vef-text-bubble__button {
	display: flex; align-items: center; gap: 10px; height: 56px; padding: 0 22px 0 18px;
	border-radius: var(--vef-radius-pill); background: var(--vef-accent); color: var(--vef-on-accent, #fff);
	font-weight: 600; text-decoration: none;
	box-shadow: 0 10px 28px -10px rgba(0, 0, 0, calc(.45 * var(--vef-shade))), 0 0 0 1px rgba(255, 255, 255, .12);
	transition: transform .15s ease, background-color .15s ease;
}
.vef-text-bubble__button { --vef-bubble-dots: var(--vef-accent); } /* the dots are cut from the button's own colour */
.vef-text-bubble__button .vef-icon { width: 26px; height: 26px; color: var(--vef-on-accent, #fff); }
.vef-text-bubble__button:hover,
.vef-text-bubble__button:focus-visible { background: var(--vef-accent-dark); color: var(--vef-on-accent, #fff); }
.vef-text-bubble__button:hover { --vef-bubble-dots: var(--vef-accent-dark); }
.vef-text-bubble__card {
	position: absolute; right: 0; bottom: calc(100% + 12px); width: min(300px, calc(100vw - 32px));
	padding: 22px 22px 20px; border-radius: var(--vef-radius-lg); background: var(--vef-canvas); color: var(--vef-text);
	box-shadow: 0 18px 40px -16px rgba(0, 0, 0, calc(.35 * var(--vef-shade))), 0 0 0 1px var(--vef-line);
}
.vef-text-bubble__card p { margin: 0; }
.vef-text-bubble__title { color: var(--vef-ink); font-size: 14px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; }
.vef-text-bubble__number { margin-top: 6px !important; color: var(--vef-ink); font-family: var(--vef-font-display); font-size: 26px; font-weight: 600; font-variant-numeric: tabular-nums; }
.vef-text-bubble__number a { color: inherit; text-decoration: none; text-decoration-thickness: 1px; text-underline-offset: 4px; }
.vef-text-bubble__number a:is(:hover, :focus-visible) { color: var(--vef-accent); text-decoration: underline; }
.vef-text-bubble__note { margin-top: 8px !important; font-size: 15px; line-height: 1.5; }
.vef-text-bubble__open { display: flex; justify-content: center; width: 100%; margin-top: 16px; }
.vef-text-bubble__close {
	position: absolute; top: 10px; right: 10px; display: flex; align-items: center; justify-content: center;
	width: 32px; height: 32px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--vef-text); cursor: pointer;
}
.vef-text-bubble__close:hover { background: var(--vef-mute); }
.vef-text-bubble__close .vef-icon { width: 18px; height: 18px; }
.vef-site-header.is-open ~ .vef-text-bubble { visibility: hidden; opacity: 0; transition: opacity .2s ease, visibility 0s linear .2s; }
@media (max-width: 640px) {
	.vef-text-bubble { right: 16px; bottom: calc(16px + env(safe-area-inset-bottom, 0px)); }
	.vef-has-callbar .vef-text-bubble { bottom: calc(56px + 14px + env(safe-area-inset-bottom, 0px)); }
	.vef-text-bubble__button { justify-content: center; width: 56px; padding: 0; border-radius: 50%; }
	.vef-text-bubble__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}
@media print { .vef-text-bubble { display: none; } }
/* Motion: every six seconds the button hops twice and a glow rings out
   from it, so it is noticed without nagging; it rests while hovered or
   while its card is open. The card springs up from the button (a small
   overshoot) and drops back down when closed (core.js waits for that
   before hiding it). None of it for visitors who ask for less motion. */
@media (prefers-reduced-motion: no-preference) {
	.vef-text-bubble__button { position: relative; animation: vef-bubble-hop 6s ease-in-out 2s infinite; }
	.vef-text-bubble__button::after {
		content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
		animation: vef-bubble-glow 6s ease-out 2s infinite;
	}
	.vef-text-bubble__button:hover,
	.vef-text-bubble.is-open .vef-text-bubble__button,
	.vef-text-bubble__button:hover::after,
	.vef-text-bubble.is-open .vef-text-bubble__button::after { animation: none; }
	.vef-text-bubble__card { transform-origin: 85% 100%; animation: vef-card-up .42s cubic-bezier(.3, 1.4, .5, 1) both; }
	.vef-text-bubble__card.is-closing { animation: vef-card-down .2s ease-in both; }
}
@keyframes vef-bubble-hop {
	0%, 80%, 100% { transform: translateY(0); }
	84% { transform: translateY(-10px); }
	88% { transform: translateY(0); }
	92% { transform: translateY(-5px); }
	95% { transform: translateY(0); }
}
@keyframes vef-bubble-glow {
	0%, 80% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--vef-primary) 70%, transparent); }
	100% { box-shadow: 0 0 0 18px color-mix(in srgb, var(--vef-primary) 0%, transparent); }
}
@keyframes vef-card-up {
	from { opacity: 0; transform: translateY(24px) scale(.94); }
	to { opacity: 1; transform: none; }
}
@keyframes vef-card-down {
	to { opacity: 0; transform: translateY(18px) scale(.96); }
}

/* Logged-in visitors: the sticky header clears WordPress's admin bar (32px;
   46px at 782px and below). Under 600px WordPress lets the admin bar scroll
   away; pin it so no gap opens above the header. */
@media (max-width: 782px) { .admin-bar .vef-site-header { top: 46px; } }
@media (max-width: 600px) { .admin-bar #wpadminbar { position: fixed; } }

/* Home hero ------------------------------------------------------------- */

/* Full height under the header; core.js measures the header into --vef-chrome. */
.vef-hero {
	position: relative; overflow: hidden;
	display: flex; flex-direction: column;
	min-height: calc(100svh - var(--vef-chrome, 126px));
	background: var(--vef-primary); color: var(--vef-on-primary);
}
.vef-lines {
	position: absolute; right: 0; bottom: 0;
	height: auto;
	stroke: var(--vef-line-primary); stroke-width: 1.5;
	pointer-events: none;
	will-change: transform;
}

/* Photo background under the overlay, in the primary color (hero and banners). */
.vef-bgphoto { position: absolute; inset: 0; }
.vef-bgphoto img { width: 100%; height: 100%; object-fit: cover; }
/* Parallax: a layer taller than the band, moved by core.js at a fraction of
   the scroll. The band clips it. */
.vef-bgphoto--parallax { overflow: hidden; }
.vef-bgphoto__drift { position: absolute; inset: -40% 0 -6% 0; will-change: transform; }
.vef-bgphoto__overlay { position: absolute; inset: 0; background: var(--vef-primary); opacity: var(--vef-overlay, .75); }
.vef-bgphoto__overlay--gradient { background: linear-gradient(90deg, var(--vef-primary) 0%, var(--vef-primary) 30%, transparent 85%); opacity: 1; }
.vef-bgphoto__overlay--gradient::before { content: ""; position: absolute; inset: 0; background: var(--vef-primary); opacity: calc(var(--vef-overlay, .75) - .35); }

.vef-hero__in {
	position: relative; flex: 1;
	display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 48px 72px;
	/* align-items centres the two columns against each other; align-content
	   centres the row itself in whatever height the hero has spare. Both are
	   needed: with align-content left to stretch, a site that top-aligns its
	   columns gets every spare pixel dumped below them. */
	align-items: center; align-content: center;
	padding-block: var(--vef-hero-pad);
}
.vef-hero__title {
	margin: 0;
	color: var(--vef-on-primary-strong); font-size: clamp(36px, 4.6vw, 60px); line-height: 1.12; letter-spacing: -.02em;
}
/* inline, not block: the highlight continues the heading line rather than starting its own. */
.vef-hero__title span { color: var(--vef-accent); }
.vef-hero__actions { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 40px; }
/* With the rating on this row it sits beside the buttons rather than above
   them (Home hero → Content). Centred against them, and it wraps under on a
   narrow screen like any other item here. */
.vef-hero__actions { align-items: center; }
.vef-hero__text {
	margin: 0; padding-left: 28px;
	border-left: 4px solid var(--vef-accent);
	font-size: 20px; line-height: 1.6;
}
.vef-hero__lede { margin: 24px 0 0; max-width: 560px; font-size: 19px; line-height: 1.6; }

/* The Google rating as a small box, white on the hero. */
.vef-rating.vef-rating--box {
	display: inline-flex; margin: 28px 0 0; padding: 10px 18px;
	border: 1px solid var(--vef-line-primary); border-radius: var(--vef-radius-pill);
	background: var(--vef-wash-primary); color: var(--vef-on-primary); text-decoration: none;
}
.vef-rating.vef-rating--box strong { color: var(--vef-on-primary-strong); }
.vef-hero .vef-rating--box { align-self: flex-start; }
/* ...except on the button row, where it is one item among several rather
   than a block under the heading: no top margin of its own, and centred
   against the buttons instead of pinned to the top of the row. Both of the
   rules above are what it has to beat, hence the extra class. */
.vef-hero__actions .vef-rating.vef-rating--box { margin: 0; align-self: center; }
a.vef-rating--box:hover { border-color: color-mix(in srgb, var(--vef-on-primary-strong) 40%, transparent); color: var(--vef-on-primary-strong); }
.vef-rating--box + .vef-hero__lede { margin-top: 20px; }
.vef-banner .vef-rating--box { margin-top: 20px; }
/* Phones: the rating box stays on one line. */
@media (max-width: 640px) {
	.vef-rating.vef-rating--box { gap: 6px 8px; padding: 8px 14px; font-size: 13px; }
	.vef-rating--box .vef-stars svg { width: 14px; height: 14px; }
	.vef-rating--box .vef-rating__g { width: 17px; height: 17px; }
	.vef-rating.vef-rating--box strong { font-size: 15px; }
}
/* On a light ground (Contact). */
.vef-rating.vef-rating--box.vef-rating--light { margin: 20px 0 8px; border-color: var(--vef-line); background: var(--vef-canvas); color: var(--vef-text); box-shadow: 0 1px 2px rgba(0, 0, 0, calc(.06 * var(--vef-shade))); }
.vef-rating.vef-rating--box.vef-rating--light strong { color: var(--vef-ink); }
a.vef-rating--box.vef-rating--light:hover { border-color: var(--vef-accent); color: var(--vef-ink); }

/* Media on the right. */
.vef-hero__media img { display: block; width: 100%; height: auto; border-radius: var(--vef-radius-md); }
.vef-hero--cutout .vef-hero__in { padding-bottom: 0; align-items: end; }
/* Image width → Balanced: half and half, like the about band's photo. */
.vef-hero--balanced .vef-hero__in { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: clamp(40px, 6vw, 88px); }
.vef-hero--cutout .vef-hero__main { align-self: center; padding-bottom: clamp(48px, 6vw, 96px); }
.vef-hero--cutout .vef-hero__media img { width: auto; max-width: 100%; max-height: min(68svh, 700px); margin-inline: auto; border-radius: 0; }
.vef-hero--cutout.vef-hero--features .vef-hero__media img { max-height: min(58svh, 620px); }

/* The video card: the cover with CORE's play button, and a bar naming the
   video and linking to where it lives. One style for every video on the
   site, the way photos have one. */
.vef-video-card { position: relative; border-radius: var(--vef-radius-md); box-shadow: 0 30px 60px -30px rgba(0, 0, 0, calc(.6 * var(--vef-shade))); }
.vef-video-card > * { position: relative; z-index: 1; }
/* The panel behind it: a corner showing past the bottom-right, not a slab the
   width of the card. Decoration only, so it is gone on phones where there is
   no room to offset anything. Every framed image at the top of a page wears
   the same panel (.vef-backed: the hero's framed image, a location banner's
   photo), so photos and videos up there read as one family. */
/* Its own stacking context with the panel at -1, so nothing inside has to be
   repositioned: a figure's caption box keeps the absolute position it has. */
.vef-backed { position: relative; isolation: isolate; }
.vef-video-card::before,
.vef-backed::before {
	content: ""; position: absolute; z-index: 0;
	right: -24px; bottom: -24px; width: 60%; height: 85%;
	border-radius: var(--vef-radius-lg); background: var(--vef-accent); opacity: .18;
}
.vef-backed::before { z-index: -1; }
.vef-video-card--bare { box-shadow: none; }
.vef-video-card--bare::before { content: none; }
.vef-video { position: relative; aspect-ratio: 16 / 9; overflow: hidden; border-radius: var(--vef-radius-md); background: #000; box-shadow: 0 30px 60px -30px rgba(0, 0, 0, calc(.6 * var(--vef-shade))); }
.vef-video-card .vef-video { border-radius: var(--vef-radius-md) var(--vef-radius-md) 0 0; box-shadow: none; }
.vef-video-card--bare .vef-video { border-radius: var(--vef-radius-md); }

.vef-video__bar {
	display: flex; align-items: center; gap: 14px; padding: 13px 16px;
	border-radius: 0 0 var(--vef-radius-md) var(--vef-radius-md);
	background: color-mix(in srgb, var(--vef-primary) 88%, #fff);
	color: var(--vef-on-primary-strong); text-decoration: none;
	transition: background .2s ease;
}
.vef-video__bar:hover, .vef-video__bar:focus-visible { background: color-mix(in srgb, var(--vef-primary) 78%, #fff); color: var(--vef-on-primary-strong); }
.vef-video__channel {
	display: grid; place-items: center; flex: none; width: 34px; height: 34px;
	border-radius: 50%; background: var(--vef-wash-primary-strong);
}
.vef-video__channel .vef-icon { width: 20px; height: 20px; color: var(--vef-on-primary-strong); }
.vef-video__meta { display: grid; gap: 2px; min-width: 0; }
.vef-video__title { color: var(--vef-on-primary-strong); font-weight: 700; font-size: 16px; line-height: 1.3; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.vef-video__watch { color: var(--vef-on-primary); font-size: 13.5px; line-height: 1.3; }
.vef-video__out { flex: none; margin-left: auto; color: var(--vef-on-primary); }
.vef-video__out .vef-icon { width: 18px; height: 18px; }
.vef-video__bar:hover .vef-video__out { color: var(--vef-on-primary-strong); }
/* A video pasted into the editor gets the same box (vef_core_video_oembed).
   The embed block keeps its own figure and caption around it, and its
   aspect-ratio spacer has nothing left to space — the box sizes itself — so
   it would only leave a gap above. */
.wp-block-embed:has(.vef-video) .wp-block-embed__wrapper::before { content: none; padding-top: 0; }
.wp-block-embed:has(.vef-video) .wp-block-embed__wrapper { padding-top: 0; }
/* A video uploaded to the Media Library plays in the browser's own player,
   which we leave alone — but it is framed like the rest. */
.wp-block-video video { display: block; width: 100%; border-radius: var(--vef-radius-md); background: #000; box-shadow: 0 30px 60px -30px rgba(0, 0, 0, calc(.6 * var(--vef-shade))); }
.vef-video img { width: 100%; height: 100%; object-fit: cover; border-radius: 0; opacity: .85; }
.vef-video iframe, .vef-video video { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.vef-play { display: inline-flex; align-items: center; gap: 18px; padding: 0; border: 0; background: none; color: var(--vef-on-primary-strong); font: 600 18px/1.3 var(--vef-font); cursor: pointer; }
.vef-video .vef-play { position: absolute; inset: 0; justify-content: center; width: 100%; }
.vef-play__icon {
	position: relative; display: flex; align-items: center; justify-content: center; flex: none;
	width: 84px; height: 84px; border-radius: 50%; background: var(--vef-play, var(--vef-accent)); color: var(--vef-on-accent, #fff);
	transition: transform .15s ease, background-color .15s ease;
}
.vef-play__icon .vef-icon { width: 46%; height: 46%; }
.vef-play__icon::after { content: ""; position: absolute; inset: -10px; border: 2px solid var(--vef-play, var(--vef-accent)); border-radius: 50%; opacity: .5; animation: vef-pulse 2s ease-out infinite; }
.vef-play:hover .vef-play__icon, .vef-play:focus-visible .vef-play__icon { transform: scale(1.06); background: var(--vef-play-hover, var(--vef-accent-dark)); }
@keyframes vef-pulse { from { transform: scale(.9); opacity: .6; } to { transform: scale(1.35); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .vef-play__icon::after { animation: none; } }
.vef-hero--media-play .vef-hero__media { display: flex; justify-content: center; }
.vef-hero--media-play .vef-play__icon { width: 112px; height: 112px; }

.vef-hero__form {
	padding: clamp(24px, 3vw, 40px); border-radius: var(--vef-radius-lg);
	background: var(--vef-canvas); color: var(--vef-text);
	box-shadow: 0 30px 60px -30px rgba(0, 0, 0, calc(.6 * var(--vef-shade)));
}
.vef-hero__form h2 { color: var(--vef-accent); font-size: clamp(22px, 2.4vw, 28px); }

.vef-video-modal { width: min(1100px, calc(100vw - 32px)); max-width: none; padding: 0; border: 0; border-radius: var(--vef-radius-md); background: #000; overflow: visible; }
.vef-video-modal::backdrop { background: rgba(0, 0, 0, .85); }
.vef-video-modal__frame { position: relative; aspect-ratio: 16 / 9; }
.vef-video-modal__frame iframe, .vef-video-modal__frame video { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; border-radius: var(--vef-radius-md); }
.vef-video-modal__close {
	position: absolute; right: 0; top: -56px; display: flex; align-items: center; justify-content: center;
	width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%; background: rgba(255, 255, 255, .15); color: #fff; cursor: pointer;
}

/* Feature boxes along the bottom, each a step darker than the last. */
/* The hero is a full-height column (.vef-header-over), so when its content
   is shorter than the viewport the slack falls to the bottom — under the
   band, which is meant to sit on the hero's bottom edge. This pushes the band
   and anything after it down onto that edge; with no slack it does nothing. */
.vef-hero--features .vef-features { margin-top: auto; }
.vef-features { position: relative; display: grid; grid-template-columns: repeat(var(--vef-n, 3), minmax(0, 1fr)); margin: 0; padding: 0; list-style: none; }
/* The small print a regulated figure needs: its own thin band on the mute
   colour, directly after the figures. Quiet, but not so quiet it stops being
   legible — it is the qualifier on a claim, not decoration. */
/* An asterisk that explains itself. The marker is a button because a bare
   asterisk with a hover cannot be reached without a mouse; the bubble is in
   the markup rather than built on demand, so it is there for a screen reader
   and a crawler whether or not anyone opens it.

   The bubble is FIXED, and core.js places it. Absolute would be simpler and
   is wrong here: the hero clips its overflow, and the figures sit on its
   bottom edge, so a bubble above them was cut off and stacked under the
   media beside it. Fixed also means one rule handles a marker near the right
   edge of a wide screen and one in a column on a phone. */
.vef-tip { display: inline-block; }
.vef-tip__btn {
	padding: 0 0 0 1px; border: 0; background: none; color: inherit;
	font: inherit; line-height: 1; cursor: help;
}
.vef-tip__btn:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; border-radius: var(--vef-radius-xs); }
.vef-tip__bubble {
	position: fixed; top: 0; left: 0; z-index: 120;
	width: max-content; max-width: min(340px, calc(100vw - 24px)); padding: 11px 14px;
	border-radius: var(--vef-radius-sm); background: var(--vef-ink); color: #fff;
	font-family: var(--vef-font); font-size: 13px; font-weight: 400; line-height: 1.5;
	letter-spacing: 0; text-align: left; text-transform: none;
	box-shadow: 0 16px 36px -14px rgba(0, 0, 0, calc(.8 * var(--vef-shade)));
	opacity: 0; visibility: hidden; transition: opacity .15s ease, visibility .15s;
}
/* Three rules, not one group: a selector a browser does not understand
   invalidates the whole rule it sits in, and taking hover and tap down with
   it would leave the note unreadable rather than merely unpolished. */
.vef-tip:hover .vef-tip__bubble { opacity: 1; visibility: visible; }
.vef-tip__btn[aria-expanded="true"] + .vef-tip__bubble { opacity: 1; visibility: visible; }
.vef-tip__btn:focus-visible + .vef-tip__bubble { opacity: 1; visibility: visible; }

/* A card on the page's own ground, between the figures and whatever follows.
   It was a full-bleed strip on the mute colour, which read as a divider
   between two sections rather than as something to read. Bordered and inset,
   it reads as a notice. */
/* All the air goes ABOVE it, and the section below is pulled in to match —
   padding on both ends of the band would have put it nearer the figures by
   exactly the next section's padding (36px above, 148px below at 1440).
   Both ends are --vef-note-gap, so the card is centred by construction and
   stays that way if the number changes. Only the section DIRECTLY after the
   note is tightened; every other one keeps a section's full breathing room. */
.vef-note-band { padding-top: var(--vef-note-gap); padding-bottom: 0; }
.vef-note-band + .vef-home { padding-top: var(--vef-note-gap); }
/* Above a listing the note is not between two things, it is the first line
   of the one below it — the filter and the results it qualifies. So it sits
   closer to them than to whatever it followed: half the gap, not the whole
   one. (This also catches a listing at all: the rule above names .vef-home,
   and an archive is .vef-listing, so it kept its own 80px and the note read
   as marooned between the breadcrumbs and the pills.) */
.vef-note-band + .vef-listing { padding-top: calc(var(--vef-note-gap) / 2); }
.vef-figures-note {
	display: flex; align-items: center; gap: 14px; margin: 0; padding: 16px 24px;
	border: 1px solid color-mix(in srgb, var(--vef-mute) 80%, var(--vef-primary));
	border-radius: var(--vef-radius-md); background: var(--vef-mute);
	color: var(--vef-ink); font-size: 15px; font-weight: 600; line-height: 1.5;
}
.vef-figures-note .vef-icon { flex: none; width: 20px; height: 20px; opacity: .72; }
.vef-figures-note a { color: inherit; text-decoration: underline; }
@media (max-width: 640px) {
	/* The mark keeps its place at the top of a note that now runs to three
	   lines, rather than floating in the middle of them. */
	.vef-figures-note { align-items: flex-start; gap: 12px; padding: 14px 16px; font-size: 14px; }
	.vef-figures-note .vef-icon { margin-top: 2px; }
}
.vef-features--1 { --vef-n: 1; }
.vef-features--2 { --vef-n: 2; }
.vef-features--4 { --vef-n: 4; }
.vef-feature { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: clamp(28px, 3vw, 44px) 20px; background: var(--vef-primary); text-align: center; }
/* The cells separate by lightening rather than darkening. Mixing toward #000
   from a primary that is already near-black has nowhere to go: on CORE's
   #111 the old ramp left cells two, three and four inside five levels of
   each other out of 255, which is no separation at all -- the last two read
   as one cell. Toward #fff every usable primary has room, because the field
   asks for a dark one, and the steps stay even whatever the brand sets.

   Four percent a step, darkest last, and the last cell is the primary itself
   so the band lifts toward its first figure. Anything past the fourth takes
   the primary from the rule above, so a fifth cell is flat rather than
   inventing a step the eye cannot read. */
.vef-feature:nth-child(1) { background: color-mix(in srgb, var(--vef-primary) 88%, #fff); }
.vef-feature:nth-child(2) { background: color-mix(in srgb, var(--vef-primary) 92%, #fff); }
.vef-feature:nth-child(3) { background: color-mix(in srgb, var(--vef-primary) 96%, #fff); }
/* These two are headings in everything but the tag — a <strong> and a <dd> —
   so the display face has to be asked for. CORE's only reaches h1–h6, which
   means any heading-shaped element outside those tags quietly renders in the
   body face: the hero and banner titles had the same hole when either line
   could carry the H1. If you give something heading sizing, give it the
   heading family in the same rule. */
.vef-feature__title { display: flex; align-items: center; gap: 14px; color: var(--vef-on-primary-strong); font-family: var(--vef-font-display); font-size: clamp(19px, 1.9vw, 26px); font-weight: 600; line-height: 1.1; letter-spacing: .01em; text-transform: uppercase; }
.vef-feature__title::before, .vef-feature__title::after { content: ""; flex: none; width: 18px; height: 4px; background: var(--vef-accent); }
.vef-feature__text { font-size: 16px; }
/* A figure's link: underlined so it reads as one on a dark panel where an
   accent colour alone does not, with the arrow stepping out on hover. */
.vef-feature__link {
	display: inline-flex; align-items: center; gap: 8px; margin-top: 14px;
	color: var(--vef-accent); font-size: 15px; font-weight: 600;
	text-decoration: underline; text-underline-offset: 4px;
}
.vef-feature__link .vef-icon { width: 16px; height: 16px; transition: transform .15s ease; }
.vef-feature__link:hover { color: var(--vef-on-primary-strong); }
.vef-feature__link:hover .vef-icon { transform: translateX(3px); }
@media (prefers-reduced-motion: reduce) { .vef-feature__link .vef-icon { transition: none; } }

@media (max-width: 900px) {
	.vef-hero { min-height: 0; }
	.vef-hero__in { grid-template-columns: 1fr; }
	.vef-hero__text { font-size: 18px; }
	.vef-hero--cutout .vef-hero__main { padding-bottom: 0; }
	.vef-hero--cutout .vef-hero__media img { max-height: 60svh; }
	.vef-header-over .vef-hero { min-height: 0; }
	/* Phones and tablets: the media follows the heading, before the rest. */
	.vef-hero--media:not(.vef-hero--cutout) .vef-hero__in { display: flex; flex-direction: column; align-items: stretch; gap: 0; }
	.vef-hero--media:not(.vef-hero--cutout) .vef-hero__main { display: contents; }
	.vef-hero--media:not(.vef-hero--cutout) .vef-hero__main > * { order: 3; }
	.vef-hero--media:not(.vef-hero--cutout) .vef-hero__main > .vef-eyebrow,
	.vef-hero--media:not(.vef-hero--cutout) .vef-hero__title { order: 1; }
	.vef-hero--media:not(.vef-hero--cutout) .vef-hero__media { order: 2; margin-top: 32px; }
	.vef-hero--media-play .vef-hero__media { justify-content: flex-start; }
	.vef-hero--media-play .vef-play__icon { width: 84px; height: 84px; }
	.vef-hero--cutout .vef-hero__in { row-gap: 32px; }
}
@media (max-width: 640px) {
	.vef-hero__actions .vef-button { flex: 1 1 100%; }
	/* One box per row. Two-up fitted CORE's own sample wording — "120 Years"
	   over "Combined experience" — and nothing a real client writes. Put a
	   sum, a sentence and a link in half a phone's width and every box turns
	   into four ragged lines. The rule that pushed the third box full-width
	   goes with it: they all are now. */
	.vef-features { grid-template-columns: minmax(0, 1fr); }
	/* Ranged left on a phone, and on the rail's own gutter so the figures
	   line up with every other line of text on the page. Centred suited a
	   narrow column with two short words in it; across the full width it
	   left a title, a sentence and a link each starting somewhere different. */
	.vef-feature { align-items: flex-start; padding: 22px var(--vef-gutter); text-align: left; }
	.vef-feature__title { font-size: 18px; }
	.vef-feature__title::before, .vef-feature__title::after { display: none; }
	.vef-feature__text { font-size: 14px; }
	.vef-play__icon { width: 68px; height: 68px; }
	.vef-video-card::before,
	.vef-backed::before { content: none; }
}

/* The header button never leaves the header. It used to hide wherever the
   call bar showed, and the two widths drifted apart (767 against 640), so a
   tablet had no booking button at all. Now, once the row gets tight, the
   number and the button shrink to 44px icon buttons beside the menu toggle;
   the words stay for screen readers. The icon is Global → Header button
   icon, the same one the call bar's booking button wears. */
.vef-button--cta .vef-icon { display: none; width: 20px; height: 20px; }
@media (max-width: 767px) {
	.vef-phone__number,
	.vef-header .vef-button__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
	.vef-phone { width: 44px; height: 44px; justify-content: center; border: 1px solid var(--vef-line); border-radius: var(--vef-radius); }
	.vef-header .vef-button--cta { width: 44px; height: 44px; padding: 0; justify-content: center; }
	.vef-header .vef-button--cta .vef-icon { display: block; }
	.vef-header__actions { gap: 8px; }
}

/* Header over the hero (homepage option): transparent with white text and
   the dark-background logo, turning white once the page scrolls. */
.vef-site-header .vef-brand__logo--dark { display: none; }
.vef-brand__logo--whitened { filter: brightness(0) invert(1); }
.vef-header-over .vef-site-header { position: fixed; left: 0; right: 0; transition: background-color .2s ease, box-shadow .2s ease; }
.vef-header-over .vef-site-header:not(.is-solid) { background: transparent; }
.vef-header-over .vef-site-header:not(.is-solid) .vef-header { border-bottom-color: transparent; }
.vef-header-over .vef-site-header:not(.is-solid) .vef-brand__logo--light { display: none; }
.vef-header-over .vef-site-header:not(.is-solid) .vef-brand__logo--dark { display: block; }
.vef-header-over .vef-site-header:not(.is-solid) .vef-brand,
.vef-header-over .vef-site-header:not(.is-solid) .vef-phone,
.vef-header-over .vef-site-header:not(.is-solid):not(.is-folded) .vef-nav__list a { color: var(--vef-on-primary-strong); }
.vef-header-over .vef-site-header:not(.is-solid):not(.is-folded) .vef-nav__list a:hover { color: var(--vef-accent); }
.vef-header-over .vef-site-header:not(.is-solid) .vef-nav-toggle,
.vef-header-over .vef-site-header:not(.is-solid) .vef-phone { border-color: color-mix(in srgb, var(--vef-on-primary-strong) 30%, transparent); background: transparent; color: var(--vef-on-primary-strong); }
/* The white above out-ranks .vef-phone:hover, so over a hero the number was
   the one thing in the header that did not answer the pointer. The nav got
   its own hover rule here; the phone never did. */
.vef-header-over .vef-site-header:not(.is-solid) .vef-phone:hover,
.vef-header-over .vef-site-header:not(.is-solid) .vef-phone:focus-visible { color: var(--vef-accent); }
.vef-header-over .vef-site-header.is-solid { box-shadow: 0 1px 0 var(--vef-line), 0 10px 30px -20px rgba(0, 0, 0, calc(.3 * var(--vef-shade))); }
/* The mark, for a bar too narrow to carry the lockup. Both the full logo and
   the mark hold their own light/dark pair, so the rules above go on choosing
   by background inside whichever one is showing, and the width here only has
   to choose between the two. A site with no mark in Global → Brand renders
   no wrappers and none of this applies.

   640px is the phone, which is where a wide lockup actually runs out of room
   beside a call to action. A project theme whose logo is wider moves the
   breakpoint rather than hiding the button, and moving it is additive — a
   copy of the two rules below at a WIDER max-width, nothing to undo, because
   this block still says the same thing under it. A media query cannot read a
   custom property, which is why this is not --vef-fold's trick. */
.vef-brand__full,
.vef-brand__mark { display: flex; align-items: center; }
.vef-brand--has-mark .vef-brand__mark { display: none; }
@media (max-width: 640px) {
	.vef-brand--has-mark .vef-brand__full { display: none; }
	.vef-brand--has-mark .vef-brand__mark { display: flex; }
}
/* A transparent header turns every nav link white for the hero behind it —
   including the links inside a dropdown, which sit on a white panel. */
.vef-header-over .vef-site-header:not(.is-solid):not(.is-folded) .vef-nav__list .sub-menu a { color: var(--vef-ink); }
.vef-header-over .vef-site-header:not(.is-solid):not(.is-folded) .vef-nav__list .sub-menu a:hover { color: var(--vef-accent); }
.vef-header-over .vef-site-header:not(.is-solid):not(.is-folded) .vef-nav__list .sub-menu .current-menu-item > a { color: var(--vef-accent); }
.vef-header-over .vef-hero { min-height: 100svh; }
/* Under a transparent header the chrome sits ON the hero, so the top inset
   has to clear it before the hero's own padding starts. It used to add a
   smaller inset than the padding below, which left the content sitting high:
   56px under the header against 120px above the band at 1440. Same pad both
   ends now, measured from under the header rather than from the top of it. */
.vef-header-over .vef-hero__in { padding-top: calc(var(--vef-chrome, 126px) + var(--vef-hero-pad)); }
/* On a phone that inset double-counts: the header already leaves its own
   padding under the logo — 22px here — so the full hero pad on top of
   --vef-chrome put 62px of nothing before the first word against 40px at the
   bottom. Half the pad reads level at 42 against 40. It has to live after
   the rule above rather than up in the mobile block, because a media query
   adds no specificity and the later rule would win. */
@media (max-width: 900px) {
	.vef-header-over .vef-hero__in { padding-top: calc(var(--vef-chrome, 126px) + var(--vef-hero-pad) / 2); }
}

/* Contact page ---------------------------------------------------------- */

/* clip-path, not overflow: hidden, to hold the background shape in. The shape
   is inset -12% top and bottom (shapes.css) so its motion never reveals an
   edge, so this section has to clip — but overflow: hidden makes the section
   the scroll container for everything inside it, and position: sticky then
   measures against the section instead of the viewport. The sticky pair below
   was the casualty: the info column sat parked 152px down its own column and
   never stuck to anything. clip-path clips the same and creates no scroll
   container. */
.vef-contact { position: relative; clip-path: inset(0); padding-block: clamp(56px, 8vw, 104px); background: var(--vef-primary); color: var(--vef-on-primary); }
.vef-contact__in { position: relative; }
.vef-contact__in { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 48px clamp(40px, 6vw, 88px); align-items: start; }
.vef-contact h1 { font-size: clamp(34px, 4.4vw, 52px); letter-spacing: -.02em; }
.vef-contact__info > h2 { margin-top: 56px; font-size: clamp(26px, 3vw, 34px); }
.vef-contact__lede { font-size: 18px; }
.vef-contact__lede > :last-child { margin-bottom: 0; }

.vef-contact__list { position: relative; margin: 40px 0 0; padding: 0; list-style: none; }
/* The line joins the icons, from one to the next, whatever the row heights. */
.vef-contact__list li:not(:last-child)::before {
	content: ""; position: absolute; left: 27px; top: 56px; bottom: -28px;
	border-left: 1px solid var(--vef-line);
}
.vef-contact__list li { position: relative; display: flex; gap: 20px; align-items: flex-start; }
.vef-contact__list li + li { margin-top: 28px; }
.vef-contact__list strong { display: block; color: var(--vef-ink); font-weight: 600; }
.vef-contact__list a { color: var(--vef-text); text-decoration: none; }
.vef-contact__list a:hover { color: var(--vef-accent); }
.vef-contact__list address { font-style: normal; }
.vef-contact__list li > span:last-child { flex: 1; min-width: 0; }

/* Address row with several locations: main office, or pills that swap it. */
.vef-contact__pills { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 14px; }
.vef-contact__pill {
	padding: 7px 14px; border: 1px solid var(--vef-line); border-radius: var(--vef-radius-pill);
	background: var(--vef-canvas); color: var(--vef-ink); font: 600 14px/1.2 var(--vef-font); cursor: pointer;
	transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.vef-contact__pill:hover { border-color: var(--vef-accent); color: var(--vef-accent); }
.vef-contact__pill.is-active { border-color: var(--vef-accent); background: var(--vef-accent); color: var(--vef-on-accent, #fff); }
.vef-contact__pill:focus-visible { outline: 2px solid var(--vef-accent); outline-offset: 2px; }
.vef-contact__place-menu {
	margin: 10px 0 14px; padding: 9px 36px 9px 14px; border: 1px solid var(--vef-line); border-radius: var(--vef-radius-sm);
	background: var(--vef-canvas); color: var(--vef-ink); font: 600 15px/1.2 var(--vef-font);
}
.vef-contact__place-name { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; color: var(--vef-ink); }
.vef-contact__tag {
	padding: 3px 9px; border-radius: var(--vef-radius-pill); background: color-mix(in srgb, var(--vef-accent) 12%, transparent);
	color: var(--vef-accent-dark); font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
}
.vef-contact__place-links { display: flex; flex-wrap: wrap; gap: 6px 20px; margin-top: 8px; font-size: 15px; }
.vef-contact__list .vef-contact__place-links a { color: var(--vef-accent); font-weight: 600; }
.vef-contact__list .vef-contact__place-links a:hover { color: var(--vef-accent-dark); }
.vef-contact__list a.vef-contact__more { display: inline-flex; gap: 6px; margin-top: 12px; color: var(--vef-ink); font-size: 15px; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.vef-contact__icon {
	display: flex; align-items: center; justify-content: center; flex: none;
	width: 56px; height: 56px; border-radius: var(--vef-radius-md);
	background: var(--vef-canvas); color: var(--vef-accent);
	box-shadow: 0 1px 2px rgba(0, 0, 0, calc(.06 * var(--vef-shade)));
}

.vef-contact__hours {
	padding: 12px 28px; border-radius: var(--vef-radius-md); background: var(--vef-canvas);
	box-shadow: 0 1px 2px rgba(0, 0, 0, calc(.06 * var(--vef-shade)));
}
.vef-contact__hours div { border-color: var(--vef-line); padding-block: 14px; }
.vef-contact__hours div:first-child { padding-top: 14px; }
.vef-contact__hours div:last-child { border-bottom: 0; }
.vef-contact__hours dt { color: var(--vef-ink); }
/* The card is canvas on the primary band: its times take the text color, not
   the band's white, or they vanish into the card. */
.vef-contact__hours dd { color: var(--vef-text); }

.vef-contact__note {
	display: flex; gap: 16px; align-items: flex-start;
	margin-top: 32px; padding: 24px 28px; border-radius: var(--vef-radius-md);
	background: var(--vef-primary); color: var(--vef-on-primary);
}
.vef-contact__note p { margin: 0; }
.vef-contact__note strong { color: var(--vef-on-primary-strong); }
.vef-contact__note a { color: var(--vef-on-primary-strong); }
.vef-contact__note-icon {
	display: flex; align-items: center; justify-content: center; flex: none;
	width: 44px; height: 44px; border-radius: 50%; background: var(--vef-accent); color: var(--vef-on-accent, #fff);
}

/* Contact on the primary color: white type, quiet outlines; the form card stays white. */
.vef-contact .vef-eyebrow { margin-bottom: 16px; }
.vef-contact h1 { margin: 0; color: var(--vef-on-primary-strong); }
.vef-contact .vef-rating.vef-rating--box { margin: 16px 0 0; }
.vef-contact__lede { margin-top: 28px; color: var(--vef-on-primary); }
.vef-contact__info > h2 { color: var(--vef-on-primary-strong); }
.vef-contact .vef-contact__list strong { color: var(--vef-on-primary-strong); }
.vef-contact .vef-contact__list a { color: var(--vef-on-primary-strong); }
.vef-contact .vef-contact__list a:hover { color: var(--vef-on-primary-strong); text-decoration: underline; text-underline-offset: 3px; }
.vef-contact .vef-contact__icon { background: var(--vef-wash-primary); box-shadow: inset 0 0 0 1px var(--vef-line-primary); }
.vef-contact .vef-contact__list li:not(:last-child)::before { border-left-color: var(--vef-line-primary); }
.vef-contact .vef-contact__pill { border-color: var(--vef-line-primary); background: transparent; color: var(--vef-on-primary-strong); }
.vef-contact .vef-contact__pill:hover { border-color: var(--vef-on-primary-strong); color: var(--vef-on-primary-strong); }
.vef-contact .vef-contact__pill.is-active { border-color: var(--vef-accent); background: var(--vef-accent); }
.vef-contact .vef-contact__place-name { color: var(--vef-on-primary-strong); }
/* The tag is a label, not a control. In the accent it read as a fourth pill
   sitting under the three real ones — the same fill, the same pill shape, so
   it looked clickable. It takes the icon boxes' treatment instead: a wash of
   the surface with a hairline, which sits back where a caption belongs. */
.vef-contact .vef-contact__tag {
	background: var(--vef-wash-primary);
	box-shadow: inset 0 0 0 1px var(--vef-line-primary);
	color: var(--vef-on-primary);
}
.vef-contact .vef-contact__list .vef-contact__place-links a { color: var(--vef-on-primary-strong); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.vef-contact .vef-contact__list a.vef-contact__more { color: var(--vef-on-primary); }
.vef-contact .vef-contact__note { background: var(--vef-wash-primary); box-shadow: inset 0 0 0 1px var(--vef-line-primary); }

.vef-contact__card {
	color: var(--vef-text);
	padding: clamp(28px, 4vw, 48px); border-radius: var(--vef-radius-lg); background: var(--vef-canvas);
	box-shadow: 0 10px 30px -12px rgba(0, 0, 0, calc(.15 * var(--vef-shade)));
}
.vef-contact__card h2 { color: var(--vef-accent); font-size: clamp(26px, 3vw, 32px); }
.vef-contact__card-text { margin: 0 0 24px; }
.vef-contact__card { scroll-margin-top: calc(var(--vef-chrome, 88px) + 16px); }
.vef-contact__card-note { margin: 24px 0 0; color: var(--vef-text); font-size: 15px; text-align: center; }

/* The card on the band (contact_card_style): the icon boxes' wash and
   hairline instead of a white card, the cards' usual padding, white type. For forms that
   bring their own white box, so it reads as one box, not a box in a box. */
.vef-contact__card--band {
	padding: clamp(24px, 3vw, 36px); color: var(--vef-on-primary);
	background: var(--vef-wash-primary); box-shadow: inset 0 0 0 1px var(--vef-line-primary);
}
.vef-contact__card--band > h2 { color: var(--vef-on-primary-strong); }
.vef-contact__card--band > .vef-contact__card-text,
.vef-contact__card--band .vef-tabs__text,
.vef-contact__card--band > .vef-contact__card-note { color: var(--vef-on-primary); }
.vef-contact__card--band .vef-tabs__list { margin-bottom: 24px; background: var(--vef-wash-primary); box-shadow: inset 0 0 0 1px var(--vef-line-primary); }
.vef-contact__card--band .vef-tabs__tab { color: var(--vef-on-primary-strong); }
.vef-contact__card--band .vef-tabs__tab:hover { color: var(--vef-on-primary-strong); background: var(--vef-wash-primary); }
.vef-contact__card--band .vef-tabs__tab.is-active { background: var(--vef-accent); color: var(--vef-on-accent, #fff); }
.vef-contact__card--band .vef-prose a { color: var(--vef-on-primary-strong); }
.vef-contact__card--band iframe { display: block; border-radius: var(--vef-radius-md); }

/* Tabs in a card: a segmented control, the open tab in the accent. */
.vef-tabs__list {
	display: flex; flex-wrap: wrap; gap: 4px; margin: 0 0 28px; padding: 4px;
	border-radius: var(--vef-radius-md); background: var(--vef-mute);
}
.vef-tabs__tab {
	flex: 1 1 0; min-width: max-content; padding: 12px 18px; border: 0;
	border-radius: calc(var(--vef-radius-md) - 2px); background: transparent;
	color: var(--vef-ink); font: 600 15px/1.2 var(--vef-font); cursor: pointer;
	transition: background-color .15s ease, color .15s ease;
}
.vef-tabs__tab:hover { color: var(--vef-accent-text, var(--vef-accent)); }
.vef-tabs__tab.is-active { background: var(--vef-accent); color: var(--vef-on-accent, #fff); }
.vef-tabs__tab:focus-visible { outline: 2px solid var(--vef-accent); outline-offset: 2px; }
.vef-tabs__text { margin: 0 0 20px; }
.vef-tabs__panel[hidden] { display: none; }

/* Gravity Forms (Orbital theme) in the brand colors and font. */
.vef-form .gform-theme--framework {
	--gf-color-primary: var(--vef-accent);
	--gf-color-primary-darker: var(--vef-accent-dark);
	--gf-color-primary-rgb: 200, 16, 46;
	--gf-ctrl-btn-bg-color-primary: var(--vef-accent);
	--gf-ctrl-border-color: #d5d5d5;
	--gf-ctrl-radius: var(--vef-radius);
	--gf-ctrl-btn-radius: var(--vef-radius);
	/* Gravity Forms paints its own shadow on fields and buttons. These are its
	   own values with the alpha put on our dial, so a site set to None flattens
	   its forms along with everything else instead of leaving them the only
	   thing still casting. The button's hover shadow reads from the button one,
	   so it follows; the focus shadow is left alone, being a focus ring. */
	--gf-ctrl-shadow: 0 1px 4px rgba(18, 25, 97, calc(.0779552 * var(--vef-shade)));
	--gf-ctrl-btn-shadow: 0 1px 4px rgba(18, 25, 97, calc(.0779552 * var(--vef-shade)));
	--gf-font-family-base: var(--vef-font);
	--gf-font-family-primary: var(--vef-font);
	--gf-font-family-secondary: var(--vef-font);
	--gf-ctrl-font-family: var(--vef-font);
	--gf-ctrl-label-font-family-primary: var(--vef-font);
	--gf-ctrl-btn-font-family: var(--vef-font);
	--gf-ctrl-size: 52px;
	--gf-ctrl-font-size: 16px;
	--gf-ctrl-label-font-size-primary: 15px;
	--gf-ctrl-label-font-weight-primary: 600;
	--gf-ctrl-btn-font-size: 16px;
	--gf-ctrl-btn-font-weight: 600;
	--gf-ctrl-btn-size: 52px;
}
.vef-form .gform_wrapper .gform_footer button.gform_button { flex: 1 1 100%; inline-size: 100%; }

/* A form set to hidden labels. Gravity Forms' Orbital theme does not act on
   the setting — it leaves every label showing — so a form that puts its field
   names in the placeholders reads each one twice. Clipped rather than
   display:none: the label is still there for a screen reader, which is the
   whole reason a placeholder is not a label. */
.vef-form .gform_wrapper .hidden_label .gfield_label,
.vef-form .gform_wrapper .gform_fields.hidden_label .gfield_label {
	position: absolute;
	inline-size: 1px;
	block-size: 1px;
	margin: -1px;
	padding: 0;
	border: 0;
	overflow: hidden;
	white-space: nowrap;
	clip-path: inset(50%);
}
/* The consent tick is the exception: its label is the only thing naming it,
   and its own wording sits beside the box, so hiding the label leaves the
   paragraph reading as if it belonged to the message field above. */
.vef-form .gform_wrapper .hidden_label .gfield--type-choice .gfield_label {
	position: static;
	inline-size: auto;
	block-size: auto;
	margin: 0 0 8px;
	clip-path: none;
}

@media (max-width: 900px) {
	.vef-contact__in { grid-template-columns: 1fr; }
}
/* Form first (Contact page → On phones): stacked, the heading and intro
   lead, then the form, then the details. The info column opens up so its
   pieces can be reordered around the card; nothing is hidden, only moved. */
@media (max-width: 900px) {
	.vef-contact--form-first .vef-contact__in { display: flex; flex-direction: column; gap: 0; }
	.vef-contact--form-first .vef-contact__info { display: contents; }
	.vef-contact--form-first .vef-contact__card { order: 1; margin-top: 28px; }
	.vef-contact--form-first .vef-contact__info > :is(.vef-contact__list, h2, .vef-contact__hours, .vef-contact__note) { order: 2; }
	.vef-contact--form-first .vef-contact__list { margin-top: 48px; scroll-margin-top: calc(var(--vef-chrome, 88px) + 16px); }
}

/* The booking sheet (inc/booking-sheet.php): the Contact page's form, full
   screen on a phone, sliding up from the foot. Its body scrolls on its own
   and the page under it holds still. */
.vef-sheet {
	position: fixed; inset: 0; width: 100%; max-width: none; height: 100%; max-height: none;
	margin: 0; padding: 0; border: 0; background: var(--vef-canvas); color: var(--vef-text);
}
.vef-sheet[open] { display: flex; flex-direction: column; }
/* Closed, on a phone, it waits just below the screen rather than hidden: a
   browser doesn't draw a frame inside something hidden, so the form would
   only start painting once the sheet opened. Kept out of reach while it
   waits (inert, set by core.js). */
@media (max-width: 767px) {
	.vef-sheet:not([open]) { display: flex; flex-direction: column; transform: translateY(100%); pointer-events: none; }
}
.vef-sheet::backdrop { background: rgba(0, 0, 0, .35); }
.vef-sheet__head {
	display: flex; align-items: center; justify-content: space-between; gap: 16px;
	padding: max(10px, env(safe-area-inset-top)) 12px 10px 20px; border-bottom: 1px solid var(--vef-line);
}
.vef-sheet__title { margin: 0; color: var(--vef-ink); font-family: var(--vef-font-display); font-size: 20px; font-weight: 600; line-height: 1.25; }
.vef-sheet__close {
	display: flex; align-items: center; justify-content: center; flex: none; width: 44px; height: 44px; padding: 0;
	border: 1px solid var(--vef-line); border-radius: var(--vef-radius-md); background: var(--vef-canvas); color: var(--vef-ink); cursor: pointer;
}
.vef-sheet__close .vef-icon { width: 20px; height: 20px; }
.vef-sheet__body { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 16px 16px max(24px, env(safe-area-inset-bottom)); }
.vef-sheet .vef-tabs__list { margin-bottom: 16px; }
.vef-sheet__more { display: block; margin-top: 20px; color: var(--vef-ink); font-weight: 600; text-align: center; }
html.vef-sheet-open { overflow: hidden; }
@media (prefers-reduced-motion: no-preference) {
	.vef-sheet { transition: transform .32s cubic-bezier(.2, .8, .2, 1); }
}
/* Two columns side by side: the shorter one stays in view while the other
   scrolls (both are sticky; only the shorter can move). One taller than the
   screen is let go (core.js), so none of it is out of reach. */
@media (min-width: 901px) {
	.vef-sticky-pair { align-items: start; }
	.vef-sticky-pair > * { position: sticky; top: calc(var(--vef-chrome, 88px) + 24px); }
	.vef-sticky-pair > .is-unstuck { position: relative; top: auto; }
}
@media (max-width: 640px) {
	.vef-contact__icon { width: 48px; height: 48px; }
	.vef-contact__list li:not(:last-child)::before { left: 23px; top: 48px; }
	.vef-contact__hours { padding-inline: 20px; }
}

/* Page banner ----------------------------------------------------------- */

.vef-banner {
	position: relative; overflow: hidden;
	padding-block: clamp(56px, 7vw, 96px);
	background: var(--vef-primary); color: var(--vef-on-primary);
}
.vef-banner__in {
	position: relative;
	/* The column gap used to read --vef-badge-gap, which only .vef-badges
	   defines: an undefined var() voids the whole declaration, so the banner
	   had no gap at all, and once the columns stack on a phone the lede sat
	   flush under the title. */
	display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); align-items: end; gap: 24px clamp(32px, 5vw, 72px);
}
.vef-banner__in--solo { grid-template-columns: minmax(0, 1fr); }
.vef-banner .vef-eyebrow { margin-bottom: 16px; }
.vef-banner__title {
	margin: 0; max-width: 20ch;
	color: var(--vef-on-primary-strong); font-size: clamp(32px, 4vw, 52px); line-height: 1.12; letter-spacing: -.02em;
	overflow-wrap: break-word;
}
.vef-banner__lede {
	margin: 0; padding-left: 24px;
	border-left: 4px solid var(--vef-accent);
	font-size: 18px; line-height: 1.6;
}
@media (max-width: 900px) {
	.vef-banner__in { grid-template-columns: minmax(0, 1fr); }
}

/* Location banner: the details, today's hours and the actions, with the
   photo or a form beside them. */
.vef-locbanner__in { align-items: center; }
.vef-locbanner__details { display: grid; gap: 12px; margin: 28px 0 0; padding: 0; list-style: none; font-size: 17px; }
.vef-locbanner__details li { display: flex; gap: 12px; align-items: flex-start; }
.vef-locbanner__details .vef-icon { flex: none; width: 20px; height: 20px; margin-top: 3px; color: var(--vef-accent); }
.vef-locbanner__details address { font-style: normal; }
.vef-locbanner__details a { color: var(--vef-on-primary-strong); text-decoration: none; }
.vef-locbanner__details a:hover { text-decoration: underline; text-underline-offset: 3px; }
.vef-locbanner__details .vef-locbanner__hours-link { color: var(--vef-on-primary); font-size: 15px; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.vef-today { display: block; color: var(--vef-on-primary-strong); }
.vef-today b { font-weight: 600; }
.vef-today b::before { content: ""; display: inline-block; width: 8px; height: 8px; margin: 0 8px 1px 0; border-radius: 50%; background: #3ccf6e; }
.vef-today.is-shut b::before { background: var(--vef-accent); }
.vef-locbanner__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 32px; }
.vef-locbanner__actions .vef-icon { width: 18px; height: 18px; }
.vef-locbanner__photo img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--vef-radius-lg); box-shadow: 0 30px 60px -30px rgba(0, 0, 0, calc(.6 * var(--vef-shade))); }
@media (max-width: 640px) {
	.vef-locbanner__actions .vef-button { flex: 1 1 calc(50% - 6px); }
	.vef-locbanner__actions .vef-button:first-child { flex-basis: 100%; }
}

/* Location page: Hours & location, with the map on request. */
.vef-visit__in { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 40px clamp(40px, 6vw, 88px); align-items: center; }
.vef-visit__in--solo { grid-template-columns: minmax(0, 1fr); max-width: 560px; }
.vef-visit h2 { margin: 0 0 24px; font-size: clamp(28px, 3.2vw, 40px); }
.vef-hours.vef-visit__hours { margin: 0 0 32px; padding: 8px 24px; border-radius: var(--vef-radius-md); background: var(--vef-canvas); }
.vef-visit__hours div:last-child { border-bottom: 0; }
.vef-visit__address { margin: 0 0 12px; font-style: normal; }
.vef-map { position: relative; overflow: hidden; aspect-ratio: 4 / 3; border-radius: var(--vef-radius-lg); background: var(--vef-canvas); }
.vef-map iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.vef-map__load {
	position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
	width: 100%; border: 1px solid var(--vef-line); border-radius: var(--vef-radius-lg); background:
		repeating-linear-gradient(0deg, transparent 0 39px, var(--vef-line) 39px 40px),
		repeating-linear-gradient(90deg, transparent 0 39px, var(--vef-line) 39px 40px), var(--vef-canvas);
	color: var(--vef-text); font: 15px/1.4 var(--vef-font); cursor: pointer;
}
.vef-map__load strong { color: var(--vef-ink); font-size: 18px; }
.vef-map__load:hover strong { color: var(--vef-accent); }
.vef-map__pin { display: flex; align-items: center; justify-content: center; width: 56px; height: 56px; margin-bottom: 6px; border-radius: 50%; background: var(--vef-accent); color: var(--vef-on-accent, #fff); box-shadow: 0 10px 24px -10px color-mix(in srgb, var(--vef-accent) min(100%, calc(100% * var(--vef-shade))), transparent); }
.vef-map__pin .vef-icon { width: 26px; height: 26px; }
@media (max-width: 900px) {
	.vef-visit__in { grid-template-columns: minmax(0, 1fr); }
}

/* Search and breadcrumbs bar -------------------------------------------- */

.vef-crumbbar { border-bottom: 1px solid var(--vef-line); background: var(--vef-canvas); font-size: 14px; }
.vef-crumbbar__in { position: relative; display: flex; align-items: center; gap: 24px; min-height: 60px; }

.vef-crumbs { min-width: 0; }
/* One line at every width; a long current title ends in "…". */
.vef-crumbs ol { display: flex; margin: 0; padding: 0; list-style: none; white-space: nowrap; }
.vef-crumbs li:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.vef-crumbs li + li::before { content: "/"; margin-inline: 10px; color: #b3b3b3; }
.vef-crumbs a { color: var(--vef-text); text-decoration: none; }
.vef-crumbs a:hover { color: var(--vef-accent); text-decoration: underline; }
.vef-crumbs [aria-current] { color: var(--vef-ink); font-weight: 600; }

.vef-search { position: relative; display: flex; align-items: center; width: 100%; max-width: 420px; }
.vef-search__field {
	width: 100%; height: 48px; padding: 0 52px 0 16px;
	border: 1px solid #d5d5d5; border-radius: var(--vef-radius);
	background: var(--vef-canvas); color: var(--vef-ink);
	font: 400 16px var(--vef-font);
	-webkit-appearance: none; appearance: none;
}
.vef-search__field::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.vef-search__field:focus { border-color: var(--vef-accent); outline: 0; box-shadow: 0 0 0 3px color-mix(in srgb, var(--vef-accent) 20%, transparent); }
.vef-search__button {
	position: absolute; right: 2px; top: 50%; transform: translateY(-50%);
	display: flex; align-items: center; justify-content: center;
	width: 44px; height: 44px; padding: 0;
	border: 0; border-radius: var(--vef-radius); background: transparent; color: var(--vef-ink); cursor: pointer;
}
.vef-search__button:hover { color: var(--vef-accent); }

/* In the bar: a short field at the right, after a rule. */
.vef-search--compact { flex: none; width: 264px; margin-left: auto; padding-left: 24px; border-left: 1px solid var(--vef-line); }
.vef-search--compact .vef-search__field { height: 40px; padding-left: 12px; font-size: 15px; }
.vef-search--compact .vef-search__button { width: 36px; height: 36px; }

/* Phones: the icon alone; core.js opens the field across the bar. */
@media (max-width: 640px) {
	.vef-crumbbar__in { gap: 16px; min-height: 52px; }
	.vef-js .vef-search--compact { width: auto; padding-left: 16px; }
	.vef-js .vef-search--compact .vef-search__field { display: none; }
	.vef-js .vef-search--compact .vef-search__button { position: static; transform: none; width: 40px; height: 40px; margin-right: -8px; }
	.vef-js .vef-search--compact.is-open {
		position: absolute; inset: 0 var(--vef-gutter); z-index: 2;
		width: auto; max-width: none; padding-left: 0; border-left: 0; background: var(--vef-canvas);
	}
	.vef-js .vef-search--compact.is-open .vef-search__field { display: block; }
	.vef-js .vef-search--compact.is-open .vef-search__button { position: absolute; right: 2px; transform: translateY(-50%); margin: 0; }
}

/* Single layout: reading column, optional sticky sidebar ---------------- */

.vef-single { padding-block: clamp(48px, 6vw, 80px); }
.vef-single--sidebar .vef-single__in {
	display: grid; grid-template-columns: minmax(0, var(--vef-rail-narrow)) minmax(0, 360px);
	justify-content: space-between; gap: 48px clamp(40px, 6vw, 96px); align-items: start;
}
.vef-single__aside { position: sticky; top: calc(var(--vef-chrome, 88px) + 24px); }

/* Byline, in the banner under the title. */
/* Team member banner: the role under the name, then the contact icons. */
.vef-banner__role { margin: 12px 0 0; color: var(--vef-on-primary); font-size: clamp(18px, 2vw, 21px); }
.vef-banner__icons { display: flex; flex-wrap: wrap; gap: 10px; margin: 24px 0 0; padding: 0; list-style: none; }
.vef-banner__icons a {
	display: flex; align-items: center; justify-content: center; width: 44px; height: 44px;
	border-radius: 50%; box-shadow: inset 0 0 0 1px var(--vef-line-primary); color: var(--vef-on-primary-strong);
	transition: background-color .15s ease, box-shadow .15s ease;
}
.vef-banner__icons a:hover, .vef-banner__icons a:focus-visible { background: var(--vef-accent); box-shadow: inset 0 0 0 1px var(--vef-accent); }
.vef-banner__icons .vef-icon { width: 19px; height: 19px; }
.vef-byline { display: flex; flex-wrap: wrap; gap: 6px 28px; margin: 24px 0 0; font-size: 15px; }
/* Each item is an icon and its words. The icon is held at the words' own
   size rather than a fixed one, so it tracks the byline if the face changes,
   and sits at the accent to separate it from white text on a dark banner. */
.vef-byline > span { display: inline-flex; align-items: center; gap: 9px; }
.vef-byline .vef-icon { flex: none; width: 1.15em; height: 1.15em; color: var(--vef-accent); }
.vef-byline a { color: var(--vef-on-primary-strong); font-weight: 600; text-decoration: none; }
.vef-byline a:hover { color: var(--vef-on-primary-strong); text-decoration: underline; }

/* Author box, after an article. */
.vef-author {
	display: flex; gap: 28px; align-items: flex-start;
	margin-top: 56px; padding: 32px; border-radius: var(--vef-radius-md);
	background: var(--vef-mute);
}
.vef-author__photo { flex: none; width: 96px; height: 96px; border-radius: 50%; overflow: hidden; }
.vef-author__photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.vef-author__photo span {
	display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;
	background: var(--vef-primary); color: var(--vef-on-primary-strong); font-size: 30px; font-weight: 600; letter-spacing: .04em;
}
.vef-author__body { min-width: 0; }
.vef-author__label { margin: 0 0 6px; color: var(--vef-accent-dark); font-size: 12px; font-weight: 600; letter-spacing: .2em; text-transform: uppercase; }
.vef-author__name { margin: 0; font-size: 24px; }
.vef-author__role { margin: 4px 0 0; color: var(--vef-ink); font-size: 15px; }
.vef-author__bio { margin-top: 16px; font-size: 16px; }
.vef-author__bio p { margin: 0 0 .8em; }
.vef-author .vef-link-arrow { margin-top: 4px; }
@media (max-width: 640px) {
	.vef-author { flex-direction: column; gap: 20px; padding: 24px; }
	.vef-author__photo { width: 80px; height: 80px; }
}

.vef-single__image { margin: 0 0 40px; }
.vef-single__image img { display: block; width: 100%; border-radius: var(--vef-radius-md); }
.vef-single__image figcaption { margin-top: 10px; font-size: 14px; }

/* Calls to action -------------------------------------------------------
 *
 * Three blocks, one voice: the panel inside the article, the card beside it,
 * the band above the footer. Each carries exactly one button, so a page never
 * asks twice in two different ways — and the card no longer repeats the phone
 * number, hours and locations that are in the footer directly below it.
 *
 * Copy comes from the page's practice group (inc/cta.php); the colours come
 * from the tokens, so the button's label stays readable on any accent.
 */

.vef-cta-card {
	padding: 32px 28px 28px; border-radius: var(--vef-radius-md);
	border: 1px solid var(--vef-line); border-top: 4px solid var(--vef-accent);
	background: var(--vef-card-ground, var(--vef-canvas));
	box-shadow: 0 14px 34px color-mix(in srgb, var(--vef-primary) min(100%, calc(8% * var(--vef-shade))), transparent);
}
/* Muted instead of white (Global → Calls to action → Sidebar card). On a
   muted ground the shadow is doing nothing but muddying the edge, so it
   goes and the 1px line carries the shape on its own. */
.vef-cta-card--mute { --vef-card-ground: var(--vef-mute); box-shadow: none; }
.vef-cta-card__title { margin: 0; font-size: 24px; }
.vef-cta-card__rule { display: block; width: 44px; height: 2px; margin-top: 16px; background: var(--vef-accent); }
.vef-cta-card__text { margin: 16px 0 20px; font-size: 19px; font-weight: 600; line-height: 1.4; color: var(--vef-primary); }
/* A light primary (Reyna Teal) is too pale to read as text on the card's
   ground, so the promise goes to ink and the primary moves to the rule,
   where a color only has to be seen. */
.vef-primary-light .vef-cta-card__text { color: var(--vef-ink); }
.vef-primary-light .vef-cta-card__rule { background: var(--vef-primary); }
/* Same for the fine print under the card's button and a post's category
   pill: ink where the primary is too light to be read as text. */
.vef-primary-light .vef-cta-fine,
.vef-primary-light .vef-pill--cat { color: var(--vef-ink); }

/* The card reads as one left-ranged column — heading, rule, promise, button,
   fine print — and the button is only as wide as its label needs. It is still
   the narrowest slot a label has to fit, so a label sized to survive here
   fits the panel and the band too. */
.vef-cta-card .vef-button { min-height: 52px; }

/* The line under the button: a promise, so it is set in the primary rather
   than greyed out, and the tick is the only ornament it gets. Ranged left,
   like the rest of the card; the band centres it below. */
.vef-cta-fine {
	display: flex; align-items: center; gap: 8px;
	margin: 14px 0 0; color: var(--vef-primary);
	font-size: 15px; font-weight: 700; line-height: 1.4;
}
.vef-cta-fine svg { flex: none; width: 18px; height: 18px; color: var(--vef-accent-text, var(--vef-accent)); }
/* In the band it has to out-rank `.vef-prefooter p { margin: 0 auto;
   max-width: 560px }`, which first collapsed the gap above it and then, once
   the gap was set, held it in a 560px box ranged left while its own contents
   centred inside that — so it read as off-centre under a centred button. */
.vef-prefooter .vef-cta-fine { justify-content: center; margin: 22px auto 0; font-size: 18px; }

.vef-cta-panel {
	position: relative; isolation: isolate; overflow: hidden;
	margin: 40px 0; padding: clamp(32px, 5vw, 44px) clamp(24px, 5vw, 48px);
	border-radius: var(--vef-radius-md);
	background: var(--vef-primary); color: var(--vef-on-primary);
}
.vef-cta-panel__in { position: relative; z-index: 1; }
/* Everything below carries the panel class as well as its own, because this
   is the one section that renders INSIDE the article. The prose rules match
   its heading and its button at the same specificity and come later in this
   file, so a single class would lose on source order alone — the heading came
   out ink-on-navy at 1.12:1 and the button gold-on-gold at 1.00:1. */
.vef-cta-panel .vef-cta-panel__title { margin: 0; font-size: clamp(22px, 3vw, 28px); color: var(--vef-on-primary-strong); }
.vef-cta-panel .vef-cta-panel__text { margin: 14px 0 0; max-width: 54ch; font-size: 17px; color: rgb(255 255 255 / .88); }
.vef-cta-panel .vef-cta-panel__source { margin: 12px 0 0; font-size: 13px; font-weight: 400; color: rgb(255 255 255 / .6); }
.vef-cta-panel .vef-cta-panel__actions { margin: 28px 0 0; }
.vef-cta-panel a.vef-button { color: var(--vef-on-accent, #fff); }
.vef-cta-panel a.vef-button:hover { color: var(--vef-on-accent, #fff); }

@media (max-width: 1023px) {
	.vef-single--sidebar .vef-single__in { grid-template-columns: minmax(0, 1fr); }
	.vef-single__aside { position: static; }
}

/* Article typography lives in prose.css. */
.vef-prose .vef-search { margin-bottom: 1.2em; }

/* 404: the code drawn in outline, like the decorative lines. */
.vef-notfound { display: flex; align-items: center; min-height: calc(80svh - var(--vef-chrome, 126px)); }
.vef-notfound__in { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; }
.vef-notfound .vef-banner__title { max-width: none; }
.vef-notfound__code {
	margin: 0 0 8px;
	color: transparent; -webkit-text-stroke: 2px var(--vef-accent);
	font-size: clamp(120px, 22vw, 280px); font-weight: 600; line-height: .9; letter-spacing: -.04em;
}
.vef-notfound__text { margin: 20px auto 36px; max-width: 520px; font-size: 18px; }

/* Listings: cards, pagination, empty state ------------------------------- */

/* Card lift ----------------------------------------------------------------
   A card whose whole face is a link rises under the pointer. Every such card
   does it, by the same --vef-card-lift, so the gesture means one thing on the
   site: this is clickable.

   Each of these cards is made clickable the same way -- an invisible overlay
   stretched over the card from the link in its title -- and that overlay is
   what makes the lift safe. It reaches BELOW the card by exactly the lift, so
   that as the card rises out from under the pointer the overlay is still
   there. Without it the pointer falls into the gap, the card drops, the
   pointer is over it again, and the card flickers at its own bottom edge.

   A card is in this list only if it has one destination. The location card is
   not: it carries a name link, a phone, directions and two buttons, so there
   is nothing for a lift to promise. */
:is(.vef-card__title, .vef-result__title, .vef-member__name, .vef-icon-card__title) a::after {
	content: ""; position: absolute; inset: 0 0 calc(var(--vef-card-lift, 0px) * -1) 0;
}
:is(.vef-card:has(.vef-card__title a), .vef-result--link, .vef-member--link, .vef-icon-card--link):is(:hover, :focus-within) {
	transform: translateY(calc(var(--vef-card-lift) * -1));
}
@media (prefers-reduced-motion: reduce) {
	:root { --vef-card-lift: 0px; }
	/* The glare runs for ever, so it is the first thing to go. The nav's beat
	   goes with it; the underline still wipes, because that is a transition
	   and short. */
	.vef-button::after { display: none; }
	.vef-nav__list > li > a:hover::after,
	.vef-nav__list > li > a:focus-visible::after { animation: none; }
	.vef-button:hover, .vef-button:focus-visible { transform: none; }
}

.vef-listing { padding-block: clamp(48px, 6vw, 80px); }
.vef-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px; }
.vef-cards--two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.vef-card {
	position: relative; display: flex; flex-direction: column;
	border: 1px solid var(--vef-line); border-radius: var(--vef-radius-md);
	background: var(--vef-canvas);
	transition: box-shadow .15s ease, border-color .15s ease, transform .15s ease;
}
.vef-card:hover, .vef-card:focus-within { border-color: transparent; box-shadow: var(--vef-card-shadow); }
/* The card no longer clips its children -- the lift's overlay has to reach
   below it -- so the image rounds its own top corners instead. 11px is the
   card's 12px less its 1px border, which is where the image actually sits. */
.vef-card__image { aspect-ratio: 16 / 10; overflow: hidden; border-radius: max(0px, calc(var(--vef-radius-md) - 1px)) max(0px, calc(var(--vef-radius-md) - 1px)) 0 0; background: var(--vef-mute); }
.vef-card__image img { display: block; width: 100%; height: 100%; object-fit: cover; }
.vef-card__image--blank { position: relative; background: var(--vef-primary); }
.vef-card__image--blank .vef-lines { width: 70%; will-change: auto; }
.vef-card__body { display: flex; flex-direction: column; flex: 1; padding: 24px 24px 28px; }
.vef-card__meta { margin: 0 0 8px; color: var(--vef-accent-dark); font-size: 13px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; }
.vef-card__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; }
.vef-pill {
	display: inline-flex; align-items: center; padding: 4px 10px; border-radius: var(--vef-radius-pill);
	background: color-mix(in srgb, var(--vef-accent) 12%, transparent); color: var(--vef-accent-text, var(--vef-accent-dark));
	font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
}
.vef-card__title { margin: 0 0 10px; font-size: 20px; }
.vef-card__title a { color: var(--vef-ink); text-decoration: none; }
/* A category pill, in the primary rather than the accent, so the categories
   read as a different kind of thing from the "Blog" pill that names the
   section. Same shape and metrics: only the colour separates them. */
.vef-pill--cat {
	background: color-mix(in srgb, var(--vef-primary) 10%, transparent);
	color: var(--vef-primary);
}

/* The second line of the meta -- a date on a post, the section elsewhere.
   It takes a row of its own only on a site that categorises; where there are
   no categories there is nothing to clear, so it stays where it always sat,
   beside the pill. The decision is made for the site rather than per card,
   so a post left in the default category -- which shows no pill -- still
   lines up with the ones beside it in the grid. It lives inside
   .vef-card__meta either way, so its typography is declared once. */
/* On its own line it wants more air than the row gap gives it: the 6px gap
   is the right distance between two pills sitting side by side, and too
   tight between a row of pills and the line under it. */
.vef-card__meta--cats .vef-card__sub { flex: 0 0 100%; margin-top: 6px; }
.vef-card:hover .vef-card__title a { color: var(--vef-accent-text, var(--vef-accent)); }
.vef-card__text { margin: 0 0 20px; font-size: 15px; }
.vef-card__more { display: inline-flex; align-items: center; gap: 8px; margin-top: auto; color: var(--vef-accent-text, var(--vef-accent)); font-size: 15px; font-weight: 600; }
.vef-card__more .vef-icon { width: 16px; height: 16px; transition: transform .15s ease; }
.vef-card:hover .vef-card__more .vef-icon { transform: translateX(3px); }

.vef-pagination { margin-top: 48px; }
.vef-pagination .nav-links, .vef-single .vef-pagination { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.vef-pagination .page-numbers, .vef-pagination .post-page-numbers {
	display: inline-flex; align-items: center; justify-content: center;
	min-width: 44px; height: 44px; padding-inline: 14px;
	border: 1px solid var(--vef-line); border-radius: var(--vef-radius);
	color: var(--vef-ink); font-weight: 600; text-decoration: none;
}
.vef-pagination a:hover { border-color: var(--vef-accent); color: var(--vef-accent); }
.vef-pagination .current { border-color: var(--vef-accent); background: var(--vef-accent); color: var(--vef-on-accent, #fff); }
.vef-pagination .dots { border-color: transparent; }

.vef-empty { max-width: var(--vef-rail-narrow); }

.vef-related { padding-block: clamp(56px, 7vw, 88px); border-top: 1px solid var(--vef-line); }
.vef-related__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 12px 24px; margin-bottom: 32px; }
.vef-related__head h2 { margin: 0; font-size: clamp(26px, 3vw, 32px); }
.vef-link-arrow { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; text-decoration: none; }
.vef-link-arrow .vef-icon { width: 16px; height: 16px; }

@media (max-width: 1023px) {
	.vef-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
	.vef-cards { grid-template-columns: minmax(0, 1fr); gap: 24px; }
}

/* FAQs ------------------------------------------------------------------ */

.vef-faqs { border-top: 1px solid var(--vef-line); }
.vef-faq { border-bottom: 1px solid var(--vef-line); }
.vef-faq__q {
	position: relative; display: block; padding: 24px 48px 24px 0;
	color: var(--vef-ink); font-size: 19px; font-weight: 600; line-height: 1.4;
	cursor: pointer; list-style: none;
}
.vef-faq__q::-webkit-details-marker { display: none; }
.vef-faq__q::after {
	content: ""; position: absolute; right: 8px; top: 50%;
	width: 10px; height: 10px; margin-top: -7px;
	border-right: 2px solid var(--vef-accent); border-bottom: 2px solid var(--vef-accent);
	transform: rotate(45deg); transition: transform .15s ease;
}
.vef-faq[open] > .vef-faq__q::after { margin-top: -2px; transform: rotate(-135deg); }
.vef-faq__q:hover { color: var(--vef-accent); }
.vef-faq__a { padding-bottom: 28px; }
/* While core.js animates an answer open or closed. */
.vef-faq.is-animating .vef-faq__a { overflow: hidden; }
.vef-faq__a .vef-prose { font-size: 17px; }
.vef-faq__a .vef-link-arrow { margin-top: 16px; font-size: 15px; }

/* FAQ topics: jump links, then a heading and accordion per topic. */
.vef-topics { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: clamp(40px, 5vw, 56px); }
.vef-topics a {
	padding: 8px 18px; border: 1px solid var(--vef-button-line, var(--vef-primary)); border-radius: var(--vef-radius-pill);
	background: transparent;
	color: var(--vef-button-line, var(--vef-primary)); font-size: 15px; font-weight: 600; text-decoration: none;
	/* The same fade the contact pills have: these all change two or three
	   colours at once, and snapping between them reads as a flicker. */
	transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.vef-topics a:hover, .vef-topics a:focus-visible { background: #fff; color: var(--vef-ink); }
/* Jump to a group. Sticky directly under the site header, which core.js
   measures into --vef-chrome. One row that scrolls sideways rather than
   wrapping: wrapped, seven pills become a sticky bar three rows deep on a
   phone, which eats the screen it is meant to help you move around. */
.vef-listing-nav {
	/* One declared height, so the scroll offset below cannot drift from what
	   the bar actually measures. The pills never wrap, so it is stable. */
	--vef-listing-nav-h: 65px;
	position: sticky;
	top: var(--vef-chrome, 88px);
	z-index: 20;
	box-sizing: border-box;
	min-height: var(--vef-listing-nav-h);
	background: var(--vef-canvas);
	border-block: 1px solid var(--vef-line);
}
.vef-listing-nav__list {
	display: flex;
	gap: 8px;
	margin: 0;
	padding: 12px 0;
	list-style: none;
	overflow-x: auto;
	scrollbar-width: thin;
	overscroll-behavior-x: contain;
}
.vef-listing-nav__pill {
	display: inline-block;
	padding: 8px 18px;
	border: 1px solid var(--vef-button-line, var(--vef-primary));
	border-radius: var(--vef-radius-pill);
	background: transparent;
	color: var(--vef-button-line, var(--vef-primary));
	font: 600 15px var(--vef-font);
	text-decoration: none;
	white-space: nowrap;
	/* The same fade the contact pills have: these all change two or three
	   colours at once, and snapping between them reads as a flicker. */
	transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.vef-listing-nav__pill:hover,
.vef-listing-nav__pill:focus-visible { background: #fff; color: var(--vef-ink); }
/* The group you are looking at, marked by core.js as you scroll. Filled, like
   the chosen pill on the home page's filter, so the two read the same. */
.vef-listing-nav__pill.is-active {
	border-color: var(--vef-accent);
	background: var(--vef-accent);
	color: var(--vef-on-accent, #fff);
}

.vef-faq-group + .vef-faq-group { margin-top: clamp(48px, 6vw, 72px); }
/* Clear of the sticky topic bar on a jump — the bar's own declared height,
   stacking on the root's scroll-padding-top. */
.vef-faq-group { scroll-margin-top: 65px; }
.vef-faq-group__title { margin: 0 0 8px; font-size: clamp(24px, 2.8vw, 30px); }
.vef-faq-group__text { margin: 0 0 20px; }
.vef-faq-group__title + .vef-faqs { margin-top: 20px; }

/* Case results: filter buttons, cards with the amount large. */
/* Unchosen pills wear the outline button's treatment: transparent with a
   primary edge, filling white under the cursor. The edge is 1px where the
   button's is 2px — thin enough that a row of seven does not shout, and a
   deliberate tell that a pill is a filter and not a call to action. The
   COLOUR is what carries the contrast, not the thickness: 1px of primary on
   a mute band is 15.75:1, far past the 3:1 a control's boundary wants.
   --vef-button-line hands them white on a dark section, same as the button. */
.vef-filter button {
	padding: 8px 18px; border: 1px solid var(--vef-button-line, var(--vef-primary)); border-radius: var(--vef-radius-pill);
	background: transparent;
	color: var(--vef-button-line, var(--vef-primary)); font: 600 15px var(--vef-font); cursor: pointer;
	/* The same fade the contact pills have: these all change two or three
	   colours at once, and snapping between them reads as a flicker. */
	transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.vef-filter button:hover, .vef-filter button:focus-visible { background: #fff; color: var(--vef-ink); }
.vef-filter button.is-active { border-color: var(--vef-accent); background: var(--vef-accent); color: var(--vef-on-accent, #fff); }
.vef-pill--place { background: var(--vef-mute); color: var(--vef-ink); }
/* A grouped listing: a section per group, each with its own heading and
   anchor. Built for the practice areas and now used by case results too, so
   it sits here rather than in one site's stylesheet. */
.vef-listing__group { padding-block: clamp(40px, 5vw, 64px); }
/* A plain listing already pads its own top, so the first group was adding a
   second one -- 61px and then 51px, 113px of nothing above the first
   heading. Its padding is for the gap BETWEEN groups, which is what the one
   below it is for; the top of the page is the listing's job.

   Not on a banded listing, which pads its own top at 0 precisely because the
   groups are coloured sections that have to pad themselves: taking the top
   off the first one leaves its background hugging the heading while the
   bottom keeps its 51px. There was never a doubling there to fix. */
.vef-listing:not(.vef-listing--bands) .vef-listing__group:first-child { padding-top: 0; }
.vef-listing__group + .vef-listing__group { border-top: 1px solid var(--vef-line); }
/* …except where the groups already alternate background. A line at the seam
   between a tinted band and a white one marks a boundary the colour has
   marked already, and reads as a crack rather than a rule. Either side being
   banded is enough to drop it. */
.vef-listing__group--alt + .vef-listing__group,
.vef-listing__group + .vef-listing__group--alt { border-top: 0; }
.vef-listing__group-title { margin: 0 0 clamp(20px, 2.4vw, 32px); font-size: clamp(26px, 2.8vw, 34px); }
/* The featured section repeats results that appear again further down, so it
   is set apart rather than reading as another practice area: the first group
   on the page has no rule above it, and this one earns a line below instead. */
.vef-listing__group--featured { border-bottom: 1px solid var(--vef-line); }
/* Clear of the sticky bar on a jump: its declared height, stacking on the
   root's scroll-padding-top. */
.vef-listing__group { scroll-margin-top: 65px; }

.vef-results { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
.vef-result {
	position: relative; display: flex; flex-direction: column;
	padding: clamp(24px, 3vw, 36px); border: 1px solid var(--vef-line); border-radius: var(--vef-radius-md); background: var(--vef-canvas);
	transition: box-shadow .15s ease, border-color .15s ease, transform .15s ease;
}
.vef-result[hidden] { display: none; }
/* A rule along the top of every card, and the accent on the one or two worth
   leading with. The word is printed too: the colour says nothing to a visitor
   who cannot see it, and a result the firm is proud of should say so. */
/* The edge is a pair: the colour it wears, and the one it does not. Both
   flip together, so featured inverts the rest (Global → Brand sets which way
   round the rest sit), and hovering a card that links flips it again — the
   edge answers the pointer in the colour the card was not already wearing. */
.vef-result {
	--vef-result-edge: var(--vef-primary);
	--vef-result-edge-alt: var(--vef-accent);
	border-top: 5px solid var(--vef-result-edge);
}
.vef-result--featured, .vef-result--accent {
	--vef-result-edge: var(--vef-accent);
	--vef-result-edge-alt: var(--vef-primary);
}
.vef-result--accent.vef-result--featured {
	--vef-result-edge: var(--vef-primary);
	--vef-result-edge-alt: var(--vef-accent);
}
/* The featured flag, in three styles. It lives in the meta row so a featured
   card is exactly as tall as every other one -- the row is already there, and
   the old version put a block above it that made featured cards taller than
   their neighbours in the same grid.

   Pill is the default: the same metrics as .vef-pill beside it, filled with
   the accent rather than tinted with it, so it reads as the louder of the two
   without being a different shape. */
.vef-result__flag {
	display: inline-flex; align-items: center; padding: 4px 10px; border-radius: var(--vef-radius-pill);
	background: var(--vef-accent); color: var(--vef-on-accent, #fff);
	font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
}
.vef-result__flag .vef-icon { display: none; }

/* Corner: a diagonal band across the top right. Absolutely positioned, so it
   costs the row nothing. The outer span is a square clipped to the card's own
   corner radius and the inner one is the band, rotated and run wide enough
   that its ends are cut off rather than stopping short. */
.vef-result--flag-corner .vef-result__flag {
	position: absolute; top: 0; right: 0; z-index: 2;
	width: 84px; height: 84px; padding: 0; overflow: hidden;
	border-radius: 0 max(0px, calc(var(--vef-radius-md) - 1px)) 0 0;
	background: none;
}
.vef-result--flag-corner .vef-result__flag-in {
	position: absolute; top: 15px; right: -32px;
	width: 130px; padding: 3px 0;
	background: var(--vef-accent); color: var(--vef-on-accent, #fff);
	font-size: 10px; letter-spacing: .06em; text-align: center;
	transform: rotate(45deg);
}

/* Star: the icon alone, but still in the filled pill, so it keeps the row's
   proportions. A bare glyph sat shorter than the tags beside it and read as
   a stray mark rather than one of them; inside the pill it is the same 26px
   as its neighbours and only narrower. The block padding comes from the rule
   above, so the height follows the pill automatically -- an 18px icon in 4px
   of padding is exactly the 18px line box the text makes. The word stays in
   the markup for a screen reader. */
.vef-result--flag-star .vef-result__flag { padding-inline: 8px; }
.vef-result--flag-star .vef-result__flag .vef-icon { display: block; width: 18px; height: 18px; }
.vef-result--flag-star .vef-result__flag-text {
	position: absolute; width: 1px; height: 1px; overflow: hidden; white-space: nowrap; clip-path: inset(50%);
}.vef-result--link:hover {
	border-color: transparent; border-top-color: var(--vef-result-edge-alt);
	box-shadow: var(--vef-card-shadow);
}
.vef-result__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 0 0 14px; }
.vef-result__area { color: var(--vef-text); font-size: 14px; }
.vef-result__amount { margin: 0 0 2px; color: var(--vef-ink); font-size: clamp(32px, 3.4vw, 42px); font-weight: 600; line-height: 1.1; letter-spacing: -.02em; }
/* What the figure is, directly under it and quiet: the number is the claim,
   this only says which kind of number it is. */
.vef-result__amount-label { margin: 10px 0 12px; color: var(--vef-text-soft); font-size: 15px; font-weight: 700; line-height: 1.3; }
.vef-result__title { margin: 0 0 10px; font-size: 18px; }
.vef-result__title a { color: inherit; text-decoration: none; }
.vef-result--link:hover .vef-result__title a { color: var(--vef-accent); }
.vef-result__text { margin: 0 0 20px; font-size: 15px; }
.vef-result .vef-card__more { margin-top: auto; }
.vef-result-summary { display: flex; flex-wrap: wrap; gap: 16px 48px; margin: 0 0 36px; padding: 24px 28px; border-radius: var(--vef-radius-md); background: var(--vef-mute); }
.vef-result-summary dt { font-size: 13px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--vef-accent-dark); }
.vef-result-summary dd { margin: 4px 0 0; color: var(--vef-ink); font-size: 18px; font-weight: 600; }
.vef-result-summary__amount dd { font-size: clamp(30px, 3.4vw, 40px); line-height: 1.1; letter-spacing: -.02em; }
@media (max-width: 1023px) { .vef-results { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .vef-results { grid-template-columns: minmax(0, 1fr); } }

/* Locations: cards with address, phone, hours and Directions / Call. */
.vef-locations__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
/* The location card answers the pointer in two places rather than one,
   because it has no single destination: the shadow comes up wherever the
   pointer is inside the card, and the photo zooms only under the photo. It
   does not take the card lift -- see the card-lift standard above. The
   shadow matches the result and icon cards, the two it sits closest to. */
.vef-location {
	display: flex; flex-direction: column;
	padding: clamp(24px, 3vw, 36px); border: 1px solid var(--vef-line); border-radius: var(--vef-radius-md);
	background: var(--vef-canvas); scroll-margin-top: calc(var(--vef-chrome, 88px) + 24px);
	transition: box-shadow .15s ease, border-color .15s ease;
}
.vef-location:hover, .vef-location:focus-within { border-color: transparent; box-shadow: var(--vef-card-shadow); }
.vef-home--alt .vef-location { border-color: transparent; }
.vef-location--photo { padding-top: 0; overflow: hidden; }
.vef-location__photo { margin: 0 calc(-1 * clamp(24px, 3vw, 36px)) clamp(20px, 2.4vw, 28px); aspect-ratio: 16 / 10; }
.vef-location__photo a { display: block; height: 100%; }
.vef-location__photo img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .3s ease; }
/* Only when the photo itself is under the pointer, and only when it is a
   link: an unlinked photo has nothing to zoom towards. */
.vef-location__photo a:hover img { transform: scale(1.03); }
.vef-location__name { margin: 0 0 16px; font-size: 22px; }
.vef-location__name a { color: inherit; text-decoration: none; }
.vef-location__name a:hover { color: var(--vef-accent); }
.vef-location__details { margin: 0 0 16px; padding: 0; list-style: none; }
.vef-location__details li { display: flex; gap: 12px; padding-block: 6px; }
.vef-location__details .vef-icon { margin-top: 3px; color: var(--vef-accent); }
.vef-location__details address { font-style: normal; }
.vef-location__details a { color: var(--vef-text); text-decoration: none; }
.vef-location__details a:hover { color: var(--vef-accent); }
.vef-location__hours { margin-bottom: 20px; font-size: 14px; }
.vef-location__hours div { padding-block: 7px; }
.vef-location__hours div:first-child { padding-top: 7px; }
.vef-location__foot { margin-top: auto; }
.vef-location__actions { display: flex; gap: 10px; }
.vef-location__actions .vef-button { flex: 1 1 0; min-width: 0; padding: 12px 18px; font-size: 15px; }
.vef-cta-card .vef-location { padding: 0; border: 0; background: none; }
/* Location page sidebar: Directions and Call side by side, half each; the main button below. */
.vef-cta-card .vef-location__hours { margin-bottom: 20px; }
.vef-location__book { width: 100%; margin-top: 10px; padding: 12px 18px; font-size: 15px; }

/* Location page form section (#get-started). */
.vef-locform h2 { margin: 0 0 16px; font-size: clamp(28px, 3.2vw, 40px); }
.vef-locform__text { margin-bottom: 32px; }
.vef-locform__text p { margin: 0 0 12px; font-size: 18px; }
.vef-locform__text > :last-child { margin-bottom: 0; }
.vef-locform__text a { color: var(--vef-accent); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; white-space: nowrap; }
.vef-locform__text a:hover { color: var(--vef-accent-dark); }
.vef-locform__text a .vef-icon { display: inline-block; width: 17px; height: 17px; margin: 0 6px -2px 2px; vertical-align: baseline; }
/* Centered heading on wider screens, left on phones. */
@media (min-width: 641px) {
	.vef-locform__text { text-align: center; }
}
.vef-visit__name { margin: 0 0 4px; color: var(--vef-ink); font-weight: 600; }

.vef-footer__all-locations a { color: var(--vef-on-primary-strong); font-weight: 600; }
.vef-footer__place { display: block; margin-bottom: 2px; color: var(--vef-on-primary-strong); font-size: 12px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; }
.vef-footer__places { margin: 0; padding: 0; list-style: none; }
.vef-footer__list .vef-footer__places li { margin: 0; }
.vef-footer__list .vef-footer__places li + li { margin-top: 6px; }
@media (max-width: 1023px) { .vef-locations__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .vef-locations__grid { grid-template-columns: minmax(0, 1fr); } }

/* Team -------------------------------------------------------------------- */

.vef-team__group + .vef-team__group { margin-top: clamp(56px, 7vw, 88px); }
.vef-team__title { margin: 0 0 8px; font-size: clamp(26px, 3vw, 32px); }
.vef-team__text { margin: 0 0 8px; max-width: 640px; }
.vef-members { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 40px 28px; margin-top: 32px; }
.vef-member { position: relative; transition: transform .15s ease; }
.vef-member__photo { aspect-ratio: 4 / 5; overflow: hidden; border-radius: var(--vef-radius-md); background: var(--vef-mute); }
.vef-member__photo img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .3s ease; }
.vef-member__photo span {
	display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;
	background: var(--vef-primary); color: var(--vef-on-primary-strong); font-size: clamp(40px, 5vw, 64px); font-weight: 600; letter-spacing: .04em;
}
.vef-member__name { margin: 18px 0 4px; font-size: 20px; }
.vef-member__name a { color: var(--vef-ink); text-decoration: none; }
.vef-member--link:hover .vef-member__name a { color: var(--vef-accent); }
.vef-member--link:hover .vef-member__photo img { transform: scale(1.03); }
.vef-member__role { margin: 0; font-size: 15px; }

/* A team of one or two: half-and-half features, photos alternating sides. */
.vef-member-features { display: grid; gap: clamp(64px, 8vw, 112px); }
.vef-member-feature { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; gap: 40px clamp(40px, 6vw, 88px); }
.vef-member-feature--flip .vef-member-feature__photo { order: 2; }
.vef-member-feature__photo { aspect-ratio: 4 / 5; }
.vef-member-feature .vef-eyebrow { margin-bottom: 12px; }
.vef-member-feature__name { margin: 0; font-size: clamp(30px, 3.8vw, 46px); letter-spacing: -.015em; }
.vef-member-feature__role { margin: 8px 0 0; color: var(--vef-ink); font-size: 18px; font-weight: 600; }
.vef-member-feature__text { margin: 20px 0 0; font-size: 18px; line-height: 1.65; }
.vef-member-feature .vef-profile__links { margin-top: 24px; }
.vef-member-feature .vef-button { margin-top: 32px; }
.vef-members--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.vef-profile { display: grid; grid-template-columns: minmax(0, 420px) minmax(0, var(--vef-rail-narrow)); gap: 48px clamp(40px, 6vw, 88px); align-items: start; }
.vef-profile__photo { position: sticky; top: calc(var(--vef-chrome, 88px) + 24px); }
.vef-profile__links { display: grid; gap: 12px; margin: 32px 0 0; padding: 24px 0 0; border-top: 1px solid var(--vef-line); list-style: none; }
.vef-profile__links li { display: flex; align-items: center; gap: 12px; }
.vef-profile__links .vef-icon { color: var(--vef-accent); }

@media (max-width: 1023px) {
	.vef-members { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	/* Tablets: still two columns, the photo about 30%. */
	.vef-profile { grid-template-columns: minmax(0, 3fr) minmax(0, 7fr); gap: 32px clamp(28px, 4vw, 48px); }
	.vef-member-feature { grid-template-columns: minmax(0, 1fr); }
	.vef-member-feature--flip .vef-member-feature__photo { order: 0; }
	.vef-member-feature__photo { max-width: 420px; }
}
@media (max-width: 640px) {
	.vef-members { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 16px; }
	/* A team member's page on phones: stacked, the photo (or initials) full width, same 4:5 shape. */
	.vef-profile { grid-template-columns: minmax(0, 1fr); }
	.vef-profile__photo { position: static; }
	/* An odd card out sits centered under the others. */
	.vef-members > .vef-member:last-child:nth-child(odd) { grid-column: 1 / -1; justify-self: center; width: calc(50% - 8px); }
	.vef-member__name { font-size: 17px; }
	.vef-faq__q { font-size: 17px; }
}

/* Home sections ---------------------------------------------------------- */

.vef-home { padding-block: var(--vef-section-pad); background: var(--vef-canvas); }
.vef-home--alt { background: var(--vef-mute); }
.vef-home--alt .vef-card { background: var(--vef-canvas); }
/* On a mute section the FAQ list becomes a white card with inner padding. */
.vef-home--alt .vef-faqs { padding: 8px clamp(20px, 3vw, 36px); border-top: 0; border-radius: var(--vef-radius-md); background: var(--vef-canvas); }
.vef-home--alt .vef-faqs .vef-faq:last-child { border-bottom: 0; }

.vef-section-head {
	display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 16px 40px;
	margin-bottom: clamp(32px, 4vw, 48px);
}
/* "View all" sits top right, level with the heading; the intro runs under the heading. */
.vef-section-head > .vef-link-arrow { grid-column: 2; grid-row: 1; }
/* With an intro, the link sits on the intro's bottom line. */
.vef-section-head:has(.vef-section-head__text) > .vef-link-arrow { grid-row: 1 / span 2; }
@media (max-width: 640px) {
	.vef-section-head { grid-template-columns: minmax(0, 1fr); }
	.vef-section-head > .vef-link-arrow { grid-column: 1; grid-row: auto; justify-self: start; }
}
/* These set spacing only. They used to name --vef-accent-dark as well — the
   hand-fix for "the accent is too light to read on paper", from before the
   colour was derived. It only reached 3.4:1, under the 4.5 it was aiming at,
   and being more specific than .vef-eyebrow it quietly beat the computed
   one. The base rule handles the colour for every ground now. */
.vef-section-head .vef-eyebrow { margin-bottom: 12px; }
.vef-section-head__title { margin: 0; max-width: 22ch; font-size: clamp(28px, 3.6vw, 44px); letter-spacing: -.015em; }
.vef-section-head__text { grid-column: 1; max-width: 680px; margin: 0; font-size: 18px; line-height: 1.6; }
.vef-section-head--center .vef-section-head__text { margin-inline: auto; }
.vef-home--stats .vef-section-head__text { color: var(--vef-on-primary); }
.vef-reviews__head .vef-section-head__text { margin-top: 16px; }
.vef-badges__text { max-width: 680px; margin: -24px auto 36px; font-size: 17px; text-align: center; }
.vef-section-head--center { grid-template-columns: minmax(0, 1fr); justify-items: center; text-align: center; }
.vef-section-head--center .vef-section-head__title { margin-inline: auto; }

/* About: photo left, text right. */
.vef-about { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; gap: 40px clamp(40px, 6vw, 88px); }
.vef-about__image img { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--vef-radius-md); }
.vef-about .vef-eyebrow { margin-bottom: 12px; }
.vef-about__text { margin: 24px 0 32px; font-size: 18px; }
.vef-about__text p { margin: 0 0 1em; }
.vef-about__text p:last-child { margin: 0; }
.vef-home--about-text .vef-about { grid-template-columns: minmax(0, var(--vef-rail-narrow)); }

/* Stats on the primary color. */
.vef-home--stats { position: relative; overflow: hidden; background: var(--vef-primary); color: var(--vef-on-primary); }
.vef-home--stats .vef-section-head__title { color: var(--vef-on-primary-strong); }
.vef-home--stats .vef-section-head .vef-eyebrow { color: var(--vef-accent); }
.vef-home--stats .vef-section-head { position: relative; }
.vef-stats { position: relative; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 32px; margin: 0; text-align: center; }
.vef-stats--1 { grid-template-columns: minmax(0, 1fr); }
.vef-stats--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.vef-stats--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.vef-stat { display: flex; flex-direction: column-reverse; }
.vef-stat + .vef-stat { border-left: 1px solid var(--vef-line-primary); }
.vef-stat__number { margin: 0; color: var(--vef-on-primary-strong); font-family: var(--vef-font-display); font-variant-numeric: tabular-nums; font-size: clamp(44px, 5.6vw, 72px); font-weight: 600; line-height: 1; letter-spacing: -.03em; }
.vef-stat__label { margin-top: 12px; font-size: 15px; letter-spacing: .04em; }

/* Gallery: a fixed rectangle, tiles placed per photo count (gallery.php). */
.vef-gallery {
	display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-template-rows: repeat(6, minmax(0, 1fr));
	gap: 12px; aspect-ratio: 16 / 9; margin: 0; padding: 0; list-style: none;
}
.vef-gallery li { grid-area: var(--vef-tile); min-height: 0; }
.vef-gallery a { display: block; width: 100%; height: 100%; overflow: hidden; border-radius: var(--vef-radius-md); background: var(--vef-primary); }
.vef-gallery img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .3s ease; }
.vef-gallery a:hover img, .vef-gallery a:focus-visible img { transform: scale(1.03); }

.vef-lightbox { width: 100vw; max-width: 100vw; height: 100vh; max-height: 100vh; margin: 0; padding: 0; border: 0; background: rgba(0, 0, 0, .92); }
.vef-lightbox::backdrop { background: transparent; }
.vef-lightbox img { position: absolute; inset: 0; margin: auto; max-width: calc(100vw - 120px); max-height: calc(100vh - 120px); border-radius: var(--vef-radius-sm); }
.vef-lightbox button {
	position: absolute; display: flex; align-items: center; justify-content: center;
	width: 48px; height: 48px; padding: 0; border: 0; border-radius: 50%;
	background: rgba(255, 255, 255, .12); color: #fff; cursor: pointer;
}
.vef-lightbox button:hover { background: var(--vef-accent); }
.vef-lightbox__close { top: 20px; right: 20px; }
.vef-lightbox__prev, .vef-lightbox__next { top: 50%; margin-top: -24px; }
.vef-lightbox__prev { left: 16px; }
.vef-lightbox__prev .vef-icon { transform: scaleX(-1); }
.vef-lightbox__next { right: 16px; }

/* Process: numbered steps down a line, photo beside. */
.vef-process { display: grid; grid-template-columns: minmax(0, 1fr); gap: 48px clamp(40px, 6vw, 96px); align-items: start; }
.vef-process--image { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.vef-steps { margin: 0; padding: 0; list-style: none; }
.vef-step { position: relative; display: flex; gap: 28px; padding-bottom: 36px; }
.vef-step:last-child { padding-bottom: 0; }
.vef-step:not(:last-child)::before { content: ""; position: absolute; left: 27px; top: 56px; bottom: 0; border-left: 2px solid var(--vef-line); transition: border-color .3s ease; }
.vef-step__n {
	display: flex; align-items: center; justify-content: center; flex: none;
	width: 56px; height: 56px; border: 2px solid var(--vef-line); border-radius: 50%;
	background: var(--vef-canvas); color: var(--vef-accent-dark); font-weight: 600;
	transition: background-color .3s ease, border-color .3s ease, color .3s ease, transform .3s ease;
}
.vef-step__title { transition: color .3s ease; }
/* Scroll highlight (core.js): the current step filled, passed ones outlined, the line filled behind them. Without JavaScript, the first step is lit. */
html:not(.vef-js) .vef-step:first-child .vef-step__n,
.vef-step.is-active .vef-step__n { border-color: var(--vef-accent); background: var(--vef-accent); color: var(--vef-on-accent, #fff); transform: scale(1.06); }
.vef-step.is-done .vef-step__n { border-color: var(--vef-accent); }
.vef-step.is-done::before { border-color: var(--vef-accent) !important; }
.vef-step.is-active .vef-step__title { color: var(--vef-accent-dark); }
.vef-process__cta { margin: 40px 0 0 84px; }
.vef-step__title { margin: 12px 0 6px; font-size: 20px; }
.vef-step__text p { margin: 0 0 .8em; }
.vef-step__text p:last-child { margin: 0; }
/* A list in a step: the content list card (prose.css), two columns when
   the step has room. */
.vef-step__text :is(ul, ol) { grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); column-gap: 28px; margin: 16px 0 20px; }
.vef-step__text :is(ul, ol):last-child { margin-bottom: 0; }
/* The photo's column runs the full height of the steps; the photo, capped to
   the screen, stays in view inside it while the steps scroll. */
.vef-process--image { align-items: stretch; }
.vef-process__image img { display: block; width: 100%; height: min(calc(100svh - var(--vef-chrome, 88px) - 64px), 540px); object-fit: cover; border-radius: var(--vef-radius-md); }
.vef-process--image .vef-step { padding-bottom: 72px; }
.vef-process--image .vef-step:last-child { padding-bottom: 0; }

/* Quote band: a full-width photo drifting under the primary color, a quote on it. */
.vef-quote-band {
	position: relative; overflow: hidden;
	display: flex; align-items: center; min-height: clamp(360px, 60svh, 620px);
	padding-block: clamp(64px, 9vw, 120px);
	background: var(--vef-primary); color: var(--vef-on-primary-strong); text-align: center;
}
.vef-quote-band__bg { position: absolute; inset: -18% 0; will-change: transform; }
.vef-quote-band__bg img { width: 100%; height: 100%; object-fit: cover; }
.vef-quote-band--image::after { content: ""; position: absolute; inset: 0; background: var(--vef-primary); opacity: .62; }
.vef-quote-band--plain::after { opacity: .25; }
.vef-quote-band__in { position: relative; z-index: 1; margin-block: 0; }
.vef-quote-band__quote { margin: 0; }
.vef-quote-band__quote p { margin: 0; color: var(--vef-on-primary-strong); font-size: clamp(24px, 3.2vw, 38px); font-weight: 600; line-height: 1.3; letter-spacing: -.01em; }
.vef-quote-band__quote p::before { content: "“"; display: block; margin-bottom: 8px; color: var(--vef-accent); font-size: 1.8em; line-height: .6; }
.vef-quote-band__cite { margin-top: 24px; color: var(--vef-on-primary); font-size: 14px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; }

/* Icon cards: icon in a tinted square, title, text; an accent CTA card last. */
/* The rule on a band of icon cards, chosen per band (Home sections), so two
   bands on one page can tell themselves apart.

   The band names two colours — its own and the other one — and everything on
   the card reads from those two names: the rule and the icon together, never
   separately, so they cannot drift apart. A card that is a link wears the
   OTHER colour and swaps back on hover, which gives a link a visible answer
   to the cursor and makes the two kinds of card legible at a glance before
   anybody has moved the mouse at all.

   'none' keeps the icons as they always were and simply drops the rule; it
   is the opt-out, not a third colour. */
.vef-icon-cards { --vef-rule: var(--vef-accent); --vef-rule-alt: var(--vef-primary); --vef-rule-w: 5px; }
.vef-icon-cards--rule-primary { --vef-rule: var(--vef-primary); --vef-rule-alt: var(--vef-accent); }
.vef-icon-cards--rule-accent { --vef-rule: var(--vef-accent); --vef-rule-alt: var(--vef-primary); }
.vef-icon-cards--rule-none { --vef-rule-w: 0px; }
.vef-icon-cards .vef-icon-card {
	border-top: var(--vef-rule-w) solid var(--vef-rule);
	transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.vef-icon-cards .vef-icon-card__icon {
	background: color-mix(in srgb, var(--vef-rule) 12%, var(--vef-canvas));
	/* Darker than its own tint, the way --vef-accent-dark is: a gold glyph on
	   a pale gold square is barely there. */
	color: color-mix(in srgb, var(--vef-rule) 82%, #000);
	transition: background-color .15s ease, color .15s ease;
}
/* A link: the other colour, until the cursor puts it back. */
.vef-icon-cards .vef-icon-card--link { border-top-color: var(--vef-rule-alt); }
.vef-icon-cards .vef-icon-card--link .vef-icon-card__icon {
	background: color-mix(in srgb, var(--vef-rule-alt) 12%, var(--vef-canvas));
	color: color-mix(in srgb, var(--vef-rule-alt) 82%, #000);
}
.vef-icon-cards .vef-icon-card--link:hover { border-top-color: var(--vef-rule); }
.vef-icon-cards .vef-icon-card--link:hover .vef-icon-card__icon {
	background: color-mix(in srgb, var(--vef-rule) 12%, var(--vef-canvas));
	color: color-mix(in srgb, var(--vef-rule) 82%, #000);
}
/* The call-to-action card is already the accent all over; a rule on top of
   itself reads as a seam, and its icon is white on that ground. */
.vef-icon-cards .vef-icon-card--cta,
.vef-icon-cards .vef-icon-card--cta:hover { border-top-color: transparent; }
.vef-icon-cards .vef-icon-card--cta .vef-icon-card__icon,
.vef-icon-cards .vef-icon-card--cta:hover .vef-icon-card__icon { background: var(--vef-wash-primary-strong); color: var(--vef-on-primary-strong); }
.vef-icon-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; margin: 0; padding: 0; list-style: none; }
.vef-icon-card {
	position: relative; display: flex; flex-direction: column;
	padding: clamp(28px, 3vw, 40px); border: 1px solid var(--vef-line); border-radius: var(--vef-radius-md); background: var(--vef-canvas);
	transition: box-shadow .15s ease, border-color .15s ease, transform .15s ease;
}
/* The sides and foot only: the top is the band's rule, which stays. */
.vef-home--alt .vef-icon-card { border-inline-color: transparent; border-bottom-color: transparent; }
.vef-icon-card--link:hover { border-color: transparent; box-shadow: var(--vef-card-shadow); }
.vef-icon-card__icon {
	display: flex; align-items: center; justify-content: center; width: 56px; height: 56px; margin-bottom: 24px;
	border-radius: var(--vef-radius-md); background: color-mix(in srgb, var(--vef-accent) 12%, var(--vef-canvas)); color: var(--vef-accent-dark);
}
.vef-icon-card__title { margin: 0 0 10px; font-size: 21px; }
.vef-icon-card__title a { color: inherit; text-decoration: none; }
/* The overlay that makes the whole card clickable, extended BELOW the card
   by exactly the hover lift. Without that, a cursor resting near the bottom
   edge falls outside the moment the card rises: hover drops, the card
   settles back, hover fires again — a flicker that only happens along that
   one edge, which is why it looked random. */
.vef-icon-card__text { margin: 0; font-size: 16px; line-height: 1.6; }

/* Key takeaways: the same card as the highlights, standing on its own above
   an article rather than in a grid. It takes the card's border, radius and
   icon block as they are; everything here is about being a block of prose
   instead of a title and a line of text. */
/* The accent edge, the same mark the call-to-action card wears: it says
   "read this first" without a label, and ties the two blocks together on a
   page that shows both. */
.vef-takeaways { margin: 0 0 36px; border-top: 4px solid var(--vef-accent); }
/* Icon and headline on one line. In a grid of highlight cards the icon sits
   above the title, where it has a column to itself; here the card is as wide
   as the article and that leaves the title stranded, so the two pair up and
   the list gets the full width underneath. */
.vef-takeaways__head { display: flex; align-items: center; gap: 16px; margin-bottom: 18px; }
.vef-takeaways__head .vef-icon-card__icon { flex: none; margin-bottom: 0; }
.vef-takeaways .vef-icon-card__title { margin: 0; }
.vef-takeaways__body { font-size: 16px; }
.vef-takeaways__body > :last-child { margin-bottom: 0; }
/* Its list wears the content list's circles, without the frame (prose.css),
   in the card's own colour: the accent of its top rule and its icon. */
.vef-takeaways { --vef-list-tint: color-mix(in srgb, var(--vef-accent) 12%, var(--vef-canvas)); --vef-list-ink: var(--vef-accent-dark); }
.vef-takeaways__body ul { margin: 0; }
.vef-icon-card--cta {
	/* On the accent, the card's type is the accent's: the on-primary tokens
	   below are re-pointed here, so a light primary's charcoal type never
	   lands on a charcoal accent card. */
	--vef-on-primary-strong: var(--vef-on-accent, #fff);
	--vef-on-primary: color-mix(in srgb, var(--vef-on-accent, #fff) 82%, transparent);
	--vef-wash-primary-strong: color-mix(in srgb, var(--vef-on-accent, #fff) 15%, transparent);
	border-color: transparent; color: var(--vef-on-primary);
	background: linear-gradient(135deg, var(--vef-accent), var(--vef-accent-dark));
}
/* Its color → Primary: the primary's own type tokens (light or dark). */
.vef-icon-card--cta-primary {
	--vef-on-primary-strong: inherit; --vef-on-primary: inherit; --vef-wash-primary-strong: inherit;
	background: linear-gradient(135deg, var(--vef-primary), color-mix(in srgb, var(--vef-primary) 82%, #000));
}
/* A light primary carries dark type, so its gradient runs lighter, not darker. */
.vef-primary-light .vef-icon-card--cta-primary { background: linear-gradient(135deg, color-mix(in srgb, var(--vef-primary) 80%, #fff), var(--vef-primary)); }
.vef-icon-card--cta .vef-icon-card__icon { background: var(--vef-wash-primary-strong); color: var(--vef-on-primary-strong); }
.vef-icon-card--cta .vef-icon-card__title { color: var(--vef-on-primary-strong); }
.vef-icon-card__more { display: inline-flex; align-items: center; gap: 8px; margin-top: auto; padding-top: 24px; color: var(--vef-on-primary-strong); font-weight: 600; }
.vef-icon-card__more .vef-icon { width: 16px; height: 16px; transition: transform .15s ease; }
.vef-icon-card--cta:hover .vef-icon-card__more .vef-icon { transform: translateX(3px); }

/* Reasons to hire us: text and an icon list on a white card; photo in view beside. */
.vef-reasons { display: grid; grid-template-columns: minmax(0, 1fr); gap: 48px clamp(40px, 6vw, 88px); align-items: stretch; }
.vef-reasons--image { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.vef-reasons__main { align-self: center; }
.vef-reasons .vef-eyebrow { margin-bottom: 12px; }
.vef-reasons__text { margin: 20px 0 0; max-width: 620px; font-size: 18px; line-height: 1.65; }
.vef-reasons__list {
	margin: 32px 0 0; padding: 8px clamp(20px, 3vw, 36px); list-style: none;
	border-radius: var(--vef-radius-lg); background: var(--vef-canvas); box-shadow: 0 18px 40px -24px rgba(0, 0, 0, calc(.25 * var(--vef-shade)));
}
.vef-home--reasons:not(.vef-home--alt) .vef-reasons__list { border: 1px solid var(--vef-line); }
.vef-reasons__list li { display: flex; align-items: center; gap: 20px; padding-block: 18px; }
.vef-reasons__list li + li { border-top: 1px solid var(--vef-line); }
.vef-reasons__icon {
	display: flex; align-items: center; justify-content: center; flex: none; width: 48px; height: 48px;
	border-radius: var(--vef-radius-sm); background: color-mix(in srgb, var(--vef-accent) 12%, var(--vef-canvas)); color: var(--vef-accent-dark);
}
.vef-reasons__item { color: var(--vef-ink); font-size: 19px; font-weight: 600; line-height: 1.35; }
.vef-reasons__media { position: relative; }
.vef-reasons__figure img { height: min(calc(100svh - var(--vef-chrome, 88px) - 64px), 720px); object-fit: cover; border-radius: var(--vef-radius-lg); }
/* The row reaching the middle of the screen lights up (core.js). */
.vef-reasons__icon { transition: background-color .3s ease, color .3s ease, transform .3s ease; }
.vef-reasons__list li.is-active .vef-reasons__icon { background: var(--vef-accent); color: var(--vef-on-accent, #fff); transform: scale(1.06); }

/* Exactly four cards share one row rather than leave the fourth alone;
   below 1024 they fall to two by two. */
@media (min-width: 1024px) {
	.vef-icon-cards:has(> :nth-child(4):last-child) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (max-width: 1023px) {
	.vef-icon-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
	.vef-reasons--image { grid-template-columns: minmax(0, 1fr); }
	.vef-reasons__figure img { height: auto; aspect-ratio: 4 / 5; max-height: 70svh; }
}
@media (max-width: 640px) {
	.vef-icon-cards { grid-template-columns: minmax(0, 1fr); gap: 16px; }
	.vef-reasons__item { font-size: 17px; }
	.vef-reasons__list li { gap: 14px; }
}

/*
 * The caption box, one style site-wide: section photos (vef_core_figure())
 * and image blocks in page and post content. A dark panel that hangs 28px
 * off the photo's edge toward the text (bottom-left by default; "Caption on
 * the right" image style, or the photo's side in split sections), and on
 * phones 28px off the bottom. Gallery, featured-image and card captions
 * keep their own plain style.
 */
.vef-figure { position: relative; margin: 0; }
.vef-figure > img { display: block; width: 100%; }
.vef-figure--sticky { position: sticky; top: calc(var(--vef-chrome, 88px) + 24px); }
.vef-prose figure:not(.wp-block-pullquote):has(> figcaption) { position: relative; margin-bottom: 2.4em; }
/* The classic editor writes the image's own pixel width onto the figure as
   an inline style — 1200px inside a 610px column, with a 663px original
   stretched to fill it. Only !important reaches an inline style, and this is
   what that is for. */
.vef-prose figure.wp-caption { width: auto !important; max-width: 100%; }
.vef-prose figure:not(.wp-block-pullquote) > img { border-radius: var(--vef-radius-md); }
:is(.vef-figure__caption, .vef-prose figure:not(.wp-block-pullquote) > figcaption) {
	position: absolute; bottom: 28px; left: -28px; z-index: 1; max-width: min(360px, 80%);
	margin: 0; padding: 22px 26px; border-radius: var(--vef-radius-md);
	background: var(--vef-primary); color: var(--vef-on-primary); font-size: 15px; line-height: 1.55; text-align: left;
	box-shadow: 0 18px 40px -20px rgba(0, 0, 0, calc(.5 * var(--vef-shade)));
}
:is(.vef-figure--right .vef-figure__caption, .vef-prose figure.is-style-caption-right > figcaption) { left: auto; right: -28px; }
:is(.vef-figure__caption, .vef-prose figure:not(.wp-block-pullquote) > figcaption) :is(b, strong) { color: var(--vef-on-primary-strong); }
:is(.vef-figure__caption, .vef-prose figure:not(.wp-block-pullquote) > figcaption) :is(h3, h4, h5) { margin: 0 0 6px; color: var(--vef-on-primary-strong); line-height: 1.25; }
:is(.vef-figure__caption, .vef-prose figure:not(.wp-block-pullquote) > figcaption) h3 { font-size: 22px; }
:is(.vef-figure__caption, .vef-prose figure:not(.wp-block-pullquote) > figcaption) h4 { font-size: 18px; }
:is(.vef-figure__caption, .vef-prose figure:not(.wp-block-pullquote) > figcaption) h5 { font-size: 15px; letter-spacing: .1em; text-transform: uppercase; }
:is(.vef-figure__caption, .vef-prose figure:not(.wp-block-pullquote) > figcaption) p { margin: 0 0 .5em; }
:is(.vef-figure__caption, .vef-prose figure:not(.wp-block-pullquote) > figcaption) > :last-child { margin-bottom: 0; }
/* A team photo with a caption lets the box hang outside its frame. */
.vef-member__photo--caption { overflow: visible; background: none; }
.vef-member__photo--caption .vef-figure, .vef-member__photo--caption .vef-figure > img { height: 100%; }
.vef-member__photo--caption .vef-figure > img { object-fit: cover; border-radius: var(--vef-radius-md); }
@media (max-width: 900px) {
	.vef-figure--sticky { position: relative; top: auto; }
	/* Phones: the box sits BELOW the photo, lapping 28px over its bottom edge.
	   It used to be absolute with bottom:-28px, which pins the box's bottom
	   and lets it grow upward — fine for a line or two, and at four lines it
	   had covered both faces in the photo it was describing. In flow with a
	   negative top margin, the overlap is 28px whatever the caption says. */
	.vef-figure:has(> .vef-figure__caption), .vef-prose figure:not(.wp-block-pullquote):has(> figcaption) { margin-bottom: 0; }
	:is(.vef-figure__caption, .vef-prose figure:not(.wp-block-pullquote) > figcaption) {
		position: relative; z-index: 1;
		left: auto !important; right: auto !important; bottom: auto;
		margin: -28px 16px 0; max-width: none;
	}
	.vef-member__photo--caption { aspect-ratio: auto; }
	.vef-member__photo--caption .vef-figure > img { height: auto; aspect-ratio: 4 / 5; }
}

/* Credentials: a centered title between rules, then pill badges. */
.vef-home--badges { padding-block: clamp(48px, 6vw, 80px); }
.vef-badges__title {
	display: flex; align-items: center; gap: 24px; margin: 0 0 40px;
	color: var(--vef-ink); font-size: clamp(14px, 1.6vw, 18px); letter-spacing: .2em; text-align: center; text-transform: uppercase;
}
.vef-badges__title::before, .vef-badges__title::after { content: ""; flex: 1; border-top: 1px solid var(--vef-line); }
/* One number for the space between marks: the gap inside a track, and the
   gap across the seam where the looping copy follows the original. They have
   to agree or the join shows — which is exactly what happened when the gap
   went from 20px to 72px and the seam stayed on the track's old 10px
   padding, putting two badges half as far apart as the rest. */
.vef-badges { --vef-badge-gap: 20px; display: flex; justify-content: center; }
.vef-badges__track { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 24px 72px; margin: 0; padding: 0 var(--vef-gutter); list-style: none; }
.vef-badge {
	display: flex; align-items: center; gap: 16px; height: 100%;
	padding: 14px 28px 14px 14px; border: 1px solid var(--vef-line); border-radius: var(--vef-radius-pill);
	background: var(--vef-canvas); color: var(--vef-ink); text-decoration: none; white-space: nowrap;
}
a.vef-badge:hover { border-color: var(--vef-accent); color: var(--vef-ink); }
.vef-badge__icon { display: flex; align-items: center; justify-content: center; flex: none; width: 52px; height: 52px; border-radius: 50%; background: var(--vef-accent); color: var(--vef-on-accent, #fff); }
.vef-badge__body { display: flex; flex-direction: column; }
.vef-badge__body strong { font-size: 18px; font-weight: 600; line-height: 1.3; }
.vef-badge__body span { color: var(--vef-text); font-size: 12px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; }
/* A logo badge is just the logo. The pill — border, ground, padding — was
   chrome around a mark that already has its own shape and its own edge, and
   at 52px the logo was the smallest thing inside it. The gap on the track
   does the separating now that nothing else does. */
.vef-badge--logo { padding: 12px 32px; }
.vef-badge--logo img { display: block; width: auto; max-width: 160px; height: 52px; object-fit: contain; }

/* "Logos only" (Global → Credentials → How the row looks). A seal already
   has its own shape and its own edge, so the card around it is chrome
   wrapped around chrome, and at 52px the artwork was the smallest thing
   inside it. Here it is the artwork and nothing else, with the gap doing the
   separating that the padding used to do.
   A credential with no logo keeps its card: dropping it would make a missing
   image look like a missing credential. */
.vef-badges--logos { --vef-badge-gap: 72px; }
.vef-badges--logos .vef-badge--logo { padding: 0; border: 0; border-radius: 0; background: none; }
.vef-badges--logos .vef-badge--logo img { max-width: 220px; height: clamp(80px, 9vw, 120px); }
.vef-badges--logos a.vef-badge--logo { transition: opacity .15s ease; }
.vef-badges--logos a.vef-badge--logo:hover { opacity: .72; }

/* Five or more: one row gliding left, faded at the edges. */
.vef-badges--loop {
	justify-content: flex-start; overflow: hidden;
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
	mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.vef-badges--loop .vef-badges__track { flex: none; flex-wrap: nowrap; padding: 0 var(--vef-badge-gap) 0 0; animation: vef-badges 40s linear infinite; }
.vef-badges--loop:hover .vef-badges__track { animation-play-state: paused; }
@keyframes vef-badges { to { transform: translateX(-100%); } }
@media (prefers-reduced-motion: reduce) {
	.vef-badges--loop { overflow-x: auto; }
	.vef-badges--loop .vef-badges__track { animation: none; }
	.vef-badges--loop .vef-badges__track[aria-hidden] { display: none; }
}

.vef-home-faqs { max-width: calc(var(--vef-rail-narrow) + 2 * var(--vef-gutter) + 160px); }

@media (max-width: 1023px) {
	.vef-gallery { aspect-ratio: 4 / 3; gap: 10px; }
	.vef-process--image { grid-template-columns: minmax(0, 1fr); }
	.vef-process__image { max-width: 420px; }
	.vef-process__image img { height: auto; aspect-ratio: 4 / 5; }
	.vef-process--image .vef-step { padding-bottom: 36px; }
	.vef-stats { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; row-gap: 48px; }
	.vef-stat:nth-child(odd) { border-left: 0; }
}
@media (max-width: 900px) {
	.vef-about { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
	/* Phones: two even columns; an odd count opens with one full-width photo. */
	.vef-gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: none; grid-auto-rows: 42vw; gap: 8px; aspect-ratio: auto; }
	.vef-gallery li { grid-area: auto; }
	.vef-gallery--1 li:first-child, .vef-gallery--3 li:first-child, .vef-gallery--5 li:first-child,
	.vef-gallery--7 li:first-child, .vef-gallery--9 li:first-child { grid-column: 1 / -1; }
	.vef-lightbox img { max-width: calc(100vw - 24px); }
	.vef-lightbox__prev, .vef-lightbox__next { top: auto; bottom: 20px; margin: 0; }
	.vef-step { gap: 18px; }
	.vef-step__n { width: 44px; height: 44px; font-size: 14px; }
	.vef-step:not(:last-child)::before { left: 21px; top: 44px; }
	.vef-process__cta { margin-left: 62px; }
	.vef-step__title { margin-top: 8px; font-size: 18px; }
	.vef-badge__body strong { font-size: 16px; }
	.vef-badges__title { gap: 12px; }
}

/* Reviews band ---------------------------------------------------------- */

.vef-reviews { padding-block: clamp(56px, 8vw, 104px); background: var(--vef-canvas); }
.vef-reviews--alt { background: var(--vef-mute); }
.vef-reviews--alt .vef-review { background: var(--vef-canvas); }
.vef-reviews__head {
	display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 24px 40px;
	margin-bottom: 40px;
}
.vef-reviews .vef-eyebrow { margin-bottom: 12px; }
.vef-reviews__title { margin: 0; font-size: clamp(28px, 3.6vw, 40px); letter-spacing: -.01em; }

.vef-stars { display: inline-flex; gap: 2px; color: #f5b301; }
.vef-stars svg { width: 18px; height: 18px; }
.vef-rating { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin: 16px 0 0; font-size: 15px; }
.vef-rating strong { color: var(--vef-ink); font-size: 17px; }
.vef-rating__g { width: 20px; height: 20px; }

.vef-reviews__cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; margin: 0; padding: 0; list-style: none; }
.vef-review {
	display: flex; flex-direction: column; gap: 16px;
	padding: 28px; border-radius: var(--vef-radius-md); background: var(--vef-mute);
}
.vef-review__text { flex: 1; margin: 0; color: var(--vef-ink); font-size: 16px; line-height: 1.65; }
.vef-review__text p { margin: 0 0 .8em; }
.vef-review__text p:last-child { margin: 0; }
.vef-review__who { display: flex; align-items: center; gap: 12px; margin: 0; }
.vef-review__avatar {
	display: flex; align-items: center; justify-content: center; flex: none;
	width: 40px; height: 40px; border-radius: 50%;
	background: var(--vef-primary); color: var(--vef-on-primary-strong); font-weight: 600;
}
.vef-review__name { flex: 1; color: var(--vef-ink); font-weight: 600; }
.vef-review__g { width: 20px; height: 20px; flex: none; }

/* Trustindex: its cards carry 8px side padding; pull them out to the rail. */
.vef-reviews__widget .ti-widget .ti-reviews-container-wrapper { margin-left: -8px !important; margin-right: -8px !important; }


@media (max-width: 1023px) {
	.vef-reviews__cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
	.vef-reviews__cards { grid-template-columns: minmax(0, 1fr); }
	.vef-reviews__head .vef-button { width: 100%; }
}

/* Pre-footer call to action ------------------------------------------- */

.vef-prefooter { padding-block: clamp(56px, 8vw, 96px); background: var(--vef-mute); text-align: center; }
/*
 * Two sections on the same ground (white after white, mute after mute) get a
 * thin rule between them, wherever they meet: inside the content, and the
 * last section against the call-to-action band (mute). The anchor spacer
 * (core.js) doesn't count as a section.
 */
:is(.vef-home--alt, .vef-reviews--alt, .vef-contact) + :is(.vef-home--alt, .vef-reviews--alt, .vef-contact),
:is(.vef-single, .vef-listing, .vef-home:not(.vef-home--alt, .vef-home--stats), .vef-reviews:not(.vef-reviews--alt)) + :is(.vef-single, .vef-listing, .vef-home:not(.vef-home--alt, .vef-home--stats), .vef-reviews:not(.vef-reviews--alt)) { border-top: 1px solid var(--vef-line); }
.vef-main:has(> :nth-last-child(1 of :not(.vef-anchor-space)):is(.vef-home--alt, .vef-reviews--alt, .vef-contact)) + .vef-prefooter { border-top: 1px solid var(--vef-line); }
/* The spotlight band sits outside the content, on the page's own ground: it
   needs the rule when the content ends on that ground too (a white section,
   or the related cards at the foot of a service). */
.vef-main:has(> :nth-last-child(1 of :not(.vef-anchor-space)):is(.vef-single, .vef-listing, .vef-related, .vef-home:not(.vef-home--alt, .vef-home--stats), .vef-reviews:not(.vef-reviews--alt))) + .vef-spotlight { border-top: 1px solid var(--vef-line); }
.vef-prefooter h2 { font-size: clamp(28px, 4vw, 36px); letter-spacing: -.01em; }
.vef-prefooter p { margin: 0 auto; max-width: 560px; font-size: 18px; }
.vef-prefooter__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 16px; margin-top: 32px; }

/* Footer ---------------------------------------------------------------- */

.vef-footer { padding-top: clamp(56px, 7vw, 88px); background: var(--vef-footer, var(--vef-primary)); color: var(--vef-on-primary); font-size: 15px; }
.vef-footer a { color: var(--vef-on-primary); text-decoration: none; }
.vef-footer a:hover { color: var(--vef-on-primary-strong); }
.vef-footer p { margin: 0 0 16px; }

.vef-footer__cols {
	display: grid; gap: 48px 40px;
	grid-template-columns: 1.4fr 1fr 1.2fr 1.2fr;
	padding-bottom: 56px;
}
.vef-footer__col--brand .vef-brand { margin-bottom: 20px; color: var(--vef-on-primary-strong); }
.vef-footer__col--brand .vef-brand__logo { max-height: 72px; }
.vef-footer__credit { font-size: 14px; }
.vef-footer__credit a { color: var(--vef-on-primary-strong); }
/* The About link is not a signature, it is a way further into the site, so
   it wears what every other footer link wears: muted until the pointer is on
   it. The arrow nudges the way a card's "Read more" does, which is the same
   gesture doing the same job. */
.vef-footer__credit--about a { display: inline-flex; align-items: center; gap: 8px; color: var(--vef-on-primary); }
.vef-footer__credit--about a:hover { color: var(--vef-on-primary-strong); }
.vef-footer__credit--about .vef-icon { width: 16px; height: 16px; transition: transform .15s ease; }
.vef-footer__credit--about a:hover .vef-icon { transform: translateX(3px); }

.vef-social { display: flex; flex-wrap: wrap; gap: 12px; margin: 28px 0 0; padding: 0; list-style: none; }
.vef-social a {
	display: flex; align-items: center; justify-content: center;
	width: 44px; height: 44px; border-radius: 50%;
	background: var(--vef-line-primary); color: var(--vef-on-primary-strong);
	transition: background-color .15s ease;
}
/* The footer's accent is --vef-footer-accent where the accent would vanish
   on the footer (a charcoal accent on a charcoal footer): setup.php picks
   the first of accent, primary or the footer's type that reads on it. */
.vef-social a:hover, .vef-social a:focus-visible { background: var(--vef-footer-accent, var(--vef-accent)); color: var(--vef-footer-on-accent, var(--vef-on-accent, #fff)); }

.vef-footer__title {
	margin: 0 0 20px;
	color: var(--vef-footer-accent, var(--vef-accent)); font-size: 13px; letter-spacing: .14em; text-transform: uppercase;
}
.vef-footer__list { margin: 0; padding: 0; list-style: none; }
.vef-footer__list li + li { margin-top: 12px; }
.vef-footer__contact li { display: flex; gap: 12px; }
.vef-footer__contact .vef-icon { margin-top: 3px; color: var(--vef-footer-accent, var(--vef-accent)); }
.vef-footer address { font-style: normal; }

.vef-hours { margin: 0; }
.vef-hours div { display: flex; justify-content: space-between; gap: 16px; padding-block: 10px; border-bottom: 1px solid var(--vef-line); }
.vef-footer .vef-hours div { border-color: var(--vef-line-primary); }
/* The rule between rows, not under the last one: there is nothing below it
   to divide, and in the location card it reads as a stray line above the
   buttons. */
.vef-hours div:last-child { border-bottom: 0; }
.vef-hours div:first-child { padding-top: 0; }
.vef-hours dt { color: var(--vef-ink); }
.vef-footer .vef-hours dt { color: var(--vef-on-primary-strong); }
.vef-hours dd { margin: 0; text-align: right; }

.vef-footer__bottom {
	display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 32px;
	padding-block: 24px; border-top: 1px solid var(--vef-line-primary); font-size: 14px;
}
.vef-footer__bottom p { margin: 0; }
.vef-footer__legal { display: flex; flex-wrap: wrap; gap: 8px 28px; margin: 0; padding: 0; list-style: none; }

@media (max-width: 1023px) {
	.vef-footer__cols { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 640px) {
	.vef-footer__cols { grid-template-columns: 1fr; gap: 40px; }
	.vef-footer__bottom { flex-direction: column; align-items: flex-start; }
	.vef-prefooter__actions .vef-button { width: 100%; }
}

/* HTML sitemap ([vef_sitemap]): groups in columns, nested pages indented. */
.vef-prose .vef-sitemap { columns: 2 280px; column-gap: 48px; }
.vef-prose .vef-sitemap__group { break-inside: avoid; margin: 0 0 2em; }
.vef-prose .vef-sitemap h2 { margin: 0 0 .5em; font-size: 22px; }
.vef-prose .vef-sitemap h2 a { color: var(--vef-ink); text-decoration: none; }
.vef-prose .vef-sitemap h2 a:hover { color: var(--vef-accent); }
.vef-prose .vef-sitemap ul { margin: 0; }
.vef-prose .vef-sitemap ul ul { margin-top: .45em; }

/* Load more: the button under a list that reveals the next few. */
.vef-more { display: flex; justify-content: center; margin-top: clamp(28px, 3vw, 40px); }
.vef-more[hidden] { display: none; }
/* Once everything is out the button says so and stops being a button. */
.vef-more .vef-button[disabled] { cursor: default; opacity: .55; }
.vef-more .vef-button[disabled]:hover { background: var(--vef-canvas); color: var(--vef-ink); }

/* Spotlight band (Global → Spotlight band) ------------------------------
   A muted panel on the page's own ground, so it reads as its own thing
   whether the band above it is canvas (a gallery) or a page's content, and
   never melts into the muted closing call to action below it. */
.vef-spotlight { padding-block: clamp(48px, 6vw, 88px); }
.vef-spotlight__panel {
	display: grid; grid-template-columns: minmax(0, 1fr); gap: 40px clamp(40px, 6vw, 88px); align-items: center;
	padding: clamp(28px, 4vw, 56px); border-radius: var(--vef-radius-md); background: var(--vef-mute);
}
.vef-spotlight__panel--image { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.vef-spotlight .vef-eyebrow { margin-bottom: 12px; }
.vef-spotlight__title { margin: 0; font-size: clamp(28px, 3.2vw, 40px); line-height: 1.15; }
.vef-spotlight__text { margin: 16px 0 0; font-size: 18px; }
.vef-spotlight__items { display: grid; gap: 18px; margin: 28px 0 0; padding: 0; list-style: none; }
.vef-spotlight__item { display: flex; gap: 14px; align-items: flex-start; }
.vef-spotlight__icon {
	display: flex; flex: none; align-items: center; justify-content: center;
	width: 44px; height: 44px; border-radius: var(--vef-radius); background: var(--vef-canvas); color: var(--vef-primary);
}
.vef-primary-light .vef-spotlight__icon { color: color-mix(in srgb, var(--vef-primary) 60%, var(--vef-ink)); }
.vef-spotlight__icon .vef-icon { width: 22px; height: 22px; }
.vef-spotlight__item-title { display: block; color: var(--vef-ink); font-size: 17px; }
.vef-spotlight__item-text { display: block; margin-top: 2px; font-size: 15px; }
.vef-spotlight .vef-button { margin-top: 32px; }
.vef-spotlight__image img { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--vef-radius-md); }
@media (max-width: 900px) {
	.vef-spotlight__panel--image { grid-template-columns: minmax(0, 1fr); }
	.vef-spotlight__image { order: -1; }
}

