/*
 * People's Choice Awards — Fragrance Edition
 * Shared public stylesheet.
 *
 * Tokens, base layout and every component that appears on more than one page.
 * Per-route rules live in assets/css/pages/{route}.css and are enqueued only on
 * the route that needs them.
 *
 * Breakpoints (spec §9):
 *   mobile   < 640px
 *   tablet   640px – 1023px
 *   desktop  >= 1024px
 *
 * Layout uses logical properties (margin-inline, padding-inline, inset-inline)
 * throughout, which is why public-rtl.css only carries the handful of rules that
 * logical properties cannot express.
 */

/* ==========================================================================
   1. Tokens
   ==========================================================================
   The magenta ramp was sampled from pcfa-logo.png (spec §2.2). Nine of these
   are re-emitted at runtime by Frontend\Assets::brand_tokens() from Settings,
   so an admin palette change flows through every component. Never hardcode a
   hex value in a component rule.
   ========================================================================== */

:root {
	--magenta-deep: #7e1747;
	--magenta-darker: #5e0f34;
	--magenta: #a41f5e;
	--magenta-bright: #c42a72;
	--magenta-50: #fbeff3;
	--magenta-100: #f3d6e2;
	--steel-200: #e6c7d4;
	--white: #ffffff;
	--ink: #3a0f26;
	--muted: #6b3d52;
	--faint: #a97b90;
	--sponsor-fill: #b87c99;
	/* The one red on the site. It exists as a token because an error colour that
	   is retyped per rule is an error colour that drifts. */
	--danger: #b3261e;
	--sponsor-stroke: #b87c99;

	--max: 1240px;
	--radius: 16px;
	--radius-sm: 12px;
	--radius-lg: 20px;
	--shadow: 0 10px 30px rgba(126, 23, 71, 0.14);

	--brand-font: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
	--brand-font-ar: 'Noto Kufi Arabic', 'Noto Sans Arabic', sans-serif;
	--brand-font-ar-body: 'Noto Sans Arabic', 'Noto Kufi Arabic', sans-serif;

	--dur: 0.25s;
	--ease: cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* ==========================================================================
   2. Base
   ========================================================================== */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	scroll-behavior: smooth;
	-webkit-text-size-adjust: 100%;
}

body.pcfa-body {
	margin: 0;
	min-height: 100vh;
	display: flex;
	flex-direction: column;
	font-family: var(--brand-font);
	color: var(--ink);
	/* The standard page background, sampled from the client reference (spec §2.3). */
	background: linear-gradient(180deg, #fcf0f4 0%, #ffffff 480px);
	background-repeat: no-repeat;
	background-attachment: scroll;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

body.pcfa-body > main {
	flex: 1 0 auto;
}

a {
	color: inherit;
	text-decoration: none;
}

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
	outline: 3px solid var(--magenta);
	outline-offset: 2px;
	border-radius: 4px;
}

img,
svg,
picture,
video {
	max-width: 100%;
}

button {
	font: inherit;
	color: inherit;
}

h1,
h2,
h3,
h4,
h5,
h6 {
	margin: 0;
	line-height: 1.18;
	letter-spacing: -0.01em;
}

p {
	margin: 0 0 1em;
	line-height: 1.65;
}

p:last-child {
	margin-bottom: 0;
}

.wrap {
	max-width: var(--max);
	margin-inline: auto;
	padding-inline: 24px;
	width: 100%;
}

.pcfa-skip-link {
	position: absolute;
	inset-inline-start: -9999px;
	top: 0;
	z-index: 200;
	padding: 12px 20px;
	background: var(--magenta-deep);
	color: var(--white);
	font-weight: 700;
	border-end-end-radius: var(--radius-sm);
}

.pcfa-skip-link:focus {
	inset-inline-start: 0;
}

/* --- Arabic typography -----------------------------------------------------
   `.ar` is a slot name, not a language: on an Arabic-reading site the `.ar`
   slot carries the English. The stamped dir attribute always wins over the
   class default, which is why the two attribute rules below exist.
   -------------------------------------------------------------------------- */

.ar {
	font-family: var(--brand-font-ar);
	direction: rtl;
	unicode-bidi: isolate;
}

.ar[dir='ltr'],
.en[dir='ltr'] {
	direction: ltr;
	unicode-bidi: isolate;
	font-family: var(--brand-font);
}

.ar[dir='rtl'],
.en[dir='rtl'] {
	direction: rtl;
	unicode-bidi: isolate;
	font-family: var(--brand-font-ar);
}

p.ar,
.ar p,
.ar-body {
	font-family: var(--brand-font-ar-body);
}

/* Numbers, codes and phone numbers must never reorder inside Arabic text. */
.pcfa-ltr,
.pcfa-code,
.pcfa-tel,
.pcfa-price,
.pcfa-count {
	direction: ltr;
	unicode-bidi: isolate;
	display: inline-block;
}

.pcfa-visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

/* ==========================================================================
   3. The bilingual row (spec §2.5) — non-negotiable, applied everywhere
   ==========================================================================
   English at the start, Arabic at the end, on ONE line, at identical size and
   weight. An earlier pass under-weighted the Arabic and had to be corrected;
   the shared rule is here so it cannot be got wrong per page.
   ========================================================================== */

.bi-row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 16px;
	flex-wrap: wrap;
}

.bi-row > .en,
.bi-row > .ar {
	margin: 0;
	font-size: inherit;
	font-weight: inherit;
	line-height: 1.2;
}

/*
 * Arabic gets its own leading. 1.2 is a Latin figure: it clips the diacritics
 * that sit above an Arabic word and the descenders that hang below it, and the
 * clipping is worst exactly where the type is largest. The row aligns on the
 * baseline, so the two halves still sit on one line however far apart their
 * leading is — and size and weight remain inherited from the row, which is what
 * spec §2.5 actually pins.
 */
.bi-row > .ar {
	color: var(--magenta);
	text-align: end;
	line-height: 1.65;
}

/* Section heading sizes. The row itself carries the size so both halves inherit
   exactly the same one — a per-half font-size is how they drift apart. */

.section-heading {
	font-size: 22px;
	font-weight: 800;
	margin-bottom: 22px;
}

.section-heading-sm {
	font-size: 17px;
	font-weight: 800;
	margin-bottom: 16px;
}

