/* ============================================================
   Empire Vein & Vascular 2026 — theme chrome (header, footer,
   blog article frame). Everything derives from the design tokens
   (assets/css/tokens/, enqueued first as design.css). Page-body
   styling comes from the token layers and, later, the blocks.
   `.evw-` = WordPress theme chrome, distinct from the design
   system's `.ev-` classes so the two never collide.
   ============================================================ */

.evw-wrap { max-width: var(--container-max); margin: 0 auto; padding-inline: var(--gutter); }
.evw-main { display: block; }

/* ── Utility bar ── */
/* The utility bar sits ABOVE the nav row in every mode, not just on desktop.
   The language dropdown lives in this bar and opens downward across the row
   below it; .evw-header is position:sticky with z-index:50, so without this
   the nav row paints over the open panel and the switcher looks dead. */
/* ── Utility bar ──────────────────────────────────────────────────────────
   Two children, one alignment rule:

     desktop   [                              msg · phone · switcher ]
     phone     [ msg · phone                              switcher   ]

   Same DOM both times — only justify-content differs. The announcement that
   used to sit on the left is gone, and with it the wrapper, the phone pulse
   and the three competing justify-content rules that had accumulated around
   them across four media queries. */
.evw-utility { background: var(--surface-dark); color: var(--text-on-dark); position: relative; z-index: 51; }
.evw-utility-row { min-height: 40px; display: flex; align-items: center; justify-content: flex-end; gap: 16px; }

/* margin-right:auto rather than space-between on the row: the row has three
   children now and space-between would strand the quick links in the middle
   instead of grouping them with the switcher on the right. */
.evw-utility-cta { display: inline-flex; align-items: center; text-decoration: none; min-width: 0; margin-right: auto; }

.evw-utility-links { display: inline-flex; align-items: center; gap: 18px; flex-shrink: 0; }
.evw-utility-link {
	display: inline-flex; align-items: center; gap: 5px;
	padding: 1px 6px; line-height: 1.2;
	font-size: var(--text-sm); font-weight: 500;
	color: var(--text-on-dark); text-decoration: none; white-space: nowrap;
	transition: color .18s var(--ease-out);
}
.evw-utility-link:hover { color: var(--ev-amber-400); text-decoration: none; }
.evw-utility-cta:hover { text-decoration: none; }
.evw-utility-cta:hover .evw-utility-phone { color: var(--ev-amber-400); }
.evw-utility-phone { color: var(--text-on-dark); font-size: var(--text-sm); font-weight: 700; white-space: nowrap; transition: color .18s var(--ease-out); }

/* Both phases occupy the same grid cell, so the box is as wide as the wider
   PAIR and nothing reflows as they swap. justify-items pins them to the side
   the bar is anchored to, which is what keeps the number from wandering.
   One keyframe drives both; the second runs at a negative delay of half the
   cycle, which makes them opposite without a second set of keyframes to keep
   in sync. */
/* start, not end: the comment above is the rule — the phases pin to the side
   the bar is anchored to. The CTA moved to the left of the row, so anchoring
   them right would leave the number drifting as the two phrases swap. */
.evw-utility-msg { display: inline-grid; justify-items: start; min-width: 0; }
.evw-utility-phase { display: inline-flex; align-items: baseline; gap: 8px; white-space: nowrap; }
.evw-utility-msg > span {
	grid-area: 1 / 1;
	/* Sized to the space that is actually left, not to a breakpoint.
	   The number (~102px), the switcher (~50px) and the gaps (16px) are
	   fixed, so the message gets viewport - 200px. At 360px that is 160px and
	   the longer phrase then ("We can check your coverage!") needed 197px at
	   14px — hence the 11px floor. 3.05vw tracks the leftover as it grows and
	   reaches the 14px ceiling around 460px, above which there is room to
	   spare. The copy is shorter since 2026-09-25 but the dot now takes 14-16px
	   of the row, so the floor stays (see the 400px and 359px rules below). */
	font-size: clamp(11px, 3.05vw, var(--text-sm)); color: var(--text-on-dark); white-space: nowrap;
	overflow: hidden; text-overflow: ellipsis;
	animation: evUtilityMsg 13s ease-in-out infinite;
}
.evw-utility-msg > span:nth-child(2) { animation-delay: -6.5s; }
/* A hand-off, not a cross-fade. Each phase is visible for a little under half
   the cycle and fully out before the other arrives, so the two never overlap at
   50% opacity — which on phones, where the phases are anchored left and their
   numbers sit at different x, would read as two faint phone numbers at once. */
@keyframes evUtilityMsg {
	0% { opacity: 0; }
	4%, 44% { opacity: 1; }
	50%, 100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
	/* No cycling: show the first phrase and retire the second, rather than
	   leaving two lines stacked in one cell at full opacity. */
	.evw-utility-msg > span { animation: none; }
	.evw-utility-msg > span:nth-child(2) { display: none; }
}

/* "We're here" dot (2026-09-25, the practice asked for a little glowing green
   dot by "Call us…", as if the line were online now). Always on, no schedule:
   the practice's call. It sits before the two phases, outside the fade, so it
   never blinks with them. A steady glow, plus a soft halo that swells and
   fades every 2.8s: transform and opacity on a pseudo-element only, so it runs
   on the compositor and never moves the text. At 2.2x the halo stays clear of
   the first letter on phones (2.6x came within 1px of it). Reduced motion
   keeps the steady glow alone.
   The green is scoped here rather than added to tokens/colors.css, which would
   put it in the block editor's palette; --ev-success (#15803d) is too dark to
   read as a light on the plum bar. Measured 7.5:1 against the bar. */
.evw-utility-cta { gap: 8px; }
.evw-utility-live {
	--evw-live: #22c55e;
	position: relative; flex-shrink: 0;
	width: 8px; height: 8px; border-radius: 50%;
	background: var(--evw-live);
	box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.22), 0 0 8px 1px rgba(34, 197, 94, 0.6);
}
.evw-utility-live::after {
	content: ""; position: absolute; inset: 0; border-radius: inherit;
	background: var(--evw-live);
	opacity: 0;
	animation: evUtilityLive 2.8s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;
}
@keyframes evUtilityLive {
	0% { transform: scale(1); opacity: 0.5; }
	65%, 100% { transform: scale(2.2); opacity: 0; }
}
/* Keyboard focus: the ring clears the glow by 4px, and the halo rests so it
   never tints the ring (it sat flush at the default 2px offset). */
.evw-utility-cta:focus-visible { outline-offset: 4px; }
.evw-utility-cta:focus-visible .evw-utility-live::after { animation: none; }
@media (prefers-reduced-motion: reduce) {
	.evw-utility-live::after { animation: none; }
}
/* Windows High Contrast: forced colours painted the dot the bar's own colour,
   leaving an empty 16px indent. It keeps a solid dot in the text colour. */
@media (forced-colors: active) {
	.evw-utility-live { forced-color-adjust: none; background: CanvasText; box-shadow: none; }
	.evw-utility-live::after { display: none; }
}

/* A shrink path, so the line can never paint over its neighbours. Each phase
   is sized to its whole nowrap line, so when room ran out (Spanish at
   768-805px once the dot arrived, or text spacing and enlarged text) it
   overflowed onto the quick links and the switcher instead of truncating.
   Now the phase is capped at the room it has, the words ellipsize first and
   the number always stays whole. Where the line fits, nothing changes. */
.evw-utility-phase { max-width: 100%; }
.evw-utility-lead { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.evw-utility-phone { flex-shrink: 0; }

/* Language switcher — a <details> dropdown: flag + code in the bar, the full
   list below it. z-index clears the sticky header (50); the utility bar itself
   does not stick, so without it the panel would slide under the nav. */
.evw-lang { position: relative; flex-shrink: 0; z-index: 60; }
.evw-lang > summary {
	display: inline-flex; align-items: center; gap: 6px;
	min-height: 32px; padding: 0 8px;
	list-style: none; cursor: pointer;
	font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 700;
	letter-spacing: 0.06em; line-height: 1;
	color: rgba(255, 255, 255, 0.78);
	border-radius: var(--radius-full);
	transition: color .18s var(--ease-out), background .18s var(--ease-out);
}
/* Both are needed: WebKit draws a ::-webkit-details-marker, everything else
   uses the list-item display type. */
.evw-lang > summary::-webkit-details-marker { display: none; }
.evw-lang > summary::marker { content: ""; }
.evw-lang > summary:hover { color: var(--ev-white); background: rgba(255, 255, 255, 0.10); }
.evw-lang > summary:focus-visible { outline: 2px solid var(--ev-amber-400); outline-offset: 2px; }
.evw-lang[open] > summary { color: var(--ev-white); background: rgba(255, 255, 255, 0.16); }
.evw-lang[open] .evw-lang-caret { transform: rotate(180deg); }
.evw-lang-caret { transition: transform .18s var(--ease-out); flex-shrink: 0; }
.evw-lang-flag { display: block; width: 18px; height: 12px; border-radius: 2px; flex-shrink: 0; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18); }

/* Explicit, rather than trusting the closed-<details> default.
   A closed <details> hides its non-summary children through a UA slot, and an
   ABSOLUTELY POSITIONED child is exactly the case engines have historically
   disagreed on. Measured here it is unpainted and not hit-testable, but it
   still reports a 210x94 box — near enough to ambiguous that a 94px white panel
   permanently over the header is not worth risking on one browser's behaviour. */
.evw-lang:not([open]) .evw-lang-menu { display: none; }

.evw-lang-menu {
	position: absolute; top: calc(100% + 8px); right: 0; z-index: 1;
	min-width: 210px; margin: 0; padding: 6px;
	list-style: none;
	background: var(--ev-white);
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-lg);
}
.evw-lang-menu li { margin: 0; }
.evw-lang-menu a {
	display: flex; align-items: center; gap: 10px;
	min-height: 40px; padding: 0 10px;
	font-size: var(--text-sm); font-weight: 600; line-height: 1.2;
	color: var(--text-heading); text-decoration: none;
	border-radius: var(--radius);
}
.evw-lang-menu a:hover { background: var(--ev-purple-50); text-decoration: none; }
/* The current language is marked with a check as well as weight, so it is not
   colour alone doing the work. */
.evw-lang-menu a[aria-current="true"] { background: var(--ev-purple-50); }
.evw-lang-menu a[aria-current="true"]::after {
	content: "";
	width: 12px; height: 7px; margin-left: auto; flex-shrink: 0;
	border-left: 2px solid var(--primary); border-bottom: 2px solid var(--primary);
	transform: rotate(-45deg) translate(1px, -2px);
}

/* The announcement is hidden exactly where it would ellipsis, and not one pixel
   sooner. Measured with the switcher and phone in place: the line needs 482px
   and has 540px at 768 wide, 472px at 700. So 767px is the real cut-off — the
   first attempt hid it below 1024 and threw away 256px of perfectly good
   tablet. Below that the bar carries the language switcher and the phone
   number, which is what it is for on a phone. */
