/*
Theme Name: BOUT Landing
Theme URI: https://boutcardgame.com
Author: Andy Cianciola
Description: Kickstarter launch landing page for BOUT — a medieval card game. Dark, cinematic block theme built around the BOUT card art.
Version: 1.0.0
Requires at least: 6.5
Tested up to: 6.9
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: bout-landing
Tags: one-column, block-patterns, full-site-editing, custom-colors
*/

/* -------------------------------------------------------------------------
   Tokens
   ---------------------------------------------------------------------- */

:root {
	--bout-ink: #0b0a09;
	--bout-ink-raised: #131110;
	--bout-parchment: #f3ece0;
	--bout-muted: #a99c88;
	--bout-gold: #c9a227;
	--bout-gold-soft: #ddc074;
	--bout-red: #9a2c20;
	--bout-red-bright: #b8402c;
	--bout-hairline: rgba(243, 236, 224, 0.14);

	--bout-card-radius: 4.2%;
	--bout-shadow-card: 0 18px 40px -12px rgba(0, 0, 0, 0.85), 0 4px 10px rgba(0, 0, 0, 0.5);
}

/* -------------------------------------------------------------------------
   Base
   ---------------------------------------------------------------------- */

body {
	background-color: var(--bout-ink);
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

/* Warm vignette behind the whole page, strongest under the hero. */
body::before {
	content: "";
	position: fixed;
	inset: 0;
	pointer-events: none;
	z-index: 0;
	background:
		radial-gradient(120% 70% at 50% 88%, rgba(154, 44, 32, 0.16) 0%, transparent 60%),
		radial-gradient(90% 55% at 50% 6%, rgba(201, 162, 39, 0.07) 0%, transparent 65%);
}

.wp-site-blocks {
	position: relative;
	z-index: 1;
}

/* Small caps is the signature of the BOUT card typography. */
.bout-smallcaps {
	font-variant: small-caps;
	letter-spacing: 0.01em;
}

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

.bout-hero {
	position: relative;
	overflow: hidden;
	padding-top: clamp(2.5rem, 6vh, 4.5rem);
	padding-bottom: 0;
	text-align: center;
}

/* Logo fills. The source SVG carried these in a <defs><style> block, which is
   stripped on output so wpautop cannot corrupt it — see bout_shortcode_logo(). */
.bout-logo .cls-1 {
	fill: currentColor;
}

.bout-logo .cls-2 {
	fill: var(--bout-red);
}

.bout-hero__inner {
	max-width: 780px;
	margin-inline: auto;
}

.bout-hero__logo {
	display: block;
	width: clamp(190px, 26vw, 290px);
	height: auto;
	margin: 0 auto clamp(1.75rem, 4vh, 2.75rem);
}

.bout-hero__title {
	font-variant: small-caps;
	font-size: clamp(2.1rem, 6.4vw, 4.25rem);
	line-height: 1.05;
	letter-spacing: 0.005em;
	margin: 0 0 clamp(0.9rem, 2.5vh, 1.5rem);
	color: var(--bout-parchment);
	text-shadow: 0 2px 24px rgba(0, 0, 0, 0.7);
}

.bout-hero__subtitle {
	/* Wide enough to hold the subhead on two lines; balance keeps those two
	   lines close to equal length rather than leaving a short widow. */
	max-width: 48ch;
	text-wrap: balance;
	margin: 0 auto clamp(1.75rem, 4vh, 2.5rem);
	font-size: clamp(1.05rem, 2.2vw, 1.3rem);
	line-height: 1.55;
	color: rgba(243, 236, 224, 0.82);
}

.bout-hero__stats {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 0.55rem 1.15rem;
	margin: clamp(1.5rem, 3.5vh, 2.25rem) 0 0;
	padding: 0;
	list-style: none;
	font-variant: small-caps;
	font-size: 1rem;
	letter-spacing: 0.13em;
	color: var(--bout-gold);
}

.bout-hero__stats li + li::before {
	content: "\00b7";
	margin-right: 1.15rem;
	color: rgba(201, 162, 39, 0.5);
}

/* Phones fit three across, which strands "72 Cards" alone on a second line.
   Two per row reads as a deliberate pair of lines instead. */
@media (max-width: 480px) {
	.bout-hero__stats {
		display: grid;
		grid-template-columns: repeat(2, auto);
		justify-content: center;
		/* Matches the flex gap, so the dot keeps equal air on both sides. */
		column-gap: 1.15rem;
	}

	/* The dot separates items within a row; it must not open one. */
	.bout-hero__stats li:nth-child(3)::before {
		content: none;
	}

	.bout-hero__stats li:nth-child(odd) {
		justify-self: end;
	}

	.bout-hero__stats li:nth-child(even) {
		justify-self: start;
	}
}

/* -------------------------------------------------------------------------
   Signup form
   ---------------------------------------------------------------------- */

.bout-signup {
	max-width: 540px;
	margin: 0 auto;
	text-align: left;
}

.bout-signup__row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 0.75rem;
	margin-bottom: 0.75rem;
}

