/*
 * Raffle Engine donor front end.
 *
 * Hand authored, no build step, consumes only the P0 tokens. Section 10: one
 * accent, generous neutrals, tabular numerals, nothing else. No gradients, no
 * glassmorphism, no colored-icon-in-rounded-square cards.
 *
 * Density here is a conversion surface, not a data tool: wide margins, one
 * action per screen. The entries table in P5 is the opposite and shares these
 * tokens without sharing this file.
 */

.rfl-raffle { /* P3 base. Composition is overridden by the P9 layer below. */
	max-width: var(--rfl-layout-donor-max);
	margin: 0 auto;
	padding: var(--rfl-space-6) var(--rfl-space-4);
	font-family: var(--rfl-font-sans);
	font-size: var(--rfl-size-base);
	line-height: var(--rfl-leading-normal);
	color: var(--rfl-color-text-primary);
}

/* Tabular figures everywhere a number can change under the reader. Section 10
   makes this mandatory: digits that shift width make a counter look unstable. */
.rfl-num {
	font-variant-numeric: tabular-nums;
	font-feature-settings: "tnum" 1;
}

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

.rfl-hero__media {
	display: grid;
	gap: var(--rfl-space-2);
	margin-bottom: var(--rfl-space-6);
}

.rfl-hero__image {
	width: 100%;
	height: auto;
	border-radius: var(--rfl-radius-lg);
	display: block;
}

.rfl-hero__title {
	font-size: var(--rfl-size-3xl);
	font-weight: var(--rfl-weight-bold);
	letter-spacing: var(--rfl-tracking-tight);
	line-height: var(--rfl-leading-tight);
	margin: 0 0 var(--rfl-space-3);
}

.rfl-hero__hook {
	font-size: var(--rfl-size-lg);
	color: var(--rfl-color-text-secondary);
	max-width: var(--rfl-layout-measure);
	margin: 0;
}

/* --------------------------------------------------------------- progress */

.rfl-progress {
	margin: var(--rfl-space-8) 0;
}

.rfl-progress__bar {
	height: 10px;
	border-radius: var(--rfl-radius-pill);
	background: var(--rfl-color-surface-sunken);
	overflow: hidden;
}

.rfl-progress__fill {
	height: 100%;
	background: var(--rfl-color-accent-base);
	border-radius: var(--rfl-radius-pill);
	transition: width var(--rfl-motion-duration-slow) var(--rfl-motion-easing-standard);
}

.rfl-progress__stats {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--rfl-space-4);
	margin: var(--rfl-space-5) 0 0;
}

@media (min-width: 40rem) {
	.rfl-progress__stats {
		grid-template-columns: repeat(4, 1fr);
	}
}

.rfl-stat__label {
	font-size: var(--rfl-size-sm);
	color: var(--rfl-color-text-muted);
	margin: 0 0 var(--rfl-space-1);
}

.rfl-stat__value {
	font-size: var(--rfl-size-xl);
	font-weight: var(--rfl-weight-semibold);
	margin: 0;
}

/* -------------------------------------------------------------- countdown */

.rfl-countdown {
	display: flex;
	align-items: baseline;
	gap: var(--rfl-space-2);
	padding: var(--rfl-space-3) var(--rfl-space-4);
	background: var(--rfl-color-surface-sunken);
	border-radius: var(--rfl-radius-md);
	margin-bottom: var(--rfl-space-8);
}

.rfl-countdown__label {
	font-size: var(--rfl-size-sm);
	color: var(--rfl-color-text-muted);
}

.rfl-countdown__value {
	font-family: var(--rfl-font-mono);
	font-weight: var(--rfl-weight-medium);
}

/* ------------------------------------------------------------ how it works */

.rfl-how {
	margin: var(--rfl-space-8) 0;
}

.rfl-how__title {
	font-size: var(--rfl-size-xl);
	font-weight: var(--rfl-weight-semibold);
	margin: 0 0 var(--rfl-space-5);
}

.rfl-how__steps {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--rfl-space-5);
}

@media (min-width: 48rem) {
	.rfl-how__steps {
		grid-template-columns: repeat(3, 1fr);
		gap: var(--rfl-space-6);
	}
}

.rfl-how__num {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.75rem;
	height: 1.75rem;
	border-radius: var(--rfl-radius-pill);
	background: var(--rfl-color-accent-muted);
	color: var(--rfl-color-accent-base);
	font-weight: var(--rfl-weight-semibold);
	font-size: var(--rfl-size-sm);
	margin-bottom: var(--rfl-space-2);
}

.rfl-how__step-title {
	font-size: var(--rfl-size-base);
	font-weight: var(--rfl-weight-semibold);
	margin: 0 0 var(--rfl-space-1);
}

.rfl-how__step-body {
	margin: 0;
	color: var(--rfl-color-text-secondary);
	font-size: var(--rfl-size-sm);
	line-height: var(--rfl-leading-relaxed);
}

/* ------------------------------------------------------------------ claim */

.rfl-claim {
	margin: var(--rfl-space-8) 0;
	padding: var(--rfl-space-6);
	background: var(--rfl-color-surface-raised);
	border: 1px solid var(--rfl-color-surface-border);
	border-radius: var(--rfl-radius-xl);
}

.rfl-claim__title {
	font-size: var(--rfl-size-xl);
	font-weight: var(--rfl-weight-semibold);
	margin: 0 0 var(--rfl-space-5);
}

.rfl-field {
	margin-bottom: var(--rfl-space-4);
}

.rfl-field--check {
	display: flex;
	align-items: center;
	gap: var(--rfl-space-2);
}

.rfl-label {
	display: block;
	font-size: var(--rfl-size-sm);
	font-weight: var(--rfl-weight-medium);
	margin-bottom: var(--rfl-space-1);
}

.rfl-label--inline {
	margin: 0;
	font-weight: var(--rfl-weight-regular);
}

