/**
 * ROYA - Home page sections
 *
 * One block per section, in page order. Loaded only on the front page.
 * Consumes tokens.css; no raw values.
 */

/* ==========================================================================
   Hero
   Figma 1:9 y 0-905. Full-bleed photo 1440x771 with the logo centered over it
   and a scroll cue near the photo's bottom edge. The design's proportions:
   logo width 709/1440 (~49%), logo top 229/771 (~30%), scroll cue bottom
   72/771 (~9%). Kept as percentages so the composition survives every width.
   ========================================================================== */

.roya-hero__media {
	position: relative;
	height: 100vh;
	height: 100svh; /* stable on mobile browser chrome; falls back to 100vh */
	overflow: hidden;
}

/* Crossfading slides. The first is visible by default so the hero renders
   even with scripting off or reduced motion; home.js rotates the rest. */
.roya-hero__slide {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0;
	transition: opacity 1.5s ease;
}

.roya-hero__slide.is-active {
	opacity: 1;
}

/* A whisper of a scrim over the photography so the light logo reads against
   busy or bright frames. Client-requested; keep it barely-there. */
.roya-hero__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background-color: rgba(0, 0, 0, 0.12);
	z-index: 1;
	pointer-events: none;
}

/* The overlaid elements sit above the scrim. */
.roya-hero__logo,
.roya-hero__scroll {
	z-index: 2;
}

.roya-hero__logo {
	position: absolute;
	inset-block-start: 30%;
	inset-inline-start: 50%;
	translate: 50% 0;   /* RTL document: +50% pulls back toward center. */
	width: clamp(220px, 49vw, 709px);
	height: auto;
}

/* Mobile: no design exists, so this is ours (client-approved direction) -
   the logo takes true center stage, larger relative to the viewport. */
@media (max-width: 767px) {
	.roya-hero__logo {
		inset-block-start: 50%;
		translate: 50% -50%;
		width: min(78vw, 420px);
	}
}

.roya-hero__scroll {
	position: absolute;
	inset-block-end: 9%;
	inset-inline-start: 50%;
	translate: 50% 0;
	width: clamp(56px, 7vw, 100px);
	transition: opacity var(--roya-transition);
}

.roya-hero__scroll:hover {
	opacity: 0.7;
}

.roya-hero__rule {
	/* Half rule anchored to the reading start - the right edge in RTL. */
	width: 50%;
	margin-inline-start: 0;
	margin-inline-end: auto;
	margin-block-start: clamp(3rem, 9.3vw, 8.375rem); /* 134px gap in design */
}


/* ==========================================================================
   Our projects
   Figma 1:9 y 975-2250. Three arch cards - the middle one 440x639, raised;
   the flanks 392x569, lower. Labels under each card. A pill button closes
   the section, sitting centered ON the full-width rule.
   Design column ratio 392:440:392 ~= 8.9 : 10 : 8.9.
   ========================================================================== */

/* ul.- prefix: must outrank the ul[class] margin reset in base.css. */
ul.roya-projects__grid {
	display: grid;
	grid-template-columns: 8.9fr 10fr 8.9fr;
	gap: clamp(var(--roya-space-3), 4.4vw, 4rem); /* 64px in design */
	align-items: start;
	/* Breathing room under the section head (client notes 2026-08-31). */
	margin-block-start: clamp(var(--roya-space-3), 3.3vw, var(--roya-space-5));
}

/* The flanking cards start lower, recreating the design's raised centre. */
.roya-projects__item:nth-child(odd) {
	margin-block-start: clamp(2rem, 11.7vw, 10.5rem); /* 168px in design */
}

.roya-arch-card {
	text-align: center;
}

.roya-arch-card__image {
	width: 100%;
	aspect-ratio: 440 / 639;
	object-fit: cover;
	border-radius: var(--roya-radius-arch);
	box-shadow: var(--roya-shadow-card);
}

.roya-arch-card__label {
	margin-block-start: 22px; /* fixed per client note 2026-08-31 */
	color: var(--roya-text);
	font-size: var(--roya-text-body);
}

/* Button centered on the closing rule: the rule is absolutely positioned at
   the vertical middle of the footer, the button floats above it. */