@media (max-width: 540px) {
	.bout-signup__row {
		grid-template-columns: 1fr;
	}
}

.bout-signup__field {
	display: block;
}

.bout-signup__label {
	display: block;
	margin-bottom: 0.35rem;
	font-variant: small-caps;
	font-size: 0.9rem;
	letter-spacing: 0.09em;
	color: var(--bout-muted);
}

.bout-signup input[type="text"],
.bout-signup input[type="email"],
.bout-signup textarea {
	/* Without this the padding is added to the 100% width and the field
	   overflows its column on narrow screens. */
	box-sizing: border-box;
	width: 100%;
	max-width: 100%;
	padding: 0.8rem 0.95rem;
	font-family: inherit;
	font-size: 1rem;
	line-height: 1.4;
	color: var(--bout-parchment);
	background-color: rgba(243, 236, 224, 0.045);
	border: 1px solid var(--bout-hairline);
	border-radius: 2px;
	transition: border-color 0.18s ease, background-color 0.18s ease, box-shadow 0.18s ease;
}

.bout-signup input::placeholder,
.bout-signup textarea::placeholder {
	color: rgba(169, 156, 136, 0.62);
}

.bout-signup input:focus,
.bout-signup textarea:focus {
	outline: none;
	border-color: rgba(201, 162, 39, 0.75);
	background-color: rgba(243, 236, 224, 0.075);
	box-shadow: 0 0 0 3px rgba(201, 162, 39, 0.16);
}

.bout-signup textarea {
	min-height: 92px;
	resize: vertical;
}

/* Honeypot — hidden from people, reachable by bots. */
.bout-signup__trap {
	position: absolute !important;
	left: -9999px !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.bout-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	margin-top: 0.85rem;
	/* letter-spacing adds a trailing space after the last letter, which drags
	   the glyphs left of centre. padding-left = padding-right + letter-spacing
	   cancels it exactly. */
	padding: 0.95rem 1.75rem 0.95rem calc(1.75rem + 0.16em);
	font-family: inherit;
	font-size: 0.95rem;
	font-weight: 700;
	/* Explicit line-height keeps the button height predictable rather than
	   inheriting the 1.65 body leading. */
	line-height: 1.2;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--bout-ink);
	background-color: var(--bout-parchment);
	border: 1px solid rgba(11, 10, 9, 0.2);
	border-radius: 2px;
	cursor: pointer;
	/* Contains the fill below and keeps it clipped to the rounded corners. */
	position: relative;
	overflow: hidden;
	isolation: isolate;
	/* The label flips colour late, once the fill is most of the way up, so it
	   never sits mid-grey over a half-filled button. */
	transition: color 0.22s ease 0.3s, transform 0.12s ease, box-shadow 0.3s ease;
}

/* Blood rising from the bottom of the button on hover. A negative z-index
   paints it over the button's own background but under the label, so the text
   stays readable the whole way up.

   Two background layers: a repeating wave that rides the surface of the
   liquid, and the solid body below it. The wave tiles every 320px and its
   three crests differ in width and height so the surface does not read as a
   regular scallop. Each segment is a cubic with horizontal handles at both
   ends, which makes every crest and trough round; the tile starts and ends
   at the same trough, so the horizontal drift is seamless. The body starts
   1px into the wave band to avoid a hairline seam where the two meet. */
