/* 2026-10-13: role surfaces supersede the historic mint mappings discussed below.
 * White helpers, paper gifts, dark closing actions; mint only for signed Diana quotes.
 */
/*
 * The front page.
 *
 * The first per-page stylesheet, and the reason the plan reserved a pages/
 * directory: this file is enqueued only where it is used, so nine other pages do
 * not carry the hero grid and the price list (plan section 1.1, engineering
 * standards section 7). It loads after components.css and may build on both it
 * and tokens.css; like both of them it declares no colour of its own.
 *
 * MOBILE FIRST, READ BACKWARDS FROM THE MOCKUP. The mockup is authored
 * desktop-first, in `max-width: 920px` blocks. Every one of them appears here as
 * the DEFAULT, with the desktop form restored at 921 px - the same translation
 * components.css performs for the navigation (config/review-rules.md rule 7).
 *
 * TWO NUMBERS WERE SNAPPED TO THE SCALE, and both are written down rather than
 * quietly rounded:
 *
 *   RADII. The design canon has three bands - 12-16 for icon boxes, 20-28 for
 *   cards, 999 for pills (sypsena-design SKILL.md, "Formos"), and qa-tokens
 *   enforces exactly those as T4. The mockup's inline styles reach outside them
 *   in a handful of places (32, 18, 10, 8 px), which is the inline-style drift
 *   AS-61 already names. Each one moves to the nearest value inside the band:
 *   32 -> 28, 18 -> 20, 10 -> 12, 8 -> 12. The mockup itself writes
 *   `clamp(20px, 2.5vw, 28px)` one section further down, so the largest of them
 *   is the file agreeing with itself.
 *
 *   SHADOWS. The mockup casts `0 8px 28px rgba(23,28,33,0.12)` under the hero's
 *   inset photograph; the token with that geometry carries 0.06. The token wins,
 *   for the reason tokens exist.
 */

/* ---------------------------------------------------------------------------
 * Section rhythm
 *
 * The mockup gives every section the same shape: no space above, a generous
 * gap below, and the shared 1100 px container. The hero is the one exception -
 * it opens the page, so it has space above the fold as well.
 */

.fp-section {
	padding-block: 0 clamp( 40px, 6vw, 72px );
}

.fp-hero {
	padding-block: clamp( 28px, 5vw, 64px ) clamp( 32px, 5vw, 64px );
}

/* ---------------------------------------------------------------------------
 * Section heads and shared pieces
 */

.fp-head {
	display: flex;
	flex-direction: column;
	gap: var( --space-2 );
	margin-bottom: clamp( 18px, 3vw, 28px );
}

.fp-head--center {
	align-items: center;
	text-align: center;
}

.fp-head .eyebrow,
.fp-head h2 {
	margin: 0;
}

.fp-lead {
	margin: 0;
	line-height: var( --lh-relaxed );
}

/* Reading widths the mockup sets on single paragraphs. They are deliberately
 * not marked as containers: I11 measures the page's grid, and a paragraph that
 * stops early is a typographic decision rather than a second grid. */
.fp-lead--560 {
	max-width: 560px;
}

.fp-lead--620 {
	max-width: 620px;
}

.fp-lead--640 {
	max-width: 640px;
}

/*
 * Both spans below are targeted by position rather than by class, and that is
 * not laziness. A class attribute inside a translated string means an ASCII
 * quotation mark inside a translated string, which qa-grep reads as G5 - the
 * rule that exists to keep straight quotes out of Lithuanian copy. The markup
 * has to stay in the string so a translator can move the highlighted words; the
 * attribute does not have to go with it.
 */

.fp-hero__title span {
	color: var( --text-link );
}

.fp-master__licence-text span {
	white-space: nowrap;
}

/* Trust and location pills. The mint pair measures 4.54:1 and the green pair
 * 5.72:1 - both cleared for text by the 2026-08-13 pass (invariant I15). */

.fp-pills {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var( --space-2 );
	margin: 0;
}

.fp-pill {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 7px 14px;
	border-radius: var( --radius-pill );
	font-size: var( --fs-eyebrow );
	font-weight: var( --fw-bold );
}

/* flex: 0 0 auto on every icon in a flex row, so a narrow phone cannot squeeze
 * a glyph below its declared size (invariant I8.3). */
.fp-pill .material-symbols-outlined {
	flex: 0 0 auto;
	font-size: 15px;
}

.fp-pill--blue {
	background: var( --tint-ice );
	color: var( --color-accent-text );
}

.fp-pill--green {
	background: var( --color-green );
	color: var( --color-green-ink );
}

/* ---------------------------------------------------------------------------
 * Hero
 */

.fp-hero__grid {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( min( 100%, 330px ), 1fr ) );
	align-items: center;
	gap: clamp( 24px, 4vw, 56px );
}

.fp-hero__copy {
	display: flex;
	flex-direction: column;
	gap: clamp( 14px, 2vw, 20px );
}

.fp-hero__title {
	margin: 0;
}

.fp-hero__lead {
	max-width: 520px;
	margin: 0;
	font-size: clamp( 16px, 2vw, 18px );
	line-height: var( --lh-body );
}

.fp-hero__reviews {
	display: inline-flex;
	align-self: flex-start;
	align-items: center;
	gap: 6px;
	min-height: 44px;
	margin: 0;
	padding-inline: 4px;
	color: var( --text-link );
	font-size: 14px;
	font-weight: var( --fw-bold );
	line-height: 1;
	text-decoration: none;
}

.fp-hero__reviews:hover {
	text-decoration: none;
}

.fp-hero__reviews:focus-visible {
	outline: 3px solid var( --focus-ring );
	outline-offset: 3px;
}

.fp-hero__reviews-thumb,
.fp-hero__reviews-arrow {
	flex: 0 0 auto;
	font-size: 18px;
}