@media (max-width: 767px) {
	/* msg+phone hard left, switcher hard right.

	   Fitting the longer phrase is the whole problem at this width. Measured
	   at 375px: the row has 343px, and "We can check your coverage!" alone
	   wants 197px at 14px — with the number (110) and the switcher (74) and
	   the gaps, that is 405px, a 62px shortfall, so it was ellipsising to
	   "We can check your co…". Rather than cut the sentence, the bar gives the
	   space back:

	     switcher drops its "EN" label   -24px   (the flag says it, and the
	                                              open menu names both in full)
	     message scales fluidly          -28px or more
	     number 14px -> 13px              -8px
	     gaps 16/8 -> 10/6                -8px

	   That is 68px against a 62px shortfall, so both phrases render whole. */
	/* The quick links move into the drawer here; this row is already at its
	   floor fitting the message, the number and the switcher into ~360px. */
	.evw-utility-links { display: none; }
	.evw-utility-row { justify-content: space-between; gap: 10px; }
	.evw-utility-msg { justify-items: start; }
	.evw-utility-cta { gap: 6px; }
	.evw-utility-phone { font-size: 13px; }
	.evw-lang-code { display: none; }

	/* Homepage hero tiles: the copy column was being squeezed to ~137px.
	   The tile art is a full-bleed photo behind the text, so the padding only
	   has to clear the subject, not the whole image — 52% of a 343px tile is
	   178px of padding for 137px of text, and "Relief from varicose veins,
	   spider veins, and heavy, aching legs." broke into four ragged lines.
	   24% gives the copy ~220px, which is what drops Knee Pain's longer line
	   from four wrapped lines to three. The copy crosses the photo slightly at
	   this width, which the practice signed off on.

	   Both tiles read it. They are MIRRORED — Vein Care has its photo on the
	   left and pads left, Knee Pain has it on the right and pads right — so the
	   one variable is applied to whichever side that tile reserves. Widening
	   only padding-left, as a first pass did, fixed Vein Care and left Knee
	   Pain exactly as cramped as before. */
	/* ── Phone geometry, derived from where the ARTWORK actually is ──────
	   Both PNGs are transparent cut-outs, so the image BOX is not the picture.
	   Measured from the files: the legs occupy 8-83% of home-vein-legs.png and
	   the knee 15-99% of home-knee-pain.png, both 512x462.

	   object-fit:cover on a tall box scales by height, so the scaled width is
	   1.108 x the tile height and the crop is anchored to the far edge. That
	   makes the empty margin beside the subject a function of HEIGHT, not of
	   the image width: 0.188 x height on the vein tile, 0.166 x height on the
	   knee one. The copy only has to clear the subject, not the box, so:

	       padding = image-width - that margin + a small gap

	   At 48% and 300px tall that is calc(48% - 44px) and calc(48% - 42px) —
	   the percentages track the tile so this holds from 320px to 767px rather
	   than at one width. The knee side is 6px deeper on purpose: its subject
	   runs 16 points further into its frame, and the practice asked for that
	   line to be a little narrower.

	   Previously a flat 24%: the copy started 40px INSIDE the legs on a 375px
	   screen, which is the overlap the practice flagged. */
	/* The image keeps its DESKTOP width here on purpose.

	   A first pass narrowed it to 38% to stop the copy crossing the artwork.
	   That cleared the overlap and was the wrong fix: object-fit:cover on a tall
	   box crops rather than scales, so a narrower box does not shrink the legs,
	   it slices them. At 38% only the rightmost quarter of the artwork survived
	   and the affected leg was mostly off-frame. Back to 60%, which shows about
	   half of it, and the copy moves right instead. */
	/* 48%, chosen by scanning 44-60% and measuring all three things that trade
	   against each other at 375px:

	         img    artwork shown    copy width    tile height
	         44%         33%           195 (3 ln)      300
	         48%         38%           182 (3 ln)      300
	         52%         43%           170 (4 ln)      319
	         60%         44%           145 (5 ln)      344

	   Past 52% the artwork stops improving and only the tile grows: narrower
	   copy wraps to more lines, the tile gets taller, and a taller box crops the
	   image harder, which is a loop that costs height without showing more leg.
	   48% holds both tiles at the 300px floor and still shows half again as much
	   artwork as the 38% this replaced. */
	.ev-hero-bigtiles > a { --ev-tile-img: 48%; --ev-tile-h: 300px; }
	.ev-hero-bigtiles > a > div { --ev-tile-pad: calc(48% - 44px); }
	.ev-hero-bigtiles > a:nth-child(2) > div { --ev-tile-pad: calc(48% - 42px); }

	/* 380px -> 300px. The copy needs 174-263px including padding depending on
	   how the line breaks, so 380px was leaving up to 180px of empty tile on
	   every phone, twice over. min-height, so a tile that needs more still
	   takes it — at 320px the longer line pushes it back to ~319px by itself. */
	.ev-hero-bigtiles > a, .ev-hero-bigtiles > a > div { min-height: var(--ev-tile-h); }
}

/* Spanish, 768-819px: the quick links are back at 768, and with the green dot
   in front (16px) "Llámanos cuando quieras" plus the number ran 5-19px into
   "Blog de Empire Vein" (measured 2026-09-25; English has 30px to spare). The
   phone row's economies close it: the switcher shows its flag only, tighter
   gaps, the number at 13px. Measured room left at 768: 13-20px. */
@media (min-width: 768px) and (max-width: 819px) {
	html:lang(es) .evw-lang-code { display: none; }
	html:lang(es) .evw-utility-row { gap: 10px; }
	html:lang(es) .evw-utility-cta { gap: 6px; }
	html:lang(es) .evw-utility-phone { font-size: 13px; }
}

/* Below 360px the bar drops the words and keeps the dot, the number and the
   switcher, which is all it really owes the reader; a line cut mid-word is
   worse than none. Measured 2026-09-25 with the dot and the current copy
   ("Check your insurance" / "Call us anytime", "Checa tu seguro" / "Llámanos
   cuando quieras"): at 360 the tightest phrase, Spanish phase 2, has 25px to
   spare (English 45px); at 320 the Spanish no longer fits (-15px). The
   number, the switcher and the gaps are fixed, so the words get what is left. */
/* 360-400px is the tightest band where the message still fits whole. The last
   pixels come from the gaps and one point off the number rather than from the
   text, which is already at its 11px floor. */
@media (max-width: 400px) {
	.evw-utility-row { gap: 6px; }
	.evw-utility-phase { gap: 5px; }
	.evw-utility-phone { font-size: 12px; }
}

@media (max-width: 359px) {
	/* Too narrow for any phrase. The number stays — it is the point of the bar
	   — so only the lead-in goes, and the cycle stops on one phase rather than
	   fading the number in and out on its own. */
	.evw-utility-lead { display: none; }
	.evw-utility-msg > span { animation: none; }
	.evw-utility-msg > span:nth-child(2) { display: none; }

}

:root { --header-h: 68px; }

/* ── Header ── */
.evw-header { background: var(--gradient-nav); position: sticky; top: 0; z-index: 50; box-shadow: 0 10px 30px rgba(16, 4, 28, 0.30); }
.evw-header-row { height: 68px; display: flex; align-items: center; gap: 18px; justify-content: space-between; }
.evw-logo { display: flex; align-items: center; flex-shrink: 0; }
/* The wordmark, at the size the design actually specifies.

   layout.jsx's Logo component renders `height: size * 1.85`, and the desktop
   header passes size:34 — so the design is 63px tall, not 34px. The port
   read the 34 as pixels and shipped the logo at 54% of its intended size,
   which is why it looked so much smaller here than in the local build.
   The mobile header passes size:25, i.e. 46px.

   --evw-logo-h carries it so the header row and this stay in step. */
.evw-logo { --evw-logo-h: 46px; }
.evw-logo img { display: block; height: var(--evw-logo-h); width: auto; }
/* gap:0 and no wrapping, matching the prototype. The theme had gap:4px and
   flex-wrap:wrap, which at 1280px pushed "Locations" onto a second row and
   made the nav 78px tall inside a 68px header row. */
.evw-nav { display: flex; align-items: center; gap: 0; flex-wrap: nowrap; }
/* Bar links only — NOT every link in the nav. The menus below are full of
   <a>, and a bare `.evw-nav a` would paint them white on white and outrank
   their own class rules. Every bar link carries .evw-nav-link. */