.section-heading-lg {
	font-size: clamp(24px, 3vw, 32px);
	font-weight: 900;
	margin-bottom: 26px;
}

/* The maroon accent bar (spec §2.6). Applied to any section or category
   heading, on any page — apply it to new headings too, for consistency. */

.accent-bar {
	border-inline-start: 5px solid var(--magenta-deep);
	padding-inline-start: 16px;
}

/* ==========================================================================
   4. Header
   ========================================================================== */

.site-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	padding: 14px 32px;
	background: var(--white);
	border-bottom: 1px solid var(--magenta-100);
	position: sticky;
	top: 0;
	z-index: 50;
}

.brand {
	display: flex;
	align-items: center;
	gap: 12px;
	min-width: 0;
}

/* Width only — the height follows the aspect ratio. Never crop this asset to a
   square and never round its container (spec §2.1). */
.brand img {
	width: 34px;
	height: auto;
	flex: none;
}

.brand .wordmark {
	display: flex;
	flex-direction: column;
	line-height: 1.25;
	min-width: 0;
}

.brand .wordmark .en {
	font-weight: 800;
	font-size: 15px;
	color: var(--magenta-deep);
	letter-spacing: 0.01em;
	text-transform: uppercase;
}

.brand .wordmark .sub {
	font-size: 11.5px;
	color: var(--magenta);
	font-weight: 600;
}

.nav-links {
	display: flex;
	align-items: center;
	gap: 30px;
	font-size: 14px;
	font-weight: 600;
	color: var(--muted);
}

.nav-links a:hover {
	color: var(--magenta-deep);
}

.nav-links a.current {
	color: var(--magenta-deep);
	border-bottom: 2px solid var(--magenta-deep);
	padding-bottom: 4px;
}

/* The Verify entry is a filled pill, distinct from the three plain links
   beside it (spec §4.1). */
.nav-links a.nav-verify {
	background: var(--magenta-deep);
	color: var(--white);
	padding: 8px 18px;
	border-radius: 999px;
	font-weight: 800;
	border-bottom: none;
}

.nav-links a.nav-verify:hover,
.nav-links a.nav-verify.current {
	background: var(--magenta);
	color: var(--white);
	border-bottom: none;
}

.header-actions {
	display: flex;
	align-items: center;
	gap: 14px;
}

.lang-pill {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	border: 1px solid var(--magenta-100);
	border-radius: 999px;
	padding: 9px 18px;
	font-size: 13px;
	font-weight: 700;
	color: var(--magenta-deep);
	white-space: nowrap;
}

.lang-pill:hover {
	border-color: var(--magenta);
}

.lang-pill .is-muted {
	color: var(--faint);
}

.lang-pill .ar {
	direction: rtl;
}

/* --- Mobile drawer --------------------------------------------------------- */

.nav-toggle {
	display: none;
	flex-direction: column;
	justify-content: center;
	gap: 4px;
	width: 40px;
	height: 40px;
	padding: 0 9px;
	border: 1px solid var(--magenta-100);
	border-radius: 10px;
	background: var(--white);
	cursor: pointer;
}

.nav-toggle span {
	display: block;
	height: 2px;
	border-radius: 2px;
	background: var(--magenta-deep);
	transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}

.nav-toggle[aria-expanded='true'] span:nth-child(1) {
	transform: translateY(6px) rotate(45deg);
}

.nav-toggle[aria-expanded='true'] span:nth-child(2) {
	opacity: 0;
}

.nav-toggle[aria-expanded='true'] span:nth-child(3) {
	transform: translateY(-6px) rotate(-45deg);
}

.mobile-nav {
	display: none;
	flex-direction: column;
	gap: 2px;
	padding: 8px 24px 18px;
	background: var(--white);
	border-top: 1px solid var(--magenta-100);
}

.mobile-nav:not([hidden]) {
	display: flex;
}

.mobile-nav-link {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 16px;
	padding: 12px 4px;
	border-bottom: 1px solid var(--magenta-50);
	font-size: 14.5px;
	font-weight: 700;
}

.mobile-nav-link .ar {
	color: var(--magenta);
	font-size: 14.5px;
	font-weight: 700;
}

.mobile-nav-link.is-current {
	color: var(--magenta-deep);
}

@media (max-width: 1023px) {
	.site-header {
		flex-wrap: wrap;
		padding: 12px 20px;
	}

	.nav-links {
		display: none;
	}

	.nav-toggle {
		display: flex;
	}

	.mobile-nav {
		flex-basis: 100%;
		margin-inline: -20px;
		margin-bottom: -12px;
	}
}

@media (max-width: 600px) {
	.brand img {
		width: 30px;
	}

	.brand .wordmark .en {
		font-size: 12.5px;
	}

	.brand .wordmark .sub {
		font-size: 10.5px;
	}

	.lang-pill {
		padding: 7px 12px;
		font-size: 12px;
	}
}

/* ==========================================================================
   5. The maroon top banner (spec §2.7)
   ==========================================================================
   The standard page-top treatment for Winners, Verify, Gift Guide, Register,
   Directory and Contact Us. Editor's Choice and Judges Excellence deliberately
   use a different treatment — do not unify them.
   ========================================================================== */

.top-banner {
	background: var(--magenta-deep);
	color: var(--white);
	text-align: center;
	padding: 44px 24px 40px;
}

.top-banner img {
	width: 54px;
	height: auto;
	margin-bottom: 16px;
	filter: drop-shadow(0 8px 18px rgba(0, 0, 0, 0.28));
}

.top-banner .eyebrow {
	display: block;
	font-size: 10.5px;
	font-weight: 800;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: #f3b8d2;
	margin-bottom: 10px;
}

.top-banner h1 {
	font-size: clamp(26px, 4vw, 40px);
	font-weight: 900;
	color: var(--white);
	margin-bottom: 8px;
}

.top-banner .ar {
	display: block;
	font-size: clamp(15px, 2vw, 19px);
	font-weight: 700;
	color: var(--magenta-100);
}

.top-banner .banner-note {
	margin-top: 14px;
	font-size: 13.5px;
	color: var(--magenta-100);
}

@media (max-width: 600px) {
	.top-banner {
		padding: 32px 20px 28px;
	}

	.top-banner img {
		width: 44px;
	}
}

/* --- The light programme header (Editor's Choice, Judges Excellence) ------- */