.roya-projects__footer {
	position: relative;
	display: flex;
	justify-content: center;
	margin-block-start: clamp(var(--roya-space-5), 6.1vw, 5.5rem); /* 88px */
}

.roya-projects__rule {
	position: absolute;
	inset-block-start: 50%;
	inset-inline: 0;
}

.roya-projects__footer .roya-button {
	position: relative;
}

@media (max-width: 767px) {
	/* Mobile (no design exists): cards stack in one column, same size,
	   centre-raised choreography dropped. */
	ul.roya-projects__grid {
		grid-template-columns: minmax(0, 260px);
		justify-content: center;
		gap: var(--roya-space-6);
	}

	/* Balance the card against its caption: smaller arch, larger dark text. */
	.roya-arch-card__label {
		font-size: 1.75rem; /* 28px */
		color: var(--roya-heading);
	}

	.roya-projects__item:nth-child(odd) {
		margin-block-start: 0;
	}
}


/* ==========================================================================
   About
   Figma 1:9 y 2327-3775. Full-bleed photo, frosted glass panel over the
   inline-end half (718/1440 = ~50%), text and a light button inside.
   ========================================================================== */

/* Image and panel share one grid cell: the photo's natural height drives the
   section (client decision), and if the text ever grows taller the cell grows
   with it - the photo then covers with a minimal crop instead of the text
   overflowing. */
.roya-about__stage {
	display: grid;
	grid-template-columns: 100%;
	margin-block-start: clamp(var(--roya-space-3), 3.3vw, var(--roya-space-5));
}

.roya-about__image {
	grid-area: 1 / 1;
	width: 100%;
	/* The design crops the photo to the frame's 1440x1204 window - reproduce
	   that exact ratio; cover decides what gets trimmed. If the text panel
	   ever outgrows it, min-height lets the photo stretch to match. */
	aspect-ratio: 1440 / 1204;
	height: auto;
	min-height: 100%;
	object-fit: cover;
}

/* Blur is expensive - contained to this element only. */
.roya-about__panel {
	grid-area: 1 / 1;
	width: 50%; /* exactly half - photo half, panel half (client note) */
	justify-self: end; /* inline-end half, like the design */
	padding: clamp(var(--roya-space-4), 4.4vw, var(--roya-space-6));
	background-color: var(--roya-glass-cream);
	backdrop-filter: blur(var(--roya-blur-strong));
	-webkit-backdrop-filter: blur(var(--roya-blur-strong));
	box-shadow: var(--roya-shadow-glass);
}

.roya-about__text {
	color: var(--roya-text);
	font-size: var(--roya-text-body);
	line-height: var(--roya-leading-relaxed);
}

.roya-about__button {
	margin-block-start: clamp(var(--roya-space-4), 3.3vw, var(--roya-space-6));
}

@media (max-width: 767px) {
	/* Mobile: no overlay - the photo first, the panel as its own block
	   below it (client note 2026-08-31). */
	.roya-about__image {
		grid-area: 1 / 1;
		min-height: 0;
	}

	.roya-about__panel {
		grid-area: 2 / 1;
		width: 100%;
	}
}


/* ==========================================================================
   ROYA mask banner
   Figma 1:62, y 3957-4711. The display word is a cutout over the photo:
   background-clip:text with background-attachment:fixed makes the photo hold
   still while the page scrolls - parallax with zero JS. Half rule above at
   the visual RIGHT (inline-start in RTL), full rule below.
   ========================================================================== */

.roya-banner__rule-top {
	width: 50%;
	margin-inline-start: 0;
	margin-inline-end: auto;
}

.roya-banner__stage {
	position: relative;
	overflow: hidden; /* the staggered panels poke past the rules otherwise */
}

/* Five full-bleed vertical paper panels behind the word, like the design's
   staggered strips - same cream as the page, visible only through the soft
   shadows at their seams. Decorative chrome, not content. */
.roya-banner__panels {
	position: absolute;
	inset: 0;
	display: flex;
}

.roya-banner__panels > span {
	flex: 1;
	background-color: var(--roya-cream);
	/* A seam, not a floating card - tight, soft, low-opacity shadow. */
	box-shadow: 0 0 14px rgba(67, 61, 53, 0.18);
}