.fp-hero__reviews-thumb {
	font-variation-settings: 'FILL' 0;
}

.fp-hero__reviews-star {
	flex: 0 0 auto;
	color: var( --color-review-spark );
	font-size: 14px;
}

/*
 * THE HERO HAS NO CALL TO ACTION ON A PHONE, and that is the design's own rule
 * rather than a shortcut. Below 921 px the sticky bar carries the booking button
 * at the bottom of every screen, so a second one here is the duplicate primary
 * action invariant I12 forbids. The decision is dated 2026-08-17 - a hero call
 * to action that the sticky bar repeats is hidden below 921 px - and every other
 * page already applies it through the mockups' own .hero-cta; this page is the
 * one that never got the class.
 *
 * The whole row is hidden rather than the button inside it: an empty flex row
 * would still spend the column's gap.
 */
.fp-hero__actions {
	display: none;
}

.fp-hero__media {
	position: relative;
	padding: 0 0 clamp( 24px, 3vw, 34px ) clamp( 24px, 3vw, 34px );
}

/* object-position is transferred exactly: the framing is part of the design
 * decision, and the files hold the whole photograph so the crop can move
 * without a re-export (docs/fotosesija-2017.md). */
.fp-hero__photo {
	width: 100%;
	height: clamp( 320px, 38vw, 460px );
	border-radius: clamp( 20px, 2.5vw, 28px );
	object-fit: cover;
	object-position: 55% 42%;
}

.fp-hero__inset {
	position: absolute;
	bottom: 0;
	left: 0;
	width: clamp( 150px, 18vw, 210px );
	height: clamp( 170px, 20vw, 240px );
	border: 6px solid var( --surface-page );
	border-radius: clamp( 20px, 2vw, 24px );
	box-shadow: var( --shadow-card );
	object-fit: cover;
	object-position: 30% 45%;
}

.fp-hero__chip {
	position: absolute;
	top: clamp( 14px, 2vw, 22px );
	right: clamp( 14px, 2vw, 22px );
	display: inline-flex;
	align-items: center;
	gap: 7px;
	margin: 0;
	padding: 10px 18px;
	/* White at 82 % over the photograph, exactly as drawn. The blur is what
	 * keeps the label readable whatever the frame underneath it is doing. */
	background: rgba( 255, 255, 255, 0.82 );
	backdrop-filter: blur( 10px );
	border-radius: var( --radius-pill );
	color: var( --text-heading );
	font-size: var( --fs-caption );
	font-weight: var( --fw-bold );
}

.fp-hero__chip .material-symbols-outlined {
	flex: 0 0 auto;
	color: var( --text-link );
	font-size: 17px;
}

/* ---------------------------------------------------------------------------
 * The specialist card
 */

.fp-master__card {
	display: grid;
	grid-template-columns: 1fr;
	max-width: 760px;
	margin-inline: auto;
	overflow: hidden;
	background: var( --surface-card );
	border-radius: var( --radius-2xl );
	box-shadow: var( --shadow-card );
}

/*
 * The photograph sits in a positioned wrapper rather than carrying its own
 * height, because `height: 100%` on the `img` itself resolves to `auto` once
 * the card becomes a two-column grid (WPS-069) - a replaced element ignores a
 * percentage height without an explicit height on its containing block, so
 * the image's own aspect ratio ended up dictating the card's height and left
 * empty space under the body's shorter column. The wrapper is an ordinary
 * block box, which grid's default `align-items: stretch` fills to the row's
 * height with no such exception, and the image inside it is absolutely
 * positioned to cover that box exactly.
 */
.fp-master__photo-wrap {
	position: relative;
	min-height: 0;
	height: clamp( 240px, 60vw, 320px );
}

.fp-master__photo {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: 50% 18%;
}

.fp-master__body {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: var( --space-3 );
	padding: clamp( 20px, 3vw, 30px );
}

.fp-master__row {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: 10px;
}

/* space-between rather than a margin-left: auto on the price. The two look the
 * same until the row wraps, and then auto throws the price to the far edge of
 * its own line (invariant I8.4). */

.fp-master__name {
	margin: 0;
}

.fp-master__price {
	margin: 0;
	color: var( --text-link );
	font-size: 24px;
	font-weight: var( --fw-black );
}

.fp-master__desc {
	margin: 0;
	color: var( --text-body );
	font-size: 14.5px;
	line-height: var( --lh-relaxed );
}

.fp-master__licence {
	display: flex;
	align-items: center;
	gap: var( --space-2 );
	margin: 0;
	color: var( --text-meta );
	font-size: 13.5px;
}

.fp-master__licence .material-symbols-outlined {
	flex: 0 0 auto;
	color: var( --text-link );
	font-size: 18px;
}

.fp-master__link {
	margin-top: var( --space-1 );
	padding: 13px;
}

.fp-master__link .material-symbols-outlined {
	flex: 0 0 auto;
	font-size: 18px;
}

@media ( min-width: 641px ) {

	/* The card turns into two columns at the width the mockup names, and the
	 * photo wrapper stops carrying a fixed height, since grid's row stretch
	 * takes over from here. */
	.fp-master__card {
		grid-template-columns: minmax( 0, 2fr ) minmax( 0, 3fr );
	}

	.fp-master__photo-wrap {
		min-height: 340px;
		height: auto;
	}
}

/* ---------------------------------------------------------------------------
 * Service and price
 */

.fp-price__grid {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( min( 100%, 320px ), 1fr ) );
	align-items: center;
	gap: clamp( 24px, 4vw, 56px );
}

.fp-price__grid .fp-head {
	margin-bottom: 0;
}

.fp-promises {
	display: flex;
	flex-direction: column;
	gap: var( --space-3 );
	margin: var( --space-2 ) 0 0;
	padding: 0;
	list-style: none;
}