.programme-header {
	text-align: center;
	padding: 46px 24px 30px;
	background: linear-gradient(180deg, var(--magenta-50) 0%, rgba(255, 255, 255, 0) 100%);
}

.programme-header .programme-logo {
	max-width: 320px;
	width: 100%;
	height: auto;
	margin-inline: auto;
}

.programme-header h1 {
	font-size: clamp(24px, 3.4vw, 34px);
	font-weight: 900;
	color: var(--magenta-deep);
}

.programme-header .ar {
	display: block;
	margin-top: 8px;
	font-size: clamp(15px, 2vw, 19px);
	font-weight: 700;
	color: var(--magenta);
}

/*
 * The Judges' Excellence artwork has not been supplied yet (spec §2.1). Rather
 * than ship the prototype's placeholder badge, this typographic lockup stands in
 * — it is the same visual language, it is honest about being type rather than a
 * logo, and it disappears the moment an administrator uploads real artwork.
 */
.judges-lockup {
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	padding: 22px 34px;
	border: 2px solid var(--magenta-deep);
	border-radius: var(--radius-lg);
	background: var(--white);
	box-shadow: var(--shadow);
}

.judges-lockup .kicker {
	font-size: 10px;
	font-weight: 800;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--magenta);
}

.judges-lockup .name {
	font-size: clamp(18px, 2.4vw, 24px);
	font-weight: 900;
	color: var(--magenta-deep);
	text-align: center;
}

.judges-lockup .tag {
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--faint);
}

/* ==========================================================================
   6. Buttons
   ========================================================================== */

.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 11px 22px;
	border-radius: 999px;
	border: 1px solid transparent;
	font-family: inherit;
	font-weight: 700;
	font-size: 13.5px;
	cursor: pointer;
	transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
		background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

.btn:disabled,
.btn[aria-disabled='true'] {
	opacity: 0.55;
	cursor: not-allowed;
	transform: none;
	box-shadow: none;
}

.btn-solid {
	background: var(--white);
	color: var(--magenta-deep);
}

.btn-solid:hover:not(:disabled) {
	transform: translateY(-2px);
	box-shadow: 0 8px 20px rgba(0, 0, 0, 0.25);
}

.btn-primary {
	background: var(--magenta-deep);
	color: var(--white);
}

.btn-primary:hover:not(:disabled) {
	background: var(--magenta);
	transform: translateY(-2px);
	box-shadow: var(--shadow);
}

.btn-outline {
	background: transparent;
	color: var(--magenta-deep);
	border-color: var(--magenta-100);
}

.btn-outline:hover:not(:disabled) {
	border-color: var(--magenta);
	background: var(--magenta-50);
}

.btn-ghost {
	background: transparent;
	color: var(--magenta);
	padding-inline: 8px;
}

.btn-ghost:hover:not(:disabled) {
	color: var(--magenta-deep);
}

.btn-block {
	width: 100%;
}

.btn-sm {
	padding: 8px 16px;
	font-size: 12.5px;
}

/* ==========================================================================
   7. Cards and grids
   ========================================================================== */

/* Standard card weight is 1.5px (spec §2.8). The homepage's six quick-link
   buttons use a heavier 4px and override this — see pages/home.css. */
.pcfa-card {
	background: var(--white);
	border: 1.5px solid var(--magenta-100);
	border-radius: var(--radius);
	transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
		border-color var(--dur) var(--ease);
}

a.pcfa-card:hover,
button.pcfa-card:hover,
.pcfa-card.is-interactive:hover {
	transform: translateY(-4px);
	border-color: var(--magenta);
	box-shadow: var(--shadow);
}

.pcfa-grid {
	display: grid;
	gap: 18px;
	grid-template-columns: repeat(5, 1fr);
}

.pcfa-grid-3 {
	grid-template-columns: repeat(3, 1fr);
}

.pcfa-grid-2 {
	grid-template-columns: repeat(2, 1fr);
}

@media (max-width: 1023px) {
	.pcfa-grid {
		grid-template-columns: repeat(3, 1fr);
	}
}

@media (max-width: 639px) {
	.pcfa-grid {
		grid-template-columns: repeat(2, 1fr);
		gap: 12px;
	}

	.pcfa-grid-3,
	.pcfa-grid-2 {
		grid-template-columns: repeat(2, 1fr);
	}
}

.pcfa-section {
	padding-block: 40px;
}

.pcfa-section-tight {
	padding-block: 22px;
}

/* ==========================================================================
   8. Perfume card and winner tile
   ========================================================================== */

.perfume-card {
	display: flex;
	flex-direction: column;
	overflow: hidden;
	text-align: center;
}

.perfume-card .shot {
	position: relative;
	aspect-ratio: 4 / 5;
	background: var(--magenta-50);
	display: block;
	overflow: hidden;
}

.perfume-card .shot img {
	width: 100%;
	height: 100%;
	/* `contain`, never `cover`: a cropped perfume bottle was rejected during
	   development (spec §5.2). The tinted backdrop fills what contain leaves. */
	object-fit: contain;
	display: block;
}

.perfume-card .shot-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	color: var(--steel-200);
}

.perfume-card .body {
	padding: 14px 12px 16px;
	display: flex;
	flex-direction: column;
	gap: 3px;
}

.perfume-card .name-en {
	font-size: 13.5px;
	font-weight: 800;
	color: var(--ink);
}

.perfume-card .name-ar {
	font-size: 13.5px;
	font-weight: 800;
	color: var(--magenta);
}

.perfume-card .house {
	margin-top: 4px;
	font-size: 11.5px;
	font-weight: 600;
	color: var(--faint);
}

.winner-tag {
	position: absolute;
	top: 10px;
	inset-inline-start: 10px;
	z-index: 2;
	padding: 5px 11px;
	border-radius: 999px;
	background: var(--magenta-deep);
	color: var(--white);
	font-size: 10px;
	font-weight: 800;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.rank-tag {
	position: absolute;
	top: 10px;
	inset-inline-end: 10px;
	z-index: 2;
	padding: 5px 11px;
	border-radius: 999px;
	background: var(--white);
	border: 1.5px solid var(--magenta-deep);
	color: var(--magenta-deep);
	font-size: 10.5px;
	font-weight: 800;
}

/* ==========================================================================
   9. Year tabs
   ========================================================================== */

.year-tabs {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 8px;
	margin-bottom: 28px;
}

.year-tab {
	padding: 8px 20px;
	border-radius: 999px;
	border: 1.5px solid var(--magenta-100);
	background: var(--white);
	font-size: 13px;
	font-weight: 700;
	color: var(--magenta-deep);
	cursor: pointer;
	transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease),
		color var(--dur) var(--ease);
}