/* Full-width word - the banner ignores the content container by design.
   Pure vw sizing so the word keeps its share of ANY viewport width
   (a rem cap here is what shrank it on wide screens). */
.roya-banner__word {
	position: relative;
	width: 100%;
	padding-block: clamp(var(--roya-space-4), 4.4vw, var(--roya-space-6));
	font-family: var(--roya-font-display);
	font-size: max(5rem, 42vw); /* ROYA ~2.2em wide -> ~95% of the viewport */
	line-height: 0.9;
	text-align: center;
	white-space: nowrap;
	/* NOT background-attachment: fixed - Chrome refuses to paint a fixed
	   background through background-clip:text (blank letters). home.js
	   drifts background-position on scroll for the parallax instead. */
	background-position: center 50%;
	background-size: cover;
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	user-select: none;
}


/* ==========================================================================
   Our services
   Figma 1:9 y 4913-8300. Zigzag rows: photo column (300px), vertical Brown
   Sugar word (120px), text card with the box shadow. Odd rows put the photos
   at the visual LEFT (inline-end in RTL), even rows mirror. Each row closes
   with a rule carrying the button on the card's side.
   Design ratios - photos 300:270 / 300:183 / 300:270, card 811 wide.
   ========================================================================== */

.roya-service__row {
	display: flex;
	align-items: center;
	gap: clamp(var(--roya-space-2), 2.4vw, 2.125rem); /* 34px in design */
	margin-block-start: clamp(var(--roya-space-4), 3.3vw, var(--roya-space-6));
}

/* Zigzag. DOM order is image, word, card; in RTL flex the first child lands
   at the visual right. Row 1: card right, image LEFT - so odd rows reverse.
   nth-of-type, NOT nth-child: the section-head <header> is the section's
   first child and would shift the count (that bug shipped once already). */
.roya-service:nth-of-type(odd) .roya-service__row {
	flex-direction: row-reverse;
}

/* One tall arch image per service (client note 2026-08-31), same column
   footprint as the design's 300x763 with fully rounded ends. */
.roya-service__image {
	flex: 0 0 clamp(140px, 20.8vw, 300px);
	width: clamp(140px, 20.8vw, 300px);
	aspect-ratio: 300 / 763;
	object-fit: cover;
	border-radius: var(--roya-radius-arch);
	box-shadow: var(--roya-shadow-card);
}

.roya-service__word {
	color: var(--roya-accent);
	font-family: var(--roya-font-display);
	font-size: var(--roya-text-vertical);
	line-height: 1;
	letter-spacing: 0.1em;
	writing-mode: vertical-rl;
	text-orientation: mixed;
	white-space: nowrap;
	align-self: stretch;
	display: flex;
	align-items: center;
	pointer-events: none;
	user-select: none;
}

.roya-service__card {
	flex: 1;
	min-width: 0;
	padding: clamp(var(--roya-space-4), 4.4vw, var(--roya-space-6));
	background-color: var(--roya-bg);
	box-shadow: var(--roya-shadow-card);
	border-radius: 20px; /* client note 2026-08-31 */
}

.roya-service__title {
	font-size: var(--roya-text-subtitle);
	font-weight: var(--roya-weight-regular);
}

.roya-service__text {
	margin-block-start: clamp(var(--roya-space-2), 2.2vw, var(--roya-space-4));
	color: var(--roya-text);
	font-size: var(--roya-text-body);
	line-height: var(--roya-leading-relaxed);
}

/* Rule + button, same motif as the projects footer, but the button aligns
   with the card's side: odd rows card is right -> button right; even left. */
.roya-service__footer {
	position: relative;
	display: flex;
	margin-block-start: clamp(var(--roya-space-5), 6.1vw, 5.5rem);
	padding-inline: var(--roya-gutter);
}

.roya-service:nth-of-type(odd) .roya-service__footer {
	justify-content: flex-start;
}

.roya-service:nth-of-type(even) .roya-service__footer {
	justify-content: flex-end;
}

.roya-service__rule {
	position: absolute;
	inset-block-start: 50%;
	inset-inline: 0;
}

.roya-service__button {
	position: relative;
}