.evw-nav .evw-nav-link { padding: 9px 14px; line-height: 1.2; font-size: var(--text-base); font-weight: 500; color: #fff; text-decoration: none; white-space: nowrap; transition: color .18s var(--ease-out); }
.evw-nav .evw-nav-link:hover { color: var(--ev-amber-400); text-decoration: none; }

/* ── Mobile drawer ────────────────────────────────────────────────────────
   One <details>: the <summary> is the hamburger, the panel slides in from
   the right, and nested <details> are the accordion rows. Everything below
   is presentation — opening, expanding and navigating all work with
   27-drawer.js absent.

   The panel and scrim must be display:block unconditionally. A closed
   <details> hides its non-summary children, and a hidden element cannot
   transition, so the slide is driven by transform + visibility instead. */
.evw-drawer { display: none; }                 /* desktop: the bar is the menu */

/* THE PANEL HAS TO OUTRANK THE BAR ABOVE IT.

   The drawer lives inside <header>, and on phones .evw-header is z-index 50
   while .evw-utility is 51 — both inside .evw-chrome. So the panel's
   z-index 61 is resolved INSIDE the header's stacking context and loses to a
   bar with a lower number, because that bar is a sibling one level up. The
   top 40px of the panel therefore rendered under the utility bar, which is
   exactly where the close X sits.

   Raising the header while the drawer is open lifts the whole subtree —
   scrim included, so the scrim dims the utility bar too, which is what a
   modal should do. :has() keeps it in CSS, so it still holds with the island
   absent, like the rest of the drawer. */
.evw-header:has(.evw-drawer[open]) { z-index: 60; }
.evw-drawer > .evw-drawer-scrim,
.evw-drawer > .evw-drawer-panel { display: block; }
.evw-drawer summary::-webkit-details-marker { display: none; }
.evw-drawer summary { list-style: none; }

.evw-drawer-btn {
	display: inline-flex; align-items: center; justify-content: center;
	width: 44px; height: 44px; flex-shrink: 0;
	cursor: pointer; border-radius: var(--radius-full);
	-webkit-tap-highlight-color: transparent;
}
.evw-drawer-bars { display: block; width: 22px; height: 16px; position: relative; }
.evw-drawer-bars i {
	position: absolute; left: 0; width: 100%; height: 2px; border-radius: 2px;
	background: var(--nav-fg, #fff);
	transition: transform .26s var(--ease-out), opacity .18s var(--ease-out), top .26s var(--ease-out);
}
.evw-drawer-bars i:nth-child(1) { top: 0; }
.evw-drawer-bars i:nth-child(2) { top: 7px; }
.evw-drawer-bars i:nth-child(3) { top: 14px; }

/* Open: the hamburger becomes the panel's close button, in place. It is the
   only control that can shut a <details> without JavaScript. */
/* The X carries NO chip. The drawer's section rows use a round filled chip
   for their +/- toggles, so a round filled chip on the close button read as
   another one of those rather than as "close". The 44px tap target stays;
   only the background goes. */
/* absolute, NOT fixed. Fixed pinned it to the viewport, so it followed the
   reader down the menu — the behaviour the practice asked to remove. An
   absolute child of the scrollport above scrolls with the content and simply
   leaves the screen, which is what a close button at the top of a long list
   should do. */
.evw-drawer[open] > .evw-drawer-btn {
	position: absolute; top: 14px; right: 14px; z-index: 62;
	background: none;
}
.evw-drawer[open] .evw-drawer-bars i { background: var(--text-heading); }
.evw-drawer[open] .evw-drawer-bars i:nth-child(1) { top: 7px; transform: rotate(45deg); }
.evw-drawer[open] .evw-drawer-bars i:nth-child(2) { opacity: 0; }
.evw-drawer[open] .evw-drawer-bars i:nth-child(3) { top: 7px; transform: rotate(-45deg); }

.evw-drawer-scrim {
	position: fixed; inset: 0; z-index: 60;
	background: rgba(28, 10, 42, 0.5);
	-webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
	opacity: 0; visibility: hidden;
	transition: opacity .28s var(--ease-out), visibility .28s var(--ease-out);
}
.evw-drawer[open] > .evw-drawer-scrim { opacity: 1; visibility: visible; }

/* The scrollport, when open. Deliberately NO transform here: the scrim is a
   fixed child, and a transformed ancestor would become its containing block
   and shrink it from the viewport to this 380px box. The slide stays on the
   panel, where it cannot do that. */
.evw-drawer[open] {
	position: fixed; top: 0; right: 0; bottom: 0; z-index: 61;
	width: min(88vw, 380px);
	display: block;
	overflow-y: auto; overscroll-behavior: contain;
}

.evw-drawer-panel {
	/* Fixed while CLOSED so it stays out of the header's flex row; in flow
	   once open, so the box above can scroll it. */
	position: fixed; top: 0; right: 0; bottom: 0; z-index: 61;
	width: min(88vw, 380px);
	/* A wash rather than flat white: the panel is the brand's own surface for
	   the length of the visit, and white read as unfinished beside it. Fixed to
	   the panel, not the content — the default background-attachment on a
	   scroll container keeps the gradient still while the list moves. */
	background: linear-gradient(168deg, var(--ev-purple-100) 0%, var(--ev-purple-50) 46%, var(--ev-purple-25) 100%);
	box-shadow: -18px 0 48px rgba(16, 4, 28, 0.28);
	display: flex; flex-direction: column;
	transform: translateX(100%); visibility: hidden;
	transition: transform .3s var(--ease-out), visibility .3s var(--ease-out);
}
.evw-drawer[open] > .evw-drawer-panel {
	position: relative; top: auto; right: auto; bottom: auto;
	width: 100%; min-height: 100%;
	transform: none; visibility: visible;
}

/* Top padding clears the close X, which is the hamburger pinned at
   top:14px and 44px tall. There is no panel header any more. */
.evw-drawer-body { padding: 72px 20px 32px; }

/* Below the menu, not above it. At the top the button, the free-screening
   line and the phone number all landed before the reader had seen a single
   link, which is what made the panel feel busy. */
.evw-drawer-book {
	display: flex; align-items: center; justify-content: center;
	margin-top: 26px;
	height: 50px; border-radius: var(--radius-full);
	background: var(--primary); color: var(--primary-foreground);
	font-size: var(--text-base); font-weight: 700; text-decoration: none;
	box-shadow: 0 8px 20px -10px rgba(73, 19, 111, 0.6);
}
.evw-drawer-book:hover { text-decoration: none; color: var(--primary-foreground); }
/* Sits under the Book button as a reason to press it, not as a heading. */
.evw-drawer-perk {
	margin: 10px 0 0; text-align: center;
	font-size: var(--text-sm); font-weight: 700; letter-spacing: 0.01em;
	color: var(--ev-amber-600, var(--ev-amber-500));
}

/* Directly under the perk line, as the quieter of the two ways to make
   contact. Its outline is the one hairline kept in the panel: it is the
   button's shape, not a divider between items. */
.evw-drawer-phone {
	display: flex; align-items: center; justify-content: center; gap: 9px;
	margin-top: 14px; padding: 13px; border-radius: var(--radius-lg);
	border: 1px solid var(--ev-purple-200); background: rgba(255, 255, 255, 0.55);
	color: var(--ev-purple-800);
	font-size: var(--text-base); font-weight: 700; text-decoration: none;
}
.evw-drawer-phone svg { color: var(--ev-amber-500); flex-shrink: 0; }
.evw-drawer-phone:hover { text-decoration: none; color: var(--ev-purple-800); }

.evw-drawer-nav { margin-top: 4px; }

/*
 * NO DIVIDERS. The rows were separated by a hairline under each section;
 * with eight of them stacked it read as a table. Spacing and the size step
 * down to the sub-items do the separating instead, which is why the rows
 * can afford to be smaller without running together.
 *
 * Two targets in one row: the label goes to the section, the + opens it.
 * Both sit inside the <summary>, so the + still works with no script — and
 * the label navigating makes the toggle it also fires irrelevant.
 *
 * Sized down from clamp(1.3rem, 5.6vw, 1.6rem). At display size eight rows
 * plus an open section pushed the actions well below the fold; this is still
 * comfortably bigger than body copy and reads as the primary navigation.
 */
.evw-drawer-row {
	display: flex; align-items: center; justify-content: space-between; gap: 10px;
	min-height: 52px; padding: 2px; cursor: pointer;
	font-size: clamp(1.05rem, 4.4vw, 1.25rem); font-weight: 800; letter-spacing: -0.015em;
	line-height: 1.15;
	color: var(--ev-purple-800); text-decoration: none;
}
.evw-drawer-row:hover { text-decoration: none; color: var(--ev-purple-800); }
/* The label fills the row so the whole left side is the link, not just the
   glyph-width of the words. */
.evw-drawer-label { flex: 1; min-width: 0; color: inherit; text-decoration: none; padding: 8px 0; }
.evw-drawer-label:hover { color: var(--ev-purple-500); text-decoration: none; }

/* + that becomes − when the section is open. */
.evw-drawer-plus {
	position: relative; flex-shrink: 0; width: 40px; height: 40px;
	display: inline-flex; align-items: center; justify-content: center;
	border-radius: var(--radius-full);
	background: rgba(255, 255, 255, 0.72);
}
.evw-drawer-plus i {
	position: absolute; width: 14px; height: 2px; border-radius: 2px;
	background: var(--ev-purple-700);
	transition: transform .22s var(--ease-out), opacity .22s var(--ease-out);
}
.evw-drawer-plus i:nth-child(2) { transform: rotate(90deg); }
.evw-drawer-sec[open] > .evw-drawer-row .evw-drawer-plus i:nth-child(2) { transform: rotate(0deg); opacity: 0; }
.evw-drawer-sub { padding: 0 0 12px; }

/*
 * Conditions / Treatments. The drawer lists every page a section owns, and
 * for the two pillars that have both kinds "Varicose Veins" and "VenaSeal"
 * are not the same sort of destination — a patient is looking for one or the
 * other. Set as a quiet label so it organises without competing with the
 * links it introduces.
 */
.evw-drawer-grouph {
	/* Outdented past its links, so the heading reads as the thing they hang
	   off rather than as another item in the same column. */
	margin: 14px 0 4px; padding-left: 0;
	font-size: 0.7rem; font-weight: 800; text-transform: uppercase;
	letter-spacing: 0.09em;
	/* A muted purple, not the slate grey this replaced: grey was the one
	   non-purple thing left in the panel. Purple-700 mixed most of the way
	   toward the wash — 5.3:1 on the palest end of the gradient, so it stays
	   legible at 11px, and clearly separate from the brighter #8c4cb0 that
	   marks the reader's current page. */
	color: #7c5499;
}

/* A hairline joining a heading to the links beneath it. The general sibling
   combinator does the scoping for free: headings only exist in the sections
   the generator split (Vein Care, Vascular Care), so only those links pick
   up the rule — the flat sections stay plain. */
.evw-drawer-grouph ~ .evw-drawer-item {
	border-left: 1px solid var(--ev-purple-200);
}
.evw-drawer-grouph:first-child { margin-top: 2px; }

/* Two steps down from the row, which is what lets the hairlines go: the
   size change is the boundary now. */
.evw-drawer-item {
	display: flex; align-items: center; min-height: 40px;
	padding: 4px 2px 4px 14px; line-height: 1.3; text-decoration: none;
	font-size: 0.95rem; font-weight: 600; color: var(--ev-purple-700);
}
.evw-drawer-item:hover { color: var(--ev-purple-500); text-decoration: none; }

/*
 * WHERE THE READER IS. Brighter than everything around it rather than
 * darker, so it reads as lit up instead of as another heading. 4.9:1 on the
 * palest end of the panel wash, so it stays legible as body-size text.
 * Server-rendered (drawer.php sets aria-current), so it is correct on first
 * paint and correct in Spanish, where the slug is the half that does not
 * change.
 */
.evw-drawer-item[aria-current="page"],
.evw-drawer-label[aria-current="page"],
.evw-drawer-row-flat[aria-current="page"] {
	color: var(--ev-purple-400); font-weight: 800;
}
.evw-drawer-utility { display: flex; flex-direction: column; margin-top: 20px; padding-top: 14px; border-top: 1px solid var(--ev-purple-200); }
.evw-drawer-utility a { min-height: 40px; display: flex; align-items: center; font-size: var(--text-sm); font-weight: 600; color: var(--ev-purple-600); text-decoration: none; }
.evw-drawer-utility a:hover { color: var(--ev-purple-400); text-decoration: none; }

@media (prefers-reduced-motion: reduce) {
	.evw-drawer-panel, .evw-drawer-scrim, .evw-drawer-bars i, .evw-drawer-plus i { transition: none; }
}

/* ── The header floats ────────────────────────────────────────────────────
   Ports layout.jsx's DesktopHeader, which is position:fixed with no background
   of its own: the hero runs under it, and the plum gradient fades in only once
   the reader scrolls.

   THIS IS NOT COSMETIC. tokens/layout.css already adds top padding to the first
   hero section to clear a floating header. While this header sat in the flow,
   the page paid for the header TWICE — 108px of chrome plus 116px of clearance
   — and every page rendered 108px lower than the design. Measured against the
   prototype at 1440px: h1 at 261px here against 153px there, to the pixel.

   Below 1025px the header returns to the flow, which is what the prototype's
   MobileHeader does, and the clearance rule does not apply there either.

   The at-rest state is the server-rendered one and is legible on every page,
   so this degrades correctly with 26-chrome.js absent — the announcement stays
   open and the nav keeps the colour its own hero calls for. */
.evw-chrome { position: relative; z-index: 50; }
.evw-chrome-bg { display: none; }

/* ── Press page: news-segment player (31-yt.js facade) ─────────────────────
   A poster with an amber play button; the island swaps it for the iframe on
   click. The hover lift mirrors the site's other clickable media. */
.ev-yt-play { position: absolute; left: 50%; top: 50%; width: 72px; height: 72px; margin: -36px 0 0 -36px; border-radius: var(--radius-full); background: var(--ev-amber-500); color: var(--ev-white); display: inline-flex; align-items: center; justify-content: center; box-shadow: 0 12px 30px rgba(16, 4, 28, 0.35); transition: transform .18s var(--ease-out), background .18s var(--ease-out); }
.ev-yt-play svg { margin-left: 4px; }
.ev-yt:hover .ev-yt-play, .ev-yt:focus-visible .ev-yt-play { transform: scale(1.06); background: var(--ev-amber-400); }
.ev-yt:focus-visible { outline: 3px solid var(--ev-amber-400); outline-offset: 3px; }
.ev-yt.is-playing { background: #000; }
@media (prefers-reduced-motion: reduce) { .ev-yt-play { transition: none; } }

/* ── Quiz pages: the opening screen at first paint (2026-09-29) ──────────
   While the quiz island is on its way (html.ev-quiz-pending, set by an inline
   head script in functions.php), draw exactly what the island's intro render
   shows: the intro with its Start button, no questions, no consult form, no
   progress row. The island clears the mark after its first render, so nothing
   moves when it takes over. Without JavaScript the mark is never set and the
   full quiz stays readable. !important beats the [hidden] toggles and inline
   styles the island owns. */
.ev-quiz-pending [data-ev-island="quiz"] [data-ev-part="questions"],
.ev-quiz-pending [data-ev-island="quiz"] [data-ev-part="form"],
.ev-quiz-pending [data-ev-island="quiz"] [data-ev-part="progress"] { display: none !important; }
.ev-quiz-pending [data-ev-island="quiz"] [data-ev-part="start-row"] { display: block !important; }

/* ── Insurance page: the benefits-check form in a narrow column ───────────
   The band is two halves of one plum panel; below 760px they stack. The form
   column can be as narrow as ~250px on a phone (section 24px + column 38px
   padding each side), so the first/last-name pair stacks once the column is
   too narrow for two fields, and the phone padding tightens so the fields
   get the width instead (client flag, 2026-09-09). The container query keys
   the stacking to the column's real width, which is what actually varies
   (tablet two-up columns are narrow too); the 560px rule is the fallback for
   engines without container queries. !important beats the block's inline
   styles. */
.ev-bcb-form { container-type: inline-size; }
/* The fields are white on the plum panel (client flag, 2026-09-28): a
   readable placeholder (--muted-foreground is 5.2:1 on white) and a visible
   amber focus ring, since the inline style turns the browser outline off. */
.ev-bcb-input::placeholder { color: var(--muted-foreground); opacity: 1; }
.ev-bcb-input:focus { border-color: var(--ev-amber-400) !important; box-shadow: 0 0 0 3px rgba(245, 148, 64, 0.55); }
@container (max-width: 340px) {
	.ev-bcb-names { grid-template-columns: minmax(0, 1fr) !important; }
}
@media (max-width: 560px) {
	.ev-bcb-col { padding: 28px 22px !important; }
	.ev-bcb-names { grid-template-columns: minmax(0, 1fr) !important; }
	.ev-bcb form .ev-btn { width: 100%; padding: 0 18px !important; }
}

/* ── Knee hub on phones (client flags, 2026-09-06) ────────────────────────
   G / A / E: the animated flow arrows only make sense between three columns
   in a row. Stacked, they landed beside a letter and shoved it off centre.
   Each step takes the full width so the letter sits dead centre, and the
   arrows go. Not a carousel: G, A and E must all be readable.
   Angiogram split: the copy column (heading, explanation) moves above the
   two figures, so the title introduces the pictures. */
@media (max-width: 767px) {
	.ev-gae-flow { display: none; }
	.ev-gae-step { flex: 0 0 100% !important; max-width: none !important; }
	.ev-aba-copy { order: -1; }
}

/* ── Vein hub recovery band on phones ──────────────────────────────────
   The oversized band-aid drifts off the right edge on desktop, clear of the
   three columns. On a phone the columns become one scroller and the picture
   landed square on the phase text (client flag, 2026-09-06). Below 768px it
   moves into the top-right corner, smaller, and the heading steps down so
   nothing sits under it. !important because the block styles inline. */
@media (max-width: 767px) {
	.ev-expect-decor { top: -30px !important; right: -18px !important; transform: rotate(-32deg) !important; width: 180px !important; opacity: .9; }
	.ev-expect-head { margin-top: 30px !important; }
}

/* ── Phones and tablets: the whole chrome sticks ─────────────────────────
   Below the floating breakpoint the chrome sits in the flow and only the nav
   row was sticky — the announcement/phone strip scrolled away. The practice
   wants that strip AND the nav to stay with the reader on mobile, on every
   page (2026-09-06). The wrapper is now the sticky element, so the header
   inside it no longer needs to be; its shadow moves to the wrapper, where a
   static header's shadow would be painted under the sections that follow.
   Sticky, not fixed: the chrome still occupies its own height in the flow,
   so no page gains or loses clearance. */
@media (max-width: 1024px) {
	.evw-chrome { position: sticky; top: 0; box-shadow: 0 10px 30px rgba(16, 4, 28, 0.30); }
	/* relative, NOT static: the header must stay a stacking context so the
	   :has() rule above (z-index 60 while the drawer is open) still lifts the
	   drawer and its close X above the announcement strip (z-index 51).
	   Static dropped that context and the strip painted over the X. */
	.evw-header { position: relative; box-shadow: none; }
	/* THE DRAWER MUST NOT LIVE INSIDE A STUCK STICKY BOX. The drawer is a
	   position:fixed child of the header, and on iOS Safari a fixed element
	   inside a sticky ancestor that is currently stuck appears to be sized and placed
	   against that ancestor, not the viewport: the panel ended at its own
	   content instead of the screen bottom, and its close X (top:14px of the
	   drawer box) sat under the announcement strip (diagnosed from a client screenshot,
	   2026-09-08). While the drawer is open the chrome steps out of sticky —
	   the scrim covers the page, so nothing is lost — and it re-sticks the
	   moment the drawer closes. The panel is also given the viewport as an
	   explicit floor, so it is never shorter than the screen. */
	.evw-chrome:has(.evw-drawer[open]) { position: relative; }
	.evw-drawer[open] > .evw-drawer-panel { min-height: 100vh; min-height: 100dvh; }
}
/* .evw-logo img above sets display:block at 0,1,1 — a bare .evw-logo-onlight
   is 0,1,0 and loses to it, which showed BOTH wordmarks stacked. Qualify. */
.evw-logo img.evw-logo-onlight { display: none; }
.evw-logo img.evw-logo-ondark { display: block; }

@media (min-width: 1025px) {
	.evw-chrome {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		/* Over a LIGHT hero the floating nav has to be dark. These are
		   tokens/layout.css's #app-inner values, rehomed onto the theme's own
		   wrapper — the prototype selector never matches in WordPress. */
		--nav-fg: var(--text-heading);
		--nav-open: var(--ev-purple-700);
		--nav-divider: rgba(40, 20, 60, 0.14);
	}
	/* Dark hero, or scrolled onto the plum: flip everything to light. */
	.evw-chrome[data-hero-dark],
	.evw-chrome.is-scrolled {
		--nav-fg: #fff;
		--nav-open: var(--ev-amber-400);
		--nav-divider: rgba(255, 255, 255, 0.20);
	}

	.evw-chrome-bg {
		display: block;
		position: absolute;
		inset: 0;
		background: var(--gradient-nav);
		opacity: 0;
		pointer-events: none;
		transition: opacity .32s var(--ease-out), box-shadow .32s var(--ease-out);
	}
	.evw-chrome.is-scrolled .evw-chrome-bg { opacity: 1; box-shadow: 0 10px 30px rgba(16, 4, 28, 0.30); }

	/* The bar itself carries no background now — .evw-chrome-bg is behind it. */
	.evw-header { position: relative; z-index: 1; }
	/* size:34 * 1.85 = 63px, which very nearly fills the 68px bar — that is
	   how the prototype looks and why the wordmark reads at a glance there. */
	.evw-logo { --evw-logo-h: 63px; }
	/* .evw-utility's z-index is set once, in the base rule above. */
	.evw-header { background: none; box-shadow: none; top: auto; }

	/* The announcement leaves on scroll, so the bar shrinks 108 -> 68.

	   It SLIDES, it is not clipped. The obvious implementation — overflow:hidden
	   plus max-height:0 on .evw-utility — also clips the language dropdown that
	   lives in that bar: the panel rendered 98px below the bar's bottom edge and
	   was not even hit-testable, so the disclosure arrow turned and nothing
	   appeared. Translating the whole fixed header up by the bar's own height
	   produces the identical result and clips nothing.

	   40px is safe to hardcode: .evw-utility-row is min-height:40px and every
	   string in it is nowrap, so the bar cannot grow a second line. */
	.evw-chrome { --evw-utility-h: 40px; transition: transform .32s var(--ease-out); }
	.evw-chrome.is-scrolled { transform: translateY(calc(var(--evw-utility-h) * -1)); }
	/* The bar is off screen now, so the availability dot's halo rests. Only at
	   this width: below 1025px the bar stays in view while scrolled, and a
	   paused halo froze there as a static ring (review, 2026-09-25). */
	.evw-chrome.is-scrolled .evw-utility-live::after { animation-play-state: paused; }
	/* The drawer is on screen in the 1025-1279px strip band, and a transformed
	   ancestor is the containing block for its fixed descendants: with the
	   scrolled translateY in place, the open drawer and its scrim were laid
	   out inside the 170px chrome box instead of the viewport (review,
	   2026-09-08). No transform while the drawer is open — and no transition,
	   because an animating transform is still a transform for .32s. */
	.evw-chrome:has(.evw-drawer[open]) { transform: none; transition: none; }

	/* Nav colours follow the hero. Same specificity as the rule above, so this
	   has to come after it — it does. */
	.evw-nav .evw-nav-link { color: var(--nav-fg); }
	.evw-nav .evw-nav-link:hover { color: var(--nav-open); }
	.evw-nav-divider { background: var(--nav-divider); }

	/* The wordmark: purple only while floating, unscrolled, over a light hero. */
	.evw-chrome:not(.is-scrolled):not([data-hero-dark]) .evw-logo img.evw-logo-onlight { display: block; }
	.evw-chrome:not(.is-scrolled):not([data-hero-dark]) .evw-logo img.evw-logo-ondark { display: none; }

	/* Book button: white on the plum, solid purple against a light hero
	   (layout.jsx picks the same two by its `light` flag). */
	.evw-chrome:not(.is-scrolled):not([data-hero-dark]) .evw-book {
		background: var(--primary);
		color: var(--primary-foreground);
		box-shadow: 0 6px 18px rgba(73, 19, 111, 0.28);
	}

	/* First-hero clearance, restated in terms of the header that is actually
	   floating. design.css hardcodes 116px, which is right only for the 68px
	   desktop bar; between 1025 and 1279 the bar is the 115px swipe-strip
	   layout and 116px would leave a 1px gap. --header-h already tracks both.

	   :first-of-type, NOT :first-child. WordPress emits an inline <script> before
	   the hero on some pages (VenaSeal, the location pages), so :first-child
	   matched nothing there and the clearance silently did not apply — which is
	   invisible while the header sits in the flow, and hides the breadcrumb
	   behind it the moment the header floats. :nth-child(-n+3) stops the rule
	   ever reaching a section further down the page. */
	#main-content > section:first-of-type:nth-child(-n+3),
	#main-content > header:first-of-type:nth-child(-n+3),
	#main-content > div:first-of-type:nth-child(-n+3) > section:first-of-type:nth-child(-n+3),
	#main-content > div:first-of-type:nth-child(-n+3) > header:first-of-type:nth-child(-n+3),
	/* <article> too. A blog post wraps its hero in one, and only <div> was
	   listed — so on every post the category and the headline rendered under
	   the floating header. Measured at 1440px: the first line of text sat at
	   y=72 beneath a header whose bottom edge is y=108. */
	#main-content > article:first-of-type:nth-child(-n+3) > header:first-of-type:nth-child(-n+3),
	#main-content > section.ev-booking-page-section { padding-top: calc(var(--header-h) + 48px) !important; }

	/* The clearance above REPLACES a hero s own top padding with a flat
	   --header-h + 48. --header-h is the nav row alone (68px), but the chrome
	   is 108px once the utility bar is counted, so that leaves 8px. Every other
	   hero absorbs it because its content carries its own top spacing; the two
	   blog heroes put text straight at the padding edge and measured 8px and
	   10px below the bar, against 69px on /vein-services/ and 106px on the GAE
	   comparison. Restored on the INNER wrapper, which the !important above
	   cannot reach, so the shared rule is left alone. */
	.evw-blog-hero > .evw-wrap,
	.evw-article-hero > .evw-article-hero-in,
	.evw-ty-hero > .evw-ty-col,
	/* The 404 page too: "Error 404" sat 8px under the bar (the practice, 2026-09-30). */
	.evw-404-hero > .evw-404-col { padding-top: 52px; }
}

@media (prefers-reduced-motion: reduce) {
	.evw-chrome,
	.evw-chrome-bg { transition: none; }
}

/* ── Primary nav menus (desktop) ──────────────────────────────────────────
   Ports NavItem / MegaMenu / StoriesMenu / SectionMenu from layout.jsx.

   The menus open on :hover AND :focus-within, in CSS, so they work with the
   island absent and a keyboard user gets the same menu a mouse user does.
   25-nav.js adds only tap-to-open on touch, Escape, and aria-expanded.

   There are THREE menu layouts, not one. A first pass rendered all three as a
   plain list, which silently dropped the Patient Stories before/after teaser
   and Knee Pain's "What is GAE?" feature link.

   Width and column ratio arrive as --evw-menu-w / --evw-menu-grid from
   nav-data.php, which carries MegaMenu's own expressions (540px for a
   Conditions+Treatments pillar; 560px at 1.15/0.85 when there is a Compare
   column). Nothing in this file decides menu geometry. */
.evw-navitem { position: relative; display: inline-flex; align-items: center; }
.evw-nav-trigger { display: inline-flex; align-items: center; gap: 3px; }
.evw-nav-trigger .evw-i-chevron-down { opacity: 0.45; transition: transform .2s var(--ease-out); flex-shrink: 0; }
.evw-navitem:hover .evw-i-chevron-down,
.evw-navitem:focus-within .evw-i-chevron-down,
.evw-navitem.is-open .evw-i-chevron-down { transform: rotate(180deg); }
/* --nav-open resolves to amber-400 on the plum bar — the same colour the
   hover rule above already sets, so an open item and a hovered link match. */
.evw-navitem:focus-within > .evw-nav-trigger,
.evw-navitem.is-open > .evw-nav-trigger { color: var(--nav-open); }
.evw-nav-divider { width: 1px; height: 22px; background: var(--nav-divider); margin: 0 6px; flex-shrink: 0; }

.evw-menu {
	position: absolute; top: 100%; left: 50%;
	transform: translateX(-50%);
	width: var(--evw-menu-w, 240px);
	max-width: calc(100vw - 32px);
	z-index: 60;
	/* The 10px is a hover bridge as much as a visual gap: without it the
	   pointer crosses dead space on the way down and the menu closes. It is
	   padding, not margin, so it stays inside the item's hover area. */
	padding-top: 10px;
	/* Hidden by geometry, not display:none — visibility keeps it out of the tab
	   order while closed and still lets opacity animate. */
	opacity: 0; visibility: hidden; pointer-events: none;
	transition: opacity .16s var(--ease-out), visibility .16s var(--ease-out);
}
.evw-navitem:hover > .evw-menu,
.evw-navitem:focus-within > .evw-menu,
.evw-navitem.is-open > .evw-menu { opacity: 1; visibility: visible; pointer-events: auto; }
/* Escape. It has to shut a panel whose trigger still holds focus, and
   :focus-within alone says that panel is open — so closing it and handing
   focus back to the trigger reopened it on the next tick and Escape looked
   inert. This rule is LAST on purpose: same specificity as the two above, so
   source order settles it. 25-nav.js clears the class when focus or the
   pointer leaves the item. */
.evw-navitem.is-dismissed > .evw-menu { opacity: 0; visibility: hidden; pointer-events: none; }

/* Edge clamp. The prototype measures the panel after mount and nudges it with
   JS (useMenuShift). This is the same result declaratively — and unlike a
   one-shot layout effect it still holds while the window is resized. The
   first nav item is the leftmost (a 540px panel centred on it would hang off
   the screen); :last-of-type is About Us, since Locations is a bare <a>. */
.evw-navitem:first-child > .evw-menu { left: 0; transform: none; }
.evw-navitem:last-of-type > .evw-menu { left: auto; right: 0; transform: none; }

.evw-menu-inner {
	background: var(--ev-white);
	border: 1px solid var(--border);
	border-radius: var(--radius-xl);
	box-shadow: var(--shadow-lg);
	text-align: left;
	animation: evFade .16s var(--ease-out);
}
.evw-menu-mega .evw-menu-inner { padding: 28px; display: grid; grid-template-columns: var(--evw-menu-grid, 1fr 1fr); gap: 28px; }
.evw-menu-stories .evw-menu-inner { padding: 22px; display: grid; grid-template-columns: 1fr 248px; gap: 24px; }
.evw-menu-list .evw-menu-inner { padding: 8px; border-radius: var(--radius-lg); }

/* ── Mega-menu columns ── */
.evw-menu-col { min-width: 0; }
.evw-menu-h { font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted-foreground); margin: 0 0 14px; }
.evw-menu-col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.evw-menu-col li { line-height: 1.3; }
.evw-menu-col li a { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 8px; font-size: var(--text-sm); color: var(--text-body); text-decoration: none; transition: color .18s var(--ease-out); }
.evw-menu-col li a:hover { color: var(--primary); text-decoration: none; }
/* "Compare Your Options" reads as article titles, not a link list. */
.evw-menu-col.is-article ul { gap: 12px; }
.evw-menu-col.is-article li a { display: block; font-weight: 500; line-height: 1.35; color: var(--muted-foreground); }
.evw-menu-col.is-article li a:hover { color: var(--primary); }

.evw-menu-badge { font-family: var(--font-sans); font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.02em; color: var(--primary-foreground); background: var(--primary); padding: 2px 7px; border-radius: var(--radius-full); white-space: nowrap; }
.evw-menu-more { display: inline-flex; align-items: center; gap: 4px; margin-top: 14px; font-size: var(--text-sm); font-weight: 700; color: var(--primary); text-decoration: none; }
.evw-menu-more:hover { text-decoration: none; }
.evw-menu-quiz { display: flex; align-items: center; gap: 6px; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); font-size: var(--text-sm); color: var(--text-body); text-decoration: none; transition: color .18s var(--ease-out); }
.evw-menu-quiz:hover { color: var(--primary); text-decoration: none; }

/* Knee Pain's feature link — the one gradient headline that lives in a menu. */
.evw-menu-feature { display: block; padding: 2px 0 4px; margin-bottom: 16px; text-decoration: none; }
.evw-menu-feature-t { display: inline-flex; align-items: center; gap: 8px; font-size: var(--text-2xl); font-weight: 800; letter-spacing: -0.02em; line-height: 1.1; }
.evw-menu-feature-arr { display: inline-flex; color: var(--ev-purple-600); transition: transform .14s var(--ease-out); }
.evw-menu-feature:hover .evw-menu-feature-arr { transform: translateX(3px); }
.evw-menu-feature-sub { display: block; margin-top: 4px; font-size: var(--text-xs); color: var(--muted-foreground); line-height: 1.4; }

/* ── Section menu (Your Visit, About Us) ── */
.evw-list-row { display: block; padding: 9px 12px; font-size: var(--text-sm); color: var(--text-body); border-radius: var(--radius-md); text-decoration: none; }
.evw-list-row:hover { background: var(--surface-muted); color: var(--text-body); text-decoration: none; }

/* ── Patient Stories menu ── */
.evw-stories-links { display: flex; flex-direction: column; gap: 6px; padding-top: 4px; }
.evw-stories-links .evw-menu-h { margin: 0 0 8px; padding-left: 12px; }
.evw-stories-row { display: flex; align-items: flex-start; gap: 12px; padding: 10px 12px; border-radius: var(--radius-md); text-decoration: none; }
.evw-stories-row:hover { background: var(--surface-muted); text-decoration: none; }
.evw-stories-icon { flex-shrink: 0; width: 34px; height: 34px; display: flex; align-items: center; justify-content: center; border-radius: var(--radius-full); background: var(--ev-purple-100); color: var(--ev-purple-700); }
.evw-stories-t { display: block; margin-bottom: 2px; font-size: var(--text-sm); font-weight: 700; color: var(--foreground); }
.evw-stories-d { display: block; font-size: var(--text-xs); line-height: 1.4; color: var(--muted-foreground); }

.evw-stories-card { display: block; overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface-page); text-decoration: none; transition: box-shadow var(--duration), transform var(--duration); }
.evw-stories-card:hover { box-shadow: var(--shadow-lg); transform: translateY(-2px); text-decoration: none; }
.evw-ba { position: relative; display: grid; grid-template-columns: 1fr 1fr; aspect-ratio: 16 / 9; }
.evw-ba-half { position: relative; overflow: hidden; display: flex; align-items: flex-start; padding: 10px; }
.evw-ba-before { justify-content: flex-start; background: linear-gradient(150deg, var(--ev-slate-200), var(--ev-slate-100)); }
.evw-ba-after { justify-content: flex-end; background: linear-gradient(150deg, var(--ev-purple-200), var(--ev-purple-100)); }
.evw-ba-half img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; }
.evw-ba-tag { position: relative; font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; background: rgba(255, 255, 255, 0.92); padding: 3px 7px; border-radius: var(--radius-full); }
.evw-ba-before .evw-ba-tag { color: var(--ev-slate-500); }
.evw-ba-after .evw-ba-tag { color: var(--ev-purple-700); }
.evw-ba-split { position: absolute; top: 0; bottom: 0; left: 50%; width: 2px; background: var(--ev-white); transform: translateX(-50%); }
.evw-stories-cap { display: block; padding: 12px 14px 14px; }
.evw-stories-cap-t { display: block; margin-bottom: 2px; font-size: var(--text-sm); font-weight: 700; color: var(--foreground); }
.evw-stories-cap-c { display: inline-flex; align-items: center; gap: 4px; font-size: var(--text-xs); font-weight: 700; color: var(--primary); }
.evw-book { display: inline-flex; align-items: center; justify-content: center; height: 40px; padding: 0 18px; border-radius: var(--radius-full); background: var(--ev-white); color: var(--primary); font-size: var(--text-sm); font-weight: 600; text-decoration: none; white-space: nowrap; box-shadow: 0 6px 18px rgba(16, 4, 28, 0.30); transition: transform .15s var(--ease-out); }
.evw-book:hover { text-decoration: none; transform: translateY(-1px); }
/* The header pill's short label. "Book Consultation" crowded the phone row
   (logo · pill · menu toggle); below 768px the pill reads "Book Now" instead
   (client, 2026-09-08). Only the header pill carries both spans. */