.year-tab:hover {
	border-color: var(--magenta);
}

.year-tab.is-active {
	background: var(--magenta-deep);
	border-color: var(--magenta-deep);
	color: var(--white);
}

/* ==========================================================================
   10. Sponsors / Co-Sponsors / Powered By (spec §4.3)
   ==========================================================================
   Marks are unicoloured, on no background box, at a deliberately understated
   size. These dimensions were reduced twice during development — do not exceed
   them without a specific client request.
   ========================================================================== */

.sponsors-section {
	padding: 8px 6vw;
	text-align: center;
}

.sponsors-section .eyebrow {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 12px;
	margin-bottom: 22px;
	font-size: 11px;
	font-weight: 800;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--sponsor-fill);
}

.sponsors-section .eyebrow .ln {
	height: 1px;
	width: 30px;
	background: var(--magenta-100);
}

.logo-row {
	display: grid;
	grid-template-columns: repeat(5, 1fr);
	gap: 14px;
	max-width: 680px;
	margin: 0 auto 40px;
	align-items: center;
}

.logo-box {
	height: 24px;
	display: flex;
	align-items: center;
	justify-content: center;
}

.logo-box > a {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
}

.logo-box svg,
.logo-box img {
	width: 100%;
	height: 100%;
	max-width: 50px;
	object-fit: contain;
}

.logo-box.main svg {
	fill: var(--sponsor-fill);
	stroke: none;
}

.logo-box.co svg {
	fill: none;
	stroke: var(--sponsor-stroke);
	stroke-width: 1.6;
}

.logo-box img {
	filter: grayscale(1) opacity(0.75);
}

.logo-wordmark {
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--sponsor-fill);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

@media (max-width: 700px) {
	.logo-row {
		grid-template-columns: repeat(3, 1fr);
		gap: 12px;
	}
}

@media (max-width: 420px) {
	.logo-row {
		grid-template-columns: repeat(2, 1fr);
	}
}

.powered {
	text-align: center;
	padding: 10px 6vw 40px;
}

.powered .label {
	font-size: 12px;
	color: var(--faint);
	margin-bottom: 14px;
}

.powered-row {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 26px;
	flex-wrap: wrap;
}

.powered-row img {
	height: 26px;
	width: auto;
	filter: grayscale(1) opacity(0.7);
}

.powered-row .logo-wordmark {
	font-size: 12.5px;
}

/* ==========================================================================
   11. Ad banner slots
   ==========================================================================
   Heights are fixed per slot and the creative is cropped with object-fit:cover,
   so a banner of any aspect ratio sits in the reserved space without shifting
   the layout when it loads.
   ========================================================================== */

.ad-section {
	padding-block: 18px;
}

.ad-banner {
	position: relative;
	display: block;
	overflow: hidden;
	border-radius: var(--radius-sm);
	background: var(--magenta-50);
	border: 1px solid var(--magenta-100);
}

.ad-banner picture,
.ad-banner img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.ad-tag {
	position: absolute;
	top: 8px;
	inset-inline-end: 8px;
	z-index: 2;
	padding: 2px 8px;
	border-radius: 4px;
	background: rgba(58, 15, 38, 0.72);
	color: var(--white);
	font-size: 9.5px;
	font-weight: 800;
	letter-spacing: 0.1em;
}

/* Editor's Choice / Judges Excellence hero banner (spec §5.2 step 4). */
.ad-section-editors_choice_banner .ad-banner,
.ad-section-judges_excellence_banner .ad-banner {
	height: 220px;
}

/* The per-category banner above each voting grid (spec §5.5 step 3). */
.ad-section-ballot_category_banner .ad-banner {
	height: 110px;
}

.ad-section-home_below_slider .ad-banner,
.ad-section-winners_below_header .ad-banner,
.ad-section-page_below_slider .ad-banner {
	height: 180px;
}

.ad-section-home_above_sponsors .ad-banner,
.ad-section-directory_below_header .ad-banner,
.ad-section-giftguide_below_header .ad-banner,
.ad-section-register_below_header .ad-banner,
.ad-section-page_footer_banner .ad-banner {
	height: 120px;
}

@media (max-width: 639px) {
	.ad-section-editors_choice_banner .ad-banner,
	.ad-section-judges_excellence_banner .ad-banner {
		height: 140px;
	}

	.ad-section-ballot_category_banner .ad-banner {
		height: 70px;
	}

	.ad-section-home_below_slider .ad-banner,
	.ad-section-winners_below_header .ad-banner,
	.ad-section-page_below_slider .ad-banner {
		height: 128px;
	}

	.ad-section-home_above_sponsors .ad-banner,
	.ad-section-directory_below_header .ad-banner,
	.ad-section-giftguide_below_header .ad-banner,
	.ad-section-register_below_header .ad-banner,
	.ad-section-page_footer_banner .ad-banner {
		height: 90px;
	}
}

/* ==========================================================================
   12. Forms
   ========================================================================== */

.pcfa-form {
	display: flex;
	flex-direction: column;
	gap: 18px;
}

.form-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 16px;
}