@media (max-width: 767px) {
	/* Mobile (no design exists): card first, photos in a row under it,
	   vertical word dropped, button centered. */
	/* Image first, full container width, no arch (client note 2026-08-31). */
	.roya-service__row,
	.roya-service:nth-of-type(odd) .roya-service__row {
		flex-direction: column;
		align-items: stretch;
	}

	/* The vertical word turns horizontal: under the image, before the text. */
	.roya-service__word {
		writing-mode: horizontal-tb;
		align-self: center;
		text-align: center;
	}

	.roya-service__image {
		flex-basis: auto;
		width: 100%;
		aspect-ratio: auto;
		border-radius: 20px;
	}

	.roya-service__footer,
	.roya-service:nth-of-type(odd) .roya-service__footer,
	.roya-service:nth-of-type(even) .roya-service__footer {
		justify-content: center;
	}
}


/* ==========================================================================
   A world of wonderful materials
   Figma 1:9 y 8510-10330, collage group 1:141 (98,8632 - 1244x1703).
   A Brown Sugar title with the Hebrew subtitle under its LEFT edge, then a
   freeform moodboard: six photos in fixed shapes over a white paper sheet
   and a thin vertical line. The collage is one proportional canvas -
   percentage insets inside an aspect-ratio box, measured from the saved
   0.25 render (the group's inner nodes were never fetched, G-12).

   PHYSICAL left/top on purpose: this is a picture, not text flow - logical
   properties would mirror the measured composition in RTL.
   ========================================================================== */

/* The head ignores the content container: the design's title box spans
   48-1394 on the 1440 canvas (wider than --roya-container), so the header
   carries its own matching gutter to keep the title on one line. */
.roya-materials__head {
	padding-inline: 3.3vw;
}

.roya-materials__title {
	color: var(--roya-heading);
	font-family: var(--roya-font-display);
	/* The design says 80px, but the delivered Brown Sugar renders a touch
	   wider than Figma's copy and the line breaks. 72px keeps the design's
	   one-line title at every width - the priority here. */
	font-size: clamp(1.75rem, 5vw, 4.5rem);
	font-weight: var(--roya-weight-regular);
	line-height: var(--roya-leading-tight);
	/* Left-aligned over the subtitle (client note 2026-08-31, was centered). */
	text-align: left;
}

/* The subtitle hangs under the title's left end, like the design. */
.roya-materials__subtitle {
	width: fit-content;
	margin-left: 0;
	margin-right: auto;
	color: var(--roya-text);
	font-size: var(--roya-text-subtitle);
	font-weight: var(--roya-weight-light);
}

.roya-materials__collage {
	position: relative;
	aspect-ratio: 1244 / 1703;
	margin-block-start: clamp(var(--roya-space-2), 2.2vw, var(--roya-space-4));
}

/* Decorative chrome: the paper sheet behind the pieces, the line at right. */
.roya-materials__sheet {
	position: absolute;
	left: 9.2%;
	top: 11.5%;
	width: 71.9%;
	height: 76.3%;
	background-color: var(--roya-paper);
	box-shadow: var(--roya-shadow-soft);
}

.roya-materials__line {
	position: absolute;
	left: 92.4%;
	top: 0;
	bottom: 0;
	width: 3px;
	background-color: var(--roya-graphite);
}

/* Six pieces. Width + aspect-ratio per slot; DOM order carries the design's
   stacking (metal ball on top of the wood and marble corners, travertine
   over the line). */
.roya-materials__piece {
	position: absolute;
	object-fit: cover;
	box-shadow: var(--roya-shadow-card);
}

.roya-materials__piece--wood {
	left: 33.9%;
	top: 5.6%;
	width: 38%;
	aspect-ratio: 473 / 607;
}

.roya-materials__piece--glass {
	left: 0.6%;
	top: 17.2%;
	width: 18.5%;
	aspect-ratio: 1;
	border-radius: var(--roya-radius-circle);
}

.roya-materials__piece--tiles {
	left: 1.8%;
	top: 44.7%;
	width: 15%;
	aspect-ratio: 187 / 833;
}

.roya-materials__piece--marble {
	left: 32.9%;
	top: 55.7%;
	width: 39.1%;
	aspect-ratio: 487 / 607;
}

.roya-materials__piece--metal {
	left: 10.9%;
	top: 32.2%;
	width: 38.6%;
	aspect-ratio: 1;
	border-radius: var(--roya-radius-circle);
}