.bout-btn::before {
	content: "";
	position: absolute;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: -1;
	height: 0;
	background-image:
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 14' preserveAspectRatio='none'%3E%3Cpath d='M0 12 C22.5 12 22.5 2 45 2 C70 2 70 11 95 11 C122.5 11 122.5 5 150 5 C182.5 5 182.5 12 215 12 C240 12 240 1 265 1 C292.5 1 292.5 12 320 12 V14 H0 Z' fill='%23b8402c'/%3E%3C/svg%3E"),
		linear-gradient(var(--bout-red), var(--bout-red));
	background-repeat: repeat-x, no-repeat;
	background-position: 0 0, left bottom;
	background-size: 320px 14px, 100% calc(100% - 13px);
	transition: height 0.6s cubic-bezier(0.35, 0, 0.25, 1);
}

/* Drifting the wave sideways makes the surface move rather than just rise. */
@keyframes bout-blood-wave {
	to {
		background-position: -320px 0, left bottom;
	}
}

.bout-btn:hover:not(:disabled),
.bout-btn:focus-visible:not(:disabled) {
	color: var(--bout-parchment);
	box-shadow: 0 8px 26px -8px rgba(184, 64, 44, 0.8);
}

/* Overfilled by the height of the wave band, so the crests clear the top of
   the button and it ends up completely red rather than notched. */
.bout-btn:hover:not(:disabled)::before,
.bout-btn:focus-visible:not(:disabled)::before {
	height: calc(100% + 14px);
	animation: bout-blood-wave 5s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
	.bout-btn::before {
		transition-duration: 0.01ms;
	}

	.bout-btn:hover:not(:disabled)::before,
	.bout-btn:focus-visible:not(:disabled)::before {
		animation: none;
	}
}

.bout-btn:active:not(:disabled) {
	transform: translateY(1px);
}

.bout-btn:focus-visible {
	outline: 2px solid var(--bout-gold);
	outline-offset: 3px;
}

.bout-btn:disabled {
	opacity: 0.6;
	cursor: progress;
}

.bout-signup__message {
	margin: 0.9rem 0 0;
	padding: 0.75rem 1rem;
	font-size: 0.95rem;
	text-align: center;
	border-radius: 2px;
	border: 1px solid transparent;
}

.bout-signup__message[hidden] {
	display: none;
}

.bout-signup__message.is-success {
	color: #d8e6cf;
	background-color: rgba(78, 122, 52, 0.18);
	border-color: rgba(120, 168, 88, 0.45);
}

.bout-signup__message.is-error {
	color: #f0cfc9;
	background-color: rgba(154, 44, 32, 0.2);
	border-color: rgba(184, 64, 44, 0.5);
}

/* -------------------------------------------------------------------------
   Signup dialog
   ---------------------------------------------------------------------- */

.bout-modal {
	width: min(560px, calc(100vw - 2rem));
	max-height: calc(100vh - 2rem);
	padding: 0;
	color: var(--bout-parchment);
	background-color: var(--bout-ink-raised);
	border: 1px solid var(--bout-hairline);
	border-radius: 4px;
	box-shadow: 0 40px 90px -20px rgba(0, 0, 0, 0.92);
	overflow: auto;
}

.bout-modal::backdrop {
	background-color: rgba(4, 3, 3, 0.8);
	backdrop-filter: blur(3px);
}

.bout-modal__inner {
	position: relative;
	padding: clamp(1.75rem, 4vw, 2.5rem);
}

.bout-modal__title {
	margin: 0 0 0.6rem;
	font-variant: small-caps;
	font-size: clamp(1.6rem, 4vw, 2.1rem);
	text-align: center;
	color: var(--bout-parchment);
}

.bout-modal__lede {
	max-width: 40ch;
	margin: 0 auto clamp(1.5rem, 3vh, 2rem);
	text-align: center;
	text-wrap: balance;
	color: rgba(243, 236, 224, 0.78);
}