.field {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.field.full {
	grid-column: 1 / -1;
}

.field > label,
.field-label {
	font-size: 12.5px;
	font-weight: 700;
	color: var(--muted);
}

.field-label .ar {
	font-weight: 700;
	color: var(--magenta);
}

.field input[type='text'],
.field input[type='email'],
.field input[type='tel'],
.field input[type='url'],
.field input[type='number'],
.field input[type='date'],
.field input[type='file'],
.field select,
.field textarea {
	width: 100%;
	padding: 11px 14px;
	border: 1.5px solid var(--magenta-100);
	border-radius: 10px;
	background: var(--white);
	font-family: inherit;
	font-size: 14px;
	color: var(--ink);
	transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.field textarea {
	min-height: 120px;
	resize: vertical;
	line-height: 1.6;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
	border-color: var(--magenta);
	box-shadow: 0 0 0 3px rgba(164, 31, 94, 0.12);
	outline: none;
}

.field .help {
	font-size: 11.5px;
	color: var(--faint);
	line-height: 1.5;
}

.field.has-error input,
.field.has-error select,
.field.has-error textarea {
	border-color: var(--danger);
}

.field .field-error {
	font-size: 11.5px;
	font-weight: 700;
	color: var(--danger);
}

.required-mark {
	color: var(--magenta);
}

.consent-row {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	padding: 14px 16px;
	border: 1.5px solid var(--magenta-100);
	border-radius: var(--radius-sm);
	background: var(--magenta-50);
}

.consent-row input[type='checkbox'] {
	margin-top: 3px;
	width: 18px;
	height: 18px;
	accent-color: var(--magenta-deep);
	flex: none;
}

.consent-row label {
	font-size: 13px;
	line-height: 1.6;
}

.consent-row .ar {
	display: block;
	margin-top: 4px;
	color: var(--magenta);
}

/* The honeypot. Hidden from sight and from assistive technology, but a real
   field a form-filling bot will populate. Never `display:none` — some bots
   skip those. */
.pcfa-hp-field {
	position: absolute !important;
	left: -9999px !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.pcfa-form-message {
	display: none;
	padding: 12px 16px;
	border-radius: 10px;
	font-size: 13px;
	font-weight: 600;
}

.pcfa-form-message.is-visible {
	display: block;
}

.pcfa-form-message.is-error {
	background: #fdecea;
	color: #8c1d18;
}

.pcfa-form-message.is-success {
	background: var(--magenta-50);
	color: var(--magenta-deep);
}

.pcfa-captcha {
	margin-block: 4px;
}

@media (max-width: 639px) {
	.form-grid {
		grid-template-columns: 1fr;
	}
}

/* ==========================================================================
   13. Notices, empty states, panels
   ========================================================================== */

.pcfa-panel {
	background: var(--white);
	border: 1.5px solid var(--magenta-100);
	border-radius: var(--radius-lg);
	padding: 26px;
	box-shadow: var(--shadow);
}

.pcfa-notice {
	padding: 14px 18px;
	border-radius: var(--radius-sm);
	border: 1.5px solid var(--magenta-100);
	background: var(--magenta-50);
	font-size: 13.5px;
	line-height: 1.6;
}

.pcfa-notice strong {
	color: var(--magenta-deep);
}

.pcfa-notice-warning {
	border-color: #f0c36d;
	background: #fdf6e3;
}

.pcfa-empty {
	text-align: center;
	padding: 44px 24px;
	border: 1.5px dashed var(--magenta-100);
	border-radius: var(--radius-lg);
	background: var(--white);
}

/*
 * The empty state's title is a bilingual pair like any other heading, so its size
 * and weight belong to the row and both halves inherit them (spec §2.5). Centred
 * rather than split to the two ends, because the whole panel is centred and a
 * space-between row inside it would strand the two languages at the margins.
 */
.pcfa-empty .bi-row {
	justify-content: center;
	font-size: 16px;
	font-weight: 800;
	margin-bottom: 10px;
}

.pcfa-empty strong {
	color: var(--magenta-deep);
}

.pcfa-empty .ar {
	color: var(--magenta);
}

.pcfa-empty p {
	font-size: 13.5px;
	color: var(--muted);
	max-width: 46ch;
	margin-inline: auto;
}

/* Two-column balanced bilingual intro, used on the programme pages, the
   directory profile and the winner detail view. */
.bi-columns {
	display: grid;
	grid-template-columns: 1fr 1px 1fr;
	gap: 26px;
	align-items: start;
}

.bi-columns .divider {
	width: 1px;
	align-self: stretch;
	background: var(--magenta-100);
}

.bi-columns .col {
	font-size: 14.5px;
	line-height: 1.75;
	color: var(--muted);
}

.bi-columns .col.ar {
	text-align: end;
}

@media (max-width: 767px) {
	.bi-columns {
		grid-template-columns: 1fr;
		gap: 16px;
	}

	.bi-columns .divider {
		width: 100%;
		height: 1px;
		align-self: auto;
	}
}

/* ==========================================================================
   14. Verification block (code + QR)
   ========================================================================== */

.verify-block {
	display: flex;
	align-items: center;
	gap: 18px;
	flex-wrap: wrap;
	padding: 18px;
	border: 1.5px solid var(--magenta-100);
	border-radius: var(--radius-sm);
	background: var(--magenta-50);
}

.verify-block .qr {
	width: 96px;
	height: 96px;
	flex: none;
	background: var(--white);
	padding: 6px;
	border-radius: 8px;
}

.verify-block .qr canvas,
.verify-block .qr img {
	display: block;
	width: 100%;
	height: auto;
}

.verify-block .meta {
	min-width: 0;
}

.verify-block .label {
	display: block;
	font-size: 10.5px;
	font-weight: 800;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--faint);
	margin-bottom: 4px;
}

.pcfa-code {
	font-family: ui-monospace, 'SFMono-Regular', 'Menlo', 'Consolas', monospace;
	font-size: 15px;
	font-weight: 700;
	letter-spacing: 0.06em;
	color: var(--magenta-deep);
}

/* ==========================================================================
   15. Media coverage — press, gallery, video (spec §5.2 step 7)
   ========================================================================== */

.media-section {
	padding-block: 30px;
}

.media-links {
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.media-link {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 14px 18px;
	border: 1.5px solid var(--magenta-100);
	border-radius: var(--radius-sm);
	background: var(--white);
	transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}

.media-link:hover {
	border-color: var(--magenta);
	transform: translateY(-2px);
}

.media-link .m-icon {
	width: 18px;
	height: 18px;
	flex: none;
	color: var(--magenta);
}

.media-link .m-text {
	flex: 1 1 auto;
	font-size: 14px;
	font-weight: 700;
	min-width: 0;
}

.media-link .m-ext {
	font-size: 12px;
	font-weight: 700;
	color: var(--magenta);
	white-space: nowrap;
}

.gallery-scroll,
.video-scroll {
	display: flex;
	gap: 12px;
	overflow-x: auto;
	padding-bottom: 10px;
	scroll-snap-type: x proximity;
	-webkit-overflow-scrolling: touch;
}

.event-photo {
	flex: none;
	width: 220px;
	aspect-ratio: 4 / 3;
	padding: 0;
	border: 1.5px solid var(--magenta-100);
	border-radius: var(--radius-sm);
	overflow: hidden;
	background: var(--magenta-50);
	cursor: pointer;
	scroll-snap-align: start;
	transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}

.event-photo:hover {
	border-color: var(--magenta);
	transform: translateY(-3px);
}

.event-photo img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.video-card {
	flex: none;
	width: 200px;
	border: 1.5px solid var(--magenta-100);
	border-radius: var(--radius-sm);
	overflow: hidden;
	background: var(--white);
	scroll-snap-align: start;
	transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}

.video-card:hover {
	border-color: var(--magenta);
	transform: translateY(-3px);
}

/* Mixed orientations by design (spec §5.2 step 7): a 9:16 vertical clip and a
   16:9 horizontal one sit in the same scroller. */
.video-card .thumb {
	position: relative;
	display: block;
	aspect-ratio: 16 / 9;
	background: var(--magenta-50);
	overflow: hidden;
}

.video-card.is-portrait {
	width: 150px;
}

.video-card.is-portrait .thumb {
	aspect-ratio: 9 / 16;
}

.video-card .thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.video-card .play {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--white);
	background: rgba(58, 15, 38, 0.28);
}

.video-card .play svg {
	width: 34px;
	height: 34px;
	filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.4));
}