.evw-book-short { display: none; }
@media (max-width: 767px) {
	.evw-book-full { display: none; }
	.evw-book-short { display: inline; }
}
.evw-book-lg { height: 48px; padding: 0 30px; font-size: var(--text-base); background: var(--primary); color: var(--primary-foreground); }

/* ── Strip mode: the header the desktop mega-menu bar cannot fit into ─────
   The switch is at 1279px, not 1024px, because that is where the desktop bar
   MEASURES as fitting — not where a phone stops being a phone.

   Rendered at 1600px: logo 87 + nav 898 + Book 160 + gaps 36 + gutters 48 =
   1229px of content in English. Below roughly 1245px the Book button is pushed
   past the right edge, where html{overflow-x:clip} silently swallows it — the
   primary CTA, gone, with no scrollbar to hint at it. The nav previously hid
   this by wrapping to two and three rows inside a 68px header row.

   Spanish gets its own gate below: the same bar measures 1175px wide there. */
@media (max-width: 1279px) {
	/* Measured, not guessed, and re-measured every time this bar changed shape:
	   34px wordmark -> 46px grew it, then the hamburger landing on the same row
	   as the logo and Book button shrank it again. A phone is 149px today:
	   utility 40 + the logo/Book/hamburger row + the four-item nav strip. */
	:root { --header-h: 149px; }
	/* Logo, Book and the hamburger share row one; the nav strip wraps below.

	   The gap has to come down for that to fit. Adding the hamburger pushed the
	   row to 117 + 160 + 44 = 321px of content plus two 18px gaps = 357px,
	   against a 343px box on a 375px phone — so the hamburger wrapped onto a
	   line of its own. 10px gaps and a slightly tighter Book button bring it to
	   ~327px, which also clears a 360px phone. Below ~340px it wraps again,
	   which is a graceful outcome rather than a broken one. */
	.evw-header-row { height: auto; padding-block: 12px; flex-wrap: wrap; gap: 10px; }
	/* margin-left:auto: the row is justify-content:space-between and the nav
	   strip wraps to its own line (order 3), which left the pill floating in
	   the middle between the logo and the menu button. Auto margin parks it
	   against the menu button instead (client flag, 2026-09-09). */
	.evw-book { padding: 0 14px; margin-left: auto; }

	/* Narrow phones (360 is a very common Android width) are ~16px short of
	   fitting logo + Book + hamburger on one row at 46px. Stepping the wordmark
	   down to 40px there buys the room and keeps the header one row shorter,
	   which is worth more than the 6px. Still well above the 34px it shipped at. */
	@media (max-width: 400px) {
		.evw-logo { --evw-logo-h: 40px; }
		.evw-header-row { gap: 8px; }
	}

	/* The nav is a SLIDEABLE STRIP on phones, not a wrapped block.
	   Six links across a 375px screen wrap to two rows, which pushes the header
	   past 110px and buries the page under chrome. The prototype's MobileHeader
	   solves it with a one-line swipe strip (layout.jsx:259 — className
	   "ev-noscroll", overflow-x auto, gap 24, flexShrink 0 on each item); this
	   is that, keeping the theme's full six links because this header has no
	   drawer behind it, so anything dropped here would be unreachable.
	   The negative margin bleeds the strip to both screen edges so it is
	   obvious it scrolls, and .ev-noscroll (tokens/base.css) hides the bar. */
	.evw-nav {
		order: 3;
		/* Full row PLUS both gutters, so the strip really does reach both screen
		   edges. width:100% would be the parent's CONTENT box — 320px on a 375px
		   phone — and the negative margins would then slide that 320 leftward,
		   leaving a 40px dead zone on the right where the strip just stops. */
		width: calc(100% + (var(--gutter) * 2));
		margin-inline: calc(var(--gutter) * -1);
		padding-inline: var(--gutter);
		flex-wrap: nowrap;
		justify-content: flex-start;
		gap: 24px;
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
	}
	/* No scroll-snap here, deliberately. The prototype's strip has none, and
	   adding it put the container at scrollLeft:20 on load — the first item
	   snapped to the scrollport edge, eating the leading gutter and butting
	   "Vein Care" against the screen edge while the logo above it stayed inset. */
	.evw-nav .evw-nav-link {
		flex: 0 0 auto;
		padding: 8px 0;
		font-size: var(--text-sm);
	}
	/* No dropdowns on the swipe strip. Every trigger is already a real link to
	   its own hub, and each hub lists what its menu would have shown, so
	   nothing becomes unreachable — it just takes the extra tap the prototype's
	   drawer saves. The drawer now carries all of it, and more than the menus
	   do: 40 destinations against the desktop menus' 24. */
	.evw-navitem { display: contents; }
	.evw-menu, .evw-nav-trigger .evw-i-chevron-down, .evw-nav-divider { display: none; }

	/* The strip is a shortcut rail now, not the whole menu: four items, in
	   the order the practice asked for, which is not the desktop order. The
	   rest are in the drawer. data-strip and --strip-order both come from
	   nav-data.php — nothing here names a page. */
	.evw-nav .evw-nav-link { order: var(--strip-order, 99); }
	.evw-navitem:not([data-strip]) { display: none; }
	.evw-nav > .evw-nav-link:not([data-strip]) { display: none; }

	/* ── The tabbed chip, and what it opens ────────────────────────────────
	   Which section the reader is in, marked on the strip so that four
	   shortcuts stop reading as the whole site. data-active comes from
	   evvs_nav_active_section() in nav-data.php — the same helper that decides
	   which drawer section auto-opens, so the two surfaces cannot disagree
	   about where you are.

	   The tint is translucent white rather than a purple token because the bar
	   is a plum gradient: white at low alpha reads as the lighter purple the
	   design asks for, and keeps doing so if the gradient is ever retuned. A
	   fixed purple would have to be re-picked every time the bar changed. */
	.evw-nav [data-active] > .evw-nav-link,
	.evw-nav > .evw-nav-link[data-active] {
		background: rgba(255, 255, 255, 0.16);
		border-radius: var(--radius-full);
		padding: 5px 13px;
		/* Negative block margin so the pill does not add height to the strip and
		   push the header rows apart. */
		margin-block: -5px;
	}

	/* Every other trigger's chevron is hidden down here — there are no dropdowns
	   on the strip. The tabbed chip is the one place it means something. */
	.evw-nav [data-active] .evw-i-chevron-down { display: inline-block; }
	.evw-nav [data-active] > .evw-nav-link[aria-expanded="true"] .evw-i-chevron-down {
		transform: rotate(180deg);
	}

	/* The panel is anchored to the header, never to .evw-nav: the nav scrolls
	   sideways, and a panel positioned inside it would slide off with the chips
	   and clip at the scrollport edge. .evw-header is position:sticky, which is
	   non-static, so it is already the containing block. */
	.evw-strip-panel {
		display: block;
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		z-index: 60;
		background: var(--ev-white);
		border-radius: 0 0 var(--radius-lg) var(--radius-lg);
		box-shadow: 0 18px 40px rgba(16, 4, 28, 0.28);
		padding: 16px var(--gutter) 20px;
		/* Vein Care owns thirteen destinations. Cap the panel and scroll inside
		   it rather than running it off the bottom of the phone. */
		max-height: 60vh;
		overflow-y: auto;
		overscroll-behavior: contain;
	}
	/* Higher specificity than the rule above, so the attribute really does hide
	   it — the UA sheet's display:none for [hidden] would otherwise lose to the
	   display:block above. */
	.evw-strip-panel[hidden] { display: none; }

	.evw-strip-group {
		font-size: var(--text-xs);
		font-weight: 700;
		text-transform: uppercase;
		letter-spacing: 0.1em;
		color: var(--ev-purple-600);
		margin: 16px 0 2px;
	}
	.evw-strip-group:first-child { margin-top: 0; }

	.evw-strip-list { list-style: none; margin: 0; padding: 0; }
	.evw-strip-list a {
		display: block;
		padding: 12px 0;
		font-size: var(--text-base);
		font-weight: 600;
		color: var(--text-heading);
		text-decoration: none;
		border-bottom: 1px solid var(--border);
	}
	.evw-strip-list a[aria-current="page"] { color: var(--ev-purple-600); }

	.evw-strip-hub {
		display: inline-flex;
		align-items: center;
		margin-top: 16px;
		font-size: var(--text-sm);
		font-weight: 800;
		color: var(--ev-purple-600);
		text-decoration: none;
	}

	.evw-drawer { display: inline-flex; }
}