.rfl-input {
	width: 100%;
	box-sizing: border-box;
	padding: var(--rfl-space-3);
	font-family: inherit;
	font-size: var(--rfl-size-base);
	color: var(--rfl-color-text-primary);
	background: var(--rfl-color-surface-page);
	border: 1px solid var(--rfl-color-surface-border-strong);
	border-radius: var(--rfl-radius-md);
}

.rfl-input:focus-visible,
.rfl-check:focus-visible,
.rfl-button:focus-visible {
	outline: 2px solid var(--rfl-color-accent-ring);
	outline-offset: 2px;
}

.rfl-help {
	margin: var(--rfl-space-1) 0 0;
	font-size: var(--rfl-size-sm);
	color: var(--rfl-color-text-muted);
}

/* The single largest source of support tickets in this category, per section 8.
   Body copy weight and contrast, never fine print. */
.rfl-disclosure {
	margin: var(--rfl-space-5) 0;
	padding: var(--rfl-space-4);
	background: var(--rfl-color-state-warning-muted);
	border-radius: var(--rfl-radius-md);
	font-size: var(--rfl-size-sm);
	line-height: var(--rfl-leading-relaxed);
	color: var(--rfl-color-text-primary);
}

.rfl-payment {
	margin: var(--rfl-space-5) 0;
}

.rfl-error {
	margin: var(--rfl-space-4) 0;
	padding: var(--rfl-space-3) var(--rfl-space-4);
	background: var(--rfl-color-state-danger-muted);
	border-radius: var(--rfl-radius-md);
	color: var(--rfl-color-state-danger);
	font-size: var(--rfl-size-sm);
}

.rfl-button {
	width: 100%;
	padding: var(--rfl-space-4);
	font-family: inherit;
	font-size: var(--rfl-size-base);
	font-weight: var(--rfl-weight-semibold);
	color: var(--rfl-color-accent-fg);
	background: var(--rfl-color-accent-base);
	border: 0;
	border-radius: var(--rfl-radius-md);
	cursor: pointer;
	transition: background var(--rfl-motion-duration-fast) var(--rfl-motion-easing-standard);
}

.rfl-button:hover:not(:disabled) {
	background: var(--rfl-color-accent-hover);
}

.rfl-button:active:not(:disabled) {
	background: var(--rfl-color-accent-active);
}

.rfl-button:disabled {
	opacity: 0.6;
	cursor: default;
}

/* ----------------------------------------------------------------- reveal */

.rfl-reveal {
	margin: var(--rfl-space-8) 0;
	padding: var(--rfl-space-8) var(--rfl-space-6);
	text-align: center;
	background: var(--rfl-color-surface-raised);
	border: 1px solid var(--rfl-color-surface-border);
	border-radius: var(--rfl-radius-xl);
}

.rfl-spinner {
	width: 2rem;
	height: 2rem;
	margin: 0 auto var(--rfl-space-4);
	border: 3px solid var(--rfl-color-surface-border);
	border-top-color: var(--rfl-color-accent-base);
	border-radius: var(--rfl-radius-pill);
	animation: rfl-spin 900ms linear infinite;
}

@keyframes rfl-spin {
	to {
		transform: rotate(360deg);
	}
}

.rfl-reveal__status {
	margin: 0;
	color: var(--rfl-color-text-secondary);
	line-height: var(--rfl-leading-relaxed);
}

.rfl-reveal__reference {
	margin: var(--rfl-space-3) 0 0;
	font-family: var(--rfl-font-mono);
	font-size: var(--rfl-size-xs);
	color: var(--rfl-color-text-muted);
	word-break: break-all;
}

/* The holding state past five minutes. Calm, not alarming: the entry is safe
   and the copy says so. It must not read as an error. */
.rfl-reveal__waiting.is-holding .rfl-spinner {
	animation: none;
	border-top-color: var(--rfl-color-surface-border);
	opacity: 0.4;
}

.rfl-reveal__eyebrow {
	margin: 0;
	font-size: var(--rfl-size-sm);
	text-transform: uppercase;
	letter-spacing: var(--rfl-tracking-wide);
	color: var(--rfl-color-text-muted);
}

/* Section 10: the emotional peak of the product. Real motion, no library. */
.rfl-reveal__number {
	margin: var(--rfl-space-2) 0;
	font-size: var(--rfl-size-reveal);
	font-weight: var(--rfl-weight-bold);
	line-height: 1;
	letter-spacing: var(--rfl-tracking-tight);
	color: var(--rfl-color-accent-base);
}

.rfl-reveal.is-revealed .rfl-reveal__result {
	animation: rfl-reveal var(--rfl-motion-duration-reveal) var(--rfl-motion-easing-reveal) both;
}

@keyframes rfl-reveal {
	from {
		opacity: 0;
		transform: scale(0.94);
	}

	to {
		opacity: 1;
		transform: scale(1);
	}
}

.rfl-reveal__amount {
	margin: 0;
	color: var(--rfl-color-text-secondary);
}

/* --------------------------------------------------------------- sold out */

.rfl-soldout {
	margin: var(--rfl-space-8) 0;
	padding: var(--rfl-space-6);
	text-align: center;
	background: var(--rfl-color-surface-sunken);
	border-radius: var(--rfl-radius-xl);
}

.rfl-soldout__title {
	margin: 0 0 var(--rfl-space-2);
	font-size: var(--rfl-size-xl);
	font-weight: var(--rfl-weight-semibold);
}

.rfl-soldout__body,
.rfl-closed {
	margin: 0;
	color: var(--rfl-color-text-secondary);
}

/* ------------------------------------------------------------- fine print */

.rfl-fineprint {
	margin-top: var(--rfl-space-8);
	padding-top: var(--rfl-space-5);
	border-top: 1px solid var(--rfl-color-surface-border);
	font-size: var(--rfl-size-xs);
	line-height: var(--rfl-leading-relaxed);
	color: var(--rfl-color-text-muted);
}