/* The form is already centred by the dialog, so drop its own cap. */
.bout-modal .bout-signup {
	max-width: none;
}

.bout-modal__close {
	position: absolute;
	top: 0.35rem;
	right: 0.5rem;
	width: 2.25rem;
	height: 2.25rem;
	padding: 0;
	font-family: inherit;
	font-size: 1.65rem;
	line-height: 1;
	color: var(--bout-muted);
	background: none;
	border: 0;
	border-radius: 2px;
	cursor: pointer;
	transition: color 0.18s ease;
}

.bout-modal__close:hover {
	color: var(--bout-parchment);
}

.bout-modal__close:focus-visible {
	outline: 2px solid var(--bout-gold);
	outline-offset: 2px;
}

/* Stop the page behind the dialog from scrolling. */
html.bout-modal-open {
	overflow: hidden;
}

@keyframes bout-modal-in {
	from { opacity: 0; transform: translateY(12px) scale(0.98); }
	to   { opacity: 1; transform: none; }
}

@keyframes bout-backdrop-in {
	from { opacity: 0; }
	to   { opacity: 1; }
}

.bout-modal[open] {
	animation: bout-modal-in 0.22s ease-out;
}

.bout-modal[open]::backdrop {
	animation: bout-backdrop-in 0.22s ease-out;
}

@media (prefers-reduced-motion: reduce) {
	.bout-modal[open],
	.bout-modal[open]::backdrop {
		animation: none;
	}
}

/* -------------------------------------------------------------------------
   Card fan
   ---------------------------------------------------------------------- */

.bout-fan {
	--fan-card-w: clamp(96px, 15.5vw, 240px);
	--fan-card-h: calc(var(--fan-card-w) * 1.4467); /* 868 / 600 */
	--fan-gap: calc(var(--fan-card-w) * 0.85);
	position: relative;
	/* Tall enough for the rotated cards plus the arc lift on the middle
	   pair — see the --dy values below. */
	height: calc(var(--fan-card-h) * 1.45);
	margin-top: clamp(1.5rem, 4vh, 2.75rem);
	overflow: hidden;
}

.bout-fan::after {
	/* Warm glow pooling behind the spread. */
	content: "";
	position: absolute;
	left: 50%;
	bottom: -30%;
	width: 120%;
	height: 130%;
	transform: translateX(-50%);
	background: radial-gradient(closest-side, rgba(154, 44, 32, 0.22), transparent 72%);
	pointer-events: none;
	z-index: 0;
}

/* Cards pivot about their own bottom edge. Rotation alone leaves every bottom
   edge on the same horizontal line, which reads as a row rather than a fan —
   so --dy also lifts the cards toward the middle of the spread. --dy follows a
   parabola (∝ distance from centre squared) with the outer pair as baseline,
   which is the curve a fanned hand actually makes. */
.bout-fan__card {
	position: absolute;
	left: 50%;
	/* Clears the dip of the outermost cards' lower corners, plus the extra
	   drop those two carry to round out the arc. */
	bottom: calc(var(--fan-card-h) * 0.2);
	z-index: 1;
	width: var(--fan-card-w);
	aspect-ratio: 600 / 868;
	margin: 0;
	border-radius: var(--bout-card-radius);
	overflow: hidden;
	transform-origin: 50% 100%;
	transform: translate(calc(-50% + var(--dx)), var(--dy)) rotate(var(--rot));
	box-shadow: var(--bout-shadow-card);
	transition: transform 0.35s cubic-bezier(0.2, 0.7, 0.3, 1), box-shadow 0.35s ease;
	will-change: transform;
}

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