.fp-promises li {
	display: flex;
	align-items: center;
	gap: 10px;
	color: var( --text-body );
	font-size: 14.5px;
}

.fp-promises .material-symbols-outlined {
	flex: 0 0 auto;
	color: var( --text-link );
	font-size: 22px;
}

.fp-pricelist {
	display: flex;
	flex-direction: column;
	padding: clamp( 18px, 2.6vw, 26px ) clamp( 14px, 2.2vw, 24px );
	background: var( --surface-card );
	border-radius: clamp( 20px, 2.5vw, 28px );
	box-shadow: var( --shadow-card );
}

.fp-pricelist__row {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: center;
	gap: clamp( 6px, 1.4vw, 12px );
	padding: 13px clamp( 6px, 1.4vw, 12px );
}

.fp-pricelist__row--lead {
	padding-block: 14px;
	background: var( --tint-sky-soft );
	border-radius: var( --radius-sm );
}

.fp-pricelist__row--divided {
	border-bottom: 1px solid var( --tint-cloud );
}

.fp-pricelist__row--divided-top {
	border-top: 1px solid var( --tint-cloud );
}

.fp-pricelist__name {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var( --space-2 );
	margin: 0;
	color: var( --text-heading );
	font-size: clamp( 13.5px, 1.8vw, 15px );
	font-weight: 600;
	line-height: 1.3;
}

.fp-pricelist__row--lead .fp-pricelist__name {
	font-size: clamp( 14px, 1.9vw, 15.5px );
	font-weight: var( --fw-bold );
}

.fp-pricelist__note {
	margin: 0;
	color: var( --text-meta );
	font-size: 12.5px;
}

/*
 * The "no shaming" note. The mockup washes it in a lighter mint that the design
 * system never named; the palette's mint surface is what carries the mint ink at
 * a measured 4.54:1, so that is what it uses. The lighter wash is registered as
 * a design finding rather than invented here (invariant I9).
 */
.fp-pricelist__kind {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin: var( --space-2 ) 0 0;
	padding: 6px 11px;
	background: var( --tint-ice );
	border-radius: var( --radius-sm );
	color: var( --color-accent-text );
	font-size: var( --fs-eyebrow );
	font-weight: 600;
	line-height: 1.35;
}

.fp-pricelist__kind .material-symbols-outlined {
	flex: 0 0 auto;
	font-size: 16px;
}

.fp-pricelist__sum {
	margin: 0;
	color: var( --text-heading );
	font-size: clamp( 15px, 2vw, 17px );
	font-weight: var( --fw-black );
	text-align: right;
}

.fp-pricelist__sum--lead {
	color: var( --text-link );
	font-size: clamp( 17px, 2.4vw, 20px );
}

.fp-badge {
	display: inline-flex;
	align-items: center;
	gap: 3px;
	padding: 3px 9px;
	background: var( --color-green );
	border-radius: var( --radius-pill );
	color: var( --color-green-ink );
	font-size: 10px;
	font-weight: var( --fw-black );
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.fp-badge__star {
	font-size: 11px;
	line-height: 1;
}

.fp-pricelist__links {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 4px 22px;
	margin: var( --space-3 ) 0 0;
}

/*
 * A text link that is still a 44 px target. 14px text at the body line-height
 * is 22.4 px, so 11 px on each side lands at 44.4 - measured, the same
 * arithmetic the footer uses.
 */
.fp-textlink {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	padding: 11px 4px;
	color: var( --text-link );
	font-size: var( --fs-caption );
	font-weight: var( --fw-bold );
	text-decoration: none;
}

.fp-textlink .material-symbols-outlined {
	flex: 0 0 auto;
	font-size: 18px;
}

.fp-textlink:hover {
	color: var( --text-heading );
}

/* ---------------------------------------------------------------------------
 * The promotion section (WPS-084)
 *
 * BETWEEN THE PRICE BLOCK AND THE PROTOCOL, which is where the mockup draws it
 * and NOT where the task file and docs/akciju-mechanika.md said it went (both
 * placed it after the protocol; measured 2026-09-07, both corrected).
 *
 * Only the layout is here. The season's colours arrive through the --promo-*
 * roles, and the badge and the corner glyph are shared components - the theme
 * loads exactly one page stylesheet, so anything the voucher page also draws
 * cannot live in this file.
 */

.fp-promo__panel {
	position: relative;
	padding: clamp( 24px, 4vw, 44px );
	overflow: hidden;
	background: var( --promo-surface );

	/*
	 * The mockup grows this to 32px, which is outside the design system's own
	 * card range (20-28) and which qa-tokens reports as T4 at 1440px. Capped at
	 * the top of the scale instead: four pixels at desktop against a rule the
	 * whole theme is measured by. The mockup's clamp is the finding, not this
	 * line - recorded in the task log.
	 */
	border-radius: clamp( 20px, 2.5vw, 28px );
	color: var( --promo-surface-ink );
}

.fp-promo__decor {
	--promo-decor-size: 210px;
	--promo-decor-opacity: 0.13;

	top: -34px;
	right: -30px;
}

/*
 * auto-fit with a min() floor rather than a breakpoint: below ~600px the two
 * columns become one without a media query, and the voucher visual keeps its
 * own width instead of being stretched by the grid.
 */
.fp-promo__grid {
	position: relative;
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( min( 100%, 260px ), 1fr ) );
	align-items: center;
	gap: clamp( 20px, 3vw, 40px );
}

.fp-promo__copy {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 14px;
}

/*
 * The heading takes the season's ink EXPLICITLY, and that is not redundant:
 * base.css colours every h1-h3 with --text-heading, which wins over the
 * panel's inherited colour. On the brand palette the two are the same value,
 * so this was invisible until a dark season arrived - qa-a11y measured the
 * launch-palette ink on the christmas panel at 1.30:1 (WPS-085).
 */