/* The panel belongs to the strip. Above 1279px the desktop mega menus are the
   navigation, and a panel left open by a resize must not float over them.
   !important because this sits after the strip block and must win regardless of
   how the two are later reordered. */
@media (min-width: 1280px) {
	.evw-strip-panel { display: none !important; }
}

/* ── Spanish: the same bar, 277px wider ──────────────────────────────────
   Measured on staging at 1600px: the nav is 898px in English and 1175px in
   Spanish, so the header needs 1504px of content width before it fits. On a
   1440px laptop — the common case — the Spanish bar would push Book Consultation
   off the right edge, exactly the failure the English gate above prevents.

   So Spanish stays in strip mode up to 1519px. That is a holding measure, not
   the answer: it costs Spanish visitors the mega menus on the most common
   laptop width. The fix is shorter nav labels ("Cuidado de las venas" is 208px
   against "Vein Care" at 119px) — a copy decision, not a CSS one — or the
   shorter nav labels. The drawer does NOT solve it and this block must stay:
   the drawer appears below 1280px (the strip band included), so it is not on screen anywhere in
   the 1280-1519 band this gate covers. (An earlier note here said to delete
   this block once the drawer landed — it landed, and deleting this would put
   a 1175px Spanish nav into a 1440px laptop, which is the exact failure the
   English gate above exists to prevent.)

   Duplicated rather than merged into the query above because a media query
   cannot be conditioned on an attribute; the two gates are different widths. */