.bout-fan__card:nth-child(1) { --dx: calc(var(--fan-gap) * -2.5); --dy: calc(var(--fan-card-w) * 0.06); --rot: -24deg; z-index: 1; }
.bout-fan__card:nth-child(2) { --dx: calc(var(--fan-gap) * -1.5); --dy: calc(var(--fan-card-w) * -0.2); --rot: -14.4deg; z-index: 2; }
.bout-fan__card:nth-child(3) { --dx: calc(var(--fan-gap) * -0.5); --dy: calc(var(--fan-card-w) * -0.3); --rot: -4.8deg; z-index: 3; }
.bout-fan__card:nth-child(4) { --dx: calc(var(--fan-gap) * 0.5); --dy: calc(var(--fan-card-w) * -0.3); --rot: 4.8deg; z-index: 4; }
.bout-fan__card:nth-child(5) { --dx: calc(var(--fan-gap) * 1.5); --dy: calc(var(--fan-card-w) * -0.2); --rot: 14.4deg; z-index: 5; }
.bout-fan__card:nth-child(6) { --dx: calc(var(--fan-gap) * 2.5); --dy: calc(var(--fan-card-w) * 0.06); --rot: 24deg; z-index: 6; }

@media (hover: hover) {
	.bout-fan__card:hover {
		z-index: 10;
		transform: translate(calc(-50% + var(--dx)), var(--dy)) rotate(var(--rot)) translateY(-3%);
		box-shadow: 0 26px 60px -14px rgba(0, 0, 0, 0.9), 0 0 30px -6px rgba(201, 162, 39, 0.35);
	}
}

/* On phones the spread has to fit the screen, so tighten the overlap rather
   than let the outer cards get clipped away. */
@media (max-width: 640px) {
	.bout-fan {
		/* The 24° rotation widens the spread's bounding box, so phones need a
		   smaller card and tighter overlap to keep the outer two unclipped. */
		--fan-card-w: 20vw;
		--fan-gap: calc(var(--fan-card-w) * 0.55);
	}
}

@media (prefers-reduced-motion: reduce) {
	.bout-fan__card { transition: none; }
}

/* -------------------------------------------------------------------------
   Sections
   ---------------------------------------------------------------------- */

/* WordPress applies the 24px root block gap as a margin on every top-level
   block, which shows up as a dark strip between these full-bleed sections.
   They each carry their own padding, so that gap is dead space. */
.wp-site-blocks > .bout-hero,
.wp-site-blocks > .bout-section,
.wp-site-blocks > footer {
	margin-block-start: 0;
}

.bout-section {
	padding-top: clamp(3.5rem, 9vh, 7rem);
	padding-bottom: clamp(3.5rem, 9vh, 7rem);
}

.bout-section--raised {
	background-color: var(--bout-ink-raised);
	border-top: 1px solid var(--bout-hairline);
	border-bottom: 1px solid var(--bout-hairline);
}

/* Back-to-back raised sections would stack two hairlines into a 2px seam. */
.bout-section--raised + .bout-section--raised {
	border-top: 0;
}

.bout-eyebrow {
	margin: 0 0 0.75rem;
	font-variant: small-caps;
	font-size: 1.19rem;
	letter-spacing: 0.22em;
	text-align: center;
	color: var(--bout-gold);
}

.bout-section__title {
	font-variant: small-caps;
	font-size: clamp(2.375rem, 5.25vw, 3.625rem);
	text-align: center;
	margin: 0 0 clamp(0.75rem, 2vh, 1.25rem);
	color: var(--bout-parchment);
}

.bout-section__lede {
	max-width: 52ch;
	margin: 0 auto clamp(2.25rem, 5vh, 3.5rem);
	text-align: center;
	color: rgba(243, 236, 224, 0.78);
}

/* Multi-paragraph ledes: only the last one carries the full gap down to
   whatever the section opens with. */
.bout-section__lede:not(:last-of-type) {
	margin-bottom: 1.15rem;
}

/* -------------------------------------------------------------------------
   Gameplay beats
   ---------------------------------------------------------------------- */

/* Introduces the card-type grid. Deliberately a step down from the section
   title so it groups the three cards without competing with it. */
.bout-subhead {
	margin: clamp(2.5rem, 6vh, 4rem) 0 0;
	font-variant: small-caps;
	/* Matched to .bout-section__title so the two headings sit at the same size. */
	font-size: clamp(2.375rem, 5.25vw, 3.625rem);
	text-align: center;
	color: var(--bout-parchment);
}

/* The subhead now carries the gap down from the diagram, so the grid only
   needs the smaller gap below the subhead itself. */