.video-card .video-card-body {
	padding: 10px 12px 12px;
	font-size: 12.5px;
	font-weight: 700;
	line-height: 1.45;
}

@media (max-width: 640px) {
	.event-photo {
		width: 168px;
	}

	.video-card {
		width: 160px;
	}

	.video-card.is-portrait {
		width: 124px;
	}
}

/* ==========================================================================
   16. Lightbox and modal
   ========================================================================== */

.pcfa-lightbox,
.pcfa-modal {
	position: fixed;
	inset: 0;
	z-index: 120;
	display: none;
	align-items: center;
	justify-content: center;
	padding: 24px;
	background: rgba(28, 6, 18, 0.82);
}

.pcfa-lightbox.is-open,
.pcfa-modal.is-open {
	display: flex;
}

.pcfa-lightbox-box {
	position: relative;
	max-width: 1000px;
	width: 100%;
	text-align: center;
}

.pcfa-lightbox-box img {
	max-width: 100%;
	max-height: 76vh;
	border-radius: var(--radius-sm);
	background: var(--white);
}

.pcfa-lightbox-close,
.pcfa-modal-close {
	position: absolute;
	top: -6px;
	inset-inline-end: -6px;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	border: 1px solid rgba(255, 255, 255, 0.4);
	background: rgba(58, 15, 38, 0.5);
	color: var(--white);
	font-size: 22px;
	line-height: 1;
	cursor: pointer;
}

.pcfa-lightbox-nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	width: 44px;
	height: 44px;
	border-radius: 50%;
	border: 1px solid rgba(255, 255, 255, 0.4);
	background: rgba(58, 15, 38, 0.4);
	color: var(--white);
	font-size: 16px;
	cursor: pointer;
}

.pcfa-lightbox-prev {
	inset-inline-start: -10px;
}

.pcfa-lightbox-next {
	inset-inline-end: -10px;
}

.pcfa-lightbox-caption {
	margin-top: 12px;
	color: var(--white);
}

.pcfa-lightbox-caption strong {
	display: block;
	font-size: 14.5px;
}

.pcfa-lightbox-caption span {
	display: block;
	font-size: 13px;
	color: var(--magenta-100);
}

.pcfa-lightbox-counter {
	margin-top: 6px;
	font-size: 12px;
	color: var(--magenta-100);
}

.pcfa-modal-box {
	position: relative;
	max-width: 980px;
	width: 100%;
	max-height: 88vh;
	overflow-y: auto;
	background: var(--white);
	border-radius: var(--radius-lg);
	padding: 28px;
	box-shadow: 0 30px 70px rgba(0, 0, 0, 0.4);
}

.pcfa-modal-close {
	position: sticky;
	top: 0;
	inset-inline-end: 0;
	float: inline-end;
	background: var(--magenta-50);
	border-color: var(--magenta-100);
	color: var(--magenta-deep);
}

@media (max-width: 639px) {
	.pcfa-lightbox,
	.pcfa-modal {
		padding: 12px;
	}

	.pcfa-modal-box {
		padding: 20px 16px;
	}

	.pcfa-lightbox-prev {
		inset-inline-start: 0;
	}

	.pcfa-lightbox-next {
		inset-inline-end: 0;
	}
}


/* ==========================================================================
   17. Footer
   ==========================================================================
   A maroon band closing the page, echoing the top banner of §5 so the document
   is bracketed by the same colour rather than trailing off into the background
   gradient. Four optional rows — social, links, contact, copyright — each of
   which the template omits entirely when nothing is configured, so the band has
   to look deliberate at one row and at four.

   Everything is centred and every dimension is logical, so the band mirrors in
   Arabic with no `[dir]` rule of its own: the separators between the links use
   `inset-inline-end` and a Y-only transform precisely so they do not need one.
   ========================================================================== */

.site-footer {
	margin-top: 72px;
	padding: 32px 24px 28px;
	background: var(--magenta-deep);
	color: rgba(255, 255, 255, 0.82);
	text-align: center;
	font-size: 13px;
}

/* Each row is centred on the same measure as the page content above it, so a
   wide screen does not spread five links across two metres of maroon. */
.site-footer > * {
	max-width: var(--max);
	margin-inline: auto;
}

/* --- Social ---------------------------------------------------------------- */

.footer-social {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 10px;
	margin-bottom: 20px;
}

.footer-social a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border: 1.5px solid rgba(255, 255, 255, 0.3);
	border-radius: 50%;
	color: var(--white);
	transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

.footer-social a:hover {
	background: rgba(255, 255, 255, 0.16);
	border-color: var(--white);
}

.footer-social svg {
	width: 17px;
	height: 17px;
	fill: currentColor;
}

/* --- Links ----------------------------------------------------------------- */

.footer-links {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	row-gap: 2px;
}

.footer-links a {
	position: relative;
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding-inline: 15px;
	font-size: 13px;
	font-weight: 700;
	color: var(--white);
	transition: color var(--dur) var(--ease);
}