/* ------------------------------------------------------------------ a11y */

@media (prefers-reduced-motion: reduce) {
	.rfl-spinner {
		animation-duration: 2400ms;
	}

	.rfl-progress__fill,
	.rfl-button {
		transition: none;
	}

	.rfl-reveal.is-revealed .rfl-reveal__result {
		animation: rfl-fade var(--rfl-motion-duration-base) linear both;
	}

	@keyframes rfl-fade {
		from {
			opacity: 0;
		}

		to {
			opacity: 1;
		}
	}
}

/* -------------------------------------------------------- number prizes */

/*
 * Announced prizes. Under the hero, above the claim form, because a prize on a
 * high number only makes high numbers sell if the donor sees it before they
 * decide.
 */

.rfl-prizes {
	margin: var(--rfl-space-10) 0;
}

.rfl-prizes__title {
	margin: 0 0 var(--rfl-space-2);
	font-size: var(--rfl-size-2xl);
	font-weight: var(--rfl-weight-bold);
	letter-spacing: var(--rfl-tracking-tight);
}

.rfl-prizes__intro {
	margin: 0 0 var(--rfl-space-5);
	max-width: var(--rfl-layout-measure);
	color: var(--rfl-color-text-secondary);
	line-height: var(--rfl-leading-relaxed);
}

/* P10. THE PRIZE RULES, moved out of the fine print and into the section they
   are about. A donor reads them while deciding whether a prize is worth
   chasing, which is not where a block below the fold is read. */
.rfl-prizes__rule {
	margin: var(--rfl-space-5) 0 0;
	max-width: var(--rfl-layout-measure);
	color: var(--rfl-color-text-muted);
	font-size: var(--rfl-size-sm);
	line-height: var(--rfl-leading-relaxed);
}

.rfl-prizes__list {
	margin: 0;
	padding: 0;
	list-style: none;
	display: grid;
	gap: var(--rfl-space-3);
}

.rfl-prize {
	display: flex;
	align-items: flex-start;
	gap: var(--rfl-space-4);
	padding: var(--rfl-space-4);
	background: var(--rfl-color-surface-raised);
	border: 1px solid var(--rfl-color-surface-border);
	border-radius: var(--rfl-radius-lg);
}

.rfl-prize__number {
	flex: 0 0 auto;
	min-width: 3.5rem;
	padding: var(--rfl-space-2) var(--rfl-space-3);
	text-align: center;
	font-size: var(--rfl-size-xl);
	font-weight: var(--rfl-weight-bold);
	color: var(--rfl-color-accent-fg);
	background: var(--rfl-color-accent-base);
	border-radius: var(--rfl-radius-md);
}

.rfl-prize__body {
	display: block;
}

.rfl-prize__label {
	display: block;
	font-size: var(--rfl-size-lg);
	font-weight: var(--rfl-weight-semibold);
}

.rfl-prize__desc {
	display: block;
	margin-top: var(--rfl-space-1);
	color: var(--rfl-color-text-secondary);
	line-height: var(--rfl-leading-relaxed);
}

.rfl-prize__state {
	display: inline-block;
	margin-top: var(--rfl-space-2);
	font-size: var(--rfl-size-sm);
	font-weight: var(--rfl-weight-medium);
	color: var(--rfl-color-state-success);
}

/*
 * A taken number stays on the page rather than disappearing. Removing it would
 * leave the pitch claiming prizes that are no longer winnable, and a donor who
 * saw it advertised yesterday would think it was never real.
 */
.rfl-prize--gone {
	opacity: 0.65;
}

.rfl-prize--gone .rfl-prize__number {
	color: var(--rfl-color-text-secondary);
	background: var(--rfl-color-neutral-200);
}

.rfl-prize--gone .rfl-prize__state {
	color: var(--rfl-color-text-muted);
}

/*
 * P7 accessibility. Visually hidden, still announced.
 *
 * Used for the countdown's spoken summary, because the ticking digits beside it
 * are aria-hidden: a live region that speaks once a second is worse than none.
 */
.rfl-sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* ==========================================================================
   P9. THE LAYOUT PASS.
   Everything above this line is P3 and P7: components that worked, unstyled as
   a page. This layer is composition, not decoration. It gives the page rhythm,
   takes the hero full bleed, and makes the claim card the only thing that
   floats. See docs/PHASE-9-PLAN.txt, THE VISUAL DIRECTION.
   ========================================================================== */

.rfl-raffle {
	/* Composition tokens, scoped here so a theme cannot inherit them by
	   accident and so the accent set from the operator sits alongside. */
	--rfl-section: clamp(3rem, 8vw, 6rem);
	--rfl-read: 40rem;
	--rfl-wide: 72rem;

	max-width: none;
	margin: 0;
	padding: 0;
	color: var(--rfl-color-text-primary);
	font-size: 1.0625rem;
	line-height: var(--rfl-leading-relaxed);
}

/* THE FULL BLEED TECHNIQUE. P9 applied it to the hero image and the progress
   bar. P11 widens it to the hero as a whole, including the typographic version
   with no image, and to the decision region, because a two column layout inside
   a reading measure is not a two column layout.

   A block dropped into somebody else's page respects that page's container
   everywhere else, because the person who placed it chose that layout. */
.rfl-raffle .rfl-hero,
.rfl-raffle .rfl-gallery,
.rfl-raffle .rfl-progress {
	width: 100vw;
	max-width: 100vw;
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
}

/* Every section that is not full bleed gets the reading measure and the
   rhythm. One rule rather than a margin on each component, so the spacing
   between sections cannot drift apart. */
.rfl-raffle > * {
	box-sizing: border-box;
	max-width: var(--rfl-read);
	margin-left: auto;
	margin-right: auto;
	padding-left: var(--rfl-space-5);
	padding-right: var(--rfl-space-5);
}

.rfl-raffle > * + * {
	margin-top: var(--rfl-section);
}

