/* Home page only. */

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

.vvt-progress {
	position: fixed; inset: 0 0 auto 0; z-index: 999;
	height: 3px; background: var(--vv-gold);
	transform: scaleX(0); transform-origin: 0 50%;
}

[data-words] { display: block; }
.vvt-w { display: inline-block; overflow: hidden; vertical-align: bottom; }
.vvt-w__i { display: inline-block; transform: translateY(105%); transition: transform .9s var(--vv-ease); }
[data-words].is-in .vvt-w__i { transform: none; }

[data-stagger] > * { opacity: 0; transform: translateY(20px); transition: opacity .6s var(--vv-ease), transform .6s var(--vv-ease); }
[data-stagger] > *.is-in { opacity: 1; transform: none; }

[data-parallax] > img { transform: translate3d(0, var(--py, 0), 0); will-change: transform; }

.vvt-kicker {
	display: inline-block; margin-bottom: .9rem;
	font-size: .68rem; font-weight: 700; letter-spacing: .26em;
	text-transform: uppercase; color: var(--vv-gold);
}

.vvt-sec-head { max-width: 720px; margin: 0 auto clamp(1.75rem, 3.5vw, 2.75rem); text-align: center; }
.vvt-sec-head h2 { margin: 0; font-size: var(--vv-h2); }
.vvt-section__more { margin: 2.75rem 0 0; text-align: center; }

/* --------------------------------------------------- hero slider ------ */

/* The banners are plain artwork now - the heading, copy and button are laid
   over them here, and the header floats on top. So the frame is a fixed
   viewport-height block and the picture fills it, rather than the old
   contain-and-match-the-image-ratio arrangement. */
.vvt-slider {
	position: relative;
	min-height: clamp(540px, 88vh, 900px);
	display: grid;
	background: var(--vv-navy-deep);
	overflow: hidden;
}

.vvt-slider__stage { position: absolute; inset: 0; }

.vvt-banner {
	position: absolute; inset: 0;
	background-image: var(--vvt-art-d);
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
	opacity: 0;
	visibility: hidden;
	transition: opacity .8s var(--vv-ease), visibility .8s;
}

.vvt-banner.is-active { opacity: 1; visibility: visible; z-index: 2; }

/* Two scrims, not one: a strong wash on the left so the copy always has
   something to sit on, and a soft top band so the floating header reads
   against a pale photograph. */
.vvt-banner::after {
	content: ""; position: absolute; inset: 0;
	background:
		linear-gradient(90deg, rgba(13, 27, 51, .72) 0%, rgba(13, 27, 51, .45) 38%, rgba(13, 27, 51, 0) 68%),
		linear-gradient(180deg, rgba(13, 27, 51, .5) 0%, rgba(13, 27, 51, 0) 22%);
	pointer-events: none;
}

/* ---- copy over the artwork ---- */

.vvt-banner__inner {
	position: relative; z-index: 2;
	display: flex; align-items: center;
	height: 100%;
	/* Clear of the floating header above and the category strip below. */
	padding: clamp(7rem, 14vh, 10rem) 0 clamp(11rem, 22vh, 14rem);
}