/* The 1025-1279 band floats the header AND still uses the strip layout with
   the announcement visible — 178px measured, against 161px on a phone where
   the announcement is hidden. This has to come AFTER the max-width:1279 rule
   above: same specificity, so source order decides, and placed before it this
   never applied at all. It is the band where --header-h drives the first-hero
   clearance, so being wrong here puts the floating header over the hero copy. */
@media (min-width: 1025px) and (max-width: 1279px) {
	:root { --header-h: 178px; }
}

@media (min-width: 1280px) and (max-width: 1519px) {
	html[lang^="es"] { --header-h: 178px; }
	html[lang^="es"] .evw-header-row { height: auto; padding-block: 12px; flex-wrap: wrap; }
	html[lang^="es"] .evw-nav {
		order: 3;
		width: calc(100% + (var(--gutter) * 2));
		margin-inline: calc(var(--gutter) * -1);
		padding-inline: var(--gutter);
		flex-wrap: nowrap;
		justify-content: flex-start;
		gap: 24px;
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
	}
	html[lang^="es"] .evw-nav .evw-nav-link { flex: 0 0 auto; padding: 8px 0; font-size: var(--text-sm); }
	html[lang^="es"] .evw-navitem { display: contents; }
	html[lang^="es"] .evw-menu,
	html[lang^="es"] .evw-nav-trigger .evw-i-chevron-down,
	html[lang^="es"] .evw-nav-divider { display: none; }
}

/* ── Page hero (blog index, generic pages, 404) ── */
.evw-page-hero { background: var(--gradient-hero); padding: clamp(48px, 6vw, 80px) 0 clamp(36px, 4.5vw, 56px); }
.evw-page-hero .ev-lead { max-width: 620px; margin-top: 14px; }

/* ── The blog index hero ──────────────────────────────────────────────
   Centred, with the publication named above the headline and a rule under
   the band, which is how the mockup draws it. The generic left-aligned
   version it replaces was the same shape as every other page hero and read
   as an archive listing rather than as a magazine front page. */
.evw-blog-hero { text-align: center; border-bottom: 1px solid var(--border); }
.evw-blog-hero .evw-wrap { max-width: calc(880px + 2 * var(--gutter)); }
.evw-blog-hero h1 { margin: 16px 0 0; text-wrap: balance; }
.evw-blog-hero .ev-lead { max-width: 560px; margin-inline: auto; margin-top: 18px; }
/* Names the publication, so it earns its place — it is not a decorative
   label over a heading that already says the same thing. */
.evw-blog-eyebrow {
	display: inline-flex; align-items: center; gap: 7px;
	font-size: var(--text-xs); font-weight: 700;
	letter-spacing: 0.08em; text-transform: uppercase;
	color: var(--ev-purple-700);
}
.evw-blog-eyebrow svg { flex-shrink: 0; }
/* 404 — the prototype design this page mirrors is a CENTERED 760px column
   on the hero wash (pages.jsx NotFoundPage), taller than the standard page
   band. Without its own column the text sat at the far left of the 1660px
   site container on desktop screens. */
.evw-404-hero { padding: clamp(104px, 13vw, 176px) 0 clamp(80px, 9vw, 128px); }
.evw-404-col { max-width: 760px; margin-inline: auto; padding-inline: var(--gutter, 24px); }
.evw-404-col .ev-lead { max-width: 560px; }
.evw-404-cta { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 28px; }
.evw-404-home { display: inline-flex; align-items: center; justify-content: center; height: 48px; padding: 0 26px; border-radius: var(--radius-full); border: 1.5px solid var(--ev-purple-300); color: var(--ev-purple-700); font-weight: 700; }
.evw-404-home:hover { border-color: var(--ev-purple-500); background: var(--ev-purple-50); }
.evw-404-links { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 22px; margin-top: 26px; }

.evw-404-links a { color: var(--ev-purple-600); font-weight: 600; }
.evw-404-links .evw-book { color: var(--primary-foreground); background: var(--primary); box-shadow: var(--shadow-sm); }

/* Thank-you page (page-thank-you.php, 2026-09-29) — where every accepted
   lead lands. The 404's centred column on the hero wash, with the booking
   form's own success mark (22-consult-form.js successMark) above the words.
   .evw-ty-copy never sets display, so [hidden] on the other sets holds. */
.evw-ty-hero { padding: clamp(96px, 12vw, 160px) 0 clamp(80px, 9vw, 128px); text-align: center; }
.evw-ty-col { max-width: 680px; margin-inline: auto; padding-inline: var(--gutter, 24px); }
.evw-ty-mark {
	width: 74px; height: 74px; margin: 0 auto 26px;
	display: flex; align-items: center; justify-content: center;
	border-radius: var(--radius-full);
	background: var(--ev-success-soft); color: var(--ev-success);
	box-shadow: 0 0 0 10px rgba(31, 138, 91, 0.08);
}
.evw-ty-copy h1 { text-wrap: balance; }
.evw-ty-copy .ev-lead { max-width: 540px; margin: 14px auto 0; }
.evw-ty-sub { font-size: var(--text-lg); font-weight: 600; line-height: 1.5; color: var(--text-heading); margin: 16px 0 0; }
.evw-ty-call { color: var(--primary); font-weight: 700; white-space: nowrap; }

/* ── Post cards ── */
.evw-postgrid-wrap { padding-block: clamp(36px, 5vw, 64px); }
.evw-postgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); gap: clamp(24px, 3vw, 40px); }
.evw-card { display: block; color: inherit; text-decoration: none; padding-top: 4px; }
.evw-card:hover { text-decoration: none; }
/* height:auto is load-bearing, not tidying.

   WordPress prints width="768" height="512" on the <img>, and those map to
   presentational style hints. This rule set width but NOT height, so the
   hint applied — and with BOTH dimensions definite, aspect-ratio is ignored
   entirely. Every card then rendered at its own source ratio: measured 512,
   406 and 529px tall side by side in one row, against the 264px the ratio
   asks for. Setting height:auto takes the hint back and lets 16/10 govern. */