.roya-materials__piece--travertine {
	left: 84.8%;
	top: 22.8%;
	width: 15%;
	aspect-ratio: 187 / 853;
	border-radius: 12px;
}

@media (max-width: 767px) {
	/* Mobile (no design exists): the vertical strips and small circle become
	   unreadably narrow when the canvas shrinks, so the collage regroups into
	   a simple two-column moodboard. Shapes keep their character - circles
	   stay circles, wide pieces span both columns. */
	.roya-materials__collage {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: var(--roya-space-3);
		aspect-ratio: auto;
	}

	.roya-materials__sheet,
	.roya-materials__line {
		display: none;
	}

	.roya-materials__piece {
		position: static;
		width: 100%;
	}

	.roya-materials__piece--wood {
		order: 1;
		grid-column: 1 / -1;
		aspect-ratio: 3 / 2;
	}

	.roya-materials__piece--glass {
		order: 2;
	}

	.roya-materials__piece--metal {
		order: 3;
	}

	.roya-materials__piece--tiles {
		order: 4;
		aspect-ratio: 2 / 3;
	}

	.roya-materials__piece--travertine {
		order: 5;
		aspect-ratio: 2 / 3;
		border-radius: 0;
	}

	.roya-materials__piece--marble {
		order: 6;
		grid-column: 1 / -1;
		aspect-ratio: 3 / 2;
	}
}


/* ==========================================================================
   Articles & tips banner
   Figma 1:9 y 10551-11817. Full-bleed sage band; frosted strip on the visual
   LEFT third (480/1440); arch image card (440x909) over it; centered cream
   title + centered body on the right half; light pill button at the content's
   inline-start; static "ARTICLES&TIPS" watermark (STRONG token) hugging the
   band's bottom edge.
   ========================================================================== */

.roya-articles-banner__band {
	/* Shared by the ghost's line-height and by the padding that reserves room
	   for it, so the two can never drift apart (they did - the button landed
	   on the glyphs). */
	--roya-articles-ghost-line: 0.8;

	position: relative;
	overflow: hidden; /* clips the oversized ghost */
	background-color: var(--roya-accent);
	padding-block-start: clamp(3rem, 6.2vw, 5.5rem);
	/* The watermark's whole line box plus a gap: Brown Sugar overshoots a
	   sub-1 line box, so the reserve has to be generous, not exact. */
	padding-block-end: calc(
		var(--roya-text-watermark-sm) * var(--roya-articles-ghost-line) +
		clamp(2.5rem, 6vw, 5.5rem)
	);
}

/* PHYSICAL left on purpose: the strip hugs the visual left edge in the
   design, and this is a measured composition, not text flow. */
.roya-articles-banner__glass {
	position: absolute;
	left: 0;
	top: 0;
	bottom: 0;
	width: 33.3%;
	background-color: var(--roya-glass-sage);
	backdrop-filter: blur(var(--roya-blur-panel));
	-webkit-backdrop-filter: blur(var(--roya-blur-panel));
	box-shadow: var(--roya-shadow-glass);
	border-inline-end: 1px solid var(--roya-glass-border);
}

/* RTL grid: column 1 sits at the visual RIGHT, so the content takes column 1
   and the image column 2 - image on the visual left, like the design.
   Ratio from the design: image 440, gap 77, content 676. */
.roya-articles-banner__grid {
	position: relative; /* above the glass strip */
	display: grid;
	grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
	gap: clamp(var(--roya-space-4), 5.3vw, 4.8rem);
	align-items: center;
}

/* Column 3 is the circle-arrow's lane, at the visual far left on the glass
   strip. This composition is wider than the shared 1230 container - in the
   design it runs from the arrow at x65 to the copy's right edge at x1403 -
   so the band gets its own box; at 1440 that hands the columns back their
   design widths (arrow 85, card 440, copy 661). */
.roya-articles-banner__grid--with-icon {
	--roya-container: 1340px;

	grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) auto;
}

.roya-articles-banner__image {
	grid-column: 2;
	grid-row: 1;
	width: 100%;
	max-width: 440px;
	justify-self: center;
	aspect-ratio: 440 / 909;
	object-fit: cover;
	border-radius: var(--roya-radius-arch);
	box-shadow: var(--roya-shadow-card);
}