.vvt-banner__copy { max-width: 34rem; color: #fff; }

.vvt-banner__title {
	margin: 0 0 1rem;
	font-family: var(--vv-serif); font-weight: 600;
	font-size: clamp(2.2rem, 5vw, 4rem);
	line-height: 1.08; letter-spacing: .005em;
	color: #fff;
	opacity: 0; transform: translateY(22px);
	transition: opacity .8s var(--vv-ease) .15s, transform .8s var(--vv-ease) .15s;
}

.vvt-banner__text {
	max-width: 26rem; margin: 0 0 1.9rem;
	font-size: clamp(.95rem, 1.3vw, 1.1rem); line-height: 1.6;
	color: rgba(255, 255, 255, .88);
	opacity: 0; transform: translateY(22px);
	transition: opacity .8s var(--vv-ease) .3s, transform .8s var(--vv-ease) .3s;
}

.vvt-banner__cta {
	display: inline-flex; align-items: center; justify-content: center;
	padding: 1rem 2.4rem;
	border: 1px solid rgba(255, 255, 255, .55);
	background: rgba(255, 255, 255, .12);
	backdrop-filter: blur(6px);
	color: #fff !important;
	font-size: .76rem; font-weight: 600;
	letter-spacing: .18em; text-transform: uppercase;
	opacity: 0; transform: translateY(22px);
	transition: opacity .8s var(--vv-ease) .45s, transform .8s var(--vv-ease) .45s,
		background .25s var(--vv-ease), border-color .25s var(--vv-ease), color .25s var(--vv-ease);
}

.vvt-banner__cta:hover { background: #fff; border-color: #fff; color: var(--vv-navy) !important; }

.vvt-banner.is-active .vvt-banner__title,
.vvt-banner.is-active .vvt-banner__text,
.vvt-banner.is-active .vvt-banner__cta { opacity: 1; transform: none; }

/* ---- collections along the bottom of the hero ---- */

.vvt-slider__cats {
	position: absolute; left: 50%; bottom: clamp(1.25rem, 3vh, 2.25rem); z-index: 5;
	transform: translateX(-50%);
	display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: clamp(.6rem, 1.2vw, 1rem);
}

.vvt-cat {
	display: grid; grid-template-columns: 46px minmax(0, 1fr);
	gap: .75rem; align-items: center;
	padding: .8rem .95rem;
	background: rgba(255, 255, 255, .14);
	border: 1px solid rgba(255, 255, 255, .3);
	backdrop-filter: blur(10px);
	color: #fff;
	transition: background .25s var(--vv-ease), border-color .25s var(--vv-ease), transform .25s var(--vv-ease);
}

.vvt-cat:hover { background: rgba(255, 255, 255, .26); border-color: rgba(255, 255, 255, .55); color: #fff; transform: translateY(-3px); }

.vvt-cat__img { display: block; width: 46px; height: 46px; overflow: hidden; background: rgba(255, 255, 255, .18); }
.vvt-cat__img img { width: 100%; height: 100%; object-fit: cover; }

.vvt-cat__body { display: grid; gap: .1rem; min-width: 0; }
.vvt-cat__body strong { font-size: .82rem; font-weight: 700; letter-spacing: .04em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vvt-cat__body em { font-style: normal; font-size: .72rem; color: rgba(255, 255, 255, .78); }

/* ---- controls ---- */

.vvt-slider__nav {
	position: absolute; top: 46%; z-index: 4;
	transform: translateY(-50%);
	display: grid; place-items: center;
	width: 44px; height: 44px;
	border: 1px solid rgba(255, 255, 255, .4); border-radius: 50%;
	background: rgba(255, 255, 255, .12);
	backdrop-filter: blur(6px);
	color: #fff;
	cursor: pointer;
	transition: background .2s, color .2s;
}

.vvt-slider__nav:hover { background: #fff; color: var(--vv-navy); }
.vvt-slider__nav--prev { left: clamp(.5rem, 1.5vw, 1.25rem); }
.vvt-slider__nav--next { right: clamp(.5rem, 1.5vw, 1.25rem); }

.vvt-slider__dots {
	position: absolute; bottom: clamp(9rem, 18vh, 11.5rem); left: clamp(1.25rem, 6vw, 5rem); z-index: 5;
	display: flex; gap: .5rem;
}

.vvt-slider__dot {
	width: 34px; height: 3px; padding: 0; border: 0;
	background: rgba(255, 255, 255, .35);
	cursor: pointer; overflow: hidden;
	transition: background .2s;
}

.vvt-slider__dot.is-active { background: rgba(255, 255, 255, .5); }

/* Progress fill inside the active dot, so the auto-advance is visible. */
.vvt-slider__dot span {
	display: block; height: 100%; width: 100%;
	background: #fff;
	transform: scaleX(0); transform-origin: 0 50%;
}

.vvt-slider__dot.is-active span { animation: vvt-tick var(--vv-slide-speed, 6s) linear forwards; }

@keyframes vvt-tick { to { transform: scaleX(1); } }

@media (max-width: 1000px) {
	.vvt-slider__cats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.vvt-banner__inner { padding-bottom: clamp(13rem, 30vh, 17rem); }
	.vvt-slider__dots { bottom: clamp(11.5rem, 27vh, 15rem); }
}

@media (max-width: 720px) {
	.vvt-slider { min-height: clamp(520px, 92vh, 760px); }
	.vvt-banner { background-image: var(--vvt-art-m, var(--vvt-art-d)); }

	/* The left-to-right wash does nothing on a portrait crop; a bottom-up one
	   keeps the copy readable wherever the subject sits. */
	.vvt-banner::after {
		background: linear-gradient(180deg, rgba(13, 27, 51, .55) 0%, rgba(13, 27, 51, .2) 30%, rgba(13, 27, 51, .8) 100%);
	}

	.vvt-banner__inner { align-items: flex-end; padding: 6rem 0 14rem; }
	.vvt-banner__copy { max-width: none; }
	.vvt-slider__nav { display: none; }
	.vvt-slider__dots { bottom: 12.5rem; left: 50%; transform: translateX(-50%); }
	.vvt-cat { padding: .6rem .7rem; grid-template-columns: 36px minmax(0, 1fr); }
	.vvt-cat__img { width: 36px; height: 36px; }
}

/* ------------------------------------------------------- editorial ---- */

.vvt-edit { padding: clamp(3rem, 7vw, 5.5rem) 0; }
.vvt-edit__grid { display: grid; grid-template-columns: .9fr 1.1fr; gap: clamp(1.5rem, 4vw, 3.5rem); align-items: center; }
.vvt-edit__copy h2 { font-size: var(--vv-h2); }
.vvt-edit__copy p { color: var(--vv-muted); max-width: 42ch; margin-bottom: 1.75rem; }
.vvt-edit__cta { display: flex; flex-wrap: wrap; gap: .7rem; }


/* ---------------------------------------------------------- chips ----- */

.vvt-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem; margin-bottom: 2rem; }

.vvt-chips a {
	padding: .5rem 1.1rem; border: 1px solid var(--vv-line); background: #fff;
	font-size: .74rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
	color: var(--vv-ink); transition: background .2s, color .2s, border-color .2s;
}

.vvt-chips a:hover { background: var(--vv-navy); border-color: var(--vv-navy); color: #fff; }

/* ---------------------------------------------------------- story ----- */

.vvt-story { padding: clamp(3rem, 7vw, 5.5rem) 0; background: var(--vv-cream); overflow: hidden; }
.vvt-story__grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.5rem, 4vw, 3.5rem); align-items: center; }
.vvt-story__media { margin: 0; overflow: hidden; aspect-ratio: 4 / 5; background: var(--vv-sand); }
.vvt-story__media img { width: 100%; height: 100%; object-fit: cover; }
.vvt-story__copy h2 { font-size: var(--vv-h2); }
.vvt-story__copy p { color: var(--vv-muted); max-width: 46ch; }

/* The line that carries the About page's closing thought onto the home page.
   The wash is a gradient rather than a painted stroke, so it reflows with the
   text instead of stretching when the line wraps. */
.vvt-story__copy .vvt-story__couplet {
	display: inline-block;
	margin: 0 0 1.9rem;
	padding: .45rem .95rem;
	background: linear-gradient(var(--vv-cream-deep), var(--vv-cream-deep));
	font-family: var(--vv-serif); font-size: 1rem; font-style: italic;
	line-height: 1.5; color: var(--vv-navy);
}

.vvt-counts {
	display: grid; grid-template-columns: repeat(3, auto); justify-content: start;
	gap: 1.75rem; margin: 2rem 0; padding: 1.5rem 0;
	list-style: none; border-top: 1px solid var(--vv-line); border-bottom: 1px solid var(--vv-line);
}

.vvt-counts li { display: grid; gap: .2rem; }
.vvt-counts b { font-family: var(--vv-serif); font-size: clamp(1.6rem, 3vw, 2.3rem); color: var(--vv-navy); line-height: 1; }
.vvt-counts span { font-size: .68rem; letter-spacing: .14em; text-transform: uppercase; color: var(--vv-muted); }

/* --------------------------------------------------------- browse ----- */

.vvt-browse { padding: clamp(3rem, 7vw, 5rem) 0; overflow: hidden; }
.vvt-browse__head { text-align: center; margin-bottom: 2.5rem; }
.vvt-browse__head h2 { margin: 0; font-size: var(--vv-h2); }

.vvt-browse__track { display: flex; gap: 1rem; width: max-content; animation: vvt-drift 44s linear infinite; }
.vvt-browse:hover .vvt-browse__track { animation-play-state: paused; }

@keyframes vvt-drift { to { transform: translateX(-50%); } }

.vvt-browse__card { flex: 0 0 auto; width: 230px; display: grid; gap: .5rem; text-align: center; }
/* 2:3, matching the vvt-card crop the photos are served at. It was 3:4, so
   cover scaled the picture to the wider box and shaved 11% off the height -
   which on a full-length product shot is the model's head and feet. */
.vvt-browse__img { display: block; aspect-ratio: 2 / 3; overflow: hidden; background: var(--vv-cream); }
.vvt-browse__img img { width: 100%; height: 100%; object-fit: cover; transition: transform .7s var(--vv-ease); }
.vvt-browse__card:hover .vvt-browse__img img { transform: scale(1.07); }
.vvt-browse__card strong { font-family: var(--vv-serif); font-size: 1.05rem; }
.vvt-browse__card em { font-style: normal; font-size: .66rem; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--vv-gold); }

/* --------------------------------------------------- testimonials ----- */

.vvt-testi {
	position: relative;
	isolation: isolate;
	padding: clamp(3rem, 7vw, 5rem) 0 clamp(3.5rem, 8vw, 6rem);
	background-color: var(--vv-cream);
	color: var(--vv-navy);
	overflow: hidden;
}

/* The artwork lives on its own layer so it can be softened. Inset bleed keeps
   the blur from feathering the section edges. */
.vvt-testi::before {
	content: "";
	position: absolute;
	inset: -12px;
	z-index: -2;
	background-image: var(--vv-testi-bg);
	background-size: cover;
	background-position: center top;
	background-repeat: no-repeat;
	filter: blur(1.5px);
}

/* Cream veil: the eyebrow is small gold type and was landing on the gold
   arch, where it all but disappeared. */
.vvt-testi::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: rgba(247, 240, 227, .5);
}

.vvt-testi__inner { position: relative; z-index: 2; }
.vvt-testi__head { text-align: center; margin-bottom: clamp(1.75rem, 3.5vw, 2.75rem); }

/* Small ornaments either side of the eyebrow. */
.vvt-testi__eyebrow {
	display: inline-flex; align-items: center; gap: .9rem;
	font-size: .78rem; font-weight: 700; letter-spacing: .26em;
	text-transform: uppercase;
	/* Deeper than the usual gold: this is small, wide-tracked type sitting on
	   patterned artwork, so it needs the extra contrast. */
	color: #6f4a1c;
}

.vvt-testi__eyebrow::before,
.vvt-testi__eyebrow::after {
	content: ""; width: 38px; height: 1px;
	background: linear-gradient(90deg, transparent, var(--vv-gold));
}

.vvt-testi__eyebrow::after { background: linear-gradient(90deg, var(--vv-gold), transparent); }

.vvt-testi__title {
	margin: .6rem 0 0;
	font-size: var(--vv-h2);
	color: var(--vv-navy);
}

.vvt-testi__rule {
	display: block; width: 260px; max-width: 60%; height: 9px;
	margin: .9rem auto 0;
	background:
		linear-gradient(90deg, transparent, var(--vv-gold) 20%, var(--vv-gold) 80%, transparent) center/100% 1px no-repeat,
		radial-gradient(circle, var(--vv-gold) 2.5px, transparent 3px) center/9px 9px no-repeat;
}

/* stage + arrows */
.vvt-testi__stage { position: relative; display: flex; align-items: center; gap: 1rem; }
.vvt-testi__viewport { flex: 1; overflow: hidden; padding: .5rem 0; }

.vvt-testi__track {
	display: flex; margin: 0; padding: 0; list-style: none;
	transition: transform .6s var(--vv-ease);
}

.vvt-testi__item { flex: 0 0 33.3333%; padding: 0 .6rem; box-sizing: border-box; display: flex; }

.vvt-testi__nav {
	flex: 0 0 auto;
	display: grid; place-items: center;
	width: 42px; height: 42px;
	border: 0; border-radius: 50%;
	background: var(--vv-navy); color: #fff;
	cursor: pointer;
	transition: background .2s, transform .2s;
}

.vvt-testi__nav:hover { background: var(--vv-navy-deep); transform: scale(1.08); }

/* the arch card */
.vvt-testi__card {
	position: relative;
	margin: 0;
	display: flex; flex-direction: column; align-items: center;
	width: 100%;
	padding: 3.25rem 1.6rem 1.9rem;
	text-align: center;
	background: rgba(253, 249, 241, .72);
	border: 1px solid rgba(192, 143, 78, .55);
	border-radius: 50% 50% 8px 8px / 26% 26% 8px 8px;
	backdrop-filter: blur(2px);
}

.vvt-testi__mark {
	font-family: var(--vv-serif); font-size: 3.4rem; line-height: .7;
	color: var(--vv-gold); margin-bottom: .6rem;
}

.vvt-testi__card blockquote {
	margin: 0 0 1.1rem;
	font-size: .93rem; line-height: 1.7;
	color: var(--vv-navy);
	max-width: 30ch;
}

.vvt-testi__stars { display: flex; gap: .22rem; color: var(--vv-gold); font-size: 1rem; line-height: 1; }
.vvt-testi__stars i { font-style: normal; }

.vvt-testi__card figcaption { display: grid; gap: .15rem; margin-top: 1.1rem; }
.vvt-testi__card strong { font-family: var(--vv-serif); font-size: 1.02rem; color: var(--vv-navy); }
.vvt-testi__card em { font-style: normal; font-size: .8rem; color: rgba(20, 40, 74, .68); }

.vvt-testi__foot {
	display: block; width: 92px; height: 7px; margin-top: 1.1rem;
	background:
		linear-gradient(90deg, transparent, var(--vv-gold) 25%, var(--vv-gold) 75%, transparent) center/100% 1px no-repeat,
		radial-gradient(circle, var(--vv-gold) 2px, transparent 2.5px) center/7px 7px no-repeat;
}

/* dots */
.vvt-testi__dots { display: flex; justify-content: center; gap: .5rem; margin-top: clamp(1.5rem, 3vw, 2.25rem); }

.vvt-testi__dot {
	width: 10px; height: 10px; padding: 0; border: 0; border-radius: 50%;
	background: rgba(192, 143, 78, .5); cursor: pointer;
	transition: background .2s, transform .2s;
}

.vvt-testi__dot.is-active { background: var(--vv-navy); transform: scale(1.15); }

/* ---------------------------------------------------------- promo ----- */

.vvt-promo { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }

.vvt-promo__card {
	position: relative; padding: 2.25rem 1.6rem 1.75rem;
	background: var(--vv-cream); border: 1px solid var(--vv-line);
	transition: transform .3s var(--vv-ease), box-shadow .3s var(--vv-ease);
}

.vvt-promo__card:hover { transform: translateY(-6px); box-shadow: var(--vv-shadow); }
.vvt-promo__num { position: absolute; top: .9rem; right: 1.1rem; font-family: var(--vv-serif); font-size: 1.5rem; color: var(--vv-gold); opacity: .6; }
.vvt-promo__card h3 { margin-bottom: .5rem; }
.vvt-promo__card p { color: var(--vv-muted); font-size: .93rem; }

/* -------------------------------------------------------- marquee ----- */

.vvt-marquee { overflow: hidden; padding: 1rem 0; background: var(--vv-ink); color: var(--vv-cream); white-space: nowrap; }
.vvt-marquee__track { display: inline-flex; align-items: center; gap: 1.6rem; animation: vvt-scroll 42s linear infinite; }
.vvt-marquee:hover .vvt-marquee__track { animation-play-state: paused; }

@keyframes vvt-scroll { to { transform: translateX(-33.333%); } }

.vvt-marquee__item { font-size: .78rem; font-weight: 600; letter-spacing: .2em; text-transform: uppercase; }
.vvt-marquee__dot { color: var(--vv-gold); font-size: .72rem; }

/* -------------------------------------------------------- service ----- */

/* One piece of artwork per breakpoint. `contain` plus the image's own ratio
   (written into the rule from PHP) means it is shown whole at every width. */
.vvt-serve { background: var(--vv-cream); }

.vvt-serve__art {
	display: block;
	width: 100%;
	background-size: contain;
	background-position: center;
	background-repeat: no-repeat;
	/* Replaced by the real dimensions in the inline rule; only a pre-load guess. */
	aspect-ratio: 2103 / 748;
}

/* ----------------------------------------------------- responsive ----- */

@media (max-width: 1100px) {
	.vvt-promo { grid-template-columns: 1fr 1fr; }
	.vvt-testi__item { flex-basis: 50%; }

}

@media (max-width: 900px) {
	.vvt-edit__grid, .vvt-story__grid { grid-template-columns: 1fr; }
	.vvt-story__media { order: -1; max-width: 440px; margin-inline: auto; }
	.vvt-counts { justify-content: space-between; }
}

@media (max-width: 720px) {
	.vvt-promo { grid-template-columns: 1fr; }
	/* Portrait artwork on phones - background swaps live with the query. */
	.vvt-banner { background-image: var(--vvt-art-m, var(--vvt-art-d)); }
	/* Sits in the gap between the copy and the models, aligned with the text. */
	.vvt-banner__cta { top: 37%; left: 11%; padding: .65rem 1.1rem; font-size: .64rem; }
	.vvt-slider__nav { width: 34px; height: 34px; }
	.vvt-slider__dot { width: 24px; }

	.vvt-testi__item { flex-basis: 100%; }

	/* Portrait artwork on a phone. The section takes the image's own aspect
	   ratio, so the artwork always spans the full width with no bars down the
	   sides. If the cards ever need more room the box grows and `cover` trims
	   from the top and bottom rather than leaving a gap. */
	/* `cover` already guarantees the artwork fills the full width, so the
	   section is left to size itself to its content - no fixed ratio to clip
	   against, and the shell keeps its own side margin. */
	.vvt-testi::before {
		inset: 0;
		background-image: var(--vv-testi-bg-mob, var(--vv-testi-bg));
		background-size: cover;
		background-position: center center;
	}

	/* The card was overpowering the frame it sits inside - pull it in. */
	.vvt-testi__card {
		border-radius: 50% 50% 8px 8px / 16% 16% 8px 8px;
		max-width: min(300px, 100%);
		margin-inline: auto;
		padding: 2.25rem 1.15rem 1.4rem;
	}

	.vvt-testi__mark { font-size: 2.6rem; margin-bottom: .4rem; }
	.vvt-testi__card blockquote { font-size: .84rem; line-height: 1.6; margin-bottom: .9rem; max-width: 27ch; }
	.vvt-testi__stars { font-size: .9rem; }
	.vvt-testi__card figcaption { margin-top: .85rem; }
	.vvt-testi__card strong { font-size: .95rem; }
	.vvt-testi__card em { font-size: .74rem; }
	.vvt-testi__foot { width: 74px; margin-top: .85rem; }

	/* Float the arrows over the card here - side by side they eat a third of
	   the width on a phone. */
	.vvt-testi__stage { gap: 0; }

	.vvt-testi__nav {
		position: absolute; top: 50%; z-index: 3;
		transform: translateY(-50%);
		width: 36px; height: 36px;
		box-shadow: 0 4px 14px rgba(13, 27, 51, .28);
	}

	.vvt-testi__nav:hover { transform: translateY(-50%) scale(1.08); }
	.vvt-testi__nav--prev { left: -6px; }
	.vvt-testi__nav--next { right: -6px; }
	.vvt-counts { grid-template-columns: repeat(3, 1fr); gap: .5rem; }
	.vvt-browse__card { width: 165px; }
}

@media (prefers-reduced-motion: reduce) {
	.vvt-marquee__track, .vvt-browse__track { animation: none; }
	.vvt-w__i { transform: none; }
	[data-stagger] > * { opacity: 1; transform: none; }
}

/* --------------------------------------- hero: artwork vs overlay ------ */

/* A slide with no heading is finished artwork - show it whole, no scrim, no
   text of ours on top of the words already printed in the picture. */
.vvt-banner--art { background-size: contain; }
.vvt-banner--art::after { display: none; }

/* A slide with a heading is a plain photograph we write over, so it fills the
   frame and takes a scrim sized to the text colour. */
.vvt-banner--copy { background-size: cover; }

/* Pale photograph, dark words: the wash only has to lift the left edge a
   little, and the copy is navy rather than white. */
.vvt-banner--ink-dark.vvt-banner--copy::after {
	background: linear-gradient(90deg, rgba(255, 255, 255, .78) 0%, rgba(255, 255, 255, .5) 34%, rgba(255, 255, 255, 0) 62%);
}

.vvt-banner--ink-dark .vvt-banner__copy { color: var(--vv-ink); }
.vvt-banner--ink-dark .vvt-banner__title { color: var(--vv-ink); }
.vvt-banner--ink-dark .vvt-banner__text { color: var(--vv-muted); }

.vvt-banner--ink-dark .vvt-banner__cta {
	border-color: var(--vv-navy);
	background: var(--vv-navy);
	color: #fff !important;
}

.vvt-banner--ink-dark .vvt-banner__cta:hover { background: var(--vv-navy-deep); border-color: var(--vv-navy-deep); }

/* Copy sits at a calmer size than the first pass - it is a banner line, not a
   page headline. */
.vvt-banner__title { font-size: clamp(1.7rem, 3.2vw, 2.7rem); }
.vvt-banner__text { font-size: clamp(.9rem, 1.05vw, 1rem); max-width: 24rem; }
.vvt-banner__copy { max-width: 30rem; }
.vvt-banner__cta { padding: .85rem 2rem; font-size: .72rem; }

/* A pale slide needs dark controls too. */
.vvt-banner--ink-dark ~ .vvt-slider__nav,
.vvt-slider:has(.vvt-banner--ink-dark.is-active) .vvt-slider__nav {
	border-color: rgba(28, 36, 51, .3); background: rgba(255, 255, 255, .7); color: var(--vv-navy);
}

.vvt-slider:has(.vvt-banner--ink-dark.is-active) .vvt-cat {
	background: rgba(255, 255, 255, .6);
	border-color: rgba(28, 36, 51, .16);
	color: var(--vv-ink);
}

.vvt-slider:has(.vvt-banner--ink-dark.is-active) .vvt-cat:hover { background: rgba(255, 255, 255, .85); color: var(--vv-ink); }
.vvt-slider:has(.vvt-banner--ink-dark.is-active) .vvt-cat__body em { color: var(--vv-muted); }
.vvt-slider:has(.vvt-banner--ink-dark.is-active) .vvt-slider__dot { background: rgba(28, 36, 51, .25); }
.vvt-slider:has(.vvt-banner--ink-dark.is-active) .vvt-slider__dot span { background: var(--vv-navy); }

/* And a pale slide means the floating header needs its dark type back. */
.vvt-page--over:has(.vvt-banner--ink-dark.is-active) .vvt-header--over:not(.is-stuck) .vvt-iconbtn,
.vvt-page--over:has(.vvt-banner--ink-dark.is-active) .vvt-header--over:not(.is-stuck) .vvt-burger span { color: var(--vv-ink); }

.vvt-page--over:has(.vvt-banner--ink-dark.is-active) .vvt-header--over:not(.is-stuck) .vvt-burger span { background: var(--vv-ink); }
.vvt-page--over:has(.vvt-banner--ink-dark.is-active) .vvt-header--over:not(.is-stuck) .vvt-header__brand img { filter: none; }

/* ------------------------------- hero: true to the artwork, bigger tiles */

/* Height comes from the picture's own ratio (anim.js writes it), so cover
   fills the frame exactly - no crop, no letterbox. min-height is only the
   floor for a very wide, very short banner. */
.vvt-slider {
	min-height: 0;
	aspect-ratio: 1707 / 921;
	max-height: 92vh;
}

/* Copy clears the floating header above and the tiles below. */
.vvt-banner__inner { padding: clamp(5rem, 11vh, 8rem) 0 clamp(9rem, 18vh, 12rem); }

/* ---- collection tiles ---- */

.vvt-slider__cats { gap: clamp(.7rem, 1.4vw, 1.15rem); }

.vvt-cat {
	grid-template-columns: 72px minmax(0, 1fr);
	gap: 1rem;
	padding: .85rem 1.1rem;
	border-radius: var(--vv-radius);
}

.vvt-cat__img { width: 72px; height: 72px; border-radius: 6px; }

.vvt-cat__body strong { font-size: 1rem; letter-spacing: .01em; }
.vvt-cat__body em { font-size: .78rem; }

@media (max-width: 1000px) {
	.vvt-cat { grid-template-columns: 58px minmax(0, 1fr); }
	.vvt-cat__img { width: 58px; height: 58px; }
	.vvt-cat__body strong { font-size: .92rem; }
}

@media (max-width: 720px) {
	.vvt-slider { aspect-ratio: auto; min-height: clamp(520px, 92vh, 780px); }
	.vvt-cat { grid-template-columns: 46px minmax(0, 1fr); padding: .7rem .8rem; }
	.vvt-cat__img { width: 46px; height: 46px; }
	.vvt-cat__body strong { font-size: .85rem; }
	.vvt-cat__body em { font-size: .72rem; }
}

/* ------------------------------------ new arrivals banner band --------- */

.vvt-nabanner { display: block; margin: 0; }
.vvt-nabanner img { width: 100%; height: auto; }
.vvt-nabanner__m { display: none; }

@media (max-width: 720px) {
	.vvt-nabanner__d { display: none; }
	.vvt-nabanner__m { display: block; }
}

/* The height cap fought the fixed ratio: on a wide screen it shortened the
   banner, and because the ratio is locked the width shrank with it, leaving a
   bare strip down the right. The picture's own shape governs, nothing else. */
.vvt-slider { max-height: none; }

/* --------------------------- bigger tiles, bigger banner copy ---------- */

/* Portrait product shots were being cropped square. A 3:4 well keeps the whole
   garment in frame, and `contain` means nothing is cut off at all. */
.vvt-cat {
	grid-template-columns: 96px minmax(0, 1fr);
	gap: 1.1rem;
	padding: 1rem 1.25rem;
}

.vvt-cat__img {
	width: 96px; height: 122px;
	background: rgba(255, 255, 255, .55);
	border-radius: 6px;
}

.vvt-cat__img img { object-fit: contain; }

.vvt-cat__body strong { font-size: 1.1rem; }
.vvt-cat__body em { font-size: .84rem; }

/* Banner copy a size up - it is the first thing on the page. */
.vvt-banner__title { font-size: clamp(2.1rem, 4vw, 3.4rem); }
.vvt-banner__text { font-size: clamp(1rem, 1.25vw, 1.15rem); max-width: 27rem; }
.vvt-banner__copy { max-width: 34rem; }
.vvt-banner__cta { padding: 1rem 2.3rem; font-size: .78rem; }

/* The tiles are taller now, so the copy needs more room above them. */
.vvt-banner__inner { padding-bottom: clamp(11rem, 21vh, 14rem); }

@media (max-width: 1000px) {
	.vvt-cat { grid-template-columns: 74px minmax(0, 1fr); }
	.vvt-cat__img { width: 74px; height: 94px; }
	.vvt-cat__body strong { font-size: .98rem; }
}

@media (max-width: 720px) {
	.vvt-cat { grid-template-columns: 56px minmax(0, 1fr); padding: .75rem .85rem; }
	.vvt-cat__img { width: 56px; height: 72px; }
	.vvt-cat__body strong { font-size: .88rem; }
	.vvt-cat__body em { font-size: .74rem; }
}

/* --------------------------- hero: tiles below the picture, not over it --- */

/* The collections were laid over the foot of the hero. On a wide desktop
   banner that works - there is a quiet strip down there to sit on. Under
   1000px the frame is far shorter than the copy and the tiles together need,
   so they collided: on a tablet the copy ran across the tiles, and on a phone
   the tiles sat on the model.

   So below 1000px the hero stops being one stacked frame. The stage takes the
   picture's own shape - anim.js writes the ratio per slide, functions.php
   prints slide one's as the floor for before the script runs - and the tiles
   drop into the flow underneath it.

   All of this is deliberately last in the file: the blocks above re-declare
   these same rules, and the later one wins. */
@media (max-width: 1000px) {
	.vvt-slider { aspect-ratio: auto; min-height: 0; display: block; }
	.vvt-slider__stage { position: relative; inset: auto; }

	/* Nothing left below the copy to clear. */
	.vvt-banner__inner { align-items: flex-end; padding: 3rem 0 2rem; }

	.vvt-slider__cats {
		position: static; transform: none;
		width: 100%; padding-block: 1.1rem 1.35rem;
	}

	/* Out of the tiles' old spot and back onto the picture. */
	.vvt-slider__dots { bottom: auto; top: .9rem; left: 50%; transform: translateX(-50%); }
}

@media (max-width: 720px) {
	/* The 90deg wash is cut for a wide banner with its copy down the left-hand
	   side. On the phone crop the copy runs the full width along the foot, so
	   the wash has to rise from the bottom instead - and stay pale, because
	   this artwork is set in dark ink. */
	.vvt-banner--ink-dark.vvt-banner--copy::after {
		background: linear-gradient(180deg, rgba(255, 255, 255, 0) 26%, rgba(255, 255, 255, .74) 60%, rgba(255, 255, 255, .93) 100%);
	}

	/* --vv-muted is a warm grey, and against the beige wall in the phone
	   artwork it vanished. Dark enough to read, still a step under the
	   headline. */
	.vvt-banner--ink-dark .vvt-banner__text { color: rgba(28, 36, 51, .82); }

	.vvt-banner__inner { padding: 2.5rem 0 1.75rem; }
}

/* --------------------------------- what we stand for ------------------- */

/* A card that lifts into the banner above it, so the two read as one block
   rather than two stacked bands. The negative pull is undone on a phone,
   where the banner is square and there is no quiet strip to lift into. */
.vvt-marks { position: relative; z-index: 3; margin-top: clamp(-4.5rem, -5vw, -2rem); }

.vvt-marks__list {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 0;
	margin: 0; padding: 0;
	list-style: none;
	background: #fff;
	border: 1px solid var(--vv-line);
	border-radius: var(--vv-radius-lg);
	box-shadow: var(--vv-shadow);
	overflow: hidden;
}

.vvt-marks__item {
	display: flex; align-items: center; gap: .9rem;
	padding: 1.35rem 1.5rem;
	border-right: 1px solid var(--vv-line);
}

.vvt-marks__item:last-child { border-right: 0; }

.vvt-marks__ico { display: grid; place-items: center; flex: 0 0 auto; color: var(--vv-gold-deep); }
.vvt-marks__ico svg { width: 30px; height: 30px; stroke-width: 1.2; }

.vvt-marks__body { display: grid; gap: .15rem; min-width: 0; }
.vvt-marks__body strong { font-family: var(--vv-serif); font-size: .95rem; color: var(--vv-ink); }
.vvt-marks__body em { font-style: normal; font-size: .76rem; color: var(--vv-muted); line-height: 1.45; }

@media (max-width: 1000px) {
	.vvt-marks__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.vvt-marks__item:nth-child(2n) { border-right: 0; }
	.vvt-marks__item:nth-child(-n+2) { border-bottom: 1px solid var(--vv-line); }
}

@media (max-width: 720px) {
	.vvt-marks { margin-top: 1.5rem; }
	.vvt-marks__item { padding: 1.1rem; }
	.vvt-marks__ico svg { width: 26px; height: 26px; }
}

/* ------------------------------------- shop by category (discs) -------- */

.vvt-cats { padding: clamp(3rem, 6vw, 4.5rem) 0 clamp(1rem, 2vw, 2rem); }

.vvt-cats__head { text-align: center; margin-bottom: clamp(1.75rem, 3vw, 2.5rem); }
.vvt-cats__head h2 { margin: 0; font-size: var(--vv-h2); }
.vvt-cats__head .vvt-divider,
.vvt-picks .vvt-sec-head .vvt-divider {
	/* justify-content alone did nothing: the divider is a plain block, so the
	   svg inside it just sat at the left edge. */
	display: flex; justify-content: center;
	margin-top: .6rem;
}

/* The rail. Arrows sit outside it on a wide screen and overlap it once the
   shell runs out of gutter. */
.vvt-cats__wrap { position: relative; }

.vvt-cats__rail {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: calc((100% - 5 * clamp(1rem, 2.2vw, 2rem)) / 6);
	gap: clamp(1rem, 2.2vw, 2rem);
	margin: 0; padding: 4px;
	list-style: none;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	overscroll-behavior-x: contain;
}

.vvt-cats__rail::-webkit-scrollbar { display: none; }
.vvt-cats__rail > li { scroll-snap-align: start; }

.vvt-cats__nav {
	position: absolute; top: calc(50% - 1.4rem); z-index: 2;
	display: grid; place-items: center;
	width: 40px; height: 40px; padding: 0;
	transform: translateY(-50%);
	background: #fff;
	color: var(--vv-navy);
	border: 1px solid var(--vv-line);
	border-radius: 50%;
	box-shadow: var(--vv-shadow-sm);
	cursor: pointer;
	transition: background .2s var(--vv-ease), color .2s var(--vv-ease);
}

.vvt-cats__nav:hover { background: var(--vv-navy); color: #fff; border-color: var(--vv-navy); }
.vvt-cats__nav[hidden] { display: none; }
.vvt-cats__nav--prev { left: -20px; }
.vvt-cats__nav--next { right: -20px; }

@media (max-width: 1360px) {
	.vvt-cats__nav--prev { left: 0; }
	.vvt-cats__nav--next { right: 0; }
}

@media (max-width: 1000px) { .vvt-cats__rail { grid-auto-columns: calc((100% - 3 * 1.25rem) / 4); } }
@media (max-width: 640px)  { .vvt-cats__rail { grid-auto-columns: calc((100% - 2 * 1rem) / 2.6); gap: 1rem; } }

/* The disc is the whole point of this row: a circular well the photograph
   fills, so a rail of very different product shots still reads as one set. */
.vvt-cats__disc {
	display: grid; place-items: center;
	width: 100%; aspect-ratio: 1;
	overflow: hidden;
	border-radius: 50%;
	background: var(--vv-cream-deep);
	transition: transform .3s var(--vv-ease), box-shadow .3s var(--vv-ease);
}

.vvt-cats__disc img { width: 100%; height: 100%; object-fit: cover; }

.vvt-cats__item:hover .vvt-cats__disc { transform: translateY(-4px); box-shadow: var(--vv-shadow); }

.vvt-cats__item strong {
	font-size: .74rem; font-weight: 700;
	letter-spacing: .14em; text-transform: uppercase;
	color: var(--vv-ink);
}


/* Artwork banners carry no button, so the picture itself is the link. */
.vvt-banner__hit { position: absolute; inset: 0; z-index: 2; }
.vvt-banner__hit:focus-visible { outline: 3px solid var(--vv-gold); outline-offset: -6px; }

/* The dots used to sit high up the banner to clear the category tiles that
   were laid over it. Those tiles are their own section now, so the dots come
   back down to the foot of the picture - above the promises card, which laps
   over the last of it. */
.vvt-slider__dots { bottom: clamp(4.5rem, 8vh, 6rem); }

@media (max-width: 1000px) { .vvt-slider__dots { bottom: clamp(4rem, 7vh, 5.5rem); } }

@media (max-width: 720px) {
	/* The card no longer overlaps on a phone, so the dots sit right at the edge. */
	.vvt-slider__dots { top: auto; bottom: 1rem; left: 50%; transform: translateX(-50%); }
}

/* ------------------------------------------ bestsellers rail ----------- */

.vvt-picks { padding: clamp(3rem, 6vw, 4.5rem) 0; }
.vvt-picks .vvt-sec-head { text-align: center; margin-bottom: clamp(1.75rem, 3vw, 2.5rem); }

.vvt-picks__wrap { position: relative; }

.vvt-picks__rail {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: calc((100% - 4 * 1.25rem) / 5);
	gap: 1.25rem;
	margin: 0; padding: 4px;
	list-style: none;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	overscroll-behavior-x: contain;
}

.vvt-picks__rail::-webkit-scrollbar { display: none; }
.vvt-picks__rail > li { scroll-snap-align: start; }

.vvt-picks__card { display: grid; gap: .55rem; text-align: center; }

.vvt-picks__img {
	display: block; aspect-ratio: 2 / 3;
	overflow: hidden;
	background: var(--vv-cream-deep);
}

.vvt-picks__img img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--vv-ease); }
.vvt-picks__card:hover .vvt-picks__img img { transform: scale(1.05); }