.rfl-hero {
	max-width: none;
	padding: 0;
}

/* THE HERO. A landscape banner across the top, sized by aspect ratio rather
   than by a fixed height so it holds its shape from a phone to a desktop
   without cropping the subject out of frame.

   TWO VERSIONS, BOTH DESIGNED. With an image the title sits over it on a
   scrim. Without one it is a typographic hero on an accent surface, at the same
   height and the same weight. P11: most raffles are created before the operator
   has photography, so the imageless version is what a client sees on their first
   look, and it must not read as a page that failed to load. */
.rfl-hero {
	position: relative;
	display: flex;
	align-items: flex-end;
	min-height: clamp(18rem, 42vw, 30rem);
	overflow: hidden;
}

/* THE IMAGELESS HERO IS SHORTER AND CENTRED, and that is the whole difference.
   Given the same 30rem as a photograph it is a large empty rectangle of brand
   colour with a word at the bottom, which looks like a section that failed to
   load rather than a title block. Sized to its own content, it reads as a
   deliberate masthead. */
.rfl-hero--type {
	align-items: center;
	min-height: clamp(11rem, 22vw, 16rem);
}

.rfl-hero__media {
	position: absolute;
	inset: 0;
	background: var(--rfl-color-surface-sunken);
}

.rfl-hero__image {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	border-radius: 0;
}

/* THE SCRIM IS OVER THE IMAGE, NOT UNDER THE TEXT. Contrast under the title
   becomes a property of the markup rather than of whichever photograph somebody
   uploaded, which is the only way white text over an arbitrary image is safe. */
.rfl-hero__scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(
		to top,
		rgba(0, 0, 0, 0.82) 0%,
		rgba(0, 0, 0, 0.55) 35%,
		rgba(0, 0, 0, 0.12) 70%,
		rgba(0, 0, 0, 0) 100%
	);
}

/* THE ACCENT AS A SURFACE, which is the P9 rule as amended in P11. The
   prohibitions are unchanged: this is not body text and not a field behind
   text. It is a large flat surface whose foreground colour Accent::derive()
   already computed for contrast. */
.rfl-hero--type {
	background: var(--rfl-color-accent-base);
	color: var(--rfl-color-accent-fg);
}

.rfl-hero__copy {
	position: relative;
	box-sizing: border-box;
	width: 100%;
	max-width: var(--rfl-wide);
	margin-left: auto;
	margin-right: auto;
	padding: var(--rfl-space-10) var(--rfl-space-5);
}

.rfl-hero--image .rfl-hero__copy {
	color: #ffffff;
}

.rfl-hero__title {
	margin: 0;
	font-size: clamp(2.5rem, 6vw, 4.5rem);
	font-weight: var(--rfl-weight-bold);
	line-height: var(--rfl-leading-tight);
	letter-spacing: var(--rfl-tracking-tight);
}

.rfl-hero__hook {
	margin-top: var(--rfl-space-4);
	max-width: var(--rfl-measure, 42rem);
	font-size: clamp(1.0625rem, 1.6vw, 1.375rem);
	line-height: var(--rfl-leading-snug);
}

.rfl-hero--image .rfl-hero__hook {
	color: rgba(255, 255, 255, 0.92);
}

/* NO OPACITY ON AN ACCENT SURFACE, ANYWHERE. Supporting copy uses a DERIVED
   colour instead, because there is no fixed opacity that is safe across
   colours: at 0.8 the default accent measured 4.04:1 and at 0.9 mid grey,
   magenta and red were still around 4.0. Accent::soften() walks down from
   DIM_MAX and stops while it still clears AA, so a colour with contrast to
   spare gets a hierarchy and one without gets full strength rather than an
   illegible line. This is the same lesson as the text and fill variants. */
.rfl-hero--type .rfl-hero__hook {
	color: var(--rfl-color-accent-fg-soft, var(--rfl-color-accent-fg));
}

/* Everything after the first image. A strip, not three competing banners. */
.rfl-gallery {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: minmax(14rem, 1fr);
	gap: var(--rfl-space-2);
	overflow-x: auto;
	scrollbar-width: thin;
}

.rfl-gallery__image {
	display: block;
	width: 100%;
	height: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
}

/* THE PROGRESS DISPLAY. P9 made this a status line: an 8px track and two small
   stats. P11 makes it the second largest thing on the page after the hero,
   because "244 left of 250" is the entire proposition and it was the least
   visible element on it. */
.rfl-progress {
	padding: var(--rfl-space-8) var(--rfl-space-5);
	background: var(--rfl-color-surface-sunken);
	border-top: 1px solid var(--rfl-color-surface-border);
	border-bottom: 1px solid var(--rfl-color-surface-border);
}

/* Inside the decision grid it is a panel rather than a band, so the full bleed
   and the borders come off and the surface does the work. */
.rfl-decide .rfl-progress {
	width: auto;
	max-width: none;
	margin: 0;
	border-radius: var(--rfl-radius-lg);
	border: 1px solid var(--rfl-color-surface-border);
}

.rfl-progress__inner {
	max-width: var(--rfl-wide);
	margin-left: auto;
	margin-right: auto;
}

.rfl-progress__eyebrow {
	margin: 0 0 var(--rfl-space-2);
	font-size: var(--rfl-size-sm);
	font-weight: var(--rfl-weight-semibold);
	text-transform: uppercase;
	letter-spacing: var(--rfl-tracking-wide);
	color: var(--rfl-color-accent-text, var(--rfl-color-text-muted));
}

.rfl-progress__headline {
	display: flex;
	align-items: baseline;
	gap: var(--rfl-space-3);
	margin: 0 0 var(--rfl-space-5);
}

/* THE NUMBER REMAINING IS THE HEADLINE. Taken is social proof, left is
   urgency, and a donor deciding in twenty seconds is moved by the second one.
   Both are still on the page; only one of them is this size. */