.fp-promo__title {
	margin: 0;
	color: var( --promo-surface-ink );
	font-size: clamp( 24px, 3.4vw, 34px );
	font-weight: var( --fw-black );
	line-height: 1.12;
}

.fp-promo__text {
	margin: 0;
	color: var( --promo-surface-sub );
	font-size: var( --fs-body );
	line-height: 1.6;
}

.fp-promo__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin: 2px 0 0;
}

/*
 * The primary action wears the season too (WPS-085): the mockup's ctaBg /
 * ctaInk pair. On the brand palette the roles resolve to the theme's own
 * black button, so launch paints exactly what it painted before; a dark
 * season turns it white or amber, because a black button on a fir-green or
 * near-black panel would vanish. Hover keeps the fill and dims it slightly
 * rather than jumping to the theme's blue, which no season palette carries.
 */
.fp-promo__actions .btn--primary {
	background: var( --promo-action-bg );
	border-color: var( --promo-action-bg );
	color: var( --promo-action-ink );
}

.fp-promo__actions .btn--primary:hover,
.fp-promo__actions .btn--primary:focus-visible {
	background: var( --promo-action-bg );
	border-color: var( --promo-action-bg );
	color: var( --promo-action-ink );
	filter: brightness( 0.94 );
}

/*
 * The outlined second action. It borrows the promotion roles rather than the
 * theme's own button colours, because the border and the ink are part of the
 * season's costume - a dark season needs a light outline here.
 */
.fp-promo__ghost {
	background: transparent;
	border: 1px solid var( --promo-cta-border );
	color: var( --promo-cta-ink );
}

.fp-promo__ghost:hover,
.fp-promo__ghost:focus-visible {
	background: var( --promo-cta-border );
	color: var( --promo-badge-ink );
}

.fp-promo__terms {
	margin: 0;
	color: var( --promo-surface-sub );
	font-size: 12.5px;
	line-height: 1.5;
	opacity: 0.85;
}

.fp-promo__visual {
	display: flex;
	justify-content: center;
}

/*
 * A gift card, drawn at a card's proportions. Its amount is the season's
 * `amount` field filled from the rules (WPS-085), and the card wears the
 * season's own card colours - the mockup's kuponasBg / kuponasInk /
 * kuponasEyebrow triple - so the black-friday voucher is dark and the
 * christmas one is cream.
 */
.fp-promo__card {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 6px;
	width: 100%;
	max-width: 320px;
	padding: 18px;
	overflow: hidden;
	aspect-ratio: 1.62 / 1;
	background: var( --promo-card-bg );
	border-radius: var( --radius-lg );
	box-shadow: var( --shadow-floating );
	box-sizing: border-box;
	color: var( --promo-card-ink );
	text-align: center;
}

.fp-promo__card-decor {
	position: absolute;
	right: -18px;
	bottom: -26px;
	color: var( --promo-card-eyebrow );
	font-size: 150px;
	line-height: 1;
	opacity: 0.12;
	pointer-events: none;
}

.fp-promo__card-eyebrow {
	position: relative;
	color: var( --promo-card-eyebrow );
	font-size: 10.5px;
	font-weight: var( --fw-black );
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.fp-promo__card-figures {
	position: relative;
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: center;
	gap: 9px;
}

/*
 * The struck base price on the card. The mockup draws it at opacity 0.5,
 * which docs/akciju-mechanika.md measured below AA in three seasons of four
 * (2.89:1 on the christmas card); 0.7 passes in every season (5.02:1 and up)
 * and is what the canon proposes, so the theme takes the measured value
 * rather than the drawn one.
 */
.fp-promo__card-was {
	font-size: 17px;
	font-weight: 600;
	opacity: 0.7;
	text-decoration: line-through;
}

.fp-promo__card-amount {
	position: relative;
	font-size: clamp( 30px, 4.5vw, 40px );
	font-weight: var( --fw-black );
	line-height: 1;
}

.fp-promo__card-note {
	position: relative;
	font-size: 12.5px;
	opacity: 0.7;
}

/* ---------------------------------------------------------------------------
 * The protocol
 */

.fp-gbt__head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: var( --space-4 );
	margin-bottom: clamp( 18px, 3vw, 28px );
}

.fp-gbt__head .fp-head {
	max-width: 620px;
	margin-bottom: 0;
}

/*
 * The badge strip: centred on its own full-width line, and it stays that way
 * as a centered full-width line below the heading.
 *
 * With all four marks, the strip is wider than the original three-mark row.
 * The same four marks are used on the visit page. Keeping the strip on its own
 * centered line prevents the fourth mark from forcing an awkward left-aligned
 * wrap at desktop widths.
 */
.fp-badges {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	width: 100%;
	gap: clamp( 10px, 2.4vw, 24px );
	opacity: 0.9;
}

.fp-badges img {
	width: auto;
	height: clamp( 62px, 6vw, 84px );
}

.fp-badges .fp-badges__ems {
	height: clamp( 32px, 4vw, 44px );
	max-width: 40vw;
}

.fp-gbt__more {
	display: flex;
	justify-content: center;
	margin: clamp( 20px, 3vw, 32px ) 0 0;
}

.fp-gbt__more .btn {
	padding: 14px 26px;
}

.fp-gbt__more .material-symbols-outlined {
	flex: 0 0 auto;
	font-size: 20px;
}

.fp-step {
	display: flex;
	flex-direction: column;
	overflow: hidden;
	background: var( --surface-card );
	border-radius: var( --radius-2xl );
}

.fp-step__photo {
	width: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover;
}