.vvt-picks__card strong {
	font-family: var(--vv-serif); font-size: .95rem; font-weight: 600;
	color: var(--vv-ink); line-height: 1.35;
}

.vvt-picks__price { font-size: .85rem; color: var(--vv-gold-deep); }
.vvt-picks__price .vvw-unit, .vvt-picks__price .vvw-moq { display: none; }

.vvt-picks__nav {
	position: absolute; top: 38%; z-index: 2;
	display: grid; place-items: center;
	width: 40px; height: 40px; padding: 0;
	transform: translateY(-50%);
	background: #fff; color: var(--vv-navy);
	border: 1px solid var(--vv-line); border-radius: 50%;
	box-shadow: var(--vv-shadow-sm);
	cursor: pointer;
	transition: background .2s var(--vv-ease), color .2s var(--vv-ease);
}

.vvt-picks__nav:hover { background: var(--vv-navy); color: #fff; border-color: var(--vv-navy); }
.vvt-picks__nav[hidden] { display: none; }
.vvt-picks__nav--prev { left: -20px; }
.vvt-picks__nav--next { right: -20px; }

@media (max-width: 1360px) {
	.vvt-picks__nav--prev { left: 0; }
	.vvt-picks__nav--next { right: 0; }
}

@media (max-width: 1000px) { .vvt-picks__rail { grid-auto-columns: calc((100% - 2 * 1.25rem) / 3); } }
@media (max-width: 640px)  { .vvt-picks__rail { grid-auto-columns: calc((100% - 1rem) / 2.2); gap: 1rem; } }


/* ============================================================ 2026-09 ===
   Category labels, and the editorial band's picture side.
   ====================================================================== */

/* ------------------------------------------- category disc labels ------ */

/* The disc row's names were sitting hard against the left of each column:
   .vvt-cats__item is an <a>, which is inline by default, so nothing was ever
   centring its contents. Making it a grid gives the disc and the label a
   column of their own to centre in. */
.vvt-cats__item {
	display: grid;
	justify-items: center;
	gap: .85rem;
	text-align: center;
}

.vvt-cats__item strong { line-height: 1.35; }


/* ------------------------------------------- our story artwork -------- */

/* The band is one photograph per breakpoint with the copy laid into the empty
   part of it. The image ratio and URL are written in from PHP, so the picture
   sets the band's height and nothing is cropped. The cream is sampled out of
   the artwork itself: it only shows if the copy ever runs taller than the
   picture, and when it does the join is invisible. */
.vvt-edit--art {
	position: relative;
	display: grid;
	align-items: center;
	padding: 0;
	background-color: #f1decc;
	background-repeat: no-repeat;
	background-position: center;
	background-size: cover;
	/* Replaced by the real image ratio from PHP; only a pre-load guess. */
	aspect-ratio: 1600 / 900;
}

/* The wide crop keeps its left 45% clear, so the copy takes one column there
   instead of the .9fr/1.1fr split the tiles needed. */
.vvt-edit--art .vvt-edit__grid { grid-template-columns: minmax(0, 46%); align-items: center; }
.vvt-edit--art .vvt-edit__copy p { max-width: 36ch; }

@media (max-width: 900px) {
	/* The copy sits on the photograph here too. The tall crop's clear cream
	   runs from about a fifth to just under half its height, and the corner
	   above that carries dark leaves - so a wash in the artwork's own cream is
	   laid over the top half, fading out before it reaches the models. It veils
	   the leaves, holds the type at full contrast, and because the colour is
	   sampled from the picture itself there is no visible edge to it. */
	.vvt-edit--art {
		align-items: start;
		aspect-ratio: auto;
		padding: 0;
	}

	/* The wash exists for one reason: the artwork's top-left corner carries
	   dark leaves that the gold kicker disappears into. Those leaves end at 29%
	   of the band, everything from there to the models is already clean cream,
	   and the standing model's head begins at a flat 50%. So the wash is solid
	   to 36%, spent by 44%, and never reaches her - it was washing over her face
	   before. Cream over cream throughout, so the fade leaves no visible edge. */
	.vvt-edit--art::before {
		content: "";
		position: absolute; inset: 0 0 auto;
		height: 44%;
		background: linear-gradient(
			180deg,
			rgba(241, 222, 204, .95) 0%,
			rgba(241, 222, 204, .95) 82%,
			rgba(241, 222, 204, 0) 100%
		);
	}

	.vvt-edit--art .vvt-edit__grid {
		position: relative; z-index: 1;
		grid-template-columns: 1fr;
		padding-top: clamp(1.5rem, 5vw, 2.25rem);
	}

	.vvt-edit--art .vvt-edit__copy p { max-width: 34ch; }
}

@media (max-width: 560px) {
	/* Tightened so the whole block finishes inside the washed half rather than
	   running down onto the models. */
	.vvt-edit--art .vvt-edit__copy h2 { font-size: clamp(1.4rem, 6.4vw, 1.85rem); margin-bottom: .6rem; }
	.vvt-edit--art .vvt-edit__copy p { font-size: .84rem; line-height: 1.55; margin-bottom: 1.1rem; }
	.vvt-edit--art .vvt-edit__cta { gap: .5rem; }
	.vvt-edit--art .vvt-edit__cta .vvt-btn { padding: .7rem 1.05rem; font-size: .68rem; }
}
@media (max-width: 400px) {
	/* At 360px the block finished about ten pixels past the solid part of the
	   wash, which put the foot of the buttons on the fade. The wash cannot be
	   taken lower - the seated model's hair starts at 48% - so the copy comes
	   up to meet it instead. */
	.vvt-edit--art .vvt-edit__grid { padding-top: 1rem; }
	.vvt-edit--art .vvt-edit__copy h2 { font-size: 1.32rem; margin-bottom: .5rem; }
	.vvt-edit--art .vvt-edit__copy p { font-size: .8rem; line-height: 1.5; margin-bottom: .85rem; }
	.vvt-edit--art .vvt-edit__cta .vvt-btn { padding: .6rem .9rem; font-size: .65rem; }
}
@media (max-width: 340px) {
	/* The heading takes an extra line at this width, which pushed the buttons
	   back onto the fade. Last step down; below this the band is narrower than
	   any phone still in use. */
	.vvt-edit--art .vvt-edit__grid { padding-top: .75rem; }
	.vvt-edit--art .vvt-edit__copy h2 { font-size: 1.18rem; margin-bottom: .4rem; }
	.vvt-edit--art .vvt-edit__copy p { font-size: .76rem; line-height: 1.45; margin-bottom: .7rem; }
	.vvt-edit--art .vvt-edit__cta .vvt-btn { padding: .55rem .8rem; font-size: .62rem; }
}