.footer-links a:hover {
	color: var(--magenta-100);
}

/*
 * The dot between two links. It is a pseudo-element rather than markup because
 * it is punctuation between items, not an item — a screen reader should hear
 * five links, not five links and four full stops. Absolute, so it sits in the
 * gap without becoming part of either link's tap target, and positioned with
 * `inset-inline-end` plus a Y-only transform so Arabic needs no override.
 */
.footer-links a:not(:last-child)::after {
	content: '·';
	position: absolute;
	inset-inline-end: -3px;
	top: 50%;
	transform: translateY(-50%);
	color: rgba(255, 255, 255, 0.45);
	font-weight: 400;
	pointer-events: none;
}

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

.footer-contact {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: 8px;
	margin-top: 10px;
	font-size: 12.5px;
	color: rgba(255, 255, 255, 0.78);
}

.footer-contact a {
	display: inline-flex;
	align-items: center;
	min-height: 32px;
	color: inherit;
	/* An address is one unbreakable token until it is told otherwise, and on a
	   320px screen an unbroken address is a horizontal scrollbar. */
	overflow-wrap: anywhere;
	transition: color var(--dur) var(--ease);
}

.footer-contact a:hover {
	color: var(--white);
	text-decoration: underline;
}

/* --- Copyright ------------------------------------------------------------- */

/*
 * When the footer is nothing but a copyright line — no social accounts, no
 * links configured — the rule below would draw a hairline with nothing above it
 * to separate from. The separator belongs to the boundary, so it exists only
 * when there is a boundary.
 */
.footer-copy:first-child {
	margin-top: 0;
	padding-top: 0;
	border-top: 0;
}

.footer-copy {
	margin-top: 18px;
	padding-top: 16px;
	/* The hairline is the only thing separating the legal line from the links,
	   and it is drawn at low opacity rather than in a second colour so it works
	   whatever the maroon is set to in Branding. */
	border-top: 1px solid rgba(255, 255, 255, 0.16);
	font-size: 12px;
	/* 1.7 rather than a Latin 1.4: this line is the one place Arabic and English
	   copyright text are set at their longest, and it wraps on a phone. */
	line-height: 1.7;
	color: rgba(255, 255, 255, 0.62);
}

/*
 * Once the row wraps, the interpuncts stop helping and start lying: the dot
 * belongs *between* two links, and the last link on a wrapped row ends up with a
 * dot trailing off into empty space. CSS cannot ask whether an item is last on
 * its row, so below the width where five links stop fitting on one line the
 * separators go and the spacing carries the job instead.
 */
@media (max-width: 767px) {
	.footer-links {
		column-gap: 4px;
		row-gap: 0;
	}

	/* `:not(:last-child)` is repeated rather than dropped: the rule it overrides
	   carries that pseudo-class, so a shorter selector here loses on specificity
	   and the dots stay. */
	.footer-links a:not(:last-child)::after {
		content: none;
	}
}

@media (max-width: 639px) {
	.site-footer {
		margin-top: 48px;
		padding: 26px 18px 24px;
	}

	/* Tighter, because five links at 15px of side padding is three ragged rows
	   on a 360px screen and two tidy ones at 10px. */
	.footer-links a {
		padding-inline: 10px;
		font-size: 12.5px;
	}

	.footer-contact {
		/* The phone and the address stack rather than wrap mid-address. */
		flex-direction: column;
		gap: 4px;
	}

	/* The interpunct the template prints between the phone and the address is
	   meaningless once they are stacked. */
	.footer-contact > span[aria-hidden='true'] {
		display: none;
	}
}

/* ==========================================================================
   18. Winner detail pop-up — shared by Winners, Editor's Choice and Judges
   ==========================================================================
   One component on three pages. It lives here rather than in three page
   stylesheets because that is exactly the drift spec §4.1 describes for the
   header: three byte-identical copies, and the third one nobody remembers to
   update. The shell (`.pcfa-modal`, `.pcfa-modal-box`, `.pcfa-modal-close`)
   and all of its behaviour are in §16 above; this is only its contents.
   ========================================================================== */

/* ==========================================================================
   2. Winner detail pop-up
   ==========================================================================
   Opened and painted by pages/winners.js from the JSON payload the template
   emits. The shell (`.pcfa-modal`, `.pcfa-modal-box`, `.pcfa-modal-close`) and
   all of its behaviour — backdrop click, Escape, focus trap — are shared.

   This block is the same component as the one in editors_choice.css and
   judges_excellence.css, with the same class names, and it is duplicated for the
   same reason they duplicate it: three pages carry it and public.css is reserved
   for components shared more widely than that. A change here is a change owed to
   both of those files. The only rules unique to this page are the category pill,
   which the two programme pages have no equivalent of, and the single-column
   description fallback.
   ========================================================================== */

/* Narrower than the shared 980px default: the hero is the whole point of this
   pop-up and a wider box makes a portrait bottle photograph look lost in it. */
.winner-modal-box {
	max-width: 880px;
}

/*
 * `contain`, never `cover` (spec §5.2, §10). An earlier pass used `cover` and
 * cropped the perfume bottles unacceptably; the dark backdrop fills whatever
 * `contain` leaves, and the fixed height means swapping a thumbnail cannot
 * reflow the box.
 */
.winner-hero {
	display: flex;
	align-items: center;
	justify-content: center;
	height: min(560px, 62vh);
	overflow: hidden;
	border-radius: var(--radius-sm);
	background: var(--ink);
}

.winner-hero img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: contain;
}

/*
 * The uppercase micro-label above the gallery strip, the fragrance house and the
 * verification code. It deliberately sets no `display`: the markup pairs it with
 * `.bi-row`, and a `display: block` here would win the cascade and collapse the
 * two languages onto one another.
 */
.detail-label {
	margin-bottom: 6px;
	font-size: 10.5px;
	font-weight: 800;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--magenta);
}

.winner-gallery {
	margin-top: 14px;
}

.winner-thumbs {
	display: flex;
	gap: 8px;
	overflow-x: auto;
	padding-bottom: 4px;
	-webkit-overflow-scrolling: touch;
}