/* Title, copy and button all hang off the same edge in the design - the
   inline start, which is the visual RIGHT here (client note 2026-08-31). */
.roya-articles-banner__content {
	grid-column: 1;
	grid-row: 1;
	display: flex;
	flex-direction: column;
	align-items: stretch;
	text-align: start;
}

/* One notch under --roya-text-section-alt (128px -> 116px): at the design's
   column width the 128px line measures 665px against 661px of column, so it
   broke in two. G-13 - never ship a tight one-line fit. */
.roya-articles-banner__title {
	color: var(--roya-on-accent);
	font-size: clamp(2.5rem, 8.05vw, 7.25rem);
	font-weight: var(--roya-weight-light);
}

.roya-articles-banner__text {
	margin-block-start: clamp(var(--roya-space-2), 2.2vw, var(--roya-space-4));
	color: var(--roya-on-accent);
	font-size: var(--roya-text-body-lg);
	font-weight: var(--roya-weight-light);
	line-height: var(--roya-leading-normal);
}

.roya-articles-banner__text p + p {
	margin-block-start: clamp(0.75rem, 2.8vw, var(--roya-paragraph-gap));
}

/* The design parks the button at the content's inline-start (visual right). */
.roya-articles-banner__button {
	margin-block-start: clamp(var(--roya-space-4), 4.4vw, var(--roya-space-6));
	align-self: flex-start;
}

/* Figma 1:154: an 85x85 cream circle-arrow on the glass strip, vertically
   centred on the row (align-items above), repeating the button's link. Same
   glyph file as the button icon, painted as a mask so it takes currentColor.
   The pseudo-element carries the mask because the anchor itself holds the
   screen-reader label - masking the anchor would erase it. */
.roya-articles-banner__icon {
	/* One variable, two sides - the mobile block retunes it in one place. */
	--roya-articles-icon-size: clamp(3rem, 5.9vw, 5.3125rem);

	grid-column: 3;
	grid-row: 1;
	display: block;
	width: var(--roya-articles-icon-size);
	height: var(--roya-articles-icon-size);
	border-radius: 50%; /* so the focus ring traces the circle */
	color: var(--roya-on-accent);
	transition: transform var(--roya-transition);
}

.roya-articles-banner__icon::before {
	content: "";
	display: block;
	width: 100%;
	height: 100%;
	background-color: currentColor;
	mask: url("../img/icon-arrow.svg") center / contain no-repeat;
	-webkit-mask: url("../img/icon-arrow.svg") center / contain no-repeat;
}

/* PHYSICAL translate on purpose: the arrow points at the visual left, so the
   nudge follows the glyph, not the writing direction. */
.roya-articles-banner__icon:hover {
	transform: translateX(-6px);
}

/* Static watermark - unlike the section heads this one does not drift; it is
   a single line pinned to the band's bottom, edge to edge. */
.roya-articles-banner__ghost {
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	color: var(--roya-watermark-strong);
	font-family: var(--roya-font-display);
	font-size: var(--roya-text-watermark-sm);
	font-weight: var(--roya-weight-regular);
	line-height: var(--roya-articles-ghost-line);
	white-space: nowrap;
	text-align: center;
	pointer-events: none;
	user-select: none;
}

@media (max-width: 767px) {
	/* Mobile (no design exists): the card keeps its arrow beside it on one
	   line and the copy takes the line under them (client note). Flex rather
	   than grid, because the pair has to centre as a pair while the copy runs
	   the full width - which no single set of columns can do.
	   The glass strip goes away with the side-by-side composition. */
	.roya-articles-banner__glass {
		display: none;
	}

	/* flex-start, not center: the pair hangs off the inline start - the visual
	   RIGHT here - on the same edge as the title, copy and button. */
	.roya-articles-banner__grid,
	.roya-articles-banner__grid--with-icon {
		display: flex;
		flex-wrap: wrap;
		justify-content: flex-start;
	}

	/* Between the first pass's 260 (too tall - the arch is 909 against 440)
	   and the 130 that followed it (client note: too small). */
	.roya-articles-banner__image {
		order: 1;
		max-width: clamp(10rem, 50vw, 14rem);
	}

	/* The arrow is last in the DOM (it repeats a link the reader has met);
	   order puts it back at the card's visual left, as on desktop. */
	.roya-articles-banner__icon {
		--roya-articles-icon-size: clamp(3.5rem, 16vw, 4.5rem);

		order: 2;
	}

	.roya-articles-banner__content {
		order: 3;
		width: 100%;
	}

	/* Retuning the component's own tokens on this instance (client note): the
	   pill's 48px/16px floor reads small under the enlarged card. Scoped here
	   rather than in tokens.css - the other sections' pills were not reviewed. */
	.roya-articles-banner__button {
		--roya-button-height: 3.5rem;  /* 56px */
		--roya-text-button: 1.25rem;   /* 20px */
		--roya-icon-size: 2.25rem;     /* 36px */
	}
}