.rfl-progress__count {
	font-size: clamp(2.5rem, 7vw, 4rem);
	font-weight: var(--rfl-weight-bold);
	line-height: 1;
	letter-spacing: var(--rfl-tracking-tight);
}

.rfl-progress__of {
	font-size: var(--rfl-size-lg);
	color: var(--rfl-color-text-secondary);
}

.rfl-progress__bar {
	height: 1rem;
	background: var(--rfl-color-surface-border);
	border-radius: var(--rfl-radius-pill);
	overflow: hidden;
	box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.08);
}

/* THE SEGMENTED BAR. Below the threshold a continuous bar lies about
   granularity: on a ten number raffle every claim moves it a tenth and a smooth
   fill implies a smoothness the pool does not have. Cells are literally what the
   inventory is. */
.rfl-progress__cells {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(0.75rem, 1fr));
	gap: 0.25rem;
}

.rfl-cell {
	height: 1.75rem;
	border-radius: var(--rfl-radius-sm, 0.25rem);
	background: var(--rfl-color-surface-border);
	box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.08);
	transition: background var(--rfl-motion-duration-base) ease-out;
}

.rfl-cell--taken {
	background: var(--rfl-color-accent-fill, var(--rfl-color-accent-base));
	box-shadow: none;
}

/* The fill uses the DERIVED fill colour, not the base. A pale accent that is
   fine behind dark text disappears against this track, and Accent::derive()
   darkens it until it clears 3:1 while keeping the hue. */
.rfl-progress__fill {
	height: 100%;
	background: var(--rfl-color-accent-fill, var(--rfl-color-accent-base));
	transition: width var(--rfl-motion-duration-base) ease-out;
}

.rfl-progress__stats {
	display: flex;
	flex-wrap: wrap;
	gap: var(--rfl-space-8);
	margin-top: var(--rfl-space-6);
}

.rfl-stat__label {
	font-size: 0.875rem;
	text-transform: uppercase;
	letter-spacing: var(--rfl-tracking-wide);
	color: var(--rfl-color-text-muted);
}

.rfl-stat__value {
	font-size: 1.5rem;
	font-weight: var(--rfl-weight-semibold);
	font-variant-numeric: tabular-nums;
}

/* THE TIMING SLOT. Every lifecycle state gets a statement of the same shape and
   the same weight: a live countdown, an open ended raffle, one that is closing,
   one that is closed, one that has been drawn. P10 unified these, because
   deciding the slot on the deadline alone rendered "Closes in 0s" on a closed
   raffle, which is a correct countdown answering the wrong question.

   A raffle with no deadline is not a raffle with a missing one, and a closed
   raffle is not a raffle with an empty slot. */
.rfl-countdown,
.rfl-timing {
	display: flex;
	align-items: baseline;
	gap: var(--rfl-space-3);
}

.rfl-timing__label {
	font-size: 0.875rem;
	text-transform: uppercase;
	letter-spacing: var(--rfl-tracking-wide);
	color: var(--rfl-color-accent-text, var(--rfl-color-text-muted));
	font-weight: var(--rfl-weight-semibold);
}

.rfl-timing__value {
	font-size: 1.25rem;
	font-weight: var(--rfl-weight-semibold);
	font-variant-numeric: tabular-nums;
}

/* A finished raffle states a fact rather than urging anything, so the accent
   comes off the label. The four places rule: the accent marks what is live. */
.rfl-timing--closed .rfl-timing__label,
.rfl-timing--drawn .rfl-timing__label {
	color: var(--rfl-color-text-muted);
}

.rfl-countdown__label {
	font-size: 0.875rem;
	text-transform: uppercase;
	letter-spacing: var(--rfl-tracking-wide);
	color: var(--rfl-color-accent-text, var(--rfl-color-text-muted));
	font-weight: var(--rfl-weight-semibold);
}

.rfl-countdown__value {
	font-size: 1.25rem;
	font-weight: var(--rfl-weight-semibold);
	font-variant-numeric: tabular-nums;
}

/* THE ONE ELEVATED SURFACE ON THE PAGE. A page where three things float is a
   page where nothing is the action. */
.rfl-claim {
	padding: var(--rfl-space-8) var(--rfl-space-6);
	background: var(--rfl-color-surface-page);
	border: 1px solid var(--rfl-color-surface-border);
	border-radius: var(--rfl-radius-lg);
	box-shadow: var(--rfl-shadow-lg);
}

.rfl-claim__title {
	font-size: 1.5rem;
	font-weight: var(--rfl-weight-semibold);
	margin-bottom: var(--rfl-space-5);
}

.rfl-button {
	min-height: 2.75rem;
	background: var(--rfl-color-accent-base);
	color: var(--rfl-color-accent-fg);
	font-size: 1.0625rem;
	font-weight: var(--rfl-weight-semibold);
}

.rfl-how__title,
.rfl-prizes__title,
.rfl-fine-print__title {
	font-size: 0.875rem;
	font-weight: var(--rfl-weight-semibold);
	text-transform: uppercase;
	letter-spacing: var(--rfl-tracking-wide);
	color: var(--rfl-color-accent-text, var(--rfl-color-text-muted));
}

.rfl-fine-print {
	font-size: 0.875rem;
	line-height: var(--rfl-leading-relaxed);
	color: var(--rfl-color-text-muted);
}

.rfl-reveal__number {
	font-size: var(--rfl-size-reveal);
	line-height: 1;
	font-weight: var(--rfl-weight-bold);
	font-variant-numeric: tabular-nums;
}

/* The raffle's own page. The theme's header and footer stay; its content
   column does not apply, because this wrapper is a direct child of body. */
.rfl-single .rfl-single__content {
	width: 100%;
	max-width: none;
	margin: 0;
	padding: 0;
}

/* ==========================================================================
   P11: THE DECISION REGION
   ========================================================================== */