.fp-step__body {
	display: flex;
	flex-direction: column;
	gap: var( --space-3 );
	padding: clamp( 20px, 3vw, 28px );
}

.fp-step__index {
	margin: 0;
	color: var( --text-link );
	font-size: var( --fs-meta );
	font-weight: var( --fw-bold );
}

.fp-step h3 {
	margin: 0;
	font-size: 19px;
}

.fp-step__text {
	margin: 0;
	color: var( --text-meta );
	font-size: var( --fs-caption );
	line-height: var( --lh-relaxed );
}

/* ---------------------------------------------------------------------------
 * Three-card grids
 *
 * One rule set serves both card rows, and the middle band is why it is not just
 * a grid. Between 561 and 920 px an auto-fit grid puts two cards on the first
 * row and stretches the third across the whole second row; the design decided on
 * 2026-08-17 that the odd card centres at half width instead. That band is a
 * breakpoint in its own right rather than a small desktop, which is the wording
 * the decision uses; it is written here as two min-width steps so the file still
 * reads in one direction.
 */

.fp-cards {
	--fp-cards-gap: clamp( 12px, 2vw, 16px );

	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( min( 100%, 260px ), 1fr ) );
	gap: var( --fp-cards-gap );
}

.fp-cards--wide {
	--fp-cards-gap: clamp( 14px, 2vw, 20px );

	grid-template-columns: repeat( auto-fit, minmax( min( 100%, 280px ), 1fr ) );
}

@media ( min-width: 561px ) {

	.fp-cards {
		display: flex;
		flex-wrap: wrap;
		justify-content: center;
	}

	.fp-cards > * {
		flex: 0 0 calc( 50% - var( --fp-cards-gap ) / 2 );
		min-width: 0;
	}
}

/*
 * BACK TO THE GRID ONLY WHERE THREE COLUMNS ACTUALLY FIT, and that is not
 * 921 px. 921 is the navigation's breakpoint - the width where the burger goes
 * away - and it says nothing about this grid. Returning to the grid there was
 * measured doing the opposite of what the centring exists for: at 921 px the
 * content is 857 px, three wide cards need 3*280 + 2*18.9 = 878, so auto-fit
 * laid out two and stretched the third across the whole second row. The odd
 * card jumped 218 px to the left of where it stood one pixel earlier.
 *
 * Each grid therefore returns at its own number, and the arithmetic is the
 * grid's own: three columns, two gaps, plus the 2 x 32 px gutters.
 *
 *   .fp-cards        3 * 260 + 2 * 16 + 64 = 876
 *   .fp-cards--wide  3 * 280 + 2 * 20 + 64 = 944
 *
 * No flex properties are reset alongside: a grid item is not a flex item, so
 * flex-basis and friends stop applying on their own.
 */

@media ( min-width: 876px ) {

	.fp-cards:not( .fp-cards--wide ) {
		display: grid;
	}
}

@media ( min-width: 944px ) {

	.fp-cards--wide {
		display: grid;
	}
}

/* ---------------------------------------------------------------------------
 * Results
 */

.fp-results__head {
	margin-bottom: var( --space-8 );
}

.fp-results__eyebrow {
	margin: 0 0 var( --space-3 );
	color: var( --color-accent-text );
	font-size: var( --fs-eyebrow );
	font-weight: var( --fw-black );
	letter-spacing: var( --ls-eyebrow );
	text-transform: uppercase;
}

.fp-results__head h2 {
	margin: 0 0 var( --space-4 );
	color: var( --text-heading );
	font-size: clamp( 28px, 4vw, 44px );
	font-weight: var( --fw-black );
	line-height: var( --lh-heading );
	letter-spacing: var( --ls-display );
}

.fp-results__intro {
	max-width: 780px;
	margin: 0;
	font-size: var( --fs-lead );
	line-height: var( --lh-relaxed );
}

.fp-results__grid {
	display: grid;
	grid-template-columns: minmax( 0, 1fr );
	gap: var( --space-6 );
}

.fp-result {
	min-width: 0;
	overflow: hidden;
	background: var( --surface-card );
	border-radius: var( --radius-lg );
	box-shadow: var( --shadow-card );
}

.fp-before-after {
	position: relative;
	aspect-ratio: 1.9;
	overflow: hidden;
	background: var( --surface-page );
	isolation: isolate;
}

.fp-before-after__image {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	pointer-events: none;
}

.fp-before-after__before {
	position: absolute;
	inset: 0;
	overflow: hidden;
	pointer-events: none;
}

.fp-before-after__label {
	position: absolute;
	top: var( --space-3 );
	z-index: 1;
	padding: 6px 12px;
	background: var( --surface-card );
	border-radius: var( --radius-pill );
	color: var( --text-heading );
	font-size: var( --fs-caption );
	font-weight: var( --fw-black );
	text-transform: uppercase;
	pointer-events: none;
}

.fp-before-after__label--before {
	left: var( --space-3 );
}

.fp-before-after__label--after {
	right: var( --space-3 );
}

.fp-before-after__divider {
	position: absolute;
	inset-block: 0;
	width: 2px;
	background: var( --surface-card );
	transform: translateX( -50% );
	pointer-events: none;
}

.fp-before-after__handle {
	position: absolute;
	top: 50%;
	left: 50%;
	display: none;
	place-items: center;
	width: 44px;
	height: 44px;
	background: var( --surface-card );
	border-radius: var( --radius-pill );
	box-shadow: var( --shadow-soft );
	color: var( --color-accent-text );
	transform: translate( -50%, -50% );
}

.fp-before-after.is-enhanced .fp-before-after__handle {
	display: grid;
}

.fp-before-after__handle .material-symbols-outlined {
	font-family: var( --font-icon );
	font-size: 24px;
}

.fp-before-after__range {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	opacity: 0;
	cursor: ew-resize;
	touch-action: pan-y;
}