.bout-subhead + .bout-beats {
	margin-top: clamp(1.25rem, 3vh, 2rem);
}

.bout-beats {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: clamp(1.25rem, 3vw, 2.25rem);
	max-width: 1100px;
	/* Sits under the army cycle diagram in the same section. */
	margin: clamp(2.5rem, 6vh, 4rem) auto 0;
	padding: 0;
	list-style: none;
}

.bout-beat {
	display: flex;
	flex-direction: column;
	padding: 1.85rem 1.6rem;
	background-color: rgba(243, 236, 224, 0.028);
	border: 1px solid var(--bout-hairline);
	border-radius: 3px;
	/* Keeps the full-bleed art inside the rounded corners. Clipped rather than
	   overflow-hidden: overflow makes the card a scroll container, which would
	   capture the art's view() timeline and freeze the parallax. */
	clip-path: inset(0 round 3px);
}

/* The card's header: icon and card-type label, running to the card edge above
   the art. */
.bout-beat__tag {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.7rem;
	margin: -1.85rem -1.6rem 0;
	padding: 0.85rem 1.6rem;
	border-bottom: 1px solid var(--bout-hairline);
	color: var(--bout-gold);
}

.bout-beat__icon {
	flex: none;
	width: 49px;
	height: 49px;
}

/* The fill comes from here rather than the source file's stripped <defs> —
   see bout_shortcode_icon(). */
.bout-beat__icon .cls-1 {
	fill: currentColor;
}

.bout-beat__tag-name {
	font-variant: small-caps;
	font-size: 1.05rem;
	line-height: 1;
	letter-spacing: 0.16em;
}

.bout-beat__title {
	margin: 0 0 0.75rem;
	font-variant: small-caps;
	font-size: clamp(1.35rem, 2.4vw, 1.65rem);
	line-height: 1.2;
	color: var(--bout-gold);
}

.bout-beat__body {
	margin: 0;
	font-size: 1rem;
	color: rgba(243, 236, 224, 0.8);
}

.bout-beat__body + .bout-beat__body {
	margin-top: 0.85rem;
}

/* Art below the card's tag. The negative side margins cancel the card's padding
   so the band runs to the card edge; it sits flush under the tag, with the gap
   below it separating it from the copy. */
/* The figure is the fixed window the art is clipped to. */
.bout-art {
	position: relative;
	margin: 0 -1.6rem 1.5rem;
	/* A band rather than the full portrait, so the illustration supports the
	   copy instead of swamping it. */
	aspect-ratio: 4 / 3;
	/* Same reason as the card: clip without becoming a scroll container. */
	clip-path: inset(0);
}

.bout-art__img {
	display: block;
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	/* Fills the window exactly, so nothing sits above the top edge waiting to
	   be cropped. */
	height: 100%;
	object-fit: cover;
	object-position: center top;
	filter: saturate(0.9) brightness(0.92);
	/* Growth happens downward from the top edge: the top of the illustration
	   never moves, and the crop tightens from the bottom instead. */
	transform-origin: center top;
}

/* A slow push-in as the card crosses the screen. 6% is enough to register as
   movement without softening the art. */
@keyframes bout-art-zoom {
	from {
		transform: scale(1);
	}

	to {
		transform: scale(1.06);
	}
}

/* Scroll-driven, so it costs no JavaScript and never runs off-screen. Where
   view timelines are unsupported the image simply holds still. */
@supports (animation-timeline: view()) {
	.bout-art__img {
		will-change: transform;
		animation: bout-art-zoom linear both;
		animation-timeline: view();
		/* Slightly inside the full pass so the push is spent over less scroll
		   and reads as movement rather than creep. */
		animation-range: cover 10% cover 90%;
	}
}

@media (prefers-reduced-motion: reduce) {
	.bout-art__img {
		animation: none;
		transform: none;
	}
}

/* The question that leaves the beat hanging — set apart from the body copy.
   Pinned to the bottom of the card so the rule above it lines up across all
   three, however much copy sits above. */
.bout-beat__ask {
	margin: 0;
	margin-top: auto;
	padding-top: 0.9rem;
	border-top: 1px solid var(--bout-hairline);
	font-style: italic;
	font-size: 1rem;
	color: var(--bout-gold-soft);
}