/* SCARCITY AND THE ACTION, SIDE BY SIDE. P9 stacked them as separate sections
   with a hundred pixels of nothing between, which measured as a 640px column
   floating in a 1280px window. The operator chooses which side the card sits on.

   ON A PHONE ALL THREE LAYOUTS ARE THE SAME THING, and that is not an
   apology: there is one column, and the action goes under the thing that
   motivated it. The setup form says so, because an operator who picks "left"
   and sees no change on their phone will report it as broken. */
/* WIDER THAN THE READING MEASURE AND NOT FULL BLEED. Two columns inside 40rem
   is not two columns; two columns across a 27 inch monitor is not a decision,
   it is a search. The selector carries the parent so it beats the blanket
   `.rfl-raffle > *` measure rule rather than relying on source order. */
.rfl-raffle .rfl-decide {
	box-sizing: border-box;
	max-width: var(--rfl-wide);
	margin-left: auto;
	margin-right: auto;
	padding-left: var(--rfl-space-5);
	padding-right: var(--rfl-space-5);
	display: grid;
	gap: var(--rfl-space-6);
}

.rfl-decide__status {
	display: grid;
	gap: var(--rfl-space-5);
	align-content: start;
}

@media (min-width: 60rem) {
	.rfl-decide--right,
	.rfl-decide--left {
		grid-template-columns: minmax(0, 1.15fr) minmax(22rem, 0.85fr);
		align-items: start;
	}

	.rfl-decide--left .rfl-decide__status {
		order: 2;
	}

	.rfl-decide--left .rfl-decide__action {
		order: 1;
	}

	/* Below keeps one column and simply constrains the card, so it does not
	   stretch to the full width of a desktop and stop reading as a card. */
	.rfl-decide--below .rfl-decide__action {
		max-width: 34rem;
		margin-left: auto;
		margin-right: auto;
	}
}

/* THE COUNTDOWN, IN CELLS, INSIDE THE DECISION REGION. It used to be a grey
   pill alone in a vertical void between two unrelated sections. Scarcity in time
   and scarcity in numbers are the same message. */
.rfl-countdown {
	display: block;
	padding: var(--rfl-space-5);
	background: var(--rfl-color-surface-page);
	border: 1px solid var(--rfl-color-surface-border);
	border-radius: var(--rfl-radius-lg);
}

.rfl-countdown__label {
	margin: 0 0 var(--rfl-space-3);
	font-size: var(--rfl-size-sm);
	font-weight: var(--rfl-weight-semibold);
	text-transform: uppercase;
	letter-spacing: var(--rfl-tracking-wide);
	color: var(--rfl-color-accent-text, var(--rfl-color-text-muted));
}

.rfl-countdown__cells {
	display: flex;
	gap: var(--rfl-space-2);
}

/* FIXED WIDTH CELLS. P10 made the countdown carry seconds at every magnitude,
   which is what makes a ticking digit worth having and also what would have made
   the layout reflow once a second if the digits shared one text node. */
.rfl-countdown__cell {
	flex: 0 0 auto;
	min-width: 3.25rem;
	padding: var(--rfl-space-2) var(--rfl-space-1);
	text-align: center;
	background: var(--rfl-color-surface-sunken);
	border-radius: var(--rfl-radius-md, 0.5rem);
}

.rfl-countdown__value {
	display: block;
	font-size: var(--rfl-size-2xl);
	font-weight: var(--rfl-weight-semibold);
	line-height: 1.1;
	font-variant-numeric: tabular-nums;
}

.rfl-countdown__unit {
	display: block;
	margin-top: var(--rfl-space-1);
	font-size: var(--rfl-size-xs);
	text-transform: uppercase;
	letter-spacing: var(--rfl-tracking-wide);
	color: var(--rfl-color-text-muted);
}

.rfl-countdown__message {
	margin: 0;
	font-size: var(--rfl-size-xl);
	font-weight: var(--rfl-weight-semibold);
}

/* ==========================================================================
   P11: THE REVEAL MOMENT
   ========================================================================== */

/* THE BEAT. Reached only on a confirmed payment, never on a pending one. See
   the reveal partial for why that distinction is load bearing. */
.rfl-reveal__holding {
	padding: var(--rfl-space-10) var(--rfl-space-5);
	text-align: center;
}

.rfl-reveal__holding-lead {
	margin: 0 0 var(--rfl-space-5);
	font-size: var(--rfl-size-xl);
	font-weight: var(--rfl-weight-semibold);
}

.rfl-reveal__pulse {
	display: flex;
	justify-content: center;
	gap: var(--rfl-space-2);
}

.rfl-reveal__pulse span {
	width: 0.625rem;
	height: 0.625rem;
	border-radius: 50%;
	background: var(--rfl-color-accent-fill, var(--rfl-color-accent-base));
	animation: rfl-pulse 1.2s ease-in-out infinite;
}

.rfl-reveal__pulse span:nth-child(2) {
	animation-delay: 0.15s;
}

.rfl-reveal__pulse span:nth-child(3) {
	animation-delay: 0.3s;
}

@keyframes rfl-pulse {
	0%, 100% { opacity: 0.25; transform: translateY(0); }
	50% { opacity: 1; transform: translateY(-0.25rem); }
}

.rfl-reveal__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--rfl-space-3);
	margin-top: var(--rfl-space-8);
}

/* A SECOND BUTTON THAT IS NOT A SECOND PRIMARY. Go again is the action; the
   ticket and the gift are available and quieter. */
.rfl-button--quiet {
	background: transparent;
	color: var(--rfl-color-accent-text, var(--rfl-color-text-primary));
	border: 1px solid var(--rfl-color-surface-border);
}

.rfl-button--quiet:hover {
	background: var(--rfl-color-surface-sunken);
}

/* WINNING A NUMBER PRIZE. It used to be three lines inside the reveal card.
   The accent as a surface, per the P11 amendment: a large flat area whose
   foreground Accent::derive() already proved readable. */