.fp-before-after:has( .fp-before-after__range:focus-visible ) {
	outline: 3px solid var( --focus-ring );
	outline-offset: -3px;
}

.fp-before-after:has( .fp-before-after__range:focus-visible ) .fp-before-after__handle {
	outline: 3px solid var( --focus-ring );
	outline-offset: 2px;
}

.fp-result__body {
	padding: var( --space-6 );
}

.fp-result__title {
	margin: 0 0 var( --space-2 );
	color: var( --text-heading );
	font-size: var( --fs-h3 );
	font-weight: var( --fw-black );
	line-height: var( --lh-heading );
}

.fp-result__text {
	margin: 0;
	color: var( --text-meta );
	font-size: var( --fs-body );
	line-height: var( --lh-relaxed );
}

@media ( min-width: 921px ) {

	.fp-results__grid {
		grid-template-columns: repeat( 3, minmax( 0, 1fr ) );
	}
}

/* ---------------------------------------------------------------------------
 * Video (WPS-048)
 */

/*
 * .fp-video__box carries the height. .fp-video__link and .fp-video__frame are
 * two alternate contents absolutely filling it - deriving the height from
 * whichever one happens to be visible would collapse the box to 0 the moment
 * main.js's setUpFrontVideo() hides the link, since its only remaining child
 * would be the frame, which is itself absolutely positioned and so takes no
 * part in auto height.
 */
.fp-video__box {
	position: relative;
	height: clamp( 220px, 32vw, 420px );
	border-radius: var( --radius-2xl );
	overflow: hidden;
}

.fp-video__link {
	position: absolute;
	inset: 0;
	display: block;
	text-decoration: none;
}

