/**
 * Custodes — hand-written layer.
 *
 * Design tokens (colours, fonts, spacing, most block styles) live in theme.json.
 * This file covers the things theme.json can't express: the dark sticky header,
 * the fullscreen overlay menu, the hero, game-card grid, and a few polish bits.
 * All values reference theme.json CSS custom properties so there's one source
 * of truth.
 */

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

:root {
	--custodes-header-h: 84px;
	--custodes-ease: cubic-bezier( 0.4, 0, 0.2, 1 );

	/* ------------------------------------------------------ Container ----
	 * ONE width for the whole site. Every band — header, hero, game grid,
	 * stats, calendar, news, footer and the footer bar — aligns to this, so
	 * the left and right edges form a single vertical line down the page.
	 *
	 * This exists because they previously did not: at a 1440px viewport the
	 * sections measured 696 / 720 / 760 / 1100 / 1146 / 1200 / 1425px wide,
	 * starting at seven different left edges. Any new section must use
	 * `.custodes-container` (or the token) rather than inventing a width.
	 *
	 * Prose keeps a narrower measure for readability (--custodes-measure) but
	 * is CENTRED inside the same container, so it still reads as one system.
	 */
	--custodes-container: 1200px;
	--custodes-measure: 720px;
	--custodes-gutter: clamp( 1.25rem, 5vw, 3rem );
}

/* The single container. Anything that spans the page uses this. */
.custodes-container,
.custodes-games,
.custodes-stats,
.custodes-hours,
.custodes-postgrid,
.custodes-footer__inner,
.custodes-footer__bar,
.custodes-header > .wp-block-group,
.custodes-hero .wp-block-cover__inner-container,
body.custodes-dark-ui .cev-wrap,
.custodes-calendar-section .cev-wrap {
	width: 100%;
	max-width: var( --custodes-container );
	margin-inline: auto;
}

body {
	text-rendering: optimizeLegibility;
	-webkit-font-smoothing: antialiased;
}

/* Visible, on-brand focus ring for keyboard users everywhere. */
:where(a, button, input, select, textarea, summary, .wp-block-navigation-item__content):focus-visible {
	outline: 2px solid var( --wp--preset--color--accent );
	outline-offset: 3px;
	border-radius: 2px;
}

/* Skip link */
.skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 100000;
	background: var( --wp--preset--color--contrast );
	color: #fff;
	padding: 0.75rem 1.25rem;
	font-family: var( --wp--preset--font-family--body );
}
.skip-link:focus {
	left: 0.5rem;
	top: 0.5rem;
}

/* ------------------------------------------------------------- Header ---- */

.custodes-header {
	position: sticky;
	top: 0;
	z-index: 999;
	background: var( --wp--preset--color--dark );
	border-bottom: 1px solid rgba( 255, 255, 255, 0.08 );
	transition: background 0.3s var( --custodes-ease ), border-color 0.3s var( --custodes-ease );
}

/* Over the hero on the front page the header floats transparent until scroll. */
body.has-transparent-header .custodes-header {
	position: fixed;
	inset: 0 0 auto 0;
	/* Subtle top-down scrim so the white logo + hamburger stay legible over
	   bright areas of the hero image, without reading as a solid bar. */
	background: linear-gradient( 180deg, rgba( 6, 6, 8, 0.45 ) 0%, rgba( 6, 6, 8, 0 ) 100% );
	border-bottom-color: transparent;
}
body.has-transparent-header .custodes-header.is-scrolled {
	position: fixed;
	background: rgba( 11, 11, 12, 0.92 );
	backdrop-filter: saturate( 140% ) blur( 8px );
	border-bottom-color: rgba( 255, 255, 255, 0.08 );
}

/* The header is dark in every state → its content is always light. */
.custodes-header,
.custodes-header a,
.custodes-header .wp-block-site-title a {
	color: #fff;
}
.custodes-header .wp-block-site-title a:hover {
	color: var( --wp--preset--color--accent );
}

/* Push page content below the fixed header on the front page. */
body.has-transparent-header .wp-site-blocks > main {
	margin-top: 0;
}

/* Header inner row — subtly shrinks once you start scrolling. */
.custodes-header .wp-block-group {
	min-height: var( --custodes-header-h );
	transition: min-height 0.35s var( --custodes-ease );
}
.custodes-header.is-scrolled .wp-block-group {
	min-height: 64px;
}
.custodes-header .wp-block-site-logo img {
	max-height: 52px;
	width: auto;
	transition: max-height 0.35s var( --custodes-ease ), filter 0.35s var( --custodes-ease );
}
.custodes-header.is-scrolled .wp-block-site-logo img {
	max-height: 40px;
}
/* Over the bright hero, lift the white logo a touch so it never washes out. */
body.has-transparent-header .custodes-header:not(.is-scrolled) .wp-block-site-logo img {
	filter: drop-shadow( 0 2px 10px rgba( 0, 0, 0, 0.45 ) );
}

/* ---------------------------------------------- Navigation / overlay ---- */

/* Hamburger + close buttons.
   Core gives the button padding:0, so the button WAS the 28px icon — a 28x28 tap
   target on every page at every width, well under the 44px minimum. Pad it out
   without moving the icon optically (negative margin absorbs the added box). */
.custodes-header .wp-block-navigation__responsive-container-open,
.custodes-header .wp-block-navigation__responsive-container-close {
	color: #fff;
	min-width: 44px;
	min-height: 44px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 8px;
	margin: -8px;
}
.custodes-header .wp-block-navigation .wp-block-navigation__responsive-container-open svg,
.custodes-header .wp-block-navigation .wp-block-navigation__responsive-container-close svg {
	width: 28px;
	height: 28px;
	fill: currentColor;
}