.evw-card-img {
	width: 100%; height: auto; aspect-ratio: 16 / 10;
	object-fit: cover; border-radius: var(--radius-lg); margin-bottom: 14px;
	background: var(--ev-purple-50);
}
.evw-card-title { font-size: var(--text-xl); font-weight: 800; letter-spacing: var(--tracking-tight); line-height: 1.25; color: var(--text-heading); margin: 6px 0 8px; }
.evw-card:hover .evw-card-title { color: var(--ev-purple-600); }
.evw-card-excerpt { font-size: var(--text-sm); color: var(--muted-foreground); line-height: 1.6; margin: 0; }
.evw-pagination { display: flex; justify-content: center; gap: 8px; margin-top: clamp(32px, 4vw, 48px); font-weight: 600; }
.evw-pagination .page-numbers { padding: 8px 14px; border-radius: var(--radius-md); color: var(--ev-purple-700); text-decoration: none; }
.evw-pagination .page-numbers.current { background: var(--ev-purple-100); }

/* ── Article ── */
.evw-article-hero { background: var(--gradient-hero); padding: clamp(44px, 5.5vw, 72px) 0 clamp(30px, 4vw, 48px); }
.evw-article-hero-in { max-width: calc(760px + 2 * var(--gutter)); }
.evw-article-cat a { color: var(--ev-purple-600); font-weight: 700; text-decoration: none; letter-spacing: 0.04em; text-transform: uppercase; }
.evw-article-hero h1 { margin: 10px 0 12px; text-wrap: balance; }
.evw-article-meta { margin: 0 0 18px; }
.evw-byline { display: flex; align-items: center; gap: 12px; padding-top: 16px; border-top: 1px solid var(--border); }
.evw-byline p { margin: 0; font-size: var(--text-sm); color: var(--text-body); }
.evw-byline a { color: var(--text-heading); text-decoration: none; }
.evw-byline a:hover { color: var(--ev-purple-600); }
/* The reviewer s face, framed by measurement rather than by eye.

   Every doctor portrait is the same 350x500 frame with the subject filling it.
   Sampling the five silhouettes: the head starts at the very top and the
   shoulders flare at 33-45% of the height, so the chest sits just below that.

   WordPress was serving the thumbnail size — a hard CENTRE crop — which began
   ~15% down and cut the head off. Switching to a proportional size and
   anchoring to the top fixed that, but cover on a square box fits by width and
   so showed the top 70%: head to waist, with the face only a third of the
   circle. scale(1.4) from the top edge shows 70/1.4 = the top 50% instead —
   face through chest. Derived from the shared format, so it holds for whoever
   reviews the next article. */
.evw-byline-avatar {
	display: block; flex-shrink: 0;
	width: 46px; height: 46px;
	border-radius: var(--radius-full); overflow: hidden;
	background: var(--ev-purple-50);
	border: 1.5px solid var(--border);
}
.evw-byline-photo {
	width: 100%; height: 100%;
	object-fit: cover; object-position: center top;
	transform: scale(1.4); transform-origin: center top;
	display: block;
}

.evw-article-body { max-width: calc(760px + 2 * var(--gutter)); padding-block: clamp(32px, 4vw, 52px); font-size: var(--text-lg); line-height: 1.75; color: var(--text-body); }
.evw-article-body > * + * { margin-top: 1.1em; }
/* Post bodies are 113 pieces of imported copy nobody is going to re-edit, and
   several end with a citation list of bare URLs. A pmc.ncbi.nlm.nih.gov link is
   one unbreakable word ~440px wide, which pushed every post that has one past a
   375px screen. anywhere (not break-word) so it also breaks mid-token when the
   line has nowhere else to go. Found 2026-08-25 measuring all three posts. */
.evw-article-body { overflow-wrap: anywhere; }
.evw-article-body a { overflow-wrap: anywhere; }
.evw-article-body h2 { font-size: var(--text-3xl); font-weight: 800; letter-spacing: var(--tracking-tight); line-height: 1.2; color: var(--text-heading); margin-top: 1.8em; }
.evw-article-body h3 { font-size: var(--text-2xl); font-weight: 800; letter-spacing: var(--tracking-tight); line-height: 1.25; color: var(--text-heading); margin-top: 1.5em; }
.evw-article-body a { color: var(--ev-purple-600); font-weight: 600; }
.evw-article-body img { max-width: 100%; height: auto; border-radius: var(--radius-lg); }
.evw-article-body ul, .evw-article-body ol { padding-left: 1.3em; }
.evw-article-body li + li { margin-top: 0.45em; }
.evw-article-body blockquote { border-left: 3px solid var(--ev-purple-200); padding-left: 20px; color: var(--text-heading); }
.evw-article-body table { width: 100%; border-collapse: collapse; font-size: var(--text-base); }
.evw-article-body th, .evw-article-body td { border-bottom: 1px solid var(--border); padding: 10px 12px; text-align: left; }

/* ── Related + CTA ── */
.evw-related { background: var(--ev-purple-25); padding-block: clamp(40px, 5vw, 64px); }
.evw-related h2 { margin-bottom: clamp(20px, 2.5vw, 32px); }
.evw-related-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); gap: clamp(22px, 2.6vw, 36px); }
.evw-cta { background: var(--surface-dark); color: var(--text-on-dark); text-align: center; padding-block: clamp(56px, 7vw, 96px); }
.evw-cta h2 { color: #fff; }
.evw-cta .ev-lead { color: var(--text-on-dark); margin: 12px auto 26px; max-width: 520px; }
.evw-cta-or { margin-left: 16px; font-size: var(--text-sm); color: var(--text-on-dark-subtle); }
.evw-cta-or a { color: var(--ev-amber-400); font-weight: 700; text-decoration: none; }

/* ── Footer ── */
.evw-footer { background: var(--surface-dark); color: var(--text-on-dark); padding: clamp(48px, 6vw, 80px) 0 28px; }
.evw-footer a { color: rgba(255, 255, 255, 0.72); text-decoration: none; font-size: var(--text-sm); transition: color .15s; }
.evw-footer a:hover { color: #fff; text-decoration: none; }
.evw-footer-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); gap: clamp(28px, 4vw, 56px); }
.evw-footer-logo { height: 34px; width: auto; margin-bottom: 14px; }
.evw-footer-tag { font-size: var(--text-sm); color: rgba(255, 255, 255, 0.72); line-height: 1.6; max-width: 260px; }
.evw-footer-phone { display: inline-block; margin-top: 8px; font-size: var(--text-lg); font-weight: 800; color: var(--ev-amber-400) !important; }
.evw-footer-h { font-size: var(--text-base); font-weight: 700; color: #fff; margin: 0 0 16px; }
.evw-footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 11px; }
.evw-footer-legal { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px 24px; margin-top: clamp(36px, 5vw, 56px); padding-top: 22px; border-top: 1px solid rgba(255, 255, 255, 0.14); font-size: var(--text-xs); color: rgba(255, 255, 255, 0.6); }
.evw-footer-legal p { margin: 0; }

/* ── Hover and press states ─────────────────────────────────────────────
   ds/Button.jsx, ds/Card.jsx and the page-level cards drove every one of
   these off React state, for one reason: inline styles cannot express
   :hover. The blocks port those inline styles verbatim and therefore ship
   only the resting state, which is why so many of them carried a
   "hover is JS in the prototype" note. None of it needs JavaScript — it
   needs a stylesheet, which is what this is.

   The !important flags are not a specificity shortcut: each of these
   properties IS set inline on the element (background, box-shadow,
   transform), and an inline declaration beats any selector. Every value
   below is the prototype's own.
   ------------------------------------------------------------------- */

/* DS Button. Hover changes the fill; the press is a half-pixel nudge.
   :focus-visible mirrors hover so keyboard users get the same feedback. */
.ev-btn-primary:hover,
.ev-btn-primary:focus-visible { background: var(--primary-hover) !important; }
.ev-btn-accent:hover,
.ev-btn-accent:focus-visible { background: var(--ev-amber-600) !important; }
/* The secondary/outline skins tint through a gradient overlay rather than
   swapping the fill (Button.jsx's `overlay`). */
.ev-btn-outline:hover,
.ev-btn-outline:focus-visible {
  background: linear-gradient(var(--elevate-hover), var(--elevate-hover)), var(--card) !important;
}
.ev-btn:active:not([disabled]) { transform: translateY(0.5px) !important; }
.ev-btn[disabled] { cursor: not-allowed; }

/* Card lift — ConditionsGrid and the article cards. */
.ev-hov-lift { transition: box-shadow .2s, transform .2s; }
.ev-hov-lift:hover,
.ev-hov-lift:focus-visible {
  box-shadow: var(--shadow-lg) !important;
  transform: translateY(-3px) !important;
}

/* Photo zoom inside a card. The photo panel already clips its overflow. */
.ev-hov-zoom img { transition: transform .35s ease; }
.ev-hov-zoom:hover img,
.ev-hov-zoom:focus-visible img { transform: scale(1.04) !important; }

/* Press wordmarks lift out of grey on hover. */
.ev-hov-wordmark:hover {
  opacity: 1 !important;
  color: var(--ev-purple-700) !important;
  filter: grayscale(0) !important;
}

/* Video play badge. */
.ev-hov-badge { transition: transform var(--duration); }
a:hover .ev-hov-badge,
button:hover .ev-hov-badge,
.ev-hov-badge:hover { transform: scale(1.06) !important; }

@media (prefers-reduced-motion: reduce) {
  .ev-hov-lift, .ev-hov-zoom img, .ev-hov-badge { transition: none; }
  .ev-hov-lift:hover, .ev-hov-lift:focus-visible { transform: none !important; }
  .ev-hov-zoom:hover img, .ev-hov-zoom:focus-visible img { transform: none !important; }
  .ev-hov-badge:hover, a:hover .ev-hov-badge, button:hover .ev-hov-badge { transform: none !important; }
}

/* Touch devices have no hover; leaving these active makes a tapped card
   stick in its lifted state until something else is touched. */
@media (hover: none) {
  .ev-hov-lift:hover { box-shadow: var(--shadow-sm) !important; transform: none !important; }
  .ev-hov-zoom:hover img { transform: none !important; }
}


/* ═══ HOMEPAGE MOBILE FOLD (client request, 2026-08-30) ═══════════════════
   The ask: the Vein and Knee tiles above the fold on phones — vein fully,
   knee with a large peek. Measured before at 375×812: tiles began at 353px
   and the knee tile at 677px, invisible on a real phone once browser chrome
   eats ~120px of the 812.

   Three levers, all homepage-scoped (body.home — WordPress stamps it):

   1. The section strip is HIDDEN on the homepage only. It names Vein Care /
      Knee Pain / Vascular Care / Locations — the four destinations the tile
      grid directly beneath it already presents bigger and better; on this
      one page it is duplication spending ~45px of the most valuable screen
      on the site. Every other page keeps it. (--header-h is deliberately NOT
      adjusted: its only two consumers — the booking page top padding and the
      philosophy sticky header — never render on the homepage.)

   2. The hero display type and spacing tighten on phones. Inline styles set
      the desktop values, so these need !important; each mirrors the inline
      clamp with a lower floor rather than a new design.

   3. The tile min-height floor drops 300 → 220 with a tighter gap. The
      copy-height analysis above (the 300px block) still governs: min-height
      only yields when content is shorter, so a tile whose copy needs 240px
      takes 240px — nothing clips, tiles just stop holding empty space. */
@media (max-width: 1279px) {
	body.home .evw-nav { display: none; }
}
/* The homepage headline's rise and fade mask, for both languages (2026-09-25).
   front-page.php writes them inline, but the Spanish headline is a
   TranslatePress translation block stored before those styles existed, so
   /es/ showed "AVANZADO" with no mask and no entrance. The same values here
   reach both; @keyframes evHeroRise and its reduced-motion rule sit in the
   <style> beside the h1 in front-page.php. */