/* margin-top:auto can collapse to nothing in the tallest card, so the minimum
   gap above the rule lives on the paragraph before it. */
.bout-beat__body:has(+ .bout-beat__ask) {
	margin-bottom: 1rem;
}

/* -------------------------------------------------------------------------
   Army cycle diagram (sword / shield / bow)

   The container is locked to 1000/800 — the same aspect ratio as the arrow
   SVG's viewBox — so the percentage-positioned cards and the arrows stay in
   register at every size.
   ---------------------------------------------------------------------- */

.bout-cycle {
	position: relative;
	aspect-ratio: 1000 / 800;
	max-width: 912px;
	margin: 0 auto;
}

.bout-cycle__arrows {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	color: var(--bout-gold);
	pointer-events: none;
	z-index: 1;
}

/* The centroid of the three cards: x is (50 + 22 + 78) / 3, and each card's
   centre sits half a card height below its top — a card being 20% of the
   container wide and 868/600 of that tall, i.e. 36.17% of the container high. */
.bout-cycle__label {
	position: absolute;
	left: 50%;
	top: 60.75%;
	z-index: 2;
	margin: 0;
	transform: translate(-50%, -50%);
	/* Full caps rather than the small-caps used elsewhere — the word has to
	   hold the middle of the diagram on its own. */
	text-transform: uppercase;
	font-size: clamp(0.95rem, 2vw, 1.35rem);
	letter-spacing: 0.24em;
	white-space: nowrap;
	color: var(--bout-gold);
}

.bout-cycle__card {
	position: absolute;
	z-index: 2;
	width: 20%;
	margin: 0;
	border-radius: var(--bout-card-radius);
	overflow: hidden;
	box-shadow: var(--bout-shadow-card);
	transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.3, 1), box-shadow 0.3s ease;
}

.bout-cycle__card img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 600 / 868;
	object-fit: cover;
}

.bout-cycle__card--sword  { left: 40%; top: 4%; }
.bout-cycle__card--bow    { left: 12%; top: 62%; }
.bout-cycle__card--shield { left: 68%; top: 62%; }

.bout-cycle__card:hover {
	transform: translateY(-8px) scale(1.03);
	box-shadow: 0 26px 55px -14px rgba(0, 0, 0, 0.9), 0 0 26px -8px rgba(201, 162, 39, 0.45);
}

/* Only used by the stacked layout below. */
.bout-cycle__step {
	display: none;
}

@media (max-width: 640px) {
	.bout-cycle {
		aspect-ratio: auto;
		max-width: 240px;
		display: flex;
		flex-direction: column;
		align-items: center;
	}

	.bout-cycle__arrows,
	.bout-cycle__label {
		display: none;
	}

	.bout-cycle__card {
		position: static;
		width: 100%;
	}

	.bout-cycle__step {
		display: block;
		margin: 0.85rem 0;
		/* Matches the desktop label. */
		text-transform: uppercase;
		font-size: 0.95rem;
		letter-spacing: 0.18em;
		text-align: center;
		color: var(--bout-gold);
	}

	.bout-cycle__step::before {
		content: "\2193";
		display: block;
		margin-bottom: 0.15rem;
		font-size: 1.15rem;
		letter-spacing: 0;
	}

	.bout-cycle__step--loop::before {
		content: "\21ba";
	}
}

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

/* -------------------------------------------------------------------------
   Art teaser strip

   Illustration only, no names or rules text — the columns are cropped tight
   and dimmed so the deck reads as withheld rather than catalogued.
   ---------------------------------------------------------------------- */

.bout-teaser-wrap {
	position: relative;
	max-width: 1200px;
	/* Sits below the Kickstarter copy in the same section. */
	margin: clamp(2.75rem, 7vh, 4.5rem) auto 0;
}

.bout-teaser {
	display: grid;
	/* One equal column per image, whatever the shortcode is given — the strip
	   always fills its width. */
	grid-auto-flow: column;
	grid-auto-columns: 1fr;
	gap: 0;
	margin: 0;
	padding: 0;
	list-style: none;
	overflow: hidden;
	border-radius: 3px;
}