.rfl-prizewin {
	margin-top: var(--rfl-space-8);
	padding: var(--rfl-space-8) var(--rfl-space-6);
	background: var(--rfl-color-accent-base);
	color: var(--rfl-color-accent-fg);
	border-radius: var(--rfl-radius-lg);
	text-align: center;
}

.rfl-prizewin__eyebrow {
	margin: 0 0 var(--rfl-space-3);
	font-size: var(--rfl-size-sm);
	font-weight: var(--rfl-weight-semibold);
	text-transform: uppercase;
	letter-spacing: var(--rfl-tracking-wide);
	color: var(--rfl-color-accent-fg-soft, var(--rfl-color-accent-fg));
}

.rfl-prizewin__image {
	display: block;
	width: 100%;
	max-width: 20rem;
	margin: 0 auto var(--rfl-space-5);
	aspect-ratio: 4 / 3;
	object-fit: cover;
	border-radius: var(--rfl-radius-md, 0.5rem);
}

.rfl-prizewin__label {
	margin: 0;
	font-size: clamp(1.75rem, 4vw, 2.5rem);
	font-weight: var(--rfl-weight-bold);
	line-height: var(--rfl-leading-tight);
}

.rfl-prizewin__body {
	margin: var(--rfl-space-3) 0 0;
	line-height: var(--rfl-leading-relaxed);
	color: var(--rfl-color-accent-fg-soft, var(--rfl-color-accent-fg));
}

.rfl-prizewin__fair {
	margin: var(--rfl-space-5) 0 0;
	font-size: var(--rfl-size-sm);
	color: var(--rfl-color-accent-fg-soft, var(--rfl-color-accent-fg));
}

/* ==========================================================================
   P11: RETURNING VISITOR AND THE PLAIN GIFT
   ========================================================================== */

.rfl-returning,
.rfl-donate {
	padding: var(--rfl-space-8) var(--rfl-space-6);
	background: var(--rfl-color-surface-page);
	border: 1px solid var(--rfl-color-surface-border);
	border-radius: var(--rfl-radius-lg);
	box-shadow: var(--rfl-shadow-lg);
}

.rfl-donate {
	margin-top: var(--rfl-space-6);
}

.rfl-returning__eyebrow,
.rfl-donate__title {
	margin: 0 0 var(--rfl-space-2);
}

.rfl-returning__eyebrow {
	font-size: var(--rfl-size-sm);
	font-weight: var(--rfl-weight-semibold);
	text-transform: uppercase;
	letter-spacing: var(--rfl-tracking-wide);
	color: var(--rfl-color-accent-text, var(--rfl-color-text-muted));
}

.rfl-returning__title,
.rfl-donate__title {
	font-size: var(--rfl-size-2xl);
	font-weight: var(--rfl-weight-semibold);
	line-height: var(--rfl-leading-snug);
}

.rfl-returning__held {
	margin: var(--rfl-space-3) 0 0;
	font-size: var(--rfl-size-lg);
	font-variant-numeric: tabular-nums;
}

.rfl-returning__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--rfl-space-3);
	margin-top: var(--rfl-space-6);
}

.rfl-returning__note,
.rfl-donate__note,
.rfl-donate__intro {
	margin: var(--rfl-space-4) 0 0;
	font-size: var(--rfl-size-sm);
	line-height: var(--rfl-leading-relaxed);
	color: var(--rfl-color-text-muted);
}

.rfl-donate__intro {
	margin-bottom: var(--rfl-space-6);
	color: var(--rfl-color-text-secondary);
	font-size: var(--rfl-size-base);
}

.rfl-donate__presets {
	display: flex;
	flex-wrap: wrap;
	gap: var(--rfl-space-2);
	margin: 0 0 var(--rfl-space-5);
	padding: 0;
	border: 0;
}

.rfl-donate__presets .rfl-label {
	flex-basis: 100%;
	margin-bottom: var(--rfl-space-2);
}

.rfl-chip {
	position: relative;
	display: inline-flex;
}

/* THE INPUT IS NOT display:none. A hidden radio is unreachable by keyboard and
   invisible to assistive technology; this one is present and transparent, so it
   still focuses and still announces, and the label draws the state. */
.rfl-chip__input {
	position: absolute;
	inset: 0;
	margin: 0;
	opacity: 0;
	cursor: pointer;
}

.rfl-chip__label {
	display: inline-block;
	padding: var(--rfl-space-3) var(--rfl-space-5);
	border: 1px solid var(--rfl-color-surface-border);
	border-radius: var(--rfl-radius-pill);
	font-weight: var(--rfl-weight-semibold);
	font-variant-numeric: tabular-nums;
}

.rfl-chip__input:checked + .rfl-chip__label {
	background: var(--rfl-color-accent-base);
	color: var(--rfl-color-accent-fg);
	border-color: var(--rfl-color-accent-base);
}

.rfl-chip__input:focus-visible + .rfl-chip__label {
	outline: 2px solid var(--rfl-color-accent-base);
	outline-offset: 2px;
}

.rfl-donate__thanks {
	margin: 0;
	font-size: var(--rfl-size-lg);
	line-height: var(--rfl-leading-relaxed);
}

/* ==========================================================================
   P11: MOTION
   ========================================================================== */

/* P7's rule, extended to everything P11 added. The beat before the number is
   skipped entirely rather than merely stilled: a donor who has asked for
   reduced motion has asked not to wait for an animation that is not there. */
@media (prefers-reduced-motion: reduce) {
	.rfl-reveal__pulse span,
	.rfl-cell,
	.rfl-progress__fill {
		animation: none;
		transition: none;
	}
}

/* ==========================================================================
   P11: PRIZE CARDS
   ========================================================================== */

/* P9 rendered a prize as a number and a label in a grey row. The image has been
   in the data since P5 and on no page at all, which made the prizes section
   argue for itself in words when it had a photograph available. */