body.home .ev-hero-advanced {
	-webkit-mask-image: linear-gradient(to bottom, #000 52%, rgba(0, 0, 0, 0.45) 78%, transparent 100%);
	mask-image: linear-gradient(to bottom, #000 52%, rgba(0, 0, 0, 0.45) 78%, transparent 100%);
	animation: evHeroRise 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
body.home .ev-hero-sub { animation: evHeroRise 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) 0.14s both; }
@media (max-width: 767px) {
	body.home .ev-hero-advanced { font-size: clamp(2.9rem, 13vw, 5rem) !important; }
	body.home .ev-hero-sub { font-size: clamp(1.15rem, 5vw, 1.6rem) !important; margin-top: 4px !important; }
	body.home .ev-hero-bigtiles { gap: 16px !important; }
	body.home .ev-hero-bigtiles > a { --ev-tile-h: 220px; }
	body.home .ev-home-hero > div { padding-top: 24px !important; }
	body.home .ev-home-hero-head { margin-bottom: 18px !important; }
}

/* ── Insurance directory: the grid, and its phone behaviour (blocks/insurance-directory) ── */
.ev-ins-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(208px, 1fr)); gap: 16px; }
.ev-ins-logo { height: 92px; padding: 16px 20px; }
.ev-ins-loadmore { position: relative; display: flex; justify-content: center; padding: 30px 0 4px; }
.ev-ins-loadmore::before { content: ""; position: absolute; left: 0; right: 0; top: -110px; height: 110px; background: linear-gradient(to bottom, rgba(255, 255, 255, 0), var(--background) 85%); pointer-events: none; }
.ev-ins-loadmore button { display: inline-flex; align-items: center; justify-content: center; height: 46px; padding: 0 26px; border: 0; border-radius: var(--radius-full); background: var(--primary); color: var(--primary-foreground); font-family: var(--font-sans); font-size: var(--text-sm); font-weight: 700; cursor: pointer; box-shadow: var(--shadow-sm); }
.ev-ins-loadmore button:focus-visible { outline: 2px solid var(--ev-amber-400); outline-offset: 3px; }
.ev-ins-pill { position: fixed; left: 50%; bottom: calc(14px + env(safe-area-inset-bottom)); transform: translateX(-50%); z-index: 70; display: inline-flex; align-items: center; height: 46px; padding: 0 22px; border-radius: var(--radius-full); background: var(--primary); color: var(--primary-foreground); font-family: var(--font-sans); font-size: var(--text-sm); font-weight: 700; white-space: nowrap; text-decoration: none; box-shadow: 0 10px 28px rgba(16, 4, 28, 0.28); }
.ev-ins-pill:hover { text-decoration: none; }
.ev-ins-pill[hidden] { display: none; }
@media (max-width: 599px) {
  .ev-ins-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .ev-ins-logo { height: 64px; padding: 10px 12px; }
}

/* ── Kept-as-is pages without the title band (page-bare.php) ───────────── */
/* A bare page brings its own layout (Greenshift rows and columns), so it gets
   the site container rather than the 760px reading column: in the reading
   column the e-book lander's two-column hero left 370px per column and its
   90px heading broke one word per line. The old site ran these pages in a
   1600px container. */
.evw-article-bare { max-width: var(--container-max); padding-top: clamp(24px, 3vw, 40px); }
/* The old site pulled a page's first row up under its own header with a
   negative top margin (the e-book lander: margin-top:-120px in the CSS
   Greenshift stores with the page). Under this theme's header that margin
   only drags the row into the nav, so the first row of an article body
   starts where the body starts. !important because the page CSS targets the
   row by id (#gspb_row-id-…) and nothing lower wins against an id. */
.evw-article-body > .gspb_row:first-child { margin-top: 0 !important; }

/* ── Kept-as-is pages: blocks nested in columns ───────────────────────────
   design.css zeroes every p and heading margin, and the article rhythm above
   (.evw-article-body > * + *) reaches direct children only. Content nested
   one level down therefore ran together: paragraphs inside Kadence columns
   (physician referrals, thank-you pages) and the whole privacy policy, which
   inc/legal.php wraps in .evvs-legal. Same 1.1em, one level down. :where()
   keeps it at class weight so the h2/h3 top margins above still win. The
   first block in a column starts flush with the column (a heading there had
   36-54px above it). */
:where(.evw-article-body) :is(.kt-inside-inner-col, .evvs-legal) > * + * { margin-top: 1.1em; }
.evw-article-body .kt-inside-inner-col > :first-child { margin-top: 0; }
/* Greenshift buttons: a label that wraps (Spanish, on a phone) stays centred. */
.evw-article-body .gspb-buttonbox { text-align: center; }
.evw-article-body .gspb-buttonbox-title { text-wrap: balance; }
/* A page photo placed above a Greenshift row lines up with the row's text,
   which Greenshift insets by min(3vw, 20px) (San Bernardino). */
.evw-article-body > .evw-page-photo:has(+ .gspb_row) { padding-inline: min(3vw, 20px); }
/* Images stacked edge to edge are one graphic (the GAE Spanish email is four
   slices): no rounded corners at the seams, outer corners kept. */
.evw-article-body > .gspb_image + .gspb_image img { border-top-left-radius: 0; border-top-right-radius: 0; }
.evw-article-body > .gspb_image:has(+ .gspb_image) img { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
/* Our Services: Greenshift fixes each row photo at 400px tall with
   object-fit:cover. The old 1018px content area gave those columns 289px; the
   760px reading column gives 212px, a 212x400 strip. A 4:5 crop keeps the
   focal points (object-position is untouched). By row id, this page only;
   !important because the height is set on ids. */
.evw-article-body :is(.kb-row-layout-id6006_e0d999-23, .kb-row-layout-id6006_3c53ba-de, .kb-row-layout-id6006_f1626d-11) .gspb_image { height: auto !important; }
.evw-article-body :is(.kb-row-layout-id6006_e0d999-23, .kb-row-layout-id6006_3c53ba-de, .kb-row-layout-id6006_f1626d-11) .gspb_image img { width: 100% !important; height: auto !important; aspect-ratio: 4 / 5; }

/* ── Kept-as-is pages on a dark ground (inc/nav.php evvs_dark_page_slugs) ──
   The e-book lander. #371052 is the page's own ground from its old-site
   style block, not a theme token: the purple fade at the foot of its
   comparison image is that exact colour. The header reads light over it
   (evvs_is_hero_dark). Greenshift's id rules still set the orange headings
   and the light tiles; everything else inherits white. */
body.evw-page-dark { background: #371052; }
.evw-page-dark .evw-article-bare { color: #fff; }
.evw-page-dark .evw-article-bare :is(h1, h2, h3, h4, h5, h6, p, li, strong) { color: inherit; }
/* The old theme's Bootstrap defaults this layout was set against: h5 at
   1.25rem, paragraphs and headings with a bottom margin. */
.evw-page-dark .evw-article-bare h5 { font-size: 1.25rem; font-weight: 500; line-height: 1.2; margin-bottom: 15px; }
.evw-page-dark .evw-article-bare h5:not(:first-child) { margin-top: 16px; }
.evw-page-dark .evw-article-bare p:not(:last-child) { margin-bottom: 1rem; }
/* theme.json pads every .wp-element-button for the site's 16px buttons;
   these carry 24px type, which made them 84px tall (50px on the old site). */
.evw-page-dark .evw-article-bare .gspb-buttonbox { padding-block: 1px; }
/* The cover's -40px pull-up was written for the old header and put its
   rotated corner on the floating nav. */
@media (min-width: 1025px) { .evw-page-dark #gspb_image-id-gsbp-bcdb802 { margin-top: 0; } }
@media (min-width: 1500px) { .evw-page-dark #gspb_image-id-gsbp-bcdb802 { margin-top: 32px; } }
/* On a phone the -60px pull under the comparison image put the button over a
   third of the table. */
@media (max-width: 767.98px) { .evw-page-dark #gspb_image-id-gsbp-ae64aaf { margin-bottom: 0; } }
/* "Inside The Book" tiles centre their titles with no side padding; the
   longer Spanish titles ran to the tile edges. */
.evw-page-dark :is(#gspb_iconsList-id-gsbp-03bacb3, #gspb_iconsList-id-gsbp-cb79be2) .gspb_iconsList__item { padding-inline: 1rem; }

/* ── English one-row header at 1280-1359px ────────────────────────────────
   The one-row bar starts at 1280px (the strip layout is max-width 1279px,
   mirrored in islands.js), a width worked out with the old 87px wordmark.
   With the 161px wordmark and 40px gutters the row needs about 1295px, so
   at 1280 (1265px beside a scrollbar) Book Consultation was clipped at the
   right edge. Trimming the seven bar links 5px a side frees 70px. Spanish
   already wraps the nav to a second row at these widths. */
@media (min-width: 1280px) and (max-width: 1359px) {
  html:not([lang^="es"]) .evw-nav .evw-nav-link { padding-inline: 9px; }
}

/* ── Page leftovers approved 2026-09-18 ────────────────────────────────── */
/* E-book lander: headings sat flush on the text below them (0px where the
   old site had 15-24px). The old theme gave h1-h5 a .75em bottom margin;
   design.css zeroes every heading margin, and Greenshift's own id rules
   (#gspb_heading-id-…{margin-bottom:0}) outrank a class rule, so
   :not(#evw-none) lifts this rule to id weight. Dark kept-as-is pages only. */
.evw-page-dark .evw-article-bare :is(h1, h2, h3, h4, h5):not(#evw-none) { margin-bottom: .75em; }
/* Physician referrals: this paragraph carries Greenshift's own
   margin-top:0 !important, so the column rhythm above could not reach it. */
.evw-article-body .kt-inside-inner-col > .gspb_text-id-gsbp-16abe5b { margin-top: 1.1em !important; }
/* Short pages: when the content is shorter than the window, the area below
   the footer showed white, because body's white background also painted the
   canvas. Giving html the footer's colour paints that area to match the
   footer instead; body itself stays white, so no page changes. */
html { background-color: var(--surface-dark); }

/* ── Patient Stories: short videos (blocks/video-stories, 2026-09-18) ──
   Three vertical Shorts posters across on desktop; on phones a free swipe
   rail with each card at 80% of the screen so the next one shows (client
   ask). The 31-yt.js facade turns a press into the player and puts any
   other player back to its poster; posters are theme assets, so YouTube
   loads nothing until then. The rail never snaps: free scroll. */
.ev-vstories-head { max-width: 640px; margin-bottom: clamp(24px, 3vw, 36px); }
.ev-vstories-intro { font-size: var(--text-lg); color: var(--muted-foreground); line-height: 1.6; margin: 16px 0 0; text-wrap: pretty; }
.ev-vstories-rail { display: flex; gap: clamp(20px, 2.5vw, 32px); overflow-x: auto; padding-bottom: 8px; scroll-snap-type: none; }
.ev-vstory { flex: 0 0 min(80%, 320px); margin: 0; }
.ev-vstory-frame { position: relative; display: block; aspect-ratio: 9 / 16; border-radius: var(--radius-xl); overflow: hidden; background: var(--surface-photo); }
.ev-vstory-frame img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.ev-vstory-cap { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin: 12px 0 0; font-size: var(--text-sm); color: var(--muted-foreground); }
.ev-vstory-cap b { color: var(--foreground); font-weight: 700; font-size: var(--text-base); }
/* Desktop: the three cards sit centred at their full size; the rail only
   scrolls if a window is too narrow for all three. */
@media (min-width: 961px) { .ev-vstories-rail { max-width: calc(3 * 320px + 2 * 32px); margin-inline: auto; } }
/* Phones and tablets: bleed to the right edge so the peeking card reads as
   scrollable. */
@media (max-width: 960px) { .ev-vstories-rail { margin-right: calc(-1 * var(--gutter)); } }