.bout-teaser__col {
	position: relative;
	margin: 0;
	overflow: hidden;
}

.bout-teaser__col + .bout-teaser__col {
	box-shadow: -1px 0 0 rgba(0, 0, 0, 0.55);
}

.bout-teaser__art {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 1 / 2;
	object-fit: cover;
	object-position: center 22%;
	/* Only a light dim — several of these illustrations are near-black
	   already, so the withholding comes from the crop and the veil. */
	filter: saturate(0.82) brightness(0.82) contrast(1.03);
	transition: filter 0.45s ease, transform 0.6s cubic-bezier(0.2, 0.7, 0.3, 1);
	will-change: filter, transform;
}

@media (hover: hover) {
	.bout-teaser__col:hover .bout-teaser__art {
		filter: saturate(1) brightness(1.04) contrast(1);
		transform: scale(1.05);
	}
}

/* Fades the strip into the page top and bottom. */
.bout-teaser__veil {
	position: absolute;
	inset: 0;
	pointer-events: none;
	border-radius: 3px;
	background: linear-gradient(
		to bottom,
		var(--bout-ink-raised) 0%,
		rgba(19, 17, 16, 0) 20%,
		rgba(19, 17, 16, 0) 74%,
		var(--bout-ink-raised) 100%
	);
}

@media (max-width: 640px) {
	.bout-teaser__art {
		/* Slimmer columns need more height to stay dramatic. */
		aspect-ratio: 1 / 3;
	}
}

/* -------------------------------------------------------------------------
   Card gallery — still available via [bout_card_gallery], not currently placed
   ---------------------------------------------------------------------- */

.bout-gallery {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(155px, 1fr));
	gap: clamp(0.9rem, 2.2vw, 1.75rem);
	max-width: 1200px;
	margin: 0 auto;
	padding: 0;
	list-style: none;
}

.bout-gallery__item {
	margin: 0;
}

.bout-gallery__figure {
	position: relative;
	margin: 0;
	border-radius: var(--bout-card-radius);
	overflow: hidden;
	box-shadow: var(--bout-shadow-card);
	transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.3, 1), box-shadow 0.3s ease;
}

.bout-gallery__figure img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 600 / 868;
	object-fit: cover;
}

.bout-gallery__item:hover .bout-gallery__figure {
	transform: translateY(-6px);
	box-shadow: 0 24px 50px -14px rgba(0, 0, 0, 0.9), 0 0 24px -8px rgba(201, 162, 39, 0.4);
}

.bout-gallery__caption {
	margin: 0.7rem 0 0;
	font-variant: small-caps;
	font-size: 0.95rem;
	letter-spacing: 0.08em;
	text-align: center;
	color: var(--bout-muted);
}

.bout-gallery__type {
	display: block;
	font-size: 0.78rem;
	letter-spacing: 0.16em;
	color: rgba(201, 162, 39, 0.6);
}

/* -------------------------------------------------------------------------
   Kickstarter call to action
   ---------------------------------------------------------------------- */

.bout-cta {
	max-width: 620px;
	margin: 0 auto;
	text-align: center;
}

.bout-cta .bout-btn {
	width: auto;
	min-width: 280px;
}

/* -------------------------------------------------------------------------
   Footer
   ---------------------------------------------------------------------- */

.bout-footer {
	padding: clamp(2.5rem, 6vh, 4rem) 0;
	text-align: center;
	background-color: #000;
}

.bout-footer__logo {
	/* Capped so it does not become a billboard on ultrawide displays. */
	width: 20%;
	min-width: 120px;
	max-width: 260px;
	height: auto;
	margin: 0 auto 1.25rem;
	opacity: 0.75;
}

.bout-footer__legal {
	margin: 0;
	font-size: 0.88rem;
	color: rgba(169, 156, 136, 0.7);
}

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

@media (prefers-reduced-motion: reduce) {
	.bout-cycle__card,
	.bout-gallery__figure,
	.bout-btn {
		transition: none;
	}
}