/*
 * Deliberately small (56×42px, spec §5.2) so the hero keeps the maximum space.
 * A thumbnail swaps the hero in place; it never opens the shared lightbox, which
 * is why it is a plain button with no `data-pcfa-lightbox-item` hook. A
 * thumbnail is a crop preview rather than the image itself, so `cover` is right
 * here and wrong on the hero above.
 */
.winner-thumb {
	flex: none;
	width: 56px;
	height: 42px;
	padding: 0;
	overflow: hidden;
	border: 2px solid transparent;
	border-radius: 6px;
	background: var(--magenta-50);
	opacity: 0.65;
	cursor: pointer;
	transition: opacity var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

.winner-thumb img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.winner-thumb:hover {
	opacity: 1;
}

/* The pressed state is the ARIA attribute rather than a class, so which image is
   showing is exposed to assistive technology and styled from one source. */
.winner-thumb[aria-pressed='true'] {
	border-color: var(--magenta);
	opacity: 1;
}

/* The size sits on the row so both names inherit exactly the same one — a
   per-half font-size is how a bilingual pair drifts apart (spec §2.5). */
.winner-names {
	margin-top: 14px;
	font-size: clamp(19px, 2.4vw, 24px);
	font-weight: 800;
}

.winner-desc {
	margin-top: 16px;
}

.winner-house {
	margin-top: 22px;
	padding-top: 18px;
	border-top: 1px solid var(--magenta-100);
}

.winner-house-value {
	font-size: 14px;
	font-weight: 800;
	color: var(--ink);
}

/* The linked and unlinked house have to look different: a plain name styled like
   a link is a dead end a visitor will click (spec §5.4). */
.winner-house-value a {
	color: var(--magenta-deep);
	border-bottom: 1.5px solid var(--magenta-deep);
}

.winner-house-value a:hover {
	color: var(--magenta);
	border-bottom-color: var(--magenta);
}

.winner-verify {
	margin-top: 18px;
	justify-content: space-between;
}

.winner-verify .meta {
	flex: 1 1 260px;
}

.verify-qr {
	display: flex;
	flex: none;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	text-align: center;
}

.verify-qr .label {
	margin-bottom: 0;
}

.verify-help {
	margin-top: 8px;
	max-width: 46ch;
	font-size: 11.5px;
	line-height: 1.55;
	color: var(--muted);
}

.verify-help a {
	font-weight: 700;
	color: var(--magenta-deep);
	text-decoration: underline;
	/* A verification URL is one unbreakable token; without this it pushes the
	   pop-up wider than the viewport on a phone. */
	word-break: break-all;
}

/* The pop-up hero gives up height on a phone so the names, the description and
   the verification block are reachable without three screens of scrolling. */
@media (max-width: 639px) {
	.winner-modal-box {
		padding: 20px 16px;
	}

	.winner-hero {
		height: min(360px, 46vh);
	}
}

/* ==========================================================================
   19. Motion and print
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
	}
}

@media print {
	.site-header,
	.site-footer,
	.ad-section,
	.pcfa-lightbox,
	.pcfa-modal,
	.nav-toggle,
	.mobile-nav {
		display: none !important;
	}

	body.pcfa-body {
		background: var(--white);
	}
}

/* ==========================================================================
   22. Touch targets
   ==========================================================================
   A control that is comfortable to click with a mouse is not necessarily one a
   thumb can hit. Everything below reaches 48px on a coarse pointer and keeps its
   drawn size on a fine one, so the desktop layout is untouched: the extra area
   is taken as padding on a content-box, or as a centred `::after` overlay where
   padding would move the icon inside the button.

   Controls that already clear 48px, or that are small marks inside a large label
   or link (a consent checkbox beside its sentence, a card-wide radio, a media
   icon inside its row), are deliberately absent — the label is the target there,
   and growing the mark would only push its own text sideways.
   ========================================================================== */

@media (pointer: coarse) {
	/*
	 * The buttons are the most-pressed controls on the site and the ones a phone
	 * gets wrong most often: 11px of padding around 13.5px type is 38px tall,
	 * which is a comfortable mouse target and a poor thumb one. `min-height` is
	 * used rather than more padding so the label stays optically centred and the
	 * pill radius is unaffected.
	 */
	.btn,
	.btn-sm {
		min-height: 48px;
	}

	/*
	 * 16px is not a taste decision here. Safari on iOS zooms the whole page in
	 * when a field with type smaller than 16px takes focus, and it does not zoom
	 * back out — so a visitor filling in the register form ends up scrolling
	 * sideways through a layout that was fitting perfectly a moment earlier. The
	 * fine-pointer size stays 14px, which is what the design asks for.
	 */
	.field input,
	.field select,
	.field textarea,
	input[type='search'],
	input[type='text'],
	input[type='email'],
	input[type='tel'] {
		font-size: 16px;
		min-height: 48px;
	}

	.field textarea {
		/* A textarea's height is its rows, not a tap target. */
		min-height: 120px;
	}

	.nav-toggle,
	.pcfa-lightbox-close,
	.pcfa-modal-close {
		box-sizing: content-box;
		padding: 4px;
	}

	.footer-links a,
	.footer-contact a {
		min-height: 48px;
	}

	.footer-social a {
		width: 48px;
		height: 48px;
	}

	/*
	 * These sit inside a fixed-width row or an absolutely positioned corner where
	 * padding would shift the glyph off centre, so the target is grown outward
	 * from the middle instead and the glyph does not move at all.
	 */
	.lang-pill,
	.year-tab,
	.verify-tab {
		position: relative;
	}

	/*
	 * The insets are negative by exactly the shortfall, so the overlay grows
	 * outward from the control's own edges and stays centred without a transform
	 * — which matters because a `translateX(-50%)` would have to change sign in
	 * Arabic and this does not. `min()` keeps the inset at zero once the control
	 * already clears 48px, so nothing that is big enough gets shrunk.
	 */
	.lang-pill::after,
	.year-tab::after,
	.verify-tab::after {
		content: '';
		position: absolute;
		inset-inline: min(0px, calc((48px - 100%) / -2));
		inset-block: min(0px, calc((48px - 100%) / -2));
	}
}

/* An unticked consent box is a validation failure like any other, and the row is
   what carries the message, so the row is what is marked. Only the colour of the
   border it already has changes, so nothing moves as the message appears. */
.consent-row.has-error {
	border-color: var(--danger);
	background: var(--white);
}