.fp-video__poster {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.fp-video__frame {
	position: absolute;
	inset: 0;
}

.fp-video__frame iframe {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
}

/*
 * 0.65, not the mockup's 0.45: measured against the actual poster photo,
 * 0.45 left the white caption text at 2.99:1 in places (qa-a11y A15.1,
 * WCAG needs 4.5:1 for 15-18px/700 text) - a photograph is not a fixed
 * colour, so the fixed dark scrim over it has to be dark enough for the
 * photo's brightest areas, not just its average.
 */
.fp-video__overlay {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var( --space-4 );
	background: rgba( 23, 28, 33, 0.65 );
}

.fp-video__play {
	display: flex;
	align-items: center;
	justify-content: center;
	width: clamp( 64px, 7vw, 84px );
	height: clamp( 64px, 7vw, 84px );
	border-radius: 50%;
	background: rgba( 255, 255, 255, 0.95 );
	box-shadow: var( --shadow-floating );
}

.fp-video__play .material-symbols-outlined {
	font-size: clamp( 34px, 3.6vw, 44px );
	color: var( --color-accent-text );
}

.fp-video__caption {
	font-size: clamp( 15px, 1.8vw, 18px );
	font-weight: var( --fw-bold );
	color: var( --color-surface );
}

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

.fp-story__panel {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var( --space-4 );
	padding: clamp( 24px, 4vw, 48px );
	background: var( --color-mint );
	border-radius: clamp( 20px, 2.5vw, 28px );
	text-align: center;
}

.fp-story__eyebrow {
	margin: 0;
	color: var( --color-mint-ink );
	font-size: var( --fs-eyebrow );
	font-weight: var( --fw-black );
	letter-spacing: var( --ls-eyebrow );
	text-transform: uppercase;
}

.fp-story__quote {
	max-width: 760px;
	margin: 0;
	color: var( --text-heading );
	font-size: clamp( 19px, 2.6vw, 26px );
	font-weight: var( --fw-medium );
	line-height: var( --lh-snug );
	text-wrap: pretty;
}

/* Caveat is Diana's hand, and this is one of the two places the canon lets it
 * appear: a signature. Never a heading. */
.fp-story__sign {
	margin: 0;
	color: var( --color-mint-ink );
	font-size: clamp( 22px, 3vw, 27px );
	line-height: 1.1;
}

/* ---------------------------------------------------------------------------
 * Review sources
 */

.fp-sources {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	max-width: 640px;
	margin-inline: auto;
	gap: var( --space-3 );
}

.fp-source {
	display: flex;
	flex: 1 1 240px;
	flex-direction: column;
	gap: var( --space-2 );
	max-width: 300px;
	padding: 16px 18px;
	background: var( --surface-card );
	border: 1px solid var( --border-hairline );
	border-radius: var( --radius-lg );
	box-shadow: var( --shadow-hairline );
	text-decoration: none;
	transition:
		border-color var( --dur ) var( --ease ),
		box-shadow var( --dur ) var( --ease );
}

.fp-source:hover {
	border-color: var( --color-accent );
	box-shadow: var( --shadow-card );
}

.fp-source__brand {
	display: flex;
	align-items: center;
	gap: 9px;
}

.fp-source__logo {
	flex: 0 0 auto;
}

.fp-source__name {
	color: var( --text-heading );
	font-size: var( --fs-sm );
	font-weight: var( --fw-black );
}

.fp-source__rating {
	display: flex;
	align-items: center;
	gap: 6px;
}

/*
 * Track-and-fill stars: the track is the "empty" scale drawn in a neutral
 * hairline colour, the fill is the same glyphs in gold, absolutely
 * positioned over it and clipped to the score's percentage via an inline
 * width + overflow: hidden. That positioning keeps the fill's own text run
 * independent of the track's width, so a 90% clip cuts mid-glyph rather
 * than rounding to a whole star.
 */
.fp-stars {
	position: relative;
	display: inline-block;
	font-size: 15px;
	letter-spacing: 2px;
	line-height: 1;
}

.fp-stars__track {
	color: var( --color-border-strong );
}

.fp-stars__fill {
	position: absolute;
	top: 0;
	left: 0;
	overflow: hidden;
	white-space: nowrap;
	color: var( --color-gold );
}

.fp-source__score {
	color: var( --text-heading );
	font-size: var( --fs-meta );
	font-weight: var( --fw-bold );
}

.fp-source__count {
	color: var( --text-meta );
	font-size: var( --fs-meta );
}

.fp-source__read {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	color: var( --text-link );
	font-size: var( --fs-meta );
	font-weight: var( --fw-bold );
}

.fp-source__read .material-symbols-outlined {
	flex: 0 0 auto;
	font-size: 15px;
}

/*
 * The catalogue profiles are a sentence, not a row of boxes. That is what makes
 * them the WCAG 2.5.8 inline exception to the 44 px floor - a flex child is
 * blockified and would be measured as a control somebody made too small.
 */
.fp-catalogues {
	margin: var( --space-4 ) 0 0;
	color: var( --text-meta );
	font-size: var( --fs-meta );
	text-align: center;
}

.fp-catalogues a {
	color: var( --text-body );
	font-weight: var( --fw-bold );
	text-decoration: underline;
	text-decoration-color: var( --tint-line-strong );
	text-underline-offset: 3px;
}

.fp-catalogues a:hover {
	color: var( --text-link );
}

.fp-feel-good {
	display: inline-flex;
	margin: 0 auto;
}

.fp-feel-good img {
	width: 96px;
	height: 96px;
}

/* ---------------------------------------------------------------------------
 * Gift band (WPS-074)
 *
 * The warm paper surface page-dovanos.php's hero introduces, reused here so
 * the band already looks like the page it points to.
 */

.fp-giftband__card {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 14px 18px;
	padding: clamp( 18px, 2.6vw, 26px ) clamp( 18px, 3vw, 30px );
	background: var( --tint-paper );
	border: 1px solid var( --tint-paper-border );
	/*
	 * The mockup's own clamp() floors at 18px, which sits outside the shape
	 * scale (invariant I9: 12-16 icon boxes, 20-28 cards, 999 pills) -
	 * qa-tokens T4 caught it. Raised to the nearest valid step
	 * (--radius-lg) rather than reproduced as drawn; a SISTEMA note for the
	 * mockup itself belongs in docs/dizaino-auditas.md, not a second copy
	 * of the same off-scale number here.
	 */
	border-radius: clamp( 20px, 2.2vw, 24px );
	text-decoration: none;
	transition: border-color var( --dur ) var( --ease );
}

.fp-giftband__card:hover {
	border-color: var( --tint-paper-border-hover );
}

.fp-giftband__icon {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	width: 46px;
	height: 46px;
	border-radius: 50%;
	background: var( --tint-paper-icon );
}

.fp-giftband__icon .material-symbols-outlined {
	font-family: var( --font-icon );
	font-size: 24px;
	color: var( --color-amber-ink );
}

.fp-giftband__text {
	flex: 1 1 300px;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 3px;
}

.fp-giftband__title {
	font-size: clamp( 16.5px, 2vw, 19px );
	font-weight: var( --fw-black );
	line-height: 1.25;
	color: var( --text-heading );
}

.fp-giftband__desc {
	font-size: var( --fs-caption );
	line-height: 1.55;
	color: var( --text-meta );
}

.fp-giftband__cta {
	display: inline-flex;
	align-items: center;
	flex-shrink: 0;
	gap: 7px;
	font-size: var( --fs-sm );
	font-weight: var( --fw-black );
	color: var( --text-link );
}

.fp-giftband__cta .material-symbols-outlined {
	font-family: var( --font-icon );
	font-size: 18px;
}

/* ---------------------------------------------------------------------------
 * Booking
 */

.fp-booking__panel {
	display: grid;
	grid-template-columns: 1fr;
	align-items: center;
	gap: clamp( 24px, 4vw, 48px );
	padding: clamp( 24px, 4vw, 48px );
	background: var( --surface-inverse );
	border-radius: clamp( 20px, 2.5vw, 28px );
}

.fp-booking__copy {
	display: flex;
	flex-direction: column;
	gap: 18px;
}

.fp-booking__eyebrow {
	margin: 0;
	color: var( --color-surface );
	font-size: var( --fs-eyebrow );
	font-weight: var( --fw-bold );
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.fp-booking__title {
	margin: 0;
	color: var( --color-surface );
}

/* White at reduced opacity over the ink panel: 7.9:1 for the lead and 7.1:1 for
 * the descriptions, both measured against the composited value rather than
 * against white. */
.fp-booking__lead {
	margin: 0;
	color: rgba( 255, 255, 255, 0.65 );
	font-size: var( --fs-sm );
	line-height: var( --lh-body );
}

.fp-booking__list {
	display: flex;
	flex-direction: column;
	gap: 14px;
	margin: 2px 0 0;
	padding: 0;
	list-style: none;
}

.fp-booking__list li {
	display: flex;
	align-items: flex-start;
	gap: 13px;
}

.fp-booking__list .material-symbols-outlined {
	flex: 0 0 auto;
	color: var( --color-surface );
	font-size: 24px;
}

.fp-booking__term {
	display: block;
	color: var( --color-surface );
	font-size: var( --fs-sm );
	font-weight: var( --fw-bold );
}

.fp-booking__desc {
	display: block;
	color: rgba( 255, 255, 255, 0.6 );
	font-size: 13.5px;
	line-height: 1.5;
}

.fp-booking__card {
	display: flex;
	flex-direction: column;
	gap: var( --space-4 );
	padding: clamp( 18px, 3vw, 26px );
	background: var( --surface-card );
	border-radius: var( --radius-xl );
}

.fp-location__card {
	display: grid;
	grid-template-columns: 1fr;
	gap: var( --space-4 );
	max-width: 640px;
	margin-inline: auto;
	padding: clamp( 20px, 3vw, 28px );
	background: var( --surface-card );
	border: 1px solid var( --border-hairline );
	border-radius: var( --radius-xl );
	box-shadow: var( --shadow-hairline );
}

.fp-location__item {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	color: var( --text-body );
	font-size: var( --fs-sm );
}

.fp-location__item > .material-symbols-outlined {
	flex: 0 0 auto;
	color: var( --text-link );
	font-size: 22px;
}

.fp-location__item div {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.fp-location__label {
	color: var( --text-meta );
	font-size: var( --fs-caption );
}

.fp-location__item strong {
	color: var( --text-heading );
	font-weight: var( --fw-bold );
}

.fp-location__item a {
	display: inline-flex;
	align-items: center;
	box-sizing: border-box;
	min-height: 44px;
	padding: 10px 0;
	margin: -10px 0;
	color: var( --text-heading );
	font-weight: var( --fw-bold );
	text-decoration: none;
}

.fp-location__item a:hover {
	color: var( --text-link );
}

@media ( min-width: 921px ) {

	/*
	 * The panel becomes two columns only here. An auto-fit grid would already
	 * have split it around 700 px, and the design forbids exactly that: when one
	 * half of a two-column section is a working widget, the widget needs the
	 * width (the mockups' .rez-grid rule).
	 */
	.fp-booking__panel {
		grid-template-columns: repeat( auto-fit, minmax( min( 100%, 300px ), 1fr ) );
	}

	.fp-hero__actions {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		gap: 14px;
		margin: 0;
	}
}

/* Approved D hierarchy and geometry, shared by the information and full views. */
.fp-head h2,
.fp-price h2 { font-size: clamp(26px, 3.6vw, 38px); line-height: 1.12; }
.fp-head .eyebrow { font-size: 12px; letter-spacing: .08em; }
.fp-lead { font-size: 16px; }
.fp-master__name { font-size: 22px; font-weight: 700; }
.fp-master__desc { color: var(--color-ink); font-weight: 400; }
.fp-master__licence { min-height: 44px; text-decoration: none; }
.fp-master__licence-text { text-decoration: underline; text-decoration-color: var(--color-border-strong); text-underline-offset: 3px; }
.fp-price__note { display: flex; align-items: flex-start; gap: 10px; margin: 6px 0 0; font-size: 14px; line-height: 1.55; color: var(--text-meta); }
.fp-price__note .material-symbols-outlined { flex: 0 0 auto; color: var(--color-accent-text); font-size: 21px; }
.fp-price h2 { max-width: 17ch; }
.fp-pricelist__links { justify-content: center; }
.fp-results h2 { font-size: clamp(28px, 4vw, 44px); }
.fp-results__grid { justify-items: center; gap: var(--space-4); }
.fp-result { width: 100%; max-width: 300px; }
.fp-result__body { padding: var(--space-4); }
.fp-result__title { margin: 0; font-size: 18px; font-weight: 700; line-height: 1.3; }
.fp-before-after__label { padding: 4px 8px; font-size: 12px; font-weight: 700; line-height: 1.2; text-transform: none; }
.fp-video__box { height: clamp(220px, 32vw, 420px); aspect-ratio: auto; background: var(--surface-inverse); }
.fp-video__poster { height: 100%; object-position: 50% 30%; opacity: .45; }
.fp-video__overlay { display: block; background: transparent; }
.fp-video__play { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: var(--surface-card); box-shadow: var(--shadow-soft); }
.fp-video__caption { position: absolute; top: calc(50% + clamp(48px, 5vw, 64px)); left: 16px; right: 16px; text-align: center; font-size: clamp(16px, 1.8vw, 20px); line-height: 1.35; text-shadow: 0 1px 6px var(--surface-inverse); }
.fp-story__eyebrow { font-size: 12px; }
.fp-feel-good img { width: 96px; height: 96px; }
.fp-reviews .fp-lead { font-size: 16px; }
.fp-sources { align-items: stretch; }
.fp-source { display: flex; flex-direction: column; }
.fp-source__read { margin-top: auto; }
.fp-gift-options { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: 16px; }
.fp-gift-option { display: grid; grid-template-columns: 46px minmax(0, 1fr); column-gap: 16px; row-gap: 8px; padding: clamp(18px, 2.6vw, 26px); }
.fp-gift-option .action-card__icon { width: 46px; height: 46px; }
.fp-gift-option .action-card__icon .material-symbols-outlined { font-size: 24px; }
.fp-gift-option h2 { margin: 0 0 3px; font-size: clamp(16.5px, 2vw, 19px); line-height: 1.25; }
.fp-gift-option p { font-size: 14px; line-height: 1.55; color: var(--text-meta); }
.fp-gift-option .action-card__actions { grid-column: 2; margin: 0; padding: 0; }
.fp-gift-option .action-card__text-link { font-size: 14.5px; }
.home .notify__title { max-width: 15ch; }
.home .notify__note { display: none; }
.home .notify__title { font-size: clamp(27px, 4vw, 40px); }
.home .site-footer__inner:has(.ft-mintis--compact) { row-gap: 12px; }
.home .ft-mintis--compact { padding: 4px 16px; }
.home .ft-mintis--compact .ft-mintis__text { margin: 0; font-size: 14px; line-height: 1.5; }
@media (min-width: 640px) {
 .fp-results__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
 .fp-result { grid-column: span 2; }
 .fp-result:last-child:nth-child(3) { grid-column: 2 / span 2; }
}
@media (min-width: 921px) {
 .fp-results__grid { gap: 24px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
 .fp-result, .fp-result:last-child:nth-child(3) { grid-column: auto; }
 .fp-result__body { padding: 24px; }
}