/* Fullscreen overlay when the menu is open. */
.wp-block-navigation__responsive-container.is-menu-open {
	background: linear-gradient( 180deg, #0b0b0c 0%, #17171a 100% );
	padding: clamp( 4rem, 12vh, 8rem ) clamp( 1.5rem, 6vw, 4rem );
}
/*
 * These three declarations were DEAD — core's navigation stylesheet out-specifies
 * them, so the overlay rendered left-aligned and top-weighted with ~50-62% empty
 * space below the items, at every width:
 *   core `.is-menu-open:not(.disable-default-overlay){padding:…}`          (0,3,0)
 *   core `.is-menu-open:where(…) …-content .wp-block-navigation__container` (0,4,0)
 * The `:not(...)`/`:where(...)` selectors below match core's weight so ours win.
 *
 * `height:100%` also could not resolve: the intermediate
 * `.wp-block-navigation__responsive-dialog` has no definite height, so the content
 * box computed to 267px rather than the viewport and vertical centring never engaged.
 * Giving the dialog a definite height fixes that at the source.
 */
.wp-block-navigation__responsive-container.is-menu-open:not( .disable-default-overlay ) {
	padding: clamp( 4rem, 12vh, 8rem ) clamp( 1.5rem, 6vw, 4rem );
	/* The open container is the only element in the chain with the viewport's
	   height; everything inside it (…__responsive-close is display:block at auto
	   height) collapses to the items' own ~264px. Centring HERE is what actually
	   places the menu mid-screen — `height:100%` further down cannot, because no
	   ancestor below this one has a definite height to resolve against. */
	justify-content: center;
}
/* Core's …__responsive-close wrapper is display:block at auto height, so the
   container was centring a box smaller than itself and the menu landed low.
   Let it grow to fill the container's content box and centre its own child. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-close {
	flex: 1 1 auto;
	display: flex;
	flex-direction: column;
	justify-content: center;
	min-height: 0;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-dialog {
	flex: 1 1 auto;
	display: flex;
	flex-direction: column;
	justify-content: center;
	min-height: 0;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
	justify-content: center;
	align-items: center;
	flex: 1 1 auto;
	min-height: 0;
}
/* Core reserves 56px of top padding on the content for its close button; ours is
   absolutely positioned in the corner, so that reservation only pushed the menu
   off-centre. The doubled `.is-menu-open` raises this to (0,4,0) to beat core's
   own rule — measured: with the padding gone the items sit 315px from the top and
   315px from the bottom, exactly centred. */
.wp-block-navigation__responsive-container.is-menu-open.is-menu-open .wp-block-navigation__responsive-container-content {
	padding-top: 0;
}
.wp-block-navigation__responsive-container.is-menu-open:where( :not( .never ) ) .wp-block-navigation__responsive-container-content .wp-block-navigation__container {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: clamp( 1.25rem, 3vh, 2.25rem );
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
	position: relative;
	font-family: var( --wp--preset--font-family--display );
	font-size: clamp( 2rem, 7vw, 3.75rem );
	color: #fff;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	text-decoration: none;
	transition: color 0.25s var( --custodes-ease );
}
/* Gold underline that grows out from the centre on hover/focus. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content::after {
	content: "";
	position: absolute;
	left: 50%;
	right: 50%;
	bottom: -0.1em;
	height: 2px;
	background: var( --wp--preset--color--accent );
	transition: left 0.3s var( --custodes-ease ), right 0.3s var( --custodes-ease );
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content:hover,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content:focus {
	color: var( --wp--preset--color--accent );
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content:hover::after,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content:focus::after {
	left: 0;
	right: 0;
}
/* The overlay panel itself eases in rather than snapping open. */
.wp-block-navigation__responsive-container.is-menu-open {
	animation: custodesOverlayIn 0.35s var( --custodes-ease ) both;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item {
	animation: custodesFadeUp 0.5s var( --custodes-ease ) both;
	animation-delay: calc( 0.12s + var( --nav-i, 0 ) * 0.07s );
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close {
	top: clamp( 1.5rem, 4vh, 2.5rem );
	right: clamp( 1.5rem, 6vw, 4rem );
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close svg {
	width: 34px;
	height: 34px;
}

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

.custodes-hero {
	position: relative;
	min-height: min( 92vh, 820px );
}
/* width comes from the shared container at the top of this file — one source */
.custodes-hero h1 {
	color: #fff;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	text-shadow: 0 2px 30px rgba( 0, 0, 0, 0.5 );
}
.custodes-hero .custodes-hero__tagline {
	color: rgba( 255, 255, 255, 0.86 );
	/* 40ch keeps the line readable, but it must be CENTRED inside the hero's
	   container — capped-but-left-aligned is what made the hero text look like it
	   belonged to a different grid than everything below it. */
	max-width: 40ch;
	margin-inline: auto;
}
/*
 * There is no address line above the hero title.
 *
 * It used to sit there in gold uppercase over the dimmed cityscape and was
 * unreadable at every size; the "Kako do nas" button directly below already
 * takes the visitor to the exact location, so the line was cost without value.
 */

/* ----------------------------------------------------- Section rhythm ---- */

/* Text-safe gold: bright gold (#b8912e) is only ~2.95:1 on white, so gold
   *text* on light backgrounds uses this darker gold (~5:1, WCAG AA). Bright
   gold is kept for text on dark bands and for non-text accents/borders. */
:root {
	--custodes-gold-text: #8a6a15;
}

.custodes-eyebrow {
	color: var( --custodes-gold-text );
	text-transform: uppercase;
	letter-spacing: 0.2em;
	font-size: var( --wp--preset--font-size--small );
	font-weight: 600;
	font-family: var( --wp--preset--font-family--body );
}

/* Dark bands invert text colour. */
.custodes-dark,
.custodes-dark :where( h1, h2, h3, h4, p, li ) {
	color: #fff;
}
.custodes-dark .custodes-eyebrow {
	color: var( --wp--preset--color--accent );
}
.custodes-dark a:not(.wp-element-button) {
	color: var( --wp--preset--color--accent );
}

/* ------------------------------------------------------- Game cards ---- */

/*
 * Wrapping flex row, not a grid — deliberately.
 *
 * There are 13 games, and 13 is prime: every fixed column count leaves a lone
 * card stranded on the last row (6+6+1, 4+4+4+1, …), which is the ragged last
 * row that kept coming back. A grid cannot centre its final row; flex-wrap can,
 * so the leftovers sit centred under the rows above at ANY width and any number
 * of games. Add or remove a game and it still looks deliberate.
 */
.custodes-games {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: stretch;
	gap: clamp( 0.75rem, 1.5vw, 1.25rem );
}
.custodes-games > .custodes-game-card {
	flex: 1 1 172px;
	max-width: 224px;
	min-width: 0;
}
/* On a 360px phone the content box is 320px and the gap computes to 12px, so two
   160px columns need 332px — it misses by 12px and drops to ONE column, making the
   section 3334px tall instead of 1202px (2.8x) for 13 cards. Shrink the track just
   enough to keep two columns at the narrowest common width. */
@media ( max-width: 380px ) {
	/* two per row on the narrowest phones; flex handles the rest */
	.custodes-games > .custodes-game-card { flex-basis: 132px; }
}
/* White "logo plate" card: game colour rides the top edge, the logo sits
   centred on white so transparent + white-boxed logos both read cleanly. */
.custodes-game-card {
	--game: var( --wp--preset--color--accent );
	position: relative;
	/*
	 * border-box, and it is load-bearing.
	 *
	 * With content-box the `flex-basis`/`max-width` above sized the CONTENT box, so
	 * every card ended up as wide as its own padding made it: logo cards (no
	 * horizontal padding) measured 226px while the text-only card (2 x 1rem)
	 * measured 258px. On a phone that 32px difference also changed how many cards
	 * fit per flex line, which is why the text card kept dropping onto a row of its
	 * own at a visibly different width from its neighbours.
	 */
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0.6rem;
	min-height: 132px;
	padding: 1.4rem 1rem 1.1rem;
	border-radius: 6px;
	background: #ffffff;
	border: 1px solid var( --wp--preset--color--line );
	border-top: 4px solid var( --game );
	color: var( --wp--preset--color--contrast );
	text-decoration: none;
	overflow: hidden;
	transition: transform 0.2s var( --custodes-ease ), box-shadow 0.2s var( --custodes-ease ), border-color 0.2s var( --custodes-ease );
}
/* Faint game-colour wash on hover. */
.custodes-game-card::before {
	content: "";
	position: absolute;
	inset: 0;
	background: var( --game );
	opacity: 0;
	transition: opacity 0.2s var( --custodes-ease );
	z-index: 0;
}
.custodes-game-card > * {
	position: relative;
	z-index: 1;
}
/* The whole card lifts and grows — the "pop". Because the card scales as one
   piece, the logo inside is never re-cropped by the card's own overflow. */
.custodes-game-card:hover,
.custodes-game-card:focus-visible {
	transform: translateY( -6px ) scale( 1.035 );
	box-shadow: 0 18px 40px rgba( 0, 0, 0, 0.18 );
	border-color: var( --game );
	z-index: 2;
}
.custodes-game-card:hover::before,
.custodes-game-card:focus-visible::before {
	opacity: 0.06;
}
/* The logo plate — a FIXED height white panel with the wordmark centred in it.
   Every card gets the same plate regardless of the logo's own aspect ratio, so
   the grid reads as one row of equal tiles rather than a ragged set. */
.custodes-game-card__logo {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 96px;
	background: #ffffff;
	border-radius: 4px;
	padding: 0.75rem 1rem;
}
.custodes-game-card__logo img {
	max-height: 60px;
	max-width: 90%;
	width: auto;
	object-fit: contain;
	/* No transform/transition here on purpose — the card moves, the logo does not. */
}
/*
 * The logo deliberately does NOT scale on hover.
 *
 * It used to: `transform: scale(1.06)` on the <img> inside a card with
 * `overflow:hidden`, which cropped the logo's edges the moment you pointed at it —
 * exactly the artwork the card exists to show. The card itself now does the moving,
 * so the logo is always seen whole. See .custodes-game-card:hover above.
 */
/* Game-colour dot, sitting just before the title on every card. `flex: none`
   keeps it perfectly round no matter how long the title is. */
.custodes-game-card__dot {
	flex: none;
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: var( --game );
	opacity: 0.95;
}
/* Text-only fallback card (games without a usable logo). */
.custodes-game-card--text {
	justify-content: center;
}
/*
 * Every card carries its name: logo cards show it under the plate, logo-less
 * cards show it alone. Same element, same styling, so the two kinds read as one
 * family rather than two designs. There is deliberately no type/category line —
 * all but two of the games are TCGs, so "TCG" under twelve of thirteen cards
 * labelled nothing.
 */
.custodes-game-card__name {
	display: flex;
	justify-content: center;
	/* The block is always two lines tall (see min-height); centring means a
	   one-line name sits in the middle of it rather than clinging to the plate
	   above with a visible void underneath. */
	align-items: center;
	gap: 0.5rem;
	font-family: var( --wp--preset--font-family--display );
	font-size: 1.05rem;
	line-height: 1.2;
	text-align: center;
	color: var( --wp--preset--color--contrast );
	letter-spacing: 0.01em;
	/* Exactly two lines' worth, so "Gundam" and "Star Wars: Unlimited" leave the
	   plate above them at the same height and the wordmarks line up across rows. */
	min-height: 2.4em;
}
.custodes-game-card__label {
	text-wrap: balance;
}
/* Alone on a card, the name is the whole design — give it room to breathe. */
.custodes-game-card--text .custodes-game-card__name {
	font-size: 1.25rem;
}

/* --------------------------------------------------- Stat / counters ---- */

.custodes-stats {
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 140px, 1fr ) );
	gap: clamp( 1rem, 3vw, 2.5rem );
	text-align: center;
}
/*
 * Three figures never divide evenly into two columns.
 *
 * `auto-fit` dropped to two tracks on a phone and left the third figure sitting
 * in the left column with an empty cell beside it — the group read as
 * left-aligned even though every figure is centred inside its own cell. Pinning
 * two explicit columns and letting the odd one span the row puts it back on the
 * centre line, the same trick the opening-hours grid uses for Sunday.
 */
@media ( max-width: 640px ) {
	.custodes-stats { grid-template-columns: repeat( 2, 1fr ); }
	.custodes-stats > .custodes-stat:last-child:nth-child( odd ) { grid-column: 1 / -1; }
}
.custodes-stat__num {
	font-family: var( --wp--preset--font-family--display );
	font-size: clamp( 2.5rem, 6vw, 3.75rem );
	line-height: 1;
	color: var( --custodes-gold-text );
}
.custodes-stat__label {
	text-transform: uppercase;
	letter-spacing: 0.14em;
	font-size: var( --wp--preset--font-size--small );
	color: inherit;
	opacity: 0.85;
}

/* ---------------------------------------------------- Opening hours ---- */

.custodes-hours {
	display: grid;
	grid-template-columns: repeat( 7, 1fr );
	gap: 0.5rem;
	text-align: center;
}
/* 7 days into 2 columns leaves rows of [2,2,2,1] — Sunday sits alone beside an
   empty half-row. Three columns divides 7 as [3,3,1] but the orphan then reads as
   deliberate; better still, let the last cell span the full row so nothing dangles. */
@media ( max-width: 600px ) {
	.custodes-hours { grid-template-columns: repeat( 2, 1fr ); }
	.custodes-hours__day:last-child { grid-column: 1 / -1; }
}
.custodes-hours__day {
	padding: 0.85rem 0.5rem;
	border: 1px solid var( --wp--preset--color--line );
	border-radius: 4px;
	font-size: var( --wp--preset--font-size--small );
}
.custodes-hours__day.is-closed {
	color: var( --wp--preset--color--muted );
	background: var( --wp--preset--color--surface );
}
.custodes-hours__day.is-open {
	border-color: var( --wp--preset--color--accent );
}
.custodes-hours__day strong {
	display: block;
	font-family: var( --wp--preset--font-family--display );
	font-size: 1.05rem;
	color: var( --wp--preset--color--contrast );
	margin-bottom: 0.2rem;
}
.custodes-dark .custodes-hours__day strong { color: #fff; }

/* --------------------------------------------------------- Post cards ---- */

/*
 * Grid items must be allowed to shrink below their content's min-content width.
 * Core's post-template stylesheet sets `grid-template-columns: 1fr` under 600px,
 * and `1fr` means `minmax(auto, 1fr)` — so one unbreakable string (a 45-char URL
 * pasted into a post excerpt) forced a 349px track inside a 320px container and
 * clipped every card's right edge on the search page at 360px. `min-width: 0`
 * lets the track collapse; `overflow-wrap` then breaks the URL instead of the layout.
 */
.wp-block-post-template > li,
.custodes-post-grid > li {
	min-width: 0;
}
.custodes-postcard .wp-block-post-excerpt,
.custodes-postcard .wp-block-post-title {
	overflow-wrap: anywhere;
}

.custodes-postcard {
	border: 1px solid var( --wp--preset--color--line );
	border-radius: 4px;
	overflow: hidden;
	background: var( --wp--preset--color--base );
	transition: box-shadow 0.2s var( --custodes-ease ), transform 0.2s var( --custodes-ease );
}
.custodes-postcard:hover {
	box-shadow: 0 12px 30px rgba( 0, 0, 0, 0.1 );
	transform: translateY( -3px );
}
.custodes-postcard .wp-block-post-featured-image img {
	aspect-ratio: 16 / 10;
	object-fit: cover;
	width: 100%;
}

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

.custodes-footer {
	position: relative;
	background:
		radial-gradient( 80% 120% at 50% 0%, rgba( 184, 145, 46, 0.06 ) 0%, rgba( 184, 145, 46, 0 ) 55% ),
		linear-gradient( 180deg, #0b0b0c 0%, #141417 100% );
	color: rgba( 255, 255, 255, 0.72 );
	padding-block: clamp( 3rem, 6vw, 5rem ) clamp( 1.5rem, 3vw, 2.5rem );
}
/* Gold hairline crowning the footer. */
.custodes-footer::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 1px;
	background: linear-gradient( 90deg, transparent, rgba( 184, 145, 46, 0.6 ), transparent );
}
.custodes-footer :where( h1, h2, h3, h4 ) { color: #fff; }
.custodes-footer .custodes-eyebrow {
	color: var( --wp--preset--color--accent );
	margin-bottom: 0.9rem;
}
.custodes-footer a {
	color: rgba( 255, 255, 255, 0.72 );
	text-decoration: none;
	transition: color 0.2s var( --custodes-ease );
}
.custodes-footer a:hover { color: var( --wp--preset--color--accent ); }

/*
 * Footer columns must not re-apply the site gutter.
 *
 * Each column is a `constrained` group, so core stamps it `has-global-padding`
 * and every one of them adds the ROOT padding — 48px a side — inside a grid that
 * `.custodes-footer__inner` has already inset. Three columns x 96px spent 288px
 * of the 1200px footer on nested padding: the nav column had 168px for its links
 * and the "Gdje smo" column 221px, which is exactly why the maps button wrapped
 * onto two lines while every other button on the site is one line and 44px tall.
 */
.custodes-footer .has-global-padding {
	padding-inline: 0;
}

/* Layout: brand a touch wider than the two utility columns; collapses on mobile. */
.custodes-footer__inner {
	grid-template-columns: 1.5fr 1fr 1.2fr;
	gap: clamp( 2rem, 5vw, 4rem );
	align-items: start;
}
.custodes-footer__wordmark {
	margin: 0.1rem 0 0.85rem;
	text-transform: uppercase;
	letter-spacing: 0.05em;
}
.custodes-footer__brand p { color: rgba( 255, 255, 255, 0.62 ); }

/* Nav links: a gold arrow slides in on hover.
   list-style/padding live here rather than as an inline style on the <ul>:
   core/list's save() emits only the typography attributes, so any extra inline
   declaration makes the block parse as invalid in the editor. */
.custodes-footer__links {
	list-style: none;
	padding-left: 0;
}
.custodes-footer__links li { position: relative; }
.custodes-footer__links a {
	position: relative;
	display: inline-block;
	padding-left: 0;
	transition: color 0.2s var( --custodes-ease ), padding-left 0.2s var( --custodes-ease );
}
.custodes-footer__links a::before {
	content: "→";
	position: absolute;
	left: -1.1rem;
	opacity: 0;
	color: var( --wp--preset--color--accent );
	transition: opacity 0.2s var( --custodes-ease ), transform 0.2s var( --custodes-ease );
}
.custodes-footer__links a:hover { padding-left: 1.1rem; }
/* The links stacked with 0px between them on mobile — adjacent 33.7px targets
   touching edge to edge is a mis-tap waiting to happen. */
.custodes-footer__links li + li { margin-top: 0.35rem; }
/* 44px touch targets — the links were 33.7px tall.
   `pointer: coarse` as well as a width query: a landscape phone is 740px wide and
   was missed by width alone, but it is still a thumb. */
@media ( max-width: 700px ), ( pointer: coarse ) {
	.custodes-footer__links a,
	.custodes-footer__social a {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}
}
.custodes-footer__social a { padding-block: 0.3rem; }
.custodes-footer__links a:hover::before { opacity: 1; left: 0; }

.custodes-footer__social { margin-top: 1.35rem; gap: 0.55rem; }
.custodes-footer__social a {
	display: inline-flex;
	align-items: center;
	gap: 0.55rem;
	font-family: var( --wp--preset--font-family--display );
	letter-spacing: 0.03em;
}
.custodes-footer__social a::before {
	content: "";
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var( --wp--preset--color--accent );
	opacity: 0.7;
	transition: opacity 0.2s var( --custodes-ease );
}
.custodes-footer__social a:hover::before { opacity: 1; }

.custodes-footer__addr {
	font-family: var( --wp--preset--font-family--display );
	font-size: 1.2rem;
	line-height: 1.5;
	color: #fff;
	margin-bottom: 0.6rem;
}
.custodes-footer__hours .is-open { color: var( --wp--preset--color--accent ); font-weight: 600; }
.custodes-footer__hours .is-closed { color: rgba( 255, 255, 255, 0.5 ); }

/* Maps link as a gold ghost button — no embedded map. */
/* The footer's maps link is a SECONDARY button (Buttons section owns its look).
   It used to be a sixth hand-rolled button — its own 4px radius, 0.82rem type and
   0.04em tracking — and with an emoji plus an arrow in the label it wrapped to two
   lines in the footer column, 69px tall next to 44px buttons everywhere else. */
.custodes-footer__maplink { margin-top: 1.15rem; }

/* Bottom bar — same container AND the same gutter as the footer above it, so the
   copyright line starts on the same vertical as everything else. It previously
   ran edge-to-edge with no padding while the footer columns were inset. */
.custodes-footer__inner,
.custodes-footer__bar {
	padding-inline: var( --custodes-gutter );
}
.custodes-footer__bar {
	margin-top: clamp( 2.5rem, 5vw, 3.5rem );
	padding-top: 1.5rem;
	border-top: 1px solid rgba( 255, 255, 255, 0.08 );
	color: rgba( 255, 255, 255, 0.45 );
	gap: 0.75rem;
}
.custodes-footer__bar p { margin: 0; }

@media ( max-width: 700px ) {
	.custodes-footer__inner { grid-template-columns: 1fr; }
}

/* --------------------------------------------------- Calendar embed ---- */

/* The custodes-events plugin ships its own calendar.css; we only give the
   embed breathing room and let it inherit our type. */
.cev-wrap {
	font-family: var( --wp--preset--font-family--body );
}

/* The calendar renders on a dark panel and expects its headings to inherit
   white. Our theme.json heading colour (#151515) would otherwise win on the
   bare <h2>, turning the month title near-invisible on black — restore it. */
.cev-wrap .cev-title,
.cev-wrap :where( h1, h2, h3, h4 ) {
	color: #fff;
}

/* ------------------------------------------- Single event detail block --- */
/* The plugin injects .cev-single into the_content (light page). We upgrade it
   to match the game-card aesthetic: white card, game-colour left edge, the
   category logo on a white plate. Scoped under post-content to win over the
   plugin's calendar.css regardless of enqueue order. */
.wp-block-post-content .cev-single {
	background: #ffffff;
	border: 1px solid var( --wp--preset--color--line );
	border-radius: 10px;
	box-shadow: 0 12px 34px rgba( 0, 0, 0, 0.07 );
	padding: clamp( 1.25rem, 3vw, 2rem );
	gap: clamp( 1.1rem, 3vw, 2rem );
	align-items: center;
}
.wp-block-post-content .cev-single-logowrap {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 132px;
	height: 96px;
	padding: 12px 16px;
	background: #fff;
	border: 1px solid var( --wp--preset--color--line );
	border-radius: 8px;
}
.wp-block-post-content .cev-single-logo {
	width: auto !important;
	height: auto !important;
	max-width: 100% !important;
	max-height: 72px;
	object-fit: contain;
}
.wp-block-post-content .cev-single-meta {
	flex: 1 1 240px;
}
.wp-block-post-content .cev-single-meta li {
	font-size: 1rem;
	line-height: 1.7;
}
.wp-block-post-content .cev-single-meta li strong {
	font-family: var( --wp--preset--font-family--display );
	font-weight: 400;
	color: var( --wp--preset--color--muted );
	margin-right: 0.35rem;
}
.wp-block-post-content .cev-single-game {
	font-family: var( --wp--preset--font-family--body );
	letter-spacing: 0.02em;
}
/* Colour/type come from the TEXT button style; only its place in the card's flex
   row belongs here. */
.wp-block-post-content .cev-single-back {
	flex: 1 1 100%;
	margin-top: 0.4rem;
}
.custodes-calendar-section .cev-wrap {
	margin-inline: auto;
}

/*
 * Reclaim the phone's width for the calendar.
 *
 * On /raspored/ the padding stacks three deep: the root group adds 20px, core
 * re-applies root padding to the alignfull .entry-content (another 20px), then
 * .cev-wrap adds its own 14px. On a 360px screen that left the agenda just 250px
 * — 30% of the viewport spent on nested gutters, on the site's primary mobile
 * view. Nothing was clipped, it was simply cramped.
 *
 * Below 600px the wrapper pulls back out through the inner padding and trims its
 * own, so the agenda gets the full content width instead.
 */
@media ( max-width: 600px ) {
	/* `body.custodes-dark-ui .cev-wrap { margin-inline: auto }` is (0,2,1), so the
	   body selector is repeated here to outrank it — without it only the padding
	   applied and the wrapper stayed put. */
	body.custodes-dark-ui .entry-content > .cev-wrap,
	body.custodes-dark-ui .wp-block-post-content > .cev-wrap,
	body .custodes-calendar-section .cev-wrap {
		/* !important is required, not lazy: core's constrained-layout rule
		   `.is-layout-constrained > :where(:not(.alignleft)…)` sets
		   `margin-left: auto !important`, which no amount of specificity beats.
		   Padding and max-width above win normally; only the margin needs this. */
		margin-inline: -20px !important;
		padding-inline: 10px;
		border-radius: 0;
		max-width: none;
		/*
		 * `width: auto` is what makes the negative margins symmetrical.
		 *
		 * .cev-wrap carries `width: 100%` from the shared container rule at the top
		 * of this file. With border-box that pinned the box to the parent's content
		 * width, so `margin-inline: -20px` could only SHIFT it left — the calendar
		 * ended flush to the left screen edge with 40px of dead gutter down the
		 * right-hand side. Letting the width resolve from the margins pulls both
		 * edges out equally.
		 */
		width: auto;
	}
}

/* ------------------------------------------------- Core pagination ---- */

/* Core's pager (index/archive/search render wp:query-pagination) is a SECONDARY
   button row — see the Buttons section, which owns its look. Unstyled, each
   number used to be a 9.2 x 22px inline link, effectively untappable; the
   44px tap target now comes from the shared button box. Only the gap is here. */
.wp-block-query-pagination { gap: 0.4rem; }

/* ========================================================== Buttons ==== *
 * ONE button component, THREE styles — and everything that acts like a button
 * uses it: core buttons, the calendar's view tabs and month arrows, both pagers
 * (core's and the plugin's), and the back / previous / next links.
 *
 * Before this there were five separate hand-rolled implementations. They
 * disagreed on border-radius (2px / 4px / 5px / 6px / 50%), on font-size
 * (0.72 / 0.78 / 0.82rem / --small), on min-height (none / 2.4rem / 40px / 44px)
 * and on what hover does — so no two controls on the site matched, and the
 * calendar's tabs looked like a different product from the buttons above them.
 *
 *   primary    (the default)                  gold fill, dark ink
 *   secondary  .is-style-outline + tabs/pagers  light ghost, hairline border
 *   text       .is-style-text + back/prev/next  no box at all
 *
 * Every front-end page is dark — `body.custodes-dark-ui` on all of them and
 * `.custodes-home` on the front page (see custodes_body_classes) — so the styles
 * need NO per-context variants. That is what let four near-identical
 * `.is-style-outline` blocks (dark band / hero / home / dark-ui) collapse to one.
 *
 * Plugin classes are addressed as `.cev-wrap .cev-*` (two classes) so they beat
 * the plugin's own single-class rules whichever stylesheet loads last.
 * ======================================================================== */

:root {
	--custodes-btn-radius: 3px;
	--custodes-btn-py: 0.8rem;
	--custodes-btn-px: 1.5rem;
	/* 13px. The audit set an 11px floor for small UI text; the old buttons ranged
	   from 9.9px to 14px, and 13px is legible while still reading as a control. */
	--custodes-btn-size: 0.8125rem;
	--custodes-btn-tracking: 0.08em;
	--custodes-btn-tap: 44px;
	--custodes-btn-fill: linear-gradient( 180deg, #d9b24e 0%, #b8912e 55%, #9c7a22 100% );
	--custodes-btn-fill-hover: linear-gradient( 180deg, #e7c161 0%, #c89c34 55%, #a9862a 100% );
	--custodes-btn-ink: #14100a;
	--custodes-btn-ghost-ink: #fff;
	--custodes-btn-ghost-line: rgba( 255, 255, 255, 0.32 );
}

/* ---- Shared by all three styles: type, hit area, motion ---- */
.wp-element-button,
.wp-block-button__link,
.cev-wrap .cev-switch-btn,
.cev-wrap .cev-nav,
.cev-gs .cev-gs-page,
.cev-gs .cev-gs-back,
.cev-single .cev-single-back,
.wp-block-post-content .cev-single-back,
.wp-block-query-pagination .page-numbers,
.wp-block-query-pagination-previous,
.wp-block-query-pagination-next,
.custodes-footer__maplink a,
.custodes-postnav .wp-block-post-navigation-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.45rem;
	font-family: var( --wp--preset--font-family--body );
	font-size: var( --custodes-btn-size );
	font-weight: 600;
	line-height: 1.2;
	letter-spacing: var( --custodes-btn-tracking );
	text-transform: uppercase;
	text-decoration: none;
	text-align: center;
	transition:
		color 0.2s var( --custodes-ease ),
		background 0.2s var( --custodes-ease ),
		border-color 0.2s var( --custodes-ease ),
		box-shadow 0.2s var( --custodes-ease ),
		transform 0.2s var( --custodes-ease );
}

/* ---- Shared box: primary + secondary (the text style has none) ---- */
.wp-element-button,
.wp-block-button__link,
.cev-wrap .cev-switch-btn,
.cev-wrap .cev-nav,
.cev-gs .cev-gs-page,
.wp-block-query-pagination .page-numbers,
.wp-block-query-pagination-previous,
.wp-block-query-pagination-next,
.custodes-footer__maplink a {
	box-sizing: border-box;
	min-height: var( --custodes-btn-tap );
	padding: var( --custodes-btn-py ) var( --custodes-btn-px );
	border: 1px solid transparent;
	border-radius: var( --custodes-btn-radius );
}

/* ---- Style 1 — PRIMARY: the main action on the page ----
   Also the "selected" state of the two switchers, so "this is where you are"
   and "this is the main action" read as the same visual weight. */
.wp-element-button,
.wp-block-button__link,
.cev-wrap .cev-switch-btn.is-active,
.cev-gs .cev-gs-page.is-current,
.wp-block-query-pagination .page-numbers.current {
	background: var( --custodes-btn-fill );
	color: var( --custodes-btn-ink );
	border-color: rgba( 255, 255, 255, 0.18 );
	box-shadow: 0 8px 22px rgba( 184, 145, 46, 0.28 );
}
.wp-element-button:hover,
.wp-element-button:focus-visible,
.wp-block-button__link:hover,
.wp-block-button__link:focus-visible {
	background: var( --custodes-btn-fill-hover );
	color: var( --custodes-btn-ink );
	border-color: rgba( 255, 255, 255, 0.3 );
	transform: translateY( -2px );
}
/* A selected tab is not a target — it must not lift or brighten on hover. */
.cev-wrap .cev-switch-btn.is-active,
.cev-gs .cev-gs-page.is-current,
.wp-block-query-pagination .page-numbers.current {
	cursor: default;
	transform: none;
}

/* ---- Style 2 — SECONDARY: the alternative action, and every unselected
   tab / page number. A hairline ghost so it never competes with the primary. */
.wp-block-button.is-style-outline .wp-block-button__link,
.cev-wrap .cev-switch-btn,
.cev-wrap .cev-nav,
.cev-gs .cev-gs-page,
.wp-block-query-pagination .page-numbers,
.wp-block-query-pagination-previous,
.wp-block-query-pagination-next,
.custodes-footer__maplink a {
	background: rgba( 255, 255, 255, 0.04 );
	color: var( --custodes-btn-ghost-ink );
	border-color: var( --custodes-btn-ghost-line );
	box-shadow: none;
}
.wp-block-button.is-style-outline .wp-block-button__link:hover,
.wp-block-button.is-style-outline .wp-block-button__link:focus-visible,
.cev-wrap a.cev-switch-btn:hover,
.cev-wrap a.cev-switch-btn:focus-visible,
.cev-wrap a.cev-nav:hover,
.cev-wrap a.cev-nav:focus-visible,
.cev-gs a.cev-gs-page:hover,
.cev-gs a.cev-gs-page:focus-visible,
.wp-block-query-pagination a.page-numbers:hover,
.wp-block-query-pagination a.page-numbers:focus-visible,
.wp-block-query-pagination-previous:hover,
.wp-block-query-pagination-next:hover,
.custodes-footer__maplink a:hover,
.custodes-footer__maplink a:focus-visible {
	/* Deliberately NOT a gold fill: that is the selected/primary look, and a
	   gold-filling hover made "hovered" and "selected" indistinguishable. */
	background: rgba( 184, 145, 46, 0.12 );
	color: #f4dc92;
	border-color: var( --wp--preset--color--accent );
	transform: translateY( -2px );
}

/* Icon-only secondary: the month arrows. Square, matching the radius of every
   other control — as circles they were the one shape nothing else shared. */
.cev-wrap .cev-nav {
	flex: none;
	width: var( --custodes-btn-tap );
	height: var( --custodes-btn-tap );
	padding: 0;
	border-radius: var( --custodes-btn-radius );
	font-size: 1.05rem;
	letter-spacing: 0;
}
/* Numeric pagination stays compact but keeps the 44px tap target. */
.cev-gs .cev-gs-page,
.wp-block-query-pagination .page-numbers {
	min-width: var( --custodes-btn-tap );
	padding-inline: 0.7rem;
}
.cev-gs .cev-gs-page.is-disabled {
	opacity: 0.35;
	cursor: default;
	transform: none;
}

/* ---- Style 3 — TEXT: no box, for in-flow "back" and prev/next links.
   Same family, size, tracking and casing as the other two, so a text button is
   recognisably the same component with its box removed — not a stray link. */
.wp-block-button.is-style-text .wp-block-button__link,
.cev-gs .cev-gs-back,
.cev-single .cev-single-back,
.wp-block-post-content .cev-single-back,
.custodes-postnav .wp-block-post-navigation-link {
	min-height: 0;
	padding: 0.35rem 0;
	border: 0;
	border-radius: 0;
	background: none;
	box-shadow: none;
	color: var( --wp--preset--color--accent );
}
.wp-block-button.is-style-text .wp-block-button__link:hover,
.wp-block-button.is-style-text .wp-block-button__link:focus-visible,
.cev-gs .cev-gs-back:hover,
.cev-gs .cev-gs-back:focus-visible,
.cev-single .cev-single-back:hover,
.cev-single .cev-single-back:focus-visible,
.wp-block-post-content .cev-single-back:hover,
.custodes-postnav .wp-block-post-navigation-link:hover,
.custodes-postnav .wp-block-post-navigation-link:focus-within {
	background: none;
	color: #f4dc92;
	transform: none;
}

/* ===================================================== Homepage (dark) ==== *
 * The front page joins the dark, gold aesthetic. The hero + Warhammer bands are
 * already dark; here the remaining light sections lose their fills, text inverts,
 * and the game / stat / hours / news boxes become dark gaming cards.
 * ========================================================================== */

/* Light section fills fall away so the dark backdrop shows through. */
.custodes-home .has-surface-background-color { background-color: transparent !important; }

/* Text inversion inside the page content. */
.custodes-home :where( h1, h2, h3, h4 ) { color: #fff; }
.custodes-home :where( p, li ) { color: rgba( 255, 255, 255, 0.76 ); }
.custodes-home .custodes-eyebrow { color: var( --wp--preset--color--accent ); }

/* --- Game cards → dark boxes with a light logo plate + gold detailing --- */
.custodes-home .custodes-game-card {
	background: linear-gradient( 180deg, rgba( 30, 30, 34, 0.92 ), rgba( 18, 18, 21, 0.94 ) );
	border: 1px solid rgba( 184, 145, 46, 0.16 );
	border-top: 3px solid var( --game );
	color: #fff;
	/* Logo image runs full-bleed from the top; only the bottom keeps padding. */
	padding: 0 0 0.9rem;
	/*
	 * One height for every card.
	 *
	 * `align-items: stretch` already equalises cards that SHARE a flex line, but
	 * the last line often holds a single card, and on a phone every card is alone
	 * on its line — so a logo-less card had nothing to stretch against and sat
	 * visibly shorter than the cards above it.
	 *
	 * The terms below ARE a logo card's stack, so the floor equals the natural
	 * height rather than guessing at it. Note the plate is content-box (see
	 * __logo below), which is why its padding is counted separately. Keep these in
	 * step if the plate height, the gap or the name's line count changes:
	 */
	min-height: calc(
		108px      /* logo plate                                */
		+ 1.7rem   /* plate padding, top + bottom               */
		+ 0.65rem  /* gap between plate and name                 */
		+ 2.52rem  /* name: min-height 2.4em at 1.05rem          */
		+ 0.9rem   /* card padding-bottom                        */
		+ 4px      /* border-top 3px + border-bottom 1px         */
	);
	justify-content: flex-start;
	gap: 0.65rem;
}
.custodes-home .custodes-game-card:hover,
.custodes-home .custodes-game-card:focus-visible {
	border-color: var( --game );
	box-shadow: 0 18px 40px rgba( 0, 0, 0, 0.5 );
}
.custodes-home .custodes-game-card:hover::before,
.custodes-home .custodes-game-card:focus-visible::before { opacity: 0.14; }
/* Full-width light logo plate, flush to the top + sides so logos read big. */
/* One fixed plate height for every card. `aspect-ratio: 5/3` with `height:auto`
   used to size each plate from the column width, so plates measured 109/130/136/181px
   and the grid looked ragged. A fixed height means every logo sits on an identical
   white panel and the wordmarks line up across rows. */
.custodes-home .custodes-game-card__logo {
	width: 100%;
	height: 108px;
	aspect-ratio: auto;
	background: #ffffff;
	border: 0;
	border-radius: 0;
	padding: 0.85rem 1rem;
	margin: 0;
}
.custodes-home .custodes-game-card__logo img {
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
}
/* Text-only cards have no plate to fill the top, so they centre their name in
   the whole card instead — the look the club signed off on for Naruto Mythos. */
.custodes-home .custodes-game-card--text {
	padding: 1.4rem 1rem;
	justify-content: center;
}
/* The dark card has no horizontal padding of its own (the plate is full-bleed),
   so the name supplies its own gutter. */
.custodes-home .custodes-game-card__name {
	color: #fff;
	padding-inline: 0.85rem;
}

/* --- Stat counters --- */
.custodes-home .custodes-stat__num { color: #e7c161; }
.custodes-home .custodes-stat__label { color: rgba( 255, 255, 255, 0.6 ); }

/* --- Opening hours --- */
.custodes-home .custodes-hours__day {
	background: rgba( 255, 255, 255, 0.025 );
	border-color: rgba( 184, 145, 46, 0.2 );
}
.custodes-home .custodes-hours__day strong { color: #fff; }
.custodes-home .custodes-hours__day.is-open {
	border-color: rgba( 184, 145, 46, 0.6 );
	background: rgba( 184, 145, 46, 0.08 );
}
.custodes-home .custodes-hours__day.is-closed {
	color: rgba( 255, 255, 255, 0.4 );
	background: rgba( 255, 255, 255, 0.015 );
}

/* --- News post cards --- */
.custodes-home .custodes-postcard {
	background: linear-gradient( 180deg, rgba( 26, 26, 30, 0.9 ), rgba( 18, 18, 21, 0.92 ) );
	border: 1px solid rgba( 184, 145, 46, 0.16 );
}
.custodes-home .custodes-postcard:hover {
	box-shadow: 0 16px 36px rgba( 0, 0, 0, 0.5 );
	border-color: rgba( 184, 145, 46, 0.4 );
}
.custodes-home .custodes-postcard :where( h1, h2, h3, a ) { color: #fff; }
.custodes-home .custodes-postcard a:hover { color: var( --wp--preset--color--accent ); }

/* --- Find-us card (no map) --- */
.custodes-find__card {
	background: linear-gradient( 180deg, rgba( 26, 26, 30, 0.9 ), rgba( 18, 18, 21, 0.92 ) );
	border: 1px solid rgba( 184, 145, 46, 0.28 );
	border-radius: 12px;
	box-shadow: 0 22px 54px rgba( 0, 0, 0, 0.45 );
	padding: clamp( 1.75rem, 4vw, 2.75rem );
}
.custodes-find__card .custodes-find__addr {
	font-family: var( --wp--preset--font-family--display );
	font-size: 1.4rem;
	color: #fff;
	margin-bottom: 0.55rem;
}
.custodes-find__card .custodes-find__hours .is-open { color: var( --wp--preset--color--accent ); font-weight: 600; }
.custodes-find__card .custodes-find__hours .is-closed { color: rgba( 255, 255, 255, 0.5 ); }

/* ============================================================= Motion ==== *
 * Delight layer. Every initial-hidden state is gated behind `html.custodes-anim`
 * (added by an inline head script only when the visitor hasn't asked for reduced
 * motion), so no-JS and reduced-motion users always see fully-rendered content.
 * ========================================================================== */

@keyframes custodesFadeUp {
	from { opacity: 0; transform: translateY( 22px ); }
	to   { opacity: 1; transform: none; }
}
@keyframes custodesFadeIn {
	from { opacity: 0; }
	to   { opacity: 1; }
}
@keyframes custodesOverlayIn {
	from { opacity: 0; }
	to   { opacity: 1; }
}

/* Anchor targets clear the sticky header when jumped to. */
[id] { scroll-margin-top: 96px; }
html { scroll-behavior: smooth; }

/* --- Scroll reveal for homepage (and card) sections --- */
.custodes-anim .custodes-reveal {
	opacity: 0;
	transform: translateY( 28px );
	transition: opacity 0.8s var( --custodes-ease ), transform 0.8s var( --custodes-ease );
	will-change: opacity, transform;
}
.custodes-anim .custodes-reveal.is-visible {
	opacity: 1;
	transform: none;
}

/* Cards inside a revealed section fade in on a stagger (opacity only, so the
   hover lift/transform stays unconflicted). --reveal-i is set per card in JS. */
.custodes-anim .custodes-reveal .custodes-game-card,
.custodes-anim .custodes-reveal .custodes-postcard,
.custodes-anim .custodes-reveal .custodes-stat {
	opacity: 0;
}
.custodes-anim .custodes-reveal.is-visible .custodes-game-card,
.custodes-anim .custodes-reveal.is-visible .custodes-postcard,
.custodes-anim .custodes-reveal.is-visible .custodes-stat {
	animation: custodesFadeIn 0.55s var( --custodes-ease ) both;
	animation-delay: calc( var( --reveal-i, 0 ) * 0.06s );
}

/* --- Hero entrance (runs on load; children are not hovered) --- */
.custodes-anim .custodes-hero .wp-block-cover__inner-container > * {
	animation: custodesFadeUp 0.8s var( --custodes-ease ) both;
}
.custodes-anim .custodes-hero h1                      { animation-delay: 0.15s; }
.custodes-anim .custodes-hero .custodes-hero__tagline { animation-delay: 0.29s; }
.custodes-anim .custodes-hero .wp-block-buttons       { animation-delay: 0.43s; }

/* The button hover lift lives in the Buttons section now, so that every control
   using the component gets it — not just core's `.wp-block-button__link`. */

/* --- Count-up numbers get a gentle pop when they land --- */
.custodes-stat__num { transition: transform 0.3s var( --custodes-ease ); }
.custodes-stat.is-counted .custodes-stat__num { animation: custodesPop 0.4s var( --custodes-ease ); }
@keyframes custodesPop {
	0%   { transform: scale( 1 ); }
	45%  { transform: scale( 1.08 ); }
	100% { transform: scale( 1 ); }
}

/* ==================================================== Game schedule ==== *
 * Per-game tournament archive (taxonomy-custodes_game). A fully dark, gold
 * art-deco-framed page over an atmospheric city-texture backdrop. Event data
 * (dates, times, game colour, logo) comes from the custodes-events plugin's
 * [custodes_game_schedule] block; everything below is the look.
 * ======================================================================== */

/* ---- Dark page + textured backdrop (archive, calendar, homepage) ----
 *
 * `.custodes-home` is the <main> of templates/front-page.html, so this backdrop
 * reaches BOTH pipelines: the front end and the editor canvas. The body-level
 * rules stay for the front end only — they paint the area outside <main> (behind
 * the header and below the footer) — but they can never apply in the editor,
 * because body_class() is a front-end template function and the canvas body is
 * `.editor-styles-wrapper`. Anything the client must SEE while editing has to
 * hang off a class that exists in the markup, not off the body.
 */
body.custodes-dark-ui,
body.home,
.custodes-home {
	background-color: #08080a;
	/* Warm vignette + faint gold deco weave, fixed so it stays put on scroll. */
	background-image:
		radial-gradient( 120% 60% at 50% 0%, rgba( 184, 145, 46, 0.14 ) 0%, rgba( 184, 145, 46, 0 ) 60% ),
		radial-gradient( 90% 55% at 50% 100%, rgba( 20, 16, 8, 0.55 ) 0%, rgba( 8, 8, 10, 0 ) 70% ),
		repeating-linear-gradient( 45deg, rgba( 184, 145, 46, 0.035 ) 0 1px, transparent 1px 22px ),
		repeating-linear-gradient( -45deg, rgba( 184, 145, 46, 0.035 ) 0 1px, transparent 1px 22px );
	background-attachment: fixed;
}
/*
 * No ghosted hero image behind this page.
 *
 * It used to paint `hero-1200.webp` at 0.14 opacity across the top 620px via a
 * `::before` (which is why `position`/`isolation` were here — to contain its
 * `z-index: -1`). Two problems: the image began at the top of <main>, so it drew
 * a hard horizontal seam right under the header that read as a header
 * background; and the homepage hero showing up again, greyed and cropped, behind
 * a per-game schedule was just noise. The body's gold vignette already gives
 * these pages their atmosphere.
 *
 * The top padding is what keeps the gold frame clear of the sticky header — the
 * frame's own margin was the only gap before, and it was not enough.
 */
.custodes-game-archive {
	padding-top: var( --wp--preset--spacing--40 );
	padding-bottom: var( --wp--preset--spacing--60 );
}

/* ---- Transparent header over the dark pages ---- */
body.custodes-dark-ui .custodes-header {
	background: transparent;
	border-bottom-color: transparent;
}
/* On scroll, a whisper of dark blur so the logo/menu stay crisp over content. */
body.custodes-dark-ui .custodes-header.is-scrolled {
	background: rgba( 8, 8, 10, 0.72 );
	backdrop-filter: saturate( 140% ) blur( 9px );
	-webkit-backdrop-filter: saturate( 140% ) blur( 9px );
	border-bottom-color: rgba( 184, 145, 46, 0.16 );
}
/* Balanced breathing room: the gap left/right of the logo + hamburger matches
   the gap above/below them. */
.custodes-header .wp-block-group {
	padding-block: 1.15rem;
	padding-inline: clamp( 1.15rem, 4vw, 2.25rem );
}

/* ---- Shared dark-UI content ---- */
body.custodes-dark-ui {
	color: rgba( 255, 255, 255, 0.8 );
	/* Inner pages lay out to the SITE container, not the 760px prose default.
	   Without this the calendar page capped its own content at 760 and the
	   calendar rendered 664px wide inside a 1440px window — one more width. */
	--wp--style--global--content-size: var( --custodes-container );
}
/* The calendar page's post-content is alignfull, so core re-applies root padding
   to it — on top of the gutter the outer group already provides. That double
   gutter is what left the calendar at 1104px starting at 161 while every other
   band sat at 1200 starting at 113. */
body.custodes-calendar-page .wp-block-post-content.has-global-padding {
	padding-inline: 0;
}

/* Prose keeps a readable measure, centred inside the 1200px container — consistent
   edges without 1200px-long lines of text. */
body.custodes-dark-ui .custodes-post-body .wp-block-post-content > *:not(.alignwide):not(.alignfull):not(.wp-block-image) {
	max-width: var( --custodes-measure );
	margin-inline: auto;
}

/* Blog index, archives, search and single posts are dark like the rest of the
   site. Cards, prose and meta all need inverting — these pages were the only
   white ones left and read as a different website mid-visit. */
body.custodes-dark-ui .custodes-postcard {
	background: linear-gradient( 180deg, rgba( 26, 26, 30, 0.9 ), rgba( 18, 18, 21, 0.92 ) );
	border: 1px solid rgba( 184, 145, 46, 0.16 );
}
body.custodes-dark-ui .custodes-postcard:hover {
	box-shadow: 0 16px 36px rgba( 0, 0, 0, 0.5 );
	border-color: rgba( 184, 145, 46, 0.4 );
}
body.custodes-dark-ui .custodes-postcard :where( h1, h2, h3, a ) { color: #fff; }
body.custodes-dark-ui .custodes-postcard a:hover { color: var( --wp--preset--color--accent ); }
body.custodes-dark-ui .custodes-postcard .wp-block-post-date,
body.custodes-dark-ui .custodes-postcard .wp-block-post-excerpt { color: rgba( 255, 255, 255, 0.7 ); }
body.custodes-dark-ui .wp-block-post-content :where( p, li ) { color: rgba( 255, 255, 255, 0.82 ); }
body.custodes-dark-ui .wp-block-post-terms,
body.custodes-dark-ui .wp-block-post-date,
body.custodes-dark-ui .wp-block-post-author-name { color: rgba( 255, 255, 255, 0.65 ); }
body.custodes-dark-ui .wp-block-separator { border-color: rgba( 184, 145, 46, 0.25 ); }
/* The dark title band would otherwise sit as a lighter box on the dark page. */
body.custodes-dark-ui .custodes-dark { background-color: transparent !important; }
body.custodes-dark-ui :where( h1, h2, h3, h4 ) { color: #fff; }
body.custodes-dark-ui .wp-block-post-content { color: rgba( 255, 255, 255, 0.8 ); }
/*
 * Gold links in PROSE — and prose only.
 *
 * On /raspored/ the whole calendar lives inside the_content, so this rule used to
 * repaint its controls: the active view tab became gold text on the gold fill
 * (1.3:1 — the label was invisible) and the inactive tabs turned gold instead of
 * white, which is why the switcher looked nothing like the identical control on
 * the homepage, where the calendar sits in a template part and never met it.
 *
 * The exclusion list is what keeps that from coming back: anything that is a
 * BUTTON or a CARD owns its own colour (see the Buttons section). All the
 * selectors inside :not() are simple class selectors on purpose — no nesting, so
 * it needs no modern-:not() support.
 */
body.custodes-dark-ui .wp-block-post-content a:not( .wp-element-button ):not( .cev-switch-btn ):not( .cev-nav ):not( .cev-gs-page ):not( .cev-gs-back ):not( .cev-single-back ):not( .cev-chip ):not( .cev-gs-card ) {
	color: var( --wp--preset--color--accent );
}
/* width now comes from the shared container at the top of this file */
/* Title bands blend into the dark page instead of reading as a lighter box. */
body.custodes-dark-ui .custodes-dark.has-dark-background-color {
	background-color: transparent !important;
}

/* Single-event detail card → dark (overrides the light-page card defined below). */
body.custodes-dark-ui .wp-block-post-content .cev-single {
	background: linear-gradient( 180deg, rgba( 26, 26, 30, 0.92 ), rgba( 18, 18, 21, 0.92 ) );
	border: 1px solid rgba( 184, 145, 46, 0.3 );
	box-shadow: 0 22px 54px rgba( 0, 0, 0, 0.5 );
}
body.custodes-dark-ui .wp-block-post-content .cev-single-logowrap {
	background: #fff;
	border-color: rgba( 255, 255, 255, 0.15 );
}
body.custodes-dark-ui .wp-block-post-content .cev-single-meta li { color: rgba( 255, 255, 255, 0.85 ); }
body.custodes-dark-ui .wp-block-post-content .cev-single-meta li strong { color: var( --wp--preset--color--accent ); }
/* ---- Gold art-deco frame ---- */
.custodes-gs-frame {
	position: relative;
	margin-top: var( --wp--preset--spacing--50 );
	border: 1px solid rgba( 184, 145, 46, 0.5 );
	border-radius: 3px;
	background:
		linear-gradient( 180deg, rgba( 23, 23, 26, 0.72 ) 0%, rgba( 10, 10, 12, 0.82 ) 100% );
	box-shadow:
		inset 0 0 0 5px rgba( 8, 8, 10, 0.55 ),
		inset 0 0 0 6px rgba( 184, 145, 46, 0.28 ),
		0 34px 90px rgba( 0, 0, 0, 0.6 );
}
/* Four crisp corner brackets, painted just inside the double border. */
.custodes-gs-frame::before {
	content: "";
	position: absolute;
	inset: 11px;
	pointer-events: none;
	--l: 30px;   /* arm length */
	--t: 2px;    /* thickness  */
	--c: rgba( 184, 145, 46, 0.9 );
	background:
		linear-gradient( var( --c ), var( --c ) ) left top / var( --l ) var( --t ) no-repeat,
		linear-gradient( var( --c ), var( --c ) ) left top / var( --t ) var( --l ) no-repeat,
		linear-gradient( var( --c ), var( --c ) ) right top / var( --l ) var( --t ) no-repeat,
		linear-gradient( var( --c ), var( --c ) ) right top / var( --t ) var( --l ) no-repeat,
		linear-gradient( var( --c ), var( --c ) ) left bottom / var( --l ) var( --t ) no-repeat,
		linear-gradient( var( --c ), var( --c ) ) left bottom / var( --t ) var( --l ) no-repeat,
		linear-gradient( var( --c ), var( --c ) ) right bottom / var( --l ) var( --t ) no-repeat,
		linear-gradient( var( --c ), var( --c ) ) right bottom / var( --t ) var( --l ) no-repeat;
}

/* ---- Frame header ---- */
.custodes-gs-head { position: relative; }
.custodes-game-archive .custodes-gs-head h1 {
	color: #fff;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	margin-top: 0.35rem;
	text-shadow: 0 2px 30px rgba( 0, 0, 0, 0.6 );
}
/* Gold hairline flourish under the game title. */
.custodes-gs-head h1::after {
	content: "";
	display: block;
	width: 72px;
	height: 2px;
	margin: 0.8rem auto 0;
	background: linear-gradient( 90deg, transparent, var( --wp--preset--color--accent ), transparent );
}
.custodes-game-archive .custodes-gs-desc {
	color: rgba( 255, 255, 255, 0.66 );
	max-width: 56ch;
	margin-inline: auto;
	margin-top: 0.9rem;
}

/* The gold primary button used to need an opt-in class here (.custodes-btn-gold),
   because the theme.json default was a dark fill that only suited a light page —
   and no page here is light. Gold IS the default now (see the Buttons section),
   so the class is gone from theme.json, the CSS and the two patterns that used it. */

/* ---- Stat bar ---- */
.cev-gs {
	--game: var( --wp--preset--color--accent ); /* fallback; inline style sets the real game colour */
	margin-top: var( --wp--preset--spacing--40 );
}
.cev-gs-stats {
	display: grid;
	grid-template-columns: repeat( 3, 1fr );
	gap: clamp( 0.5rem, 2vw, 1rem );
	margin-bottom: var( --wp--preset--spacing--40 );
}
.cev-gs-stat {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0.35rem;
	padding: 1rem 0.75rem;
	text-align: center;
	background: rgba( 255, 255, 255, 0.025 );
	border: 1px solid rgba( 184, 145, 46, 0.22 );
	border-radius: 4px;
}
.cev-gs-stat-num {
	font-family: var( --wp--preset--font-family--display );
	font-size: clamp( 1.75rem, 4vw, 2.5rem );
	line-height: 1;
	color: var( --wp--preset--color--accent );
}
.cev-gs-stat-next {
	font-size: clamp( 1rem, 2.4vw, 1.4rem );
	letter-spacing: 0.01em;
}
.cev-gs-stat-label {
	font-family: var( --wp--preset--font-family--body );
	font-size: 0.72rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: rgba( 255, 255, 255, 0.55 );
}

/* ---- Section + month headings ---- */
.cev-gs-h {
	font-family: var( --wp--preset--font-family--display );
	font-size: var( --wp--preset--font-size--large );
	color: #fff;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	margin: 0 0 1rem;
	display: flex;
	align-items: center;
	gap: 0.9rem;
}
.cev-gs-h::after {
	content: "";
	flex: 1;
	height: 1px;
	background: linear-gradient( 90deg, rgba( 184, 145, 46, 0.5 ), transparent );
}
.cev-gs-month {
	font-family: var( --wp--preset--font-family--body );
	font-size: 0.78rem;
	font-weight: 700;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: var( --wp--preset--color--accent );
	margin: 1.6rem 0 0.75rem;
}
.cev-gs-group:first-child .cev-gs-month { margin-top: 0; }

/* ---- Event list + cards ---- */
.cev-gs-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.6rem;
}
.cev-gs-card {
	position: relative;
	display: flex;
	align-items: center;
	gap: clamp( 0.85rem, 2.5vw, 1.35rem );
	padding: 0.85rem 1rem 0.85rem 0.85rem;
	text-decoration: none;
	color: #fff;
	background: linear-gradient( 180deg, rgba( 26, 26, 30, 0.9 ), rgba( 18, 18, 21, 0.9 ) );
	border: 1px solid rgba( 255, 255, 255, 0.07 );
	border-left: 4px solid var( --game );
	border-radius: 6px;
	overflow: hidden;
	transition: transform 0.2s var( --custodes-ease ), border-color 0.2s var( --custodes-ease ), box-shadow 0.2s var( --custodes-ease ), background 0.2s var( --custodes-ease );
}
/* Faint game-colour wash that lifts on hover. */
.cev-gs-card::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient( 90deg, var( --game ), transparent 60% );
	opacity: 0.06;
	transition: opacity 0.2s var( --custodes-ease );
	pointer-events: none;
}
a.cev-gs-card:hover,
a.cev-gs-card:focus-visible {
	transform: translateX( 4px );
	border-color: rgba( 184, 145, 46, 0.55 );
	box-shadow: -6px 0 0 -2px var( --game ), 0 16px 34px rgba( 0, 0, 0, 0.45 );
	background: linear-gradient( 180deg, rgba( 32, 32, 37, 0.95 ), rgba( 22, 22, 26, 0.95 ) );
}
a.cev-gs-card:hover::before,
a.cev-gs-card:focus-visible::before { opacity: 0.12; }

/* Date badge — a gold "ticket stub". */
.cev-gs-date {
	flex: 0 0 auto;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	width: 58px;
	padding: 0.45rem 0;
	border-radius: 5px;
	background: linear-gradient( 180deg, rgba( 184, 145, 46, 0.22 ), rgba( 184, 145, 46, 0.08 ) );
	border: 1px solid rgba( 184, 145, 46, 0.4 );
	line-height: 1;
}
.cev-gs-dow {
	/* 11px floor: was 0.62rem (9.92px). */
	font-size: 0.6875rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: rgba( 231, 193, 97, 0.85 );
}
.cev-gs-day {
	font-family: var( --wp--preset--font-family--display );
	font-size: 1.7rem;
	color: #f4dc92;
	margin: 0.05rem 0;
}
.cev-gs-mon {
	/* 11px floor: was 0.66rem (10.56px). */
	font-size: 0.6875rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: rgba( 231, 193, 97, 0.85 );
}

.cev-gs-main {
	flex: 1 1 auto;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
}
.cev-gs-title {
	font-family: var( --wp--preset--font-family--display );
	font-size: 1.2rem;
	line-height: 1.2;
	color: #fff;
	letter-spacing: 0.01em;
}
.cev-gs-meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem 1rem;
	font-family: var( --wp--preset--font-family--body );
	font-size: 0.82rem;
	color: rgba( 255, 255, 255, 0.6 );
}
.cev-gs-time {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	color: var( --wp--preset--color--accent );
	font-variant-numeric: tabular-nums;
	letter-spacing: 0.02em;
}
.cev-gs-ico { opacity: 0.9; }

.cev-gs-go {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	border-radius: 50%;
	color: var( --wp--preset--color--accent );
	border: 1px solid rgba( 184, 145, 46, 0.3 );
	transition: transform 0.2s var( --custodes-ease ), background 0.2s var( --custodes-ease ), color 0.2s var( --custodes-ease );
}
a.cev-gs-card:hover .cev-gs-go,
a.cev-gs-card:focus-visible .cev-gs-go {
	background: var( --wp--preset--color--accent );
	color: #14100a;
	transform: translateX( 3px );
}

/* Empty state. */
.cev-gs-empty {
	padding: 1.5rem;
	text-align: center;
	color: rgba( 255, 255, 255, 0.7 );
	background: rgba( 255, 255, 255, 0.025 );
	border: 1px dashed rgba( 184, 145, 46, 0.3 );
	border-radius: 6px;
}

/* ---- History heading + back link ---- */
.cev-gs-anchor { position: relative; }
.cev-gs-h-page {
	margin-left: auto;
	flex: 0 0 auto;
	font-family: var( --wp--preset--font-family--body );
	font-size: 0.72rem;
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: rgba( 255, 255, 255, 0.5 );
}
/* When the heading carries a page label, the rule sits between title and label. */
.cev-gs-h:has( .cev-gs-h-page )::after {
	flex: 0 1 auto;
	width: clamp( 1rem, 6vw, 4rem );
}
/* The archive back-link is a TEXT button (Buttons section) — only its spacing
   inside the schedule is a local concern. */
.cev-gs-back {
	margin-bottom: 1rem;
}

/* ---- Pager ---- */
/* The page chips themselves are SECONDARY buttons and the current page is
   PRIMARY, both from the Buttons section. This is only the row that holds them. */
.cev-gs-pager {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 0.4rem;
	margin-top: var( --wp--preset--spacing--40 );
	padding-top: var( --wp--preset--spacing--30 );
	border-top: 1px solid rgba( 184, 145, 46, 0.18 );
}
/* The count badge must fit INSIDE the button's content box (44px minus 25.6px of
   vertical padding = 18.4px), or it pushes the archive bar to 52px while every
   other control on the site is 44px. */
.cev-gs-page-count {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* 16px, so 16 + 25.6px padding + 2px border = 43.6px and the button's 44px
	   min-height governs. At 18px the bar grew to 46px. */
	min-width: 1rem;
	height: 1rem;
	padding: 0 0.35rem;
	border-radius: 999px;
	background: rgba( 184, 145, 46, 0.18 );
	color: var( --wp--preset--color--accent );
	/* 11px — the small-text floor the audit set. */
	font-size: 0.6875rem;
	letter-spacing: 0.04em;
}
.cev-gs-ellipsis {
	color: rgba( 255, 255, 255, 0.4 );
	padding: 0 0.15rem;
}
/* The "into the archive" link on page 1 is the same SECONDARY button stretched
   to the full width of the list — a bar, not a new style. */
.cev-gs-pager--intro { border-top: 0; justify-content: stretch; }
.cev-gs .cev-gs-pager--intro .cev-gs-page--more {
	width: 100%;
	padding-inline: 1rem;
}

/* Past rows read quieter than upcoming. */
.cev-gs-list.is-past .cev-gs-card {
	padding-top: 0.6rem;
	padding-bottom: 0.6rem;
	opacity: 0.72;
}
.cev-gs-list.is-past .cev-gs-date {
	background: rgba( 255, 255, 255, 0.03 );
	border-color: rgba( 255, 255, 255, 0.1 );
}
.cev-gs-list.is-past .cev-gs-day { color: rgba( 255, 255, 255, 0.75 ); }
.cev-gs-list.is-past .cev-gs-dow,
.cev-gs-list.is-past .cev-gs-mon { color: rgba( 255, 255, 255, 0.45 ); }
.cev-gs-list.is-past .cev-gs-title { font-size: 1.05rem; color: rgba( 255, 255, 255, 0.82 ); }

/* ---- Narrow screens ---- */
@media ( max-width: 600px ) {
	.cev-gs-stats { grid-template-columns: 1fr; }
	.cev-gs-card { flex-wrap: wrap; padding-right: 0.85rem; }
	.cev-gs-go { display: none; }
	.custodes-gs-frame::before { inset: 7px; --l: 20px; }
}

/* Respect reduced motion — kill every transition/animation and static-render. */
@media ( prefers-reduced-motion: reduce ) {
	html { scroll-behavior: auto; }
	*, *::before, *::after {
		transition-duration: 0.01ms !important;
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
	}
	.custodes-anim .custodes-reveal,
	.custodes-anim .custodes-reveal .custodes-game-card,
	.custodes-anim .custodes-reveal .custodes-postcard,
	.custodes-anim .custodes-reveal .custodes-stat,
	.custodes-anim .custodes-hero .wp-block-cover__inner-container > * {
		opacity: 1 !important;
		transform: none !important;
	}
}


/* ====================================== Single post body ==== *
 * News articles are the ONE inner page with no gold art-deco frame.
 *
 * The frame (still used by the per-game schedule as `.custodes-gs-frame`) reads as
 * chrome around a compact, self-contained panel. Around a long article — boxing
 * body copy, a featured image and a comment thread inside ornamental borders — it
 * did not fit, so the post body is now a plain centred column on the shared dark
 * backdrop. `.custodes-page-frame` had no other user, so its rules,
 * its corner-bracket `::before` and its mobile overrides are gone rather than
 * left behind as dead CSS.
 * =========================================================== */
/*
 * The explicit clamps below are deliberate, NOT laziness.
 *
 * `var(--wp--preset--spacing--50)` currently resolves to 1.5rem and --60 to
 * 2.25rem — CORE's default spacing scale, not the fluid one theme.json declares in
 * `settings.spacing.spacingSizes`. Those custom sizes are being discarded because
 * core's auto-generated `spacingScale` is still active alongside them (it needs
 * `"spacingScale": { "steps": 0 }` to stand down). Until that is decided — it would
 * resize padding on every section of the site — the preset tokens are ~40% tighter
 * than they read in theme.json, so the separation asked for here is stated directly.
 */
body.custodes-dark-ui .custodes-post-body {
	margin-block: clamp( 1.75rem, 4vw, 3rem );
}

/* ---- Previous / next post navigation ----
 *
 * Two problems, both visible on any news article:
 *
 * The two links used to be full-width stacked blocks of underlined gold body text —
 * the only navigation on the site that looked like nothing else on it. They are now
 * a pair of TEXT buttons on one row, previous left and next right, set clearly
 * apart from the article above so they read as leaving it rather than ending it.
 */
.custodes-postnav {
	gap: 0.75rem 1.5rem;
	margin-top: clamp( 1.25rem, 2vw, 1.75rem );
}
/*
 * With the frame gone there is no border between the article and its navigation,
 * so this rule and the space above it are what separate them. The gap belongs
 * ABOVE the rule: pushed clear of the last paragraph, the pair reads as "leaving
 * the article" rather than as one more line of it.
 */
.custodes-post-body .wp-block-separator {
	margin-top: clamp( 2.5rem, 5vw, 4rem );
	margin-bottom: 0;
}
/* With only one neighbour (first or last post) the lone link must still sit on its
   own side, so `space-between` has something to push against. */
.custodes-postnav .wp-block-post-navigation-link { margin: 0; }
.custodes-postnav .post-navigation-link-next { margin-inline-start: auto; }
/*
 * Core renders the arrow as a SPAN NEXT TO the <a>, not inside it — so the button
 * styling has to sit on the wrapper, or the arrow is left behind as loose text in
 * the page's body font while the label alone looks like a control. The <a> then
 * just carries the words and inherits the wrapper's colour, and the shared button
 * `gap` spaces label and arrow (core's own arrow margins are dropped).
 */
.custodes-postnav .wp-block-post-navigation-link a {
	color: inherit;
	text-decoration: none;
}
.custodes-postnav .wp-block-post-navigation-link__arrow-previous,
.custodes-postnav .wp-block-post-navigation-link__arrow-next {
	margin: 0;
	font-size: 1rem;
	line-height: 1;
}

/* Every inner page ends with the same breathing room above the footer — the
   single-game page had none, so its content ran straight into the footer. */
body.custodes-dark-ui .wp-site-blocks > main {
	padding-bottom: var( --wp--preset--spacing--60 );
}