.rfl-prizes__list {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
	gap: var(--rfl-space-5);
	list-style: none;
	padding: 0;
}

.rfl-prize {
	display: flex;
	flex-direction: column;
	gap: var(--rfl-space-3);
	padding: var(--rfl-space-5);
	background: var(--rfl-color-surface-page);
	border: 1px solid var(--rfl-color-surface-border);
	border-radius: var(--rfl-radius-lg);
}

.rfl-prize__image {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	border-radius: var(--rfl-radius-md, 0.5rem);
}

.rfl-prize__number {
	align-self: flex-start;
	padding: var(--rfl-space-1) var(--rfl-space-3);
	background: var(--rfl-color-accent-base);
	color: var(--rfl-color-accent-fg);
	border-radius: var(--rfl-radius-pill);
	font-weight: var(--rfl-weight-bold);
	font-variant-numeric: tabular-nums;
}

.rfl-prize__body {
	display: flex;
	flex-direction: column;
	gap: var(--rfl-space-2);
}

.rfl-prize__label {
	font-size: var(--rfl-size-lg);
	font-weight: var(--rfl-weight-semibold);
	line-height: var(--rfl-leading-snug);
}

.rfl-prize__desc {
	color: var(--rfl-color-text-secondary);
	line-height: var(--rfl-leading-relaxed);
}

.rfl-prize__state {
	font-size: var(--rfl-size-sm);
	text-transform: uppercase;
	letter-spacing: var(--rfl-tracking-wide);
	color: var(--rfl-color-text-muted);
}

/* A TAKEN PRIZE IS DIMMED, NOT HIDDEN, and never dimmed to the point of failing
   contrast: the state line stays fully legible because it is the sentence that
   stops somebody buying for a reason that no longer exists. */
.rfl-prize--gone .rfl-prize__image {
	opacity: 0.45;
}

.rfl-prize--gone .rfl-prize__number {
	background: var(--rfl-color-surface-border);
	color: var(--rfl-color-text-muted);
}

/* The prizes section is wider than reading measure, because a grid of cards at
   40rem is a single column list of cards. */
.rfl-raffle .rfl-prizes {
	max-width: var(--rfl-wide);
}

/* ==========================================================================
   P11: THE PHONE
   ========================================================================== */

/* Desktop and tablet never see the jump bar: the real button is on screen. */
.rfl-claim-jump {
	display: none;
}

@media (max-width: 40rem) {

	/* THE FOLD GETS ITS OWN BUTTON. The status stack, the claim card and the
	   section 8 disclosure cannot all fit above an 844px fold, and none of
	   them is droppable: the disclosure is required above the submit, and the
	   card goes under the status by the approved layout rule. So the primary
	   action is pinned to the bottom edge, which is where a phone thumb
	   already is, and one tap lands on the real form. Pure markup and CSS: it
	   costs the script budget nothing. */
	.rfl-claim-jump {
		position: fixed;
		left: var(--rfl-space-4);
		right: var(--rfl-space-4);
		bottom: var(--rfl-space-4);
		z-index: 40;
		display: flex;
		align-items: center;
		justify-content: center;
		min-height: 3rem;
		padding: var(--rfl-space-3) var(--rfl-space-5);
		background: var(--rfl-color-accent-base);
		color: var(--rfl-color-accent-fg);
		font-size: 1.0625rem;
		font-weight: var(--rfl-weight-semibold);
		text-decoration: none;
		border-radius: var(--rfl-radius-pill);
		box-shadow: var(--rfl-shadow-lg);
	}

	/* GONE THE MOMENT IT WOULD BE NOISE. Once the reveal is on screen, or the
	   returning panel replaced the claim, a floating "claim" button over the
	   moment is a distraction at best and a misdirection at worst. The jump is
	   the last sibling in the action region so these combinators can see the
	   states before it. */
	[data-rfl-reveal]:not([hidden]) ~ .rfl-claim-jump,
	[data-rfl-claim][hidden] ~ .rfl-claim-jump,
	[data-rfl-returning]:not([hidden]) ~ .rfl-claim-jump {
		display: none;
	}

	/* And gone once it has been used. The tap sets the URL fragment to the
	   claim card, :target reads it back, and the donor who is now looking at
	   the form is not shown a second copy of its button. No script involved. */
	[data-rfl-claim]:target ~ .rfl-claim-jump {
		display: none;
	}

	/* Room for the bar, so it never sits over the last line of the page. */
	.rfl-raffle {
		padding-bottom: 5rem;
	}

	/* THE STATUS STACK, AT PHONE SCALE. The same content and the same order,
	   with the air taken out: on a 390px screen the desktop paddings were
	   spending a third of the first viewport on nothing. Presence on a phone
	   comes from the count and the cells, not from 32px of surface around
	   them. */
	.rfl-raffle .rfl-decide {
		margin-top: var(--rfl-space-5);
		gap: var(--rfl-space-4);
	}

	.rfl-decide__status {
		gap: var(--rfl-space-3);
	}

	.rfl-decide .rfl-progress {
		padding: var(--rfl-space-4);
	}

	.rfl-progress__headline {
		margin-bottom: var(--rfl-space-3);
	}

	.rfl-progress__count {
		font-size: 2.25rem;
	}

	.rfl-cell {
		height: 1.25rem;
	}

	.rfl-progress__stats {
		margin-top: var(--rfl-space-3);
		gap: var(--rfl-space-5);
	}

	.rfl-stat__value {
		font-size: 1.125rem;
	}

	.rfl-countdown {
		padding: var(--rfl-space-3) var(--rfl-space-4);
	}

	.rfl-countdown__label {
		margin-bottom: var(--rfl-space-2);
	}

	.rfl-countdown__cell {
		min-width: 2.75rem;
	}

	.rfl-countdown__value {
		font-size: 1.25rem;
	}

	.rfl-claim {
		margin-top: 0;
		padding: var(--rfl-space-5) var(--rfl-space-4);
	}
}