/* ==========================================================================
   Testimonials
   Figma 1:9 y 12032-12800. Section head, then a strip of 269x296 cards 32px
   apart that bleeds off both edges of the frame. Full-bleed and always in
   motion (client note): a marquee, not a scroller - see D-15.
   ========================================================================== */

.roya-testimonials__slider {
	margin-block-start: clamp(var(--roya-space-4), 7.3vw, 6.5rem); /* 105px */

	/*
	 * LTR on purpose, in an RTL document. The marquee drifts left, so the
	 * track has to be physically LEFT-anchored with its overhang on the right
	 * (G-09): drifting left then pulls the overhang in and never opens a gap.
	 * In RTL the block would anchor right and the gap would appear instantly.
	 * The strip is photographs - it carries no reading order to protect.
	 */
	direction: ltr;

	/* clip, not hidden: hidden leaves a programmatically scrollable box, and
	   focusing an off-screen card would scroll it out from under the
	   animation. clip cannot scroll at all. */
	overflow: hidden;
	overflow: clip;
}

/* ul.- prefix: must outrank the ul[class] margin reset in base.css. */
ul.roya-testimonials__track {
	display: flex;
	/* width: max-content keeps the flex line from shrinking the cards to fit. */
	width: max-content;
	/* The duration is set from the measured width in home.js, so the strip
	   drifts at a constant speed however many photos the client adds. */
	animation: roya-testimonials-drift 60s linear infinite;
	will-change: transform;
}

/*
 * -50% must land on a whole number of copies, which is why the JS clones an
 * EVEN number of them. Transform only - it runs on the compositor, so the
 * strip costs nothing per frame (G-09).
 */
@keyframes roya-testimonials-drift {
	from {
		transform: translateX(0);
	}

	to {
		transform: translateX(-50%);
	}
}

/* Deliberately no pause - not on hover, not on focus, not while the lightbox
   is open (client note: motion 100% of the time). The drift is slow enough
   that a card stays easy to hit, and pausing on focus meant the strip froze
   after the lightbox closed and handed focus back to the card. */

.roya-testimonials__slide {
	flex: 0 0 auto;
	width: clamp(11rem, 18.6vw, 16.8125rem); /* 269px in the design */
	/* The gap rides INSIDE each slide rather than in a flex `gap`: a gap is
	   dropped after the last item, which would leave the loop point one gap
	   short and show a visible stutter every cycle (G-09). */
	margin-inline-end: clamp(var(--roya-space-2), 2.2vw, var(--roya-space-4)); /* 32px */
}

/* The card is a button: it opens the lightbox. Stripped back to the image. */
.roya-testimonials__card {
	display: block;
	width: 100%;
	padding: 0;
	background: none;
	border: 0;
	cursor: pointer;
	transition: transform var(--roya-transition);
}

.roya-testimonials__card:hover {
	transform: scale(1.02);
}

.roya-testimonials__image {
	display: block;
	width: 100%;
	aspect-ratio: 269 / 296;
	object-fit: cover;
	background-color: var(--roya-media-placeholder);
	/* Flat, unlike the arch cards: 1:171-176 carry no shadow in the design. */
	-webkit-user-drag: none;
	user-select: none;
}

/* The hero logo carries the page's h1 (accessibility pass, 7.4). The wrapper
   must not change the layout: the image inside is `position: absolute`, so all
   this does is remove the heading's UA margin and stop it taking a line box. */
.roya-hero__title {
	margin: 0;
	font-size: inherit;
	line-height: 0;
}
