/**
 * Aravaipa Elements
 *
 * Scoped entirely under .arv- prefixes. Selectors are kept to a single class
 * wherever possible so X theme and Cornerstone's own generated CSS can still
 * win when an editor overrides something in the builder: this file sets the
 * baseline, it does not fight the page.
 *
 * Type sizes are in pixels, from the scale below. They used to be in rem, on
 * the reasoning that inheriting X's root scale beat pinning a size the rest
 * of the site does not use. Measured, that reasoning was backwards: the rest
 * of the site sets its body copy at 15px, X's root is 15px on desktop and
 * 12px under 620px, and these elements were written against an assumed 16px
 * root, so inheriting the root scale is exactly what pinned them below the
 * page around them.
 */

/* Type scale, in pixels on purpose.

   The theme sets html { font-size: 15px } on desktop and 12px under 620px,
   so every rem in this plugin resolved against a root smaller than the 16px
   the elements were written for, and smaller again on a phone. The rest of
   the site sets its body copy at 15px; these elements were landing their
   meta lines at 12.3px, their buttons at 10.8px and their smallest labels at
   9px, so every block this plugin renders read a size or two below the page
   around it. Sizing in rem hands the theme control of legibility, and the
   theme is not using that control to say anything deliberate, so the scale
   is stated outright and the phone breakpoint adjusts the scale rather than
   each of a hundred and forty rules.

   On :root rather than the element roots because Leaflet portals its popups
   out of the map's subtree, and a scale the popup cannot see would leave it
   with no font-size at all. These are namespaced and inert until used.

   --arv-fs-body is 15px because that is what the rest of the site uses:
   matching it is the whole point. --arv-fs-input never drops below 16px,
   since iOS Safari zooms the page in on focusing any smaller field. */
:root {
	--arv-fs-micro: 11px;
	--arv-fs-label: 12px;
	--arv-fs-btn: 13px;
	--arv-fs-meta: 14px;
	--arv-fs-body: 15px;
	--arv-fs-input: 16px;
	--arv-fs-lead: 17px;
	--arv-fs-name: 19px;
	--arv-fs-title: 24px;
	--arv-fs-heading: 30px;
}

@media (max-width: 619px) {
	/* Only the display sizes come down. Body copy, labels and controls hold
	   their size, because a phone is where they most need to stay readable. */
	:root {
		--arv-fs-btn: 12px;
		--arv-fs-lead: 16px;
		--arv-fs-name: 18px;
		--arv-fs-title: 22px;
		--arv-fs-heading: 26px;
	}
}

.arv-distances,
.arv-timeline,
.arv-partners,
.arv-countdown,
.arv-region-map,
.arv-races,
.arv-hero {
	--arv-accent: #ff2a13;
	--arv-ink: #272727;
	--arv-line: rgba(0, 0, 0, 0.12);
	box-sizing: border-box;
}

.arv-distances *,
.arv-timeline *,
.arv-partners *,
.arv-countdown *,
.arv-region-map *,
.arv-races *,
.arv-hero * {
	box-sizing: inherit;
}

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

.arv-hero {
	position: relative;
	padding: 5rem 1.5rem;
	background-color: var(--arv-ink);
	background-size: cover;
	background-position: center;
	color: #fff;
	overflow: hidden;
}

.arv-hero--image {
	background-image: var(--arv-hero-image);
}

/* The scrim is a pseudo element rather than a background blend so the overlay
   opacity control works the same whether or not an image is set. */
.arv-hero--image::before {
	content: "";
	position: absolute;
	inset: 0;
	background: #000;
	opacity: var(--arv-overlay, 0.55);
}

.arv-hero__inner {
	position: relative;
	max-width: 60rem;
	margin: 0 auto;
}

.arv-hero--center .arv-hero__inner {
	text-align: center;
}

.arv-hero__date {
	margin: 0 0 0.5rem;
	font-size: var(--arv-fs-body);
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--arv-accent);
}

.arv-hero__name {
	margin: 0 0 0.5rem;
	font-size: clamp(32px, 6vw, 64px);
	line-height: 1.05;
	font-weight: 800;
	color: #fff;
}

.arv-hero__location {
	margin: 0;
	font-size: var(--arv-fs-lead);
	opacity: 0.85;
}

.arv-hero__status {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.6rem;
	margin: 1.25rem 0 0;
}

.arv-hero--center .arv-hero__status {
	justify-content: center;
}

.arv-hero__badge {
	display: inline-block;
	padding: 0.3rem 0.7rem;
	border-radius: 2px;
	font-size: var(--arv-fs-label);
	font-weight: 800;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	background: var(--arv-accent);
	color: #fff;
}

.arv-hero__badge--closed {
	background: rgba(255, 255, 255, 0.22);
}

.arv-hero__badge--waitlist,
.arv-hero__badge--lottery {
	background: #d99000;
}

.arv-hero__note {
	font-size: var(--arv-fs-meta);
	opacity: 0.85;
}

.arv-hero__cta {
	display: inline-block;
	margin-top: 1.5rem;
	padding: 0.85rem 2rem;
	border-radius: 2px;
	background: var(--arv-accent);
	color: #fff;
	font-weight: 800;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	text-decoration: none;
	transition: filter 0.15s ease;
}

.arv-hero__cta:hover,
.arv-hero__cta:focus {
	filter: brightness(0.88);
	color: #fff;
}

/* ----------------------------------------------------------- Distances -- */

.arv-distances__heading,
.arv-timeline__heading,
.arv-partners__heading,
.arv-countdown__heading {
	margin: 0 0 1.5rem;
	font-size: clamp(24px, 3vw, 32px);
	font-weight: 800;
	text-align: center;
	color: var(--arv-ink);
}

.arv-distances__grid {
	display: grid;
	gap: 1.25rem;
	grid-template-columns: repeat(var(--arv-cols, 3), minmax(0, 1fr));
}

.arv-distance {
	display: flex;
	flex-direction: column;
	padding: 1.5rem;
	border: 1px solid var(--arv-line);
	border-top: 4px solid var(--arv-accent);
	background: #fff;
}

.arv-distance__name {
	margin-bottom: 1rem;
	font-size: var(--arv-fs-title);
	font-weight: 800;
	line-height: 1.1;
	color: var(--arv-ink);
}

.arv-distance__stats {
	margin: 0 0 1.25rem;
	padding: 0;
	/* Pushes the CTA to the bottom so buttons line up across cards whose stat
	   counts differ, which they routinely do between distances. */
	flex: 1 1 auto;
}

.arv-distance__stat {
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	padding: 0.5rem 0;
	border-bottom: 1px solid var(--arv-line);
}

.arv-distance__stat:last-child {
	border-bottom: 0;
}

.arv-distance__stat dt {
	margin: 0;
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	opacity: 0.6;
}

.arv-distance__stat dd {
	margin: 0;
	font-weight: 700;
	text-align: right;
	color: var(--arv-ink);
}

.arv-distance__cta {
	display: block;
	padding: 0.7rem 1rem;
	background: var(--arv-accent);
	color: #fff;
	font-weight: 800;
	font-size: var(--arv-fs-btn);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	text-align: center;
	text-decoration: none;
	transition: filter 0.15s ease;
}

.arv-distance__cta:hover,
.arv-distance__cta:focus {
	filter: brightness(0.88);
	color: #fff;
}

/* ------------------------------------------------------------ Timeline -- */

.arv-timeline__day + .arv-timeline__day {
	margin-top: 1.75rem;
}

.arv-timeline__day-label {
	margin: 0 0 0.5rem;
	padding-bottom: 0.5rem;
	border-bottom: 2px solid var(--arv-accent);
	font-size: var(--arv-fs-lead);
	font-weight: 800;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--arv-ink);
}

.arv-timeline__entries {
	margin: 0;
	padding: 0;
	list-style: none;
}

.arv-timeline__entry {
	display: flex;
	gap: 1.25rem;
	padding: 0.7rem 0;
	border-bottom: 1px solid var(--arv-line);
}

.arv-timeline__entry:last-child {
	border-bottom: 0;
}

.arv-timeline__time {
	flex: 0 0 8rem;
	font-weight: 800;
	color: var(--arv-accent);
	font-variant-numeric: tabular-nums;
}

.arv-timeline__what {
	flex: 1 1 auto;
	color: var(--arv-ink);
}

/* ------------------------------------------------------------ Partners -- */

.arv-partners__grid {
	display: grid;
	gap: 1.5rem 2rem;
	grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
	align-items: center;
}

.arv-partners__item {
	display: flex;
	align-items: center;
	justify-content: center;
}

/* Tiers scale by column span rather than font size so a title sponsor reads
   larger without the grid falling out of alignment. */
.arv-partners__item--title {
	grid-column: span 2;
}

.arv-partners__link {
	display: block;
	width: 100%;
}

.arv-partners__item img {
	display: block;
	width: 100%;
	height: auto;
	max-height: 5rem;
	object-fit: contain;
	margin: 0 auto;
}

.arv-partners__item--title img {
	max-height: 8rem;
}

.arv-partners__item--presenting img {
	max-height: 6.5rem;
}

.arv-partners--grayscale .arv-partners__item img {
	filter: grayscale(100%);
	opacity: 0.75;
	transition: filter 0.2s ease, opacity 0.2s ease;
}

.arv-partners--grayscale .arv-partners__item:hover img {
	filter: grayscale(0);
	opacity: 1;
}

/* ----------------------------------------------------------- Countdown -- */

.arv-countdown {
	text-align: center;
}

.arv-countdown__units {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 1rem;
}

.arv-countdown__unit {
	min-width: 5.5rem;
	padding: 1rem 0.75rem;
	border: 1px solid var(--arv-line);
	border-top: 4px solid var(--arv-accent);
	background: #fff;
}

.arv-countdown__value {
	display: block;
	font-size: clamp(30px, 5vw, 48px);
	font-weight: 800;
	line-height: 1;
	color: var(--arv-ink);
	font-variant-numeric: tabular-nums;
}

.arv-countdown__label {
	display: block;
	margin-top: 0.35rem;
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	opacity: 0.6;
}

.arv-countdown__expired {
	margin: 0;
	font-size: var(--arv-fs-lead);
	font-weight: 700;
	color: var(--arv-accent);
}

/* --------------------------------------------------------- Region Map -- */

/* Two themes, because this section can sit on a light race page or stand as
   its own band. The dark panel is the default: on a white page the map was
   a pale shape floating in whitespace with no edge to it, and the pins had
   nothing to read against. Colours are the site's own, sampled off
   aravaiparunning.com rather than invented (#ff2a13 accent, #272727 ink,
   and the logo's teals). */
.arv-region-map {
	--arv-teal: #5bb5a2;
	--arv-teal-deep: #2a5e6b;
	position: relative;
	text-align: center;
}

.arv-region-map--dark {
	--arv-map-land: #33403f;
	--arv-map-line: #253130;
	--arv-map-text: #f4f4f4;
	--arv-map-muted: rgba(244, 244, 244, 0.62);
	--arv-map-chip: #1c2524;
	--arv-map-rule: rgba(244, 244, 244, 0.14);
	background: #212a29;
	color: var(--arv-map-text);
}

.arv-region-map--light {
	--arv-map-land: #dfe6e3;
	--arv-map-line: #fff;
	--arv-map-text: var(--arv-ink);
	--arv-map-muted: rgba(39, 39, 39, 0.62);
	--arv-map-chip: #fff;
	--arv-map-rule: rgba(0, 0, 0, 0.12);
	color: var(--arv-map-text);
}

/* Full bleed inside a Cornerstone column: the dark band should run edge to
   edge like the site's other dark sections, while the content inside it
   stays on the page's own measure. */
.arv-region-map__inner {
	max-width: 68rem;
	margin: 0 auto;
	padding: 4rem 1.5rem;
}

.arv-region-map__eyebrow {
	margin: 0 0 0.6rem;
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--arv-teal);
}

.arv-region-map--light .arv-region-map__eyebrow {
	color: var(--arv-teal-deep);
}

.arv-region-map__heading {
	margin: 0 0 0.6rem;
	font-size: clamp(30px, 4vw, 48px);
	font-weight: 800;
	line-height: 1.05;
	color: var(--arv-map-text);
}

.arv-region-map__intro {
	max-width: 34rem;
	margin: 0 auto;
	color: var(--arv-map-muted);
}

/* Aspect ratio, not a fixed height: the pins are positioned by percentage of
   this box, so it has to keep the same proportions as us-outline.svg
   (960x609) at every width or every pin drifts off its state as the page
   resizes. */
.arv-region-map__stage {
	position: relative;
	max-width: 60rem;
	margin: 2.5rem auto 0;
	aspect-ratio: 960 / 609;
}

.arv-region-map__base {
	display: block;
	width: 100%;
	height: 100%;
}

/* The outline ships with no fill or stroke of its own so both can follow the
   theme from here. That is the reason it is inlined rather than served as an
   <img>, which the page stylesheet could not reach into. */
.arv-region-map__states {
	fill: var(--arv-map-land);
	stroke: var(--arv-map-line);
}

.arv-region-map__pin {
	position: absolute;
	/* Zero size on purpose: this is a positioning point, not a box. The dot
	   and name used to be flex children centred by this element's own box,
	   which broke the moment a long name (White Mountain Endurance) landed
	   near the map's right edge: centring a wide label under a point 92% of
	   the way across the stage pushes half of it straight out past the
	   stage, and past the whole page after it, since nothing here was ever
	   clipped. Both are now absolutely positioned against this single point
	   instead, free to anchor to whichever edge has room. */
	display: block;
	width: 0;
	height: 0;
	text-decoration: none;
	color: inherit;
	z-index: 1;
}

.arv-region-map__pin:focus-visible {
	z-index: 3;
	outline: none;
}

.arv-region-map__dot {
	position: absolute;
	top: 0;
	left: 0;
	transform: translate(-50%, -50%);
	width: 0.7rem;
	height: 0.7rem;
	border-radius: 50%;
	background: var(--arv-teal);
	box-shadow: 0 0 0 3px rgba(91, 181, 162, 0.25);
	transition: transform 0.15s ease, box-shadow 0.15s ease;
}

/* Headquarters, distinguished by size and ring weight rather than by hue.

   It used to be the accent red. Red means one thing everywhere else on this
   site, "there is something to buy", and it was already doing that job on
   this same panel: the View races button in the hover card is red. A map
   marker is not an offer, so it was the second meaning of red on one small
   surface. Same reasoning as the race map's pins, which are teal for the
   same reason. Bigger and more heavily ringed still reads as "this one is
   different" without spending a colour on it. */
.arv-region-map__pin--primary .arv-region-map__dot {
	width: 1rem;
	height: 1rem;
	background: var(--arv-teal);
	box-shadow: 0 0 0 5px rgba(91, 181, 162, 0.35);
}
.arv-region-map__pin:focus-visible .arv-region-map__dot {
	transform: translate(-50%, -50%) scale(1.3);
	box-shadow: 0 0 0 5px rgba(91, 181, 162, 0.4);
}

.arv-region-map__name {
	position: absolute;
	top: 0.55rem;
	left: 0;
	/* Centred under the dot by default. The edge modifiers below override
	   only this translate, sliding the label fully to one side instead of
	   splitting it evenly across the dot, which is what keeps a long name
	   near the map's edge from running past the stage and taking the whole
	   page into a horizontal scroll with it. */
	transform: translateX(-50%);
	padding: 0.12rem 0.4rem;
	background: var(--arv-map-chip);
	color: var(--arv-map-text);
	font-size: var(--arv-fs-micro);
	font-weight: 700;
	letter-spacing: 0.02em;
	white-space: nowrap;
	transition: color 0.15s ease;
}

.arv-region-map--light .arv-region-map__name {
	border: 1px solid var(--arv-map-rule);
}

/* The label follows the dot: white like every other region's. A red name
   under a teal dot was the last trace of the accent-coloured HQ treatment
   and read as an error rather than an emphasis. */
.arv-region-map__pin--primary .arv-region-map__name {
	color: inherit;
}

/* Lifts the label above the dot. Paired with a neighbour that keeps the
   default below, this is what separates two pins too close together
   horizontally for their labels to sit on the same line. */
.arv-region-map__pin--name-above .arv-region-map__name {
	top: auto;
	bottom: 0.55rem;
}

.arv-region-map__pin--edge-left .arv-region-map__name {
	transform: translateX(0);
}

.arv-region-map__pin--edge-right .arv-region-map__name {
	transform: translateX(-100%);
}

/* A real element the whole time, positioned and ready, so the transition is
   opacity alone rather than a display toggle Cornerstone's own CSS or an X
   theme animation library would otherwise fight to enter. */
.arv-region-map__detail {
	position: absolute;
	bottom: calc(100% + 0.5rem);
	left: 50%;
	transform: translateX(-50%) translateY(4px);
	width: max-content;
	max-width: 15rem;
	padding: 0.7rem 0.85rem;
	/* Near-black, and no accent rule along the top.
	
	   The card used to be solid accent red, which was the loudest thing on
	   the panel for what is only a one-line description. Replacing that with
	   a dark card was right; keeping a 2px teal line across its top was the
	   fix overshooting. That line encodes nothing, it is the same decorative
	   stripe every dark template card has, and the shadow and the near-black
	   fill already separate the card from the map perfectly well without it. */
	background: #121817;
	color: var(--arv-map-text);
	font-size: var(--arv-fs-label);
	font-weight: 500;
	line-height: 1.4;
	text-align: left;
	box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.15s ease, transform 0.15s ease;
}

.arv-region-map--light .arv-region-map__detail {
	background: var(--arv-ink);
	color: #fff;
}

/* Brand mark inside the hover card, for the regions that have one. Capped
   by height rather than width so a square logo and a wide horizontal
   lockup both land at the same optical weight. */
.arv-region-map__detail-logo {
	display: block;
	max-width: 100%;
	max-height: 2.6rem;
	width: auto;
	margin-bottom: 0.5rem;
	object-fit: contain;
	object-position: left center;
}

/* Only at phone width, where the label beside the dot is hidden and the
   card would otherwise describe an unnamed place. See the matching comment
   in includes/elements/region-map.php. */
.arv-region-map__detail-name {
	display: none;
}

.arv-region-map__detail-text {
	display: block;
}

/* The call to action inside the card. A block, not an inline pill: no
   rounded corners, no shadow, squared off like the name chips and the
   section's rules, so it reads as part of the same graphic language rather
   than a UI button borrowed from somewhere else. */
.arv-region-map__cta {
	display: block;
	margin-top: 0.6rem;
	padding: 0.32rem 0.55rem;
	background: var(--arv-teal);
	color: #0d1211;
	font-size: var(--arv-fs-btn);
	font-weight: 800;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	text-align: center;
	transition: background 0.15s ease;
}

.arv-region-map__cta::after {
	content: "→";
	margin-left: 0.35rem;
	display: inline-block;
	transition: transform 0.15s ease;
}

/* No separate treatment for headquarters here either. Every card's button
   does the same thing, "go to this region's races", and styling one of them
   red and the other eight teal made the same action look like two different
   ones depending on which pin you hovered. Headquarters is already
   distinguished by its dot. */

/* Without this the card is scenery: it opens on hover but the pointer cannot
   reach it, so the button inside would swallow nothing and the click would
   fall through to the map behind it. Only enabled while the card is actually
   visible, so a hidden card never intercepts a click meant for the pin
   underneath it. */
.arv-region-map__pin:hover .arv-region-map__detail,
.arv-region-map__pin:focus-within .arv-region-map__detail,
.arv-region-map__pin:focus-visible .arv-region-map__detail,
.arv-region-map__pin.is-open .arv-region-map__detail {
	pointer-events: auto;
}

/* Bridges the gap between the dot and the card. Moving the pointer off the
   dot and toward the button crosses a few pixels of bare map, and without
   something covering them the anchor stops being hovered, the card closes,
   and the button vanishes from under the pointer mid-travel. Transparent,
   and inert whenever the card itself is (it inherits pointer-events), so it
   never blocks a neighbouring pin. */
.arv-region-map__detail::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: 100%;
	height: 1.1rem;
}

/* Card flipped below the dot: the bridge flips with it, and reaches further
   because that variant clears the always-visible name label as well. */
.arv-region-map__pin--label-below .arv-region-map__detail::after {
	top: auto;
	bottom: 100%;
	height: 2.2rem;
}

/* .is-open is set by assets/aravaipa-region-map.js on a first tap, only on
   devices with no real pointer. It is listed alongside :focus-visible rather
   than given rules of its own so the tapped card and the keyboard card are
   the same card, and a future change to one cannot quietly skip the other. */
.arv-region-map__pin:focus-visible .arv-region-map__detail,
.arv-region-map__pin.is-open .arv-region-map__detail {
	opacity: 1;
	transform: translateX(-50%) translateY(0);
}

.arv-region-map__pin.is-open {
	z-index: 3;
}

.arv-region-map__pin.is-open .arv-region-map__dot {
	transform: translate(-50%, -50%) scale(1.3);
	box-shadow: 0 0 0 5px rgba(91, 181, 162, 0.4);
}

/* Flips the card below the pin for the regions in the top slice of the map,
   where above would push it off the top of the stage. Cleared further down
   than the above-pin version so it lands below the always-visible name
   label rather than on top of it: both measure from the same zero-size
   point, and the name already occupies the first ~1.5rem below it. */
.arv-region-map__pin--label-below .arv-region-map__detail {
	bottom: auto;
	top: calc(100% + 2rem);
	transform: translateX(-50%) translateY(-4px);
}

.arv-region-map__pin--label-below:focus-visible .arv-region-map__detail,
.arv-region-map__pin--label-below.is-open .arv-region-map__detail {
	transform: translateX(-50%) translateY(0);
}

/* Re-anchors the card to whichever edge has room, for a region close enough
   to the left or right of the map that a centred card would run off the
   stage. */
.arv-region-map__pin--edge-left .arv-region-map__detail {
	left: 0;
	transform: translateX(0) translateY(4px);
}

.arv-region-map__pin--edge-left:focus-visible .arv-region-map__detail,
.arv-region-map__pin--edge-left.is-open .arv-region-map__detail {
	transform: translateX(0) translateY(0);
}

.arv-region-map__pin--edge-right .arv-region-map__detail {
	left: auto;
	right: 0;
	transform: translateX(0) translateY(4px);
}

.arv-region-map__pin--edge-right:focus-visible .arv-region-map__detail,
.arv-region-map__pin--edge-right.is-open .arv-region-map__detail {
	transform: translateX(0) translateY(0);
}

/* The same regions again as text. On a phone the pins are a few millimetres
   across with labels set small enough not to collide, so this is what
   actually makes the section usable there, and it is the only part a search
   engine can read: the map is one decorative SVG with no place names in it.
   Deliberately not cards. No rounded corners, no shadows, no left accent
   bars: hairline rules and type only, so it reads as an index rather than a
   dashboard. */
/* Column counts are explicit rather than auto-fit, and chosen to divide the
   number of regions evenly. A last row that is not full leaves bottom rules
   stopping partway across, which reads as a half-drawn table. Nine regions
   go three, three and three; at eight this was four. Worth re-checking
   whenever a region is added or removed, since auto-fit picks whatever the
   width allows and cannot know the count. */
.arv-region-map__list {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 0 2rem;
	margin-top: 3rem;
	border-top: 1px solid var(--arv-map-rule);
	text-align: left;
}

@media (min-width: 600px) {
	.arv-region-map__list {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 1024px) {
	.arv-region-map__list {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

.arv-region-map__item {
	display: flex;
	align-items: flex-start;
	gap: 0.75rem;
	padding: 1.1rem 0 1.2rem;
	border-bottom: 1px solid var(--arv-map-rule);
	text-decoration: none;
	color: inherit;
}

/* Fixed box so every row's text starts on the same left edge whether or
   not that region has a logo yet, instead of the list ragging in and out
   as brands get added. */
.arv-region-map__item-logo {
	flex: 0 0 2.25rem;
	display: flex;
	align-items: center;
	justify-content: center;
	height: 2.25rem;
}

.arv-region-map__item-logo img {
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	object-fit: contain;
}

.arv-region-map__item-body {
	min-width: 0;
	flex: 1 1 auto;
}

.arv-region-map__item-name {
	display: block;
	font-size: var(--arv-fs-body);
	font-weight: 700;
	color: var(--arv-map-text);
	transition: color 0.15s ease;
}

/* The arrow is a pseudo element so the link text stays clean for a screen
   reader, which would otherwise read the character out. */
.arv-region-map__item-name::after {
	content: "→";
	margin-left: 0.4rem;
	color: var(--arv-teal);
	opacity: 0;
	transition: opacity 0.15s ease, transform 0.15s ease;
	display: inline-block;
}

.arv-region-map--light .arv-region-map__item-name::after {
	color: var(--arv-teal-deep);
}

.arv-region-map__item-detail {
	display: block;
	margin-top: 0.2rem;
	font-size: var(--arv-fs-meta);
	line-height: 1.45;
	color: var(--arv-map-muted);
}

.arv-region-map__item:focus-visible {
	outline: 2px solid var(--arv-teal);
	outline-offset: -2px;
}

.arv-region-map__item:focus-visible .arv-region-map__item-name::after {
	opacity: 1;
}

/* Two columns on a phone too, and stripped to the logo and the name. At one
   full-width row per region, each carrying a blurb, nine regions ran about
   1200px: the list was longer than the map, the hero and the featured race
   put together, and it sat between the map and everything below it. The
   blurb is not lost, it is the body of the card the matching pin opens, so
   the map explains and the list navigates. */
@media (max-width: 599px) {
	.arv-region-map__list {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 0 1.25rem;
		margin-top: 2rem;
	}

	.arv-region-map__item {
		align-items: center;
		gap: 0.55rem;
		padding: 0.8rem 0;
	}

	.arv-region-map__item-logo {
		flex-basis: 1.75rem;
		height: 1.75rem;
	}

	.arv-region-map__item-name {
		font-size: var(--arv-fs-body);
		line-height: 1.25;
	}

	.arv-region-map__item-detail {
		display: none;
	}
}

/* :hover only, gated behind a real pointer that can actually hover. Without
   this, iOS Safari treats the first tap on a link with a :hover rule as
   triggering the hover state rather than following the link, so visitors on
   the device most of this page's traffic comes from would need to tap every
   pin twice to reach the landing page it points to. Touch gets the card a
   different way, from assets/aravaipa-region-map.js, which opens it on the
   first tap deliberately rather than as a side effect of a hover rule that
   was never meant to fire there. */
@media (hover: hover) and (pointer: fine) {
	.arv-region-map__pin:hover {
		z-index: 3;
	}

	.arv-region-map__pin:hover .arv-region-map__dot {
		transform: translate(-50%, -50%) scale(1.3);
		box-shadow: 0 0 0 5px rgba(91, 181, 162, 0.4);
	}

	.arv-region-map__pin--primary:hover .arv-region-map__dot {
		box-shadow: 0 0 0 6px rgba(255, 42, 19, 0.35);
	}

	.arv-region-map__pin:hover .arv-region-map__detail {
		opacity: 1;
		transform: translateX(-50%) translateY(0);
	}

	.arv-region-map__pin--label-below:hover .arv-region-map__detail {
		transform: translateX(-50%) translateY(0);
	}

	.arv-region-map__pin--edge-left:hover .arv-region-map__detail {
		transform: translateX(0) translateY(0);
	}

	.arv-region-map__pin--edge-right:hover .arv-region-map__detail {
		transform: translateX(0) translateY(0);
	}

	.arv-region-map__cta:hover {
		background: #6fc7b4;
	}

	.arv-region-map__pin--primary .arv-region-map__cta:hover {
		background: #ff4a30;
	}

	.arv-region-map__cta:hover::after {
		transform: translateX(3px);
	}

	.arv-region-map__item:hover .arv-region-map__item-name {
		color: var(--arv-teal);
	}

	.arv-region-map--light .arv-region-map__item:hover .arv-region-map__item-name {
		color: var(--arv-teal-deep);
	}

	.arv-region-map__item:hover .arv-region-map__item-name::after {
		opacity: 1;
		transform: translateX(3px);
	}
}

/* --------------------------------------------------------- Responsive -- */

@media (max-width: 979px) {
	.arv-distances__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 767px) {
	.arv-hero {
		padding: 3.5rem 1.25rem;
	}

	.arv-region-map__inner {
		padding: 3rem 1.25rem;
	}

	/* Labels come off the map entirely at phone width. Four of the eight
	   regions sit within about 25% of the map's width, so at 390px their
	   labels overlap each other no matter how small the type is set, and
	   the earlier attempt to shrink them into fitting just made an
	   unreadable pile instead of a readable one. The list below names every
	   region in full, so nothing is lost: the map goes back to showing
	   where, and the list says what. Dots stay, and stay tappable. */
	.arv-region-map__name {
		display: none;
	}

	.arv-region-map__detail {
		max-width: 11rem;
		font-size: var(--arv-fs-label);
	}

	.arv-region-map__detail-name {
		display: block;
		margin-bottom: 0.25rem;
		font-size: var(--arv-fs-meta);
		font-weight: 800;
		line-height: 1.2;
		color: #fff;
	}

	/* Without labels the dots carry the map on their own, so they get a
	   little bigger rather than reading as specks. */
	.arv-region-map__dot {
		width: 0.8rem;
		height: 0.8rem;
	}

	.arv-region-map__pin--primary .arv-region-map__dot {
		width: 1.1rem;
		height: 1.1rem;
	}

	.arv-region-map__stage {
		margin-top: 2rem;
	}

	.arv-region-map__list {
		margin-top: 2.25rem;
	}

	.arv-region-map__item {
		padding-right: 0;
	}

	.arv-distances__grid {
		grid-template-columns: minmax(0, 1fr);
	}

	.arv-timeline__entry {
		flex-direction: column;
		gap: 0.15rem;
	}

	.arv-timeline__time {
		flex-basis: auto;
	}

	.arv-partners__item--title {
		grid-column: span 1;
	}

	/* Cards stack on mobile, so the flex spacer that keeps buttons aligned
	   across a row has nothing left to align against and just leaves a gap
	   under any card without a register link. */
	.arv-distance__stats {
		flex: 0 0 auto;
	}

	/* Four units at the desktop min-width overflow a 390px viewport by a few
	   pixels and wrap one unit onto its own line. Narrower keeps the clock on
	   a single row, which is the whole point of it. */
	.arv-countdown__units {
		gap: 0.5rem;
	}

	.arv-countdown__unit {
		min-width: 0;
		flex: 1 1 0;
		padding: 0.85rem 0.35rem;
	}
}


/* ============================================================ Races == */
/* Built against the live site's own computed values rather than guessed:
   body is Lato 15px/1.7 on white, the theme's container is 1200px, its
   accent is #ff2a13 with #c61300 as the pressed state, its small labels are
   14px/700 uppercase at 2px letter-spacing, and nothing on the site has a
   border radius. All of that is reproduced here so the module reads as part
   of the page rather than a component dropped onto it. */

.arv-races {
	text-align: left;
	/* The logo teals, shared with the region map, which is where they are
	   also defined. Repeated rather than hoisted to :root so the elements
	   stay self-contained: each one can be dropped into a page on its own. */
	--arv-teal: #5bb5a2;
	--arv-teal-deep: #2a5e6b;
	--arv-races-bg: #ffffff;
	--arv-races-ink: #272727;
	--arv-races-muted: #7a7a7a;
	--arv-races-rule: #ebebeb;
	--arv-races-card: #f7f7f7;
	padding: 3.5rem 0;
	background: var(--arv-races-bg);
	color: var(--arv-races-ink);
	font-family: Lato, "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.arv-races--dark {
	--arv-races-bg: #1d2624;
	--arv-races-ink: #f2f2f2;
	--arv-races-muted: #9aa8a4;
	--arv-races-rule: #2f3b38;
	--arv-races-card: #212c2a;
}

.arv-races__inner {
	max-width: 1200px;
	margin: 0 auto;
	padding: 0 1.25rem;
}

/* The site's own small-label convention, lifted off its h4: 14px, 700,
   uppercase, 2px tracking. Reused rather than reinvented so this section's
   eyebrow matches every other label on the site. */
.arv-races__eyebrow {
	margin: 0 0 0.4rem;
	font-size: var(--arv-fs-meta);
	font-weight: 700;
	letter-spacing: 2px;
	text-transform: uppercase;
	color: var(--arv-accent);
}

.arv-races__heading {
	margin: 0 0 0.5rem;
	font-size: clamp(30px, 4vw, 44px);
	font-weight: 700;
	line-height: 1.15;
	color: var(--arv-races-ink);
}

.arv-races__intro {
	margin: 0 0 2rem;
	max-width: 46rem;
	font-size: var(--arv-fs-lead);
	line-height: 1.7;
	color: var(--arv-races-muted);
}

.arv-races__heading + .arv-races__grid,
.arv-races__eyebrow + .arv-races__grid {
	margin-top: 2rem;
}

.arv-races__grid {
	display: grid;
	gap: 1.5rem;
	grid-template-columns: repeat(3, minmax(0, 1fr));
}

.arv-races--cols-2 .arv-races__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.arv-races--cols-4 .arv-races__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.arv-races__card {
	display: flex;
	flex-direction: column;
	background: var(--arv-races-card);
	/* Square, like everything else on this site. */
	border-radius: 0;
}

/* Fixed aspect box so a grid of race tiles lines up whatever shape the
   artwork is. Contain rather than cover, and 4:3 rather than 16:9, because
   Aravaipa's race images are square badge logos, not landscape photos:
   cropping them to a letterbox cut the name straight off the top and bottom
   of the badge. Contain letterboxes a wide photo instead, which is the
   better failure of the two. */
/* 3:2 rather than 4:3, and padded, so the badge reads as a mark on the card
   rather than the card being a frame around a badge. At three across on a
   1200px container this is about 100px of artwork instead of 190. */
.arv-races__media {
	position: relative;
	aspect-ratio: 3 / 2;
	overflow: hidden;
	padding: 0.9rem;
	background: var(--arv-races-rule);
}

.arv-races__img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	display: block;
}

/* The artwork links to the race page, because it is the most obviously
   clickable thing on the card and was doing nothing. */
.arv-races__media-link {
	display: block;
	width: 100%;
	height: 100%;
}

.arv-races__media-link:focus-visible {
	outline: 2px solid var(--arv-accent);
	outline-offset: -2px;
}

.arv-races__body {
	display: flex;
	flex-direction: column;
	flex: 1;
	/* No bottom padding: the actions row underneath carries it now, so a
	   card with no buttons at all still ends flush rather than with a
	   double gap. */
	padding: 1.1rem 1.2rem 0.6rem;
}

.arv-races__date {
	display: block;
	margin-bottom: 0.35rem;
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 1.5px;
	text-transform: uppercase;
	color: var(--arv-accent);
}

.arv-races__name {
	margin: 0 0 0.4rem;
	font-size: var(--arv-fs-name);
	font-weight: 700;
	line-height: 1.25;
	color: var(--arv-races-ink);
}

.arv-races__link {
	color: inherit;
	text-decoration: none;
}

.arv-races__distances {
	margin: 0 0 0.3rem;
	font-size: var(--arv-fs-body);
	line-height: 1.5;
	color: var(--arv-races-ink);
}

.arv-races__where {
	margin: 0 0 1rem;
	font-size: var(--arv-fs-meta);
	line-height: 1.5;
	color: var(--arv-races-muted);
}

/* Pushed to the bottom of the card so the buttons line up across a row even
   when one race has four distances and its neighbour has one. A sibling of
   the body rather than a child of it, so it can span the full card when the
   card goes two-column on a phone; that means it carries the body's own
   horizontal padding itself instead of inheriting it. */
.arv-races__actions {
	display: flex;
	align-items: stretch;
	justify-content: center;
	gap: 0.6rem;
	margin-top: auto;
	padding: 0 1.2rem 1.2rem;
}

.arv-races__cta,
.arv-races__cta:link,
.arv-races__cta:visited {
	display: inline-block;
	padding: 0.62rem 1.15rem;
	background: var(--arv-accent);
	color: #fff;
	font-size: var(--arv-fs-btn);
	font-weight: 700;
	letter-spacing: 1.5px;
	text-transform: uppercase;
	text-decoration: none;
	border-radius: 0;
	transition: background 0.15s ease;
}

/* The secondary of the pair: same size and shape as the primary, hollow
   instead of filled. Always present, so the row of buttons keeps its shape
   whatever phase a race is in and the eye is not re-learning the layout on
   every card down the list. */
.arv-races__details {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0.62rem 1.15rem;
	background: transparent;
	border: 2px solid var(--arv-races-rule);
	color: var(--arv-races-ink);
	font-size: var(--arv-fs-btn);
	font-weight: 700;
	letter-spacing: 1.5px;
	text-transform: uppercase;
	text-decoration: none;
	white-space: nowrap;
	border-radius: 0;
	transition: border-color 0.15s ease, color 0.15s ease;
}

/* The primary carries a border of its own width so the two buttons are the
   same height, rather than the filled one sitting a couple of pixels short
   of the hollow one beside it. */
.arv-races__cta {
	border: 2px solid var(--arv-accent);
}

/* Once a race is running or done there is nothing left to sell, and a red
   button next to it would still read as "buy". Live and results share the
   teal used elsewhere for information rather than action.

   :link and :visited are restated here at the same specificity as the base
   rule's, not left to source order: ".arv-races__cta:link" is two classes
   worth of specificity (a pseudo-class counts as one), so without a matching
   ":link" of its own this rule would lose to the red base rule on every
   actual anchor tag regardless of which came second in the file. Exactly
   what happened the first time this shipped: every Live Results button
   rendered red with only a teal border. */
.arv-races__cta--live,
.arv-races__cta--live:link,
.arv-races__cta--live:visited,
.arv-races__cta--results,
.arv-races__cta--results:link,
.arv-races__cta--results:visited {
	background: var(--arv-teal-deep);
	border-color: var(--arv-teal-deep);
}

/* Entries have closed but the race has not run. Nothing to click, so this is
   a label rather than a button: flat, muted, and deliberately not carrying
   the accent, so the eye skips it and lands on Race Details beside it, which
   is the only thing here that does anything. */
.arv-races__cta--closed {
	background: transparent;
	border-color: var(--arv-races-rule);
	color: var(--arv-races-muted);
	cursor: default;
}

/* Sold out, but there is still somewhere to click: goldenrod rather than
   the red "buy" accent, since the offer is a waitlist and not open entries,
   and rather than the closed style's grey, since it is not a dead end
   either.

   Dark text on this, not white, and that is not a style preference. White
   on #daa520 measures 2.24:1, under even the 3:1 floor for large text;
   the ink colour measures 6.68:1 and clears AA comfortably. Goldenrod is
   simply too light a background to carry white type. */
.arv-races__cta--waitlist,
.arv-races__cta--waitlist:link,
.arv-races__cta--waitlist:visited {
	background: #daa520;
	border-color: #daa520;
	color: var(--arv-ink, #272727);
}

.arv-races__cta:focus-visible,
.arv-races__details:focus-visible,
.arv-races__link:focus-visible {
	outline: 2px solid var(--arv-accent);
	outline-offset: 2px;
}

.arv-races__all {
	margin: 2rem 0 0;
	text-align: center;
}

.arv-races__all a {
	font-size: var(--arv-fs-btn);
	font-weight: 700;
	letter-spacing: 2px;
	text-transform: uppercase;
	color: var(--arv-accent);
	text-decoration: none;
	border-bottom: 1px solid currentColor;
	padding-bottom: 2px;
}

/* Same gating as the region map: on iOS Safari a :hover rule on a link makes
   the first tap trigger hover rather than follow the link, so a runner on a
   phone would have to tap Register twice. */
@media (hover: hover) and (pointer: fine) {
	/* #c61300 is the theme's own pressed red, not a shade picked by eye. */
	/* Colour is restated on every hover state, not just background. The X
	   theme sets its own a:hover colour site-wide, which won here and turned
	   the label the same red as the button it sits on: a solid red rectangle
	   with the word gone. */
	a.arv-races__cta:hover,
	a.arv-races__cta:focus,
	a.arv-races__cta:active {
		background: #c61300;
		border-color: #c61300;
		color: #fff;
	}

	a.arv-races__cta--live:hover,
	a.arv-races__cta--live:focus,
	a.arv-races__cta--results:hover,
	a.arv-races__cta--results:focus {
		background: #22505b;
		border-color: #22505b;
		color: #fff;
	}

	a.arv-races__cta--waitlist:hover,
	a.arv-races__cta--waitlist:focus {
		background: #c9971d;
		border-color: #c9971d;
		color: var(--arv-ink, #272727);
	}
	.arv-races__link:hover { color: var(--arv-accent); }
	.arv-races__details:hover {
		color: var(--arv-accent);
		border-color: var(--arv-accent);
	}
	.arv-races__all a:hover { color: #c61300; }
}

@media (max-width: 979px) {
	.arv-races__grid,
	.arv-races--cols-2 .arv-races__grid,
	.arv-races--cols-4 .arv-races__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* Phones get a different card, not a narrower one.
   Stacking the desktop card put a full-width 4:3 badge above every race,
   which measured 422px per card and 3.3 screens of scrolling for six races.
   The artwork is the least useful thing on a phone and it was taking the
   most room, so it becomes a small square thumbnail and the card turns into
   a row. Same information, roughly a third of the height. */
@media (max-width: 619px) {
	.arv-races { padding: 2.5rem 0; }

	.arv-races__grid,
	.arv-races--cols-2 .arv-races__grid,
	.arv-races--cols-4 .arv-races__grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 0.75rem;
	}

	/* Logo on the left, everything else stacked in the column beside it:
	   date, name, distances, where, then the buttons.
	
	   The buttons briefly lived in a third row spanning the whole card,
	   because in this column they were wrapping "Join Waitlist" onto two
	   lines. That turned out to be the specificity bug, not a width
	   problem: every font-size and padding this block sets was losing to
	   the base rule's ".arv-races__cta:link", so the buttons were rendering
	   at the desktop's 0.78rem and 1.15rem padding no matter what was set
	   here. With that fixed they fit the column at a smaller size, which is
	   also less shouty than two full-card-width blocks per row down a list
	   of eighty. */
	.arv-races__card {
		display: grid;
		grid-template-columns: 72px minmax(0, 1fr);
		grid-template-areas:
			"media body"
			".     actions";
		align-items: start;
	}

	.arv-races__media { grid-area: media; }
	.arv-races__body { grid-area: body; }
	/* Second row, but still in the text column rather than spanning the
	   card: the empty cell under the logo is deliberate, so the buttons
	   line up with the race name above them instead of sliding back under
	   the artwork. The markup has actions as a sibling of the body, not a
	   child, so this placement is what keeps them in the same column. */
	.arv-races__actions { grid-area: actions; }

	/* Square, and fixed width so every row's text starts on the same line
	   down the list however tall the card ends up. 80 rather than 96: the
	   16px goes to the buttons below, which is where this width was actually
	   costing something. */
	.arv-races__media {
		aspect-ratio: 1 / 1;
		align-self: flex-start;
		margin-top: 0.8rem;
		margin-left: 0.8rem;
		padding: 0;
		/* No tile behind the badge at this size. The tile colour is one step
		   from the card colour, so stacked it does not read as a frame, it
		   reads as a grey hole punched in the card, and the emptier the
		   artwork the bigger the hole. The fixed square still does the
		   alignment work; it just does it invisibly. */
		background: transparent;
	}

	.arv-races__body {
		padding: 0.75rem 0.9rem 0.1rem;
		min-width: 0;
	}

	.arv-races__name { font-size: var(--arv-fs-name); }
	.arv-races__distances { font-size: var(--arv-fs-body); }
	.arv-races__where { margin-bottom: 0.7rem; font-size: var(--arv-fs-meta); }

	/* Two equal columns rather than two content-sized buttons. Sized to
	   their labels the pair ends at a different point on every card, so a
	   scrolling list has a ragged right edge that moves as the phase changes
	   down it (Register, Live Results and Join Waitlist are all different
	   widths). Equal columns across the full card width fit the longest
	   label at a readable size and line every card up with the one above. */
	/* Two equal columns rather than two content-sized buttons. Sized to
	   their labels the pair ends at a different point on every card, so a
	   scrolling list has a ragged right edge that moves as the phase changes
	   down it (Register, Live Results and Join Waitlist are all different
	   widths). Equal columns line every card up with the one above. */
	.arv-races__actions {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: 0.45rem;
		padding: 0.35rem 0.9rem 0.85rem 0;
	}

	/* 31px measured on a real iPhone viewport, against Apple's 44px minimum
	   for a touch target. Registration is the one thing on this page anyone
	   is trying to tap.
	
	   The :link and :visited copies are load bearing, not noise. The base
	   rule is written as ".arv-races__cta, .arv-races__cta:link,
	   .arv-races__cta:visited" so that a theme's own anchor styles cannot
	   recolour these buttons, and that makes it two classes' worth of
	   specificity. A media query adds none, so a plain ".arv-races__cta"
	   here loses to it on every anchor: until this was matched, everything
	   below that the base rule also sets (padding, font-size,
	   letter-spacing) was silently ignored on every real button, and only
	   min-height, which the base rule does not set, ever took effect. */
	.arv-races__cta,
	.arv-races__cta:link,
	.arv-races__cta:visited,
	.arv-races__details,
	.arv-races__details:link,
	.arv-races__details:visited {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		/* 40px rather than the 44px Apple asks for. These sit inside the
		   text column now, so the width they have is what is left after the
		   logo, and a shorter button is what buys the label enough room to
		   stay on one line. Still a long way from the 31px this started at,
		   and the whole row is tappable padding, not just the text. */
		min-height: 40px;
		padding: 0.45rem 0.4rem;
		font-size: var(--arv-fs-btn);
		letter-spacing: 0.4px;
		/* Grid items default to min-width:auto, so a nowrap label wider than
		   its 1fr track cannot shrink into it and spills out of the card
		   instead. This is what lets the track govern the button rather than
		   the longest label governing the track. */
		min-width: 0;
		/* Both, not just the secondary. Only .arv-races__details carried
		   nowrap, so "Race Details" stayed on one line while "Live Results"
		   and "Join Waitlist" broke over two beside it, making the primary
		   button the taller of a pair that is supposed to match. */
		white-space: nowrap;
	}
}

/* The longest label in the set, "Join Waitlist", still runs about 8px past
   an equal half of a 320px screen. Rather than shrink every button on every
   phone to suit the narrowest one and the rarest phase, the type steps down
   only here. Below this there is no width left to win back and the pair
   would have to stack. */
@media (max-width: 359px) {
	/* Same specificity dance as the block above. */
	.arv-races__cta,
	.arv-races__cta:link,
	.arv-races__cta:visited,
	.arv-races__details,
	.arv-races__details:link,
	.arv-races__details:visited {
		padding-left: 0.4rem;
		padding-right: 0.4rem;
		font-size: var(--arv-fs-btn);
		letter-spacing: 0.3px;
	}
}

/* ======================================================== Calendar == */
/* The full-season reference: one line per race, grouped by month, no
   registration claim of any kind. Deliberately plain, list-not-cards, so it
   reads as an index rather than a second copy of the Upcoming Races grid. */

.arv-calendar {
	/* Set explicitly, not left to inherit. These elements get dropped into
	   whatever Cornerstone column an editor happens to pick, and a centred
	   column turned the entire calendar into centred text on mobile. An
	   element should not change shape based on the box it lands in. */
	text-align: left;
	--arv-teal: #5bb5a2;
	--arv-teal-deep: #2a5e6b;
	/* Matches .arv-map's, and for the same reason: the two stack. */
	padding: 2rem 0;
	background: #ffffff;
	color: #272727;
	font-family: Lato, "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.arv-calendar--dark {
	background: #1d2624;
	color: #f2f2f2;
}

.arv-calendar__inner {
	max-width: 900px;
	margin: 0 auto;
	padding: 0 1.25rem;
}

.arv-calendar__eyebrow {
	margin: 0 0 0.4rem;
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 2px;
	text-transform: uppercase;
	color: var(--arv-accent, #ff2a13);
}

.arv-calendar__heading {
	margin: 0 0 0.5rem;
	font-size: clamp(30px, 4vw, 42px);
	font-weight: 700;
}

.arv-calendar__intro {
	margin: 0 0 2.5rem;
	max-width: 40rem;
	font-size: var(--arv-fs-lead);
	line-height: 1.6;
	opacity: 0.72;
}

.arv-calendar__month + .arv-calendar__month {
	margin-top: 2rem;
}

/* A full-width 2px accent rule under every month was the loudest thing on
   the page and there are thirteen of them: the eye reads a stack of red bars
   before it reads a single race. The accent now marks only the label itself,
   the width of the word, and a hairline carries the rest of the line. Same
   structure, a tenth of the shouting. */
.arv-calendar__month-name {
	position: relative;
	display: flex;
	align-items: center;
	gap: 0.9rem;
	margin: 0 0 0.9rem;
	padding: 0;
	border: 0;
	font-size: var(--arv-fs-meta);
	font-weight: 700;
	letter-spacing: 2.5px;
	text-transform: uppercase;
	color: var(--arv-accent, #ff2a13);
}

/* The hairline, drawn as a flexible sibling so it fills whatever the label
   leaves rather than being a border the label sits on top of. */
.arv-calendar__month-name::after {
	content: "";
	flex: 1 1 auto;
	height: 1px;
	background: rgba(128, 128, 128, 0.22);
}

.arv-calendar__rows {
	display: flex;
	flex-direction: column;
}

.arv-calendar__row {
	display: flex;
	align-items: center;
	gap: 1rem;
	padding: 0.7rem 0;
	border-bottom: 1px solid rgba(128, 128, 128, 0.18);
	color: inherit;
	text-decoration: none;
}

/* The filter JS hides a non-matching row by setting the `hidden` attribute.
   That only works if nothing else claims the `display` property for this
   selector: an unconditional `display: flex` above has equal specificity to
   the browser's own `[hidden] { display: none }` default and, being an
   author rule, always wins the tie regardless of source order. Without this,
   every filter (search, state, month, open-only) sets `hidden` correctly and
   nothing visibly changes. */
.arv-calendar__row[hidden] {
	display: none;
}

.arv-calendar__logo {
	flex: 0 0 56px;
	width: 56px;
	height: 56px;
	display: flex;
	align-items: center;
	justify-content: center;
}

.arv-calendar__logo img {
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
	display: block;
}

/* Month over day rather than "AUG 29" on one line: the day is what the eye
   scans for and stacking lets it stay large while the month stays quiet, in
   a column narrow enough not to push the race name around. */
.arv-calendar__day {
	flex: 0 0 3.1rem;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	line-height: 1.1;
}

.arv-calendar__day-month {
	font-size: var(--arv-fs-micro);
	font-weight: 700;
	letter-spacing: 1.5px;
	text-transform: uppercase;
	color: var(--arv-accent, #ff2a13);
}

.arv-calendar__day-num {
	font-size: var(--arv-fs-name);
	font-weight: 700;
	color: inherit;
}

.arv-calendar__body {
	flex: 1 1 auto;
	min-width: 0;
	display: flex;
	flex-direction: column;
}

.arv-calendar__name {
	font-weight: 700;
	font-size: var(--arv-fs-lead);
}

.arv-calendar__distances,
.arv-calendar__where {
	font-size: var(--arv-fs-meta);
	opacity: 0.65;
}

.arv-calendar__status {
	flex: 0 0 auto;
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 0.5px;
	text-transform: uppercase;
	color: var(--arv-teal-deep);
	white-space: nowrap;
}

.arv-calendar--dark .arv-calendar__status {
	color: var(--arv-teal);
}

.arv-calendar__arrow {
	flex: 0 0 auto;
	opacity: 0.35;
	transition: transform 0.15s ease, opacity 0.15s ease;
}

@media (hover: hover) and (pointer: fine) {
	.arv-calendar__row:hover .arv-calendar__arrow {
		opacity: 1;
		transform: translateX(3px);
	}
	.arv-calendar__row:hover .arv-calendar__name {
		color: var(--arv-accent, #ff2a13);
	}
}

.arv-calendar__row:focus-visible {
	outline: 2px solid var(--arv-accent, #ff2a13);
	outline-offset: -2px;
}

@media (max-width: 619px) {
	.arv-calendar { padding: 2.5rem 0; }
	.arv-calendar__row {
		gap: 0.7rem;
		flex-wrap: wrap;
	}
	.arv-calendar__logo { flex-basis: 44px; width: 44px; height: 44px; }
	.arv-calendar__day { flex-basis: 2.6rem; }
	.arv-calendar__day-num { font-size: var(--arv-fs-name); }
	.arv-calendar__day-month { font-size: var(--arv-fs-micro); }
	.arv-calendar__name { font-size: var(--arv-fs-lead); }
	.arv-calendar__status { display: none; }

	/* Buttons drop to their own full line rather than squeezing in beside a
	   wrapped race name, which is what made them unreadable at 390px. */
	.arv-calendar__actions {
		flex-basis: 100%;
		margin-left: 0;
		padding-left: calc(44px + 0.7rem);
		justify-content: flex-start;
	}

	/* Race Info goes exactly where tapping the row already goes, so on a
	   phone it is a duplicate costing a line per race. Dropping it took the
	   page from 17.9 screens back to 13.4 without losing anything reachable:
	   the row itself is still the link. The state button stays, because
	   "Register" and "Live Results" go somewhere the row does not. */
	.arv-calendar__info { display: none; }

	/* With one button left there is no need for it to own a whole line. */
	.arv-calendar__actions:not(:has(.arv-calendar__action)) { display: none; }
	.arv-calendar__info,
	.arv-calendar__action {
		min-height: 36px;
		padding: 0.4rem 0.7rem;
	}
}

/* A date nobody has committed to yet. Muted rather than accent-coloured: it
   is genuinely less informative than a real date and should not compete with
   one for attention down the list. */
.arv-calendar__day--tbd {
	color: inherit;
	opacity: 0.45;
	font-size: var(--arv-fs-meta);
	letter-spacing: 0.5px;
}

.arv-calendar__hiatus {
	margin-top: 2.5rem;
	padding-top: 0.5rem;
}

.arv-calendar__hiatus-intro {
	margin: 0.5rem 0 0.75rem;
	font-size: var(--arv-fs-body);
	opacity: 0.65;
}

/* No date column at all, so the body starts where a dated row's logo would.
   Left as a plain block rather than faked with an empty spacer: these rows
   are a different kind of thing and reading slightly differently is correct. */
.arv-calendar__row--hiatus {
	opacity: 0.75;
}

.arv-calendar__month-name + .arv-calendar__hiatus-intro {
	margin-top: 0.5rem;
}

/* The row is a container now rather than the link itself, so the main link
   carries the layout it used to. */
.arv-calendar__main {
	display: flex;
	align-items: center;
	gap: 1rem;
	flex: 1 1 auto;
	min-width: 0;
	color: inherit;
	text-decoration: none;
}

/* Live results / results, for the races whose state we actually know. Small
   and teal: it is a secondary offer on a reference list, not the reason the
   row exists. */
.arv-calendar__actions {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	gap: 0.4rem;
	margin-left: 0.9rem;
}

.arv-calendar__info {
	display: inline-flex;
	align-items: center;
	padding: 0.3rem 0.6rem;
	border: 1px solid rgba(128, 128, 128, 0.35);
	color: inherit;
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 1px;
	text-transform: uppercase;
	text-decoration: none;
	white-space: nowrap;
	transition: border-color 0.15s ease, color 0.15s ease;
}

.arv-calendar__action {
	flex: 0 0 auto;
	padding: 0.3rem 0.6rem;
	border: 1px solid var(--arv-teal-deep);
	color: var(--arv-teal-deep);
	font-size: var(--arv-fs-btn);
	font-weight: 700;
	letter-spacing: 1px;
	text-transform: uppercase;
	text-decoration: none;
	white-space: nowrap;
	transition: background 0.15s ease, color 0.15s ease;
}

.arv-calendar--dark .arv-calendar__action {
	border-color: var(--arv-teal);
	color: var(--arv-teal);
}

/* Red means the same thing here as everywhere else on the site: there is
   something to buy. Filled rather than outlined so it out-ranks Race Info
   beside it without needing to be bigger. */
.arv-calendar__action--upcoming,
.arv-calendar__action--upcoming:link,
.arv-calendar__action--upcoming:visited {
	background: var(--arv-accent, #ff2a13);
	border-color: var(--arv-accent, #ff2a13);
	color: #fff;
}

/* Same goldenrod as the homepage cards: sold out, but a waitlist is still
   a real place to click, so it stays filled rather than falling back to the
   default outlined style live/results use. Dark text for the contrast
   reason spelled out on the cards' rule. */
.arv-calendar__action--waitlist,
.arv-calendar__action--waitlist:link,
.arv-calendar__action--waitlist:visited {
	background: #daa520;
	border-color: #daa520;
	color: var(--arv-ink, #272727);
}

@media (hover: hover) and (pointer: fine) {
	.arv-calendar__action:hover {
		background: var(--arv-teal-deep);
		color: #fff;
	}
	.arv-calendar__info:hover {
		border-color: var(--arv-accent, #ff2a13);
		color: var(--arv-accent, #ff2a13);
	}
	a.arv-calendar__action--upcoming:hover {
		background: #c61300;
		border-color: #c61300;
		color: #fff;
	}
	a.arv-calendar__action--waitlist:hover {
		background: #c9971d;
		border-color: #c9971d;
		color: var(--arv-ink, #272727);
	}
	.arv-calendar--dark .arv-calendar__action:hover {
		background: var(--arv-teal);
		color: #12201d;
	}
}

.arv-calendar__action:focus-visible {
	outline: 2px solid var(--arv-teal-deep);
	outline-offset: 2px;
}

@media (max-width: 619px) {
	.arv-calendar__main { gap: 0.7rem; }
	.arv-calendar__action {
		margin-left: 0.5rem;
		padding: 0.4rem 0.5rem;
		font-size: var(--arv-fs-btn);
	}
}


/* ------------------------------------------------ Calendar, phones -- */
/* These come last on purpose. The base .arv-calendar__info rule was appended
   to this file after the mobile block that hides it, so on equal specificity
   source order handed the win to the wrong one and Race Info stayed visible
   on every row. Restating here removes the dependency on where in the file a
   rule happens to sit. */
@media (max-width: 619px) {
	.arv-calendar__info {
		display: none;
	}

	/* One button left, so the row does not need to give it a whole line. */
	.arv-calendar__actions {
		flex-basis: auto;
		width: auto;
		margin-left: auto;
		padding-left: 0;
	}

	/* Long race names wrap; keeping the button clear of them stops the row
	   collapsing into a stack. */
	.arv-calendar__body {
		min-width: 0;
	}
}

/* The row itself has to stop wrapping for any of the above to take effect.
   .arv-calendar__row sets flex-wrap: wrap higher up, from when the button
   was deliberately given its own full-width line, and flex-wrap decides
   where to break from each item's content size before any shrinking
   happens. So the block above could hand the actions `flex-basis: auto` and
   `margin-left: auto` all it liked and they still landed on a second line,
   just right-aligned there instead of left.

   That second line is what made every row read as top-justified: with the
   button below the text rather than beside it, the text sits at the top of
   a much taller row and the button's centre ended up 65 to 99px below the
   row's. Measured at three phone widths; with the row held on one line it
   is within 1px at all of them.

   Not applied below 380px. There genuinely is not room for two columns on a
   360px screen: holding the row together there squeezes the text column
   until names wrap more, and the list came out ~10% taller (14302px to
   15738px) with rows up to 335px. Above 380 it is shorter on both counts,
   12645px to 10912px at 430. So the small phones keep the stacked layout,
   which is the honest answer for the space they have. */
@media (max-width: 619px) and (min-width: 380px) {
	.arv-calendar__row {
		flex-wrap: nowrap;
	}

	/* The series chip is white-space: nowrap, so on the narrower text column
	   a one-line label runs straight out of it and lands on top of the
	   button. "WHITE MOUNTAIN ENDURANCE" did exactly that. Holding the row on
	   one line is what exposed this; the chip was always overflowing, it just
	   had a full-width line to overflow into before. Clipped rather than
	   allowed to wrap, so the chip stays one line tall and the row height
	   stays predictable. */
	.arv-calendar__body {
		overflow: hidden;
	}

}

/* ------------------------------------------------ Calendar filters -- */
/* Hidden until the script that drives it has run. A search box that does
   nothing because its JavaScript failed to load is worse than no search box:
   it reads as broken rather than absent, and the list underneath is complete
   either way. */
.arv-calendar__filters {
	display: none;
}

.arv-calendar__filters.is-ready {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: 0.9rem;
	margin: 0 0 1.75rem;
	padding-bottom: 1.25rem;
	border-bottom: 1px solid rgba(128, 128, 128, 0.22);
}

.arv-calendar__field {
	display: flex;
	flex-direction: column;
	gap: 0.3rem;
	/* State, Series and Month share one width so they wrap together as a
	   clean row rather than however many happen to fit next to Search. Search
	   itself overrides this below to claim the full row on its own instead. */
	flex: 1 1 9rem;
}

.arv-calendar__field--search {
	/* Full width, always, not just on the mobile breakpoint below: a text
	   input is a different kind of control than the three dropdowns beside
	   it, and at in-between widths letting it share a row with them was what
	   pushed Month (and the checkbox trailing it) onto an orphaned line of
	   their own. Search on its own row, dropdowns together on the next,
	   wrapping evenly, is the same shape at every width. */
	flex: 1 1 100%;
	min-width: 0;
}

.arv-calendar__field-label {
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 1.5px;
	text-transform: uppercase;
	opacity: 0.6;
}

.arv-calendar__search,
.arv-calendar__select {
	padding: 0.55rem 0.7rem;
	border: 1px solid rgba(128, 128, 128, 0.4);
	border-radius: 0;
	background: transparent;
	color: inherit;
	font-family: inherit;
	/* 16px, not 0.92rem. Same fix as the map's search box: the comment below
	   describes the right idea but the value above it did not actually
	   deliver it, at 14.72px, which is what let iOS zoom the page on focus
	   in spite of the comment. The label above carries the small type
	   instead, so the input itself can afford to be a full size larger. */
	font-size: var(--arv-fs-input);
	min-height: 44px;
}

.arv-calendar__search:focus,
.arv-calendar__select:focus {
	outline: 2px solid var(--arv-accent, #ff2a13);
	outline-offset: -1px;
	border-color: transparent;
}

.arv-calendar__toggle {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	min-height: 44px;
	font-size: var(--arv-fs-btn);
	cursor: pointer;
}

.arv-calendar__toggle input {
	width: 1rem;
	height: 1rem;
	accent-color: var(--arv-accent, #ff2a13);
}

.arv-calendar__count {
	flex: 1 0 100%;
	margin: 0;
	font-size: var(--arv-fs-meta);
	opacity: 0.7;
}

/* Every month heading hidden means the filter matched nothing, and the
   section would otherwise be a heading over blank space. */
.arv-calendar.is-empty .arv-calendar__list {
	opacity: 0.35;
}

@media (max-width: 619px) {
	.arv-calendar__filters.is-ready {
		gap: 0.6rem;
	}
	.arv-calendar__field {
		flex: 1 1 8rem;
	}
}

/* ========================================================= Race map == */

.arv-map {
	text-align: left;
	/* The map and the calendar sit directly on top of each other on /races/,
	   so these paddings stack: 3.5rem each made a 7rem trench between "Find a
	   race near you" and the heading below it, which read as a gap rather
	   than as separation. 2rem each still separates them clearly at 4rem
	   total. */
	padding: 2rem 0;
	font-family: Lato, "Helvetica Neue", Helvetica, Arial, sans-serif;
	color: #272727;
}

.arv-map__inner {
	max-width: 1200px;
	margin: 0 auto;
	padding: 0 1.25rem;
}

/* Anchors the collapse toggle, which floats over the map's top right
   corner while the map is open.

   The toggle is positioned against this rather than against
   .arv-map__inner, and that distinction was a real bug: inner starts at the
   eyebrow, so on a map with a heading the button landed level with the
   heading instead of over the map. This wrapper starts at the map itself,
   so "10px from the top" means 10px into the map at any heading length,
   including none. */
.arv-map__stage {
	position: relative;
}

/* Full bleed. The heading stays in the content column, since a heading at
   the window edge stops lining up with every other heading on the page;
   only the panel holding the canvas escapes.

   This has to break out of an ancestor whose width this stylesheet does not
   know: the element is dropped into a Cornerstone section, row and column,
   each with its own max-width and padding. Undoing only this plugin's own
   padding, which is what the first version did, gets the map to the edge of
   the Cornerstone column and no further, which looked identical to full
   width not working at all.

   So it is measured from the viewport instead. 50% is half the parent,
   50vw is half the window, and the difference between them is exactly how
   far the parent's left edge sits from the window's, whatever chain of
   containers produced it.

   --arv-sbw is the scrollbar width, measured once in JS and set on <html>.
   It is the whole reason this is not a plain calc(50% - 50vw): 100vw counts
   the scrollbar on Windows and Linux but not on macOS's overlay scrollbars,
   so the unadjusted version overhangs by ~15px and adds a horizontal
   scrollbar that is invisible to anyone checking on a Mac. It defaults to
   0px, which is correct when there is no scrollbar and when JS never runs. */
.arv-map--full .arv-map__panel {
	margin-left: calc(50% - 50vw + (var(--arv-sbw, 0px) / 2));
	margin-right: calc(50% - 50vw + (var(--arv-sbw, 0px) / 2));
}

/* Sits flush under whatever is above it when full width, so a hero and the
   map read as one surface rather than two stacked boxes. */
.arv-map--full {
	padding-top: 0;
}

.arv-map__eyebrow {
	margin: 0 0 0.4rem;
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 2px;
	text-transform: uppercase;
	color: var(--arv-accent, #ff2a13);
}

.arv-map__heading {
	margin: 0 0 1rem;
	font-size: clamp(30px, 4vw, 42px);
	font-weight: 700;
	line-height: 1.15;
}

.arv-map__canvas {
	width: 100%;
	background: #eceff1;
}

/* Tiles are left at the 256px Leaflet gives them, deliberately.

   They used to be forced to 258px on retina, to overlap away the pale
   hairline that appears where two upscaled tiles meet. On this site that
   made it worse, not better, and visibly so: thick white seams on both
   axes rather than faint ones. Reported from an iPad, reproduced at 2x and
   3x on the live /races/ page.

   The reason the original measurement disagreed is that it was taken with
   the map sitting at a whole pixel. Here it does not: the full-bleed
   breakout puts .arv-map__canvas at x = 18.75 inside a 986.5px container,
   so every tile lands on a half device pixel and gets resampled. Upscaling
   256 to 258 then paints each tile's own softened edge on top of its
   neighbour's good pixels, which is the bright line, and the overlap is
   what creates it rather than what hides it.

   Measured on the live page by summing the brightness spike at each tile
   boundary against the columns either side, lower being flatter:

                    2x        3x
     256 (none)    103.7     110.5
     257           127.1     127.6
     258           128.0     128.1
     259           127.8     128.4
     260           127.1     127.9

   256 wins at both densities, and the difference is obvious side by side.
   Pixel-snapping the tile pane and image-rendering: -webkit-optimize-contrast
   were both tried on top and scored identically to plain 256, so neither is
   carried. What is left at 256 is a faint hairline from the fractional
   container offset, an order of magnitude less visible than what it
   replaces, and not fixable from CSS without moving the container itself. */

/* Race pin. A divIcon, so this is styling a real element rather than an
   image: Leaflet's stock marker is a fixed PNG that cannot be recoloured,
   and it also resolves its own image path relative to the CSS, which breaks
   when the CSS is on a CDN and the page is not. */
.arv-map__pin {
	background: none;
	border: 0;
}

.arv-map__pin svg {
	display: block;
	filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.4));
}

/* Cluster count bubble. MarkerCluster.Default.css, the plugin's stock
   green-and-yellow skin, is deliberately not loaded; this replaces it in
   Aravaipa's teal rather than overriding it. */
.arv-map__cluster {
	background: none;
	border: 0;
}

.arv-map__cluster span {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	border-radius: 50%;
	background: #2a5e6b;
	/* A ring in the tile background's colour, not white, so the bubble reads
	   as sitting on the map rather than as a hole punched through it. */
	box-shadow: 0 0 0 4px rgba(42, 94, 107, 0.28);
	color: #fff;
	font-weight: 700;
	font-size: var(--arv-fs-label);
	line-height: 1;
}

/* Jump-to-a-race search. Lives inside the map as a bottom-left Leaflet
   control, with its results opening upward.
   
   Upward is what makes this possible. A list dropping downward from a
   control sitting near the bottom of the canvas gets clipped by the canvas
   edge, which is exactly where it would open from; opening upward it
   expands into the map instead, over the tiles, where there is always room.
   
   z-index sits above Leaflet's marker and popup panes (600 and 700) so a
   result is never drawn behind a pin or an open popup. */
.arv-map__search {
	position: relative;
	/* A row, because Near me now sits in here beside the input rather than in
	   a corner of its own: the two answer the same question and belong
	   together. The input takes the slack, the button keeps its own width. */
	display: flex;
	align-items: stretch;
	gap: 6px;
	width: 24rem;
	max-width: calc(100vw - 4rem);
	margin: 0;
	z-index: 900;
}

.arv-map__search-input {
	flex: 1 1 auto;
	min-width: 0;
}

/* Near me, inline beside the search rather than as its own Leaflet control.
   The .leaflet-bar class comes along for the border and shadow, but the
   corner positioning it normally implies does not apply here. */
.arv-map__nearme--inline {
	flex: 0 0 auto;
	position: static;
	margin: 0;
}

/* Matches the search input beside it rather than keeping Leaflet's heavier
   bar treatment. The two boxes were already the same height, but
   .leaflet-bar draws a 2px near-black border where the input draws a 1px
   grey one, so the button read as the chunkier of the pair and the two did
   not look like one control.

   Scoped under .arv-map__canvas for the same reason as everything else that
   fights Leaflet here: ".leaflet-bar" is one class and prints after this
   file, so a plain ".arv-map__nearme--inline" ties and loses on source
   order. Measured after changing it rather than assumed, which is how the
   first attempt at this rule was caught still rendering at 2px. */
.arv-map__canvas .leaflet-bar.arv-map__nearme--inline {
	border: 1px solid rgba(0, 0, 0, 0.2);
	box-shadow: 0 1px 5px rgba(0, 0, 0, 0.4);
}

.arv-map__search-input {
	padding: 0.55rem 0.7rem;
	border: 1px solid rgba(0, 0, 0, 0.2);
	border-radius: 0;
	/* Opaque, not transparent: this sits over map tiles now, and a
	   see-through input over a road map is unreadable. */
	background: #fff;
	color: #272727;
	font-family: inherit;
	/* 16px, not the 0.92rem (14.72px) every other input on this page uses.
	   The comment already here claimed this was handled and it was not: iOS
	   Safari zooms the entire page in on focus for any input under 16px,
	   whatever a comment two lines below says about it. That is what "the
	   screen zooms when I go to type" was: not the map zooming, the whole
	   viewport, triggered by focusing this exact input. Every browser's
	   default form-control size is already 16px; this only exists to
	   override the smaller size the rest of the map's type uses. */
	font-size: var(--arv-fs-input);
	box-shadow: 0 1px 5px rgba(0, 0, 0, 0.4);
	min-height: 44px;
}

.arv-map__search-input::placeholder {
	color: #6b6b6b;
	opacity: 1;
}

.arv-map__search-input:focus {
	outline: 2px solid var(--arv-accent, #ff2a13);
	outline-offset: -1px;
	border-color: transparent;
}

.arv-map__results {
	display: none;
	position: absolute;
	z-index: 1;
	/* Opens upward, so it never runs off the bottom of the canvas. */
	bottom: 100%;
	left: 0;
	/* Sized to the input rather than stretched across Near me beside it, so
	   the list lines up with the thing that produced it. */
	width: 19rem;
	max-width: 100%;
	margin: 0 0 4px;
	padding: 0;
	list-style: none;
	background: #fff;
	border: 1px solid rgba(0, 0, 0, 0.2);
	box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.25);
	/* Sized to fit all six results exactly, given the fixed row height the
	   truncation below guarantees. Without that, a long race name wrapped to
	   two lines and the sixth result was clipped mid-word against this
	   ceiling, which reads as broken rather than as "scroll for more".
	   overflow stays on as a backstop for large text settings. */
	max-height: 22rem;
	overflow-y: auto;
}

.arv-map__search.is-open .arv-map__results {
	display: block;
}

.arv-map__results li {
	display: flex;
	flex-direction: column;
	gap: 0.1rem;
	padding: 0.5rem 0.7rem;
	cursor: pointer;
	color: #272727;
}

.arv-map__results li.is-active,
.arv-map__results li:hover {
	background: rgba(42, 94, 107, 0.1);
}

/* One line each, ellipsised. Race names run long ("Javelina Jundred
   Presented by: HOKA", "Snow Mountain Ranch Trail Running Festival") and
   wrapping them made every row a different height, which both looked
   unsettled and made the list's height unpredictable enough to clip the
   last result. The distinguishing part of a race name is at the front, so
   the tail is the safe thing to lose. */
.arv-map__result-name,
.arv-map__result-where {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.arv-map__result-name {
	font-size: var(--arv-fs-body);
	font-weight: 700;
}

.arv-map__result-where {
	font-size: var(--arv-fs-meta);
	opacity: 0.7;
}

.arv-map__missing {
	margin: 1rem 0 0;
	font-size: var(--arv-fs-body);
	opacity: 0.7;
}

.arv-map__fallback ul {
	margin: 1rem 0 0;
	padding-left: 1.1rem;
	font-size: var(--arv-fs-body);
}

/* Series affiliation on a calendar row. Set apart from the distance pills
   sitting next to it: those are what you can enter, this is what the race
   belongs to, and they should not read as the same kind of thing. Outlined
   rather than filled grey, and it does not wrap.

   Teal, not the accent red. Red is already doing two jobs on this page: it
   is the month heading and it is the Register button. A series chip is
   neither a heading nor an action, it is metadata, and a third red thing
   in the same row made the list read as busier than it is. Teal is what
   the rest of the plugin already uses for "information, not an offer",
   which is exactly what this is. */
.arv-calendar__series {
	display: inline-block;
	align-self: flex-start;
	margin: 0.1rem 0;
	padding: 0.05rem 0.35rem;
	border: 1px solid var(--arv-teal-deep, #2a5e6b);
	font-size: var(--arv-fs-micro);
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	line-height: 1.6;
	white-space: nowrap;
	color: var(--arv-teal-deep, #2a5e6b);
}

@media (max-width: 619px) {
	/* Wraps rather than truncates, and stated here rather than in the
	   calendar's mobile query further up the file, because the base rule
	   above is declared below that query and would win on source order.

	   At the 7.8px this chip used to render at, "White Mountain Endurance"
	   fitted its column and the ellipsis never fired. At a legible size it
	   wants 187px against the 149px the narrowest row gives it, so holding one
	   line now means clipping the series name off every White Mountain race. A
	   row one line taller costs less than a series nobody can read. */
	.arv-calendar__series {
		max-width: 100%;
		white-space: normal;
	}
}

/* Distance chips in the calendar list, matching the map popup's. */
.arv-calendar__distances {
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem;
	margin: 0.15rem 0;
}

.arv-calendar__pill {
	display: inline-block;
	padding: 0.05rem 0.35rem;
	background: rgba(0, 0, 0, 0.06);
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 0.3px;
	line-height: 1.5;
	white-space: nowrap;
	opacity: 1;
}

/* Hide map / Show map toggle. Right-aligned above the map so it reads as
   belonging to the panel it folds, rather than to the heading above it. */
.arv-map__toggle {
	display: flex;
	align-items: center;
	gap: 0.35rem;
	margin: 0 0 0.5rem auto;
	padding: 0.35rem 0.6rem;
	border: 1px solid rgba(0, 0, 0, 0.2);
	background: #fff;
	font-family: inherit;
	font-size: var(--arv-fs-btn);
	font-weight: 700;
	letter-spacing: 0.5px;
	text-transform: uppercase;
	color: var(--arv-ink, #272727);
	cursor: pointer;
}

/* While the map is open the toggle floats over its top right corner, the
   same treatment the other map controls get, so the strip of page above the
   map disappears and the map starts immediately.

   Only while open, deliberately. A control positioned over a collapsed map
   would be positioned over nothing: the panel it was covering is display
   none and has no height, so the button would land on whatever followed.
   Collapsed, it drops back into normal flow where it is still the only
   thing to press. */
.arv-map__toggle[aria-expanded="true"] {
	position: absolute;
	top: 10px;
	right: 22px;
	z-index: 800;
	margin: 0;
	box-shadow: 0 1px 5px rgba(0, 0, 0, 0.4);
}

.arv-map--full .arv-map__toggle[aria-expanded="true"] {
	right: 10px;
}

/* Collapsed, this stops being a small button in a corner and becomes a
   full-width bar.

   Hidden, the map contributes no height at all, so a 90px button floated to
   the right of an empty strip was the only trace left that there had ever
   been a map, and on a phone it was a thumbnail-sized target with no
   context. Expanded it can afford to be small and out of the way because
   the map underneath explains it; collapsed there is nothing left to
   explain it, so it has to say so itself. */
.arv-map__toggle[aria-expanded="false"] {
	width: 100%;
	justify-content: center;
	gap: 0.5rem;
	margin: 0;
	padding: 0.9rem 1rem;
	border: 1px solid rgba(0, 0, 0, 0.15);
	background: var(--arv-races-card, #f7f7f7);
	font-size: var(--arv-fs-btn);
}

.arv-map__toggle[aria-expanded="false"]:hover {
	background: #f0f0f0;
	/* The shared hover turns the border accent red, which on a small button
	   is a highlight and on a bar spanning the page is two long red rules.
	   The label still goes red; the frame stays quiet. */
	border-color: rgba(0, 0, 0, 0.15);
}

/* Full width and collapsed, the bar spans the window, so its own side
   border would be the only thing suggesting an edge that is not there. */
.arv-map--full .arv-map__toggle[aria-expanded="false"] {
	border-left: 0;
	border-right: 0;
}

/* Push Leaflet's own top-right controls clear of the overlaid toggle, so
   Near Me sits under it rather than behind it. */
.arv-map__canvas .leaflet-top.leaflet-right {
	margin-top: 34px;
}

.arv-map__toggle:hover {
	border-color: var(--arv-accent, #ff2a13);
	color: var(--arv-accent, #ff2a13);
}

.arv-map__toggle-caret {
	width: 0;
	height: 0;
	border-left: 4px solid transparent;
	border-right: 4px solid transparent;
	border-top: 5px solid currentColor;
	transition: transform 0.15s ease;
}

/* Points down when open (click to fold), up when closed (click to reveal). */
.arv-map__toggle[aria-expanded="false"] .arv-map__toggle-caret {
	transform: rotate(180deg);
}

/* "Near me" control. Sits in Leaflet's own .leaflet-bar so it inherits the
   zoom buttons' border, shadow and stacking, then widens to fit a label:
   a lone circle glyph reads as decoration, the words say what it does. */
.arv-map__nearme {
	background: #fff;
}

/* Every property here is scoped past Leaflet, not just the width. Leaflet's
   ".leaflet-bar a" sets display:block, and a bare ".arv-map__nearme a" ties
   with it on specificity and loses on source order, so display:flex never
   applied and the gap it depends on did nothing: the glyph and the label
   rendered flush against each other. */
.arv-map__canvas .leaflet-bar.arv-map__nearme a {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.3rem;
	font-family: Lato, "Helvetica Neue", Helvetica, Arial, sans-serif;
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 0.5px;
	text-transform: uppercase;
	text-decoration: none;
	white-space: nowrap;
}

/* Leaflet sets a fixed square on its bar buttons, and it does it twice:
   ".leaflet-bar a" at 26px and ".leaflet-touch .leaflet-bar a" at 30px. The
   first ties with a bare ".arv-map__nearme a" on specificity and wins on
   source order (Leaflet's stylesheet is enqueued from the render function,
   so it prints after this file), and the second outranks it outright. Either
   way the button stayed 26px wide and the label spilled out of the white
   box. Scoping under .arv-map__canvas puts this at three classes plus a
   type, which clears both. Same specificity trap as the popup name link. */
.arv-map__canvas .leaflet-bar.arv-map__nearme a,
.arv-map__canvas .leaflet-bar.arv-map__nearme a:hover {
	width: auto;
	/* 44px, not Leaflet's 26 or 30. This is a primary action on a phone and
	   those sizes are below every published minimum for a touch target; the
	   button was a 30px box holding a hairline glyph. Height matches the
	   search input beside it so the pair reads as one control. */
	min-width: 44px;
	height: 44px;
	padding: 0 0.6rem;
	color: var(--arv-ink, #272727);
}

.arv-map__nearme-icon {
	flex: 0 0 auto;
	display: block;
}

/* Lift the search row clear of the tile attribution. Leaflet puts that in
   the opposite bottom corner but in the same horizontal band, so at any map
   width where this row reaches across, the two collided.

   Scoped under .arv-map__canvas because Leaflet's own
   ".leaflet-bottom .leaflet-control { margin-bottom: 10px }" is two classes
   and prints after this file, so a plain ".arv-map__search" loses to it and
   the margin silently does nothing. Same trap as the Near me sizing above
   and the popup name link: this stylesheet is enqueued before Leaflet's. */
.arv-map__canvas .leaflet-bottom .arv-map__search {
	margin-bottom: 26px;
}

.arv-map__canvas .leaflet-bar.arv-map__nearme a.is-busy {
	opacity: 0.55;
	pointer-events: none;
}

@media (max-width: 480px) {
	/* On a phone the label competes with the map itself for width, so the
	   icon carries it. The button stays a full 44px square rather than
	   shrinking to the icon: dropping the text is a reason to make the
	   target simpler, not smaller. */
	.arv-map__nearme-label {
		display: none;
	}

	.arv-map__canvas .leaflet-bar.arv-map__nearme a {
		padding: 0;
		width: 44px;
	}

	/* Narrow enough that the row cannot reach the attribution in the
	   opposite corner. */
	.arv-map__search {
		width: calc(100vw - 5.5rem);
	}
}

/* Pin hover: subtle lift so pins read as clickable. Gated on fine pointer so
   iOS Safari does not require a double-tap to open a popup. */
@media (hover: hover) and (pointer: fine) {
	.arv-map__canvas .leaflet-marker-icon {
		transition: transform 0.15s ease, filter 0.15s ease;
		cursor: pointer;
	}

	.arv-map__canvas .leaflet-marker-icon:hover {
		transform: scale(1.18) translateY(-3px);
		filter: brightness(0.82) saturate(1.4);
	}
}

/* Leaflet's popup is a white rounded card by default. These rules bring the
   contents into the site's own language without fighting the container it
   draws, which it positions and sizes itself. */
.arv-map__popup {
	min-width: 13rem;
	font-family: Lato, "Helvetica Neue", Helvetica, Arial, sans-serif;
}

/* Division logo at the top of the card. Max-height keeps a square badge and
   a wide lockup at roughly the same visual weight. */
/* White-on-transparent artwork needs something to sit against. Only Bad
   Beard's mark is like this; the other five average a luminance of 74-149
   against its 255, so this is deliberately opt-in per logo rather than a
   backing behind all of them. Padded and inline-block so the chip hugs the
   mark instead of spanning the card. */
.arv-map__popup-logo--dark {
	padding: 0.2rem 0.3rem;
	background: var(--arv-ink, #272727);
	border-radius: 2px;
	box-sizing: content-box;
}

.arv-map__popup-logo {
	display: block;
	max-width: 100%;
	max-height: 2rem;
	width: auto;
	height: auto;
	object-fit: contain;
	object-position: left center;
	margin-bottom: 0.45rem;
}

.arv-map__popup-date {
	margin: 0 0 0.1rem;
	font-family: Bitter, Georgia, "Times New Roman", serif;
	font-size: var(--arv-fs-label);
	font-weight: 600;
	font-style: italic;
	letter-spacing: 0.3px;
	color: var(--arv-accent, #ff2a13);
}

.arv-map__popup-name {
	margin: 0 0 0.25rem;
	font-size: var(--arv-fs-lead);
	font-weight: 700;
	line-height: 1.2;
}

/* Scoped under .arv-map__popup, not bare .arv-map__popup-name-link: Leaflet's
   own CSS carries ".leaflet-container a { color: #0078A8; }" (one class + one
   type = higher specificity than this single class alone), so an unscoped
   rule here lost to Leaflet's blue regardless of source order. The race name
   rendered as a default-looking hyperlink instead of the site's own ink the
   moment it became clickable. Two classes beats Leaflet's class+type. */
.arv-map__popup .arv-map__popup-name-link {
	color: inherit;
	text-decoration: none;
}

.arv-map__popup .arv-map__popup-name-link:hover {
	color: var(--arv-accent, #ff2a13);
	text-decoration: none;
}

/* Distances as inline pills instead of a comma list. */
.arv-map__popup-distances {
	display: flex;
	flex-wrap: wrap;
	gap: 0.3rem;
	margin: 0 0 0.2rem;
}

.arv-map__popup-pill {
	display: inline-block;
	padding: 0.1rem 0.4rem;
	background: rgba(0, 0, 0, 0.06);
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 0.3px;
	line-height: 1.5;
	white-space: nowrap;
}

.arv-map__popup-where {
	margin: 0 0 0.15rem;
	font-size: var(--arv-fs-meta);
	line-height: 1.4;
	opacity: 0.7;
}

.arv-map__popup-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	margin: 0.5rem 0 0;
}

.arv-map__popup-cta,
.arv-map__popup-info {
	display: inline-flex;
	align-items: center;
	padding: 0.4rem 0.7rem;
	font-size: var(--arv-fs-btn);
	font-weight: 700;
	letter-spacing: 1px;
	text-transform: uppercase;
	text-decoration: none;
	white-space: nowrap;
	border: 1px solid transparent;
}

.arv-map__popup-cta--upcoming {
	background: var(--arv-accent, #ff2a13);
	border-color: var(--arv-accent, #ff2a13);
	color: #fff;
}

.arv-map__popup-cta--live,
.arv-map__popup-cta--results {
	background: #2a5e6b;
	border-color: #2a5e6b;
	color: #fff;
}

.arv-map__popup-cta--waitlist {
	background: #daa520;
	border-color: #daa520;
	color: #272727;
}

.arv-map__popup-info {
	border-color: rgba(128, 128, 128, 0.45);
	color: #272727;
}

/* Leaflet sets its own link colour globally; these are buttons, not links,
   and must not inherit it. */
.arv-map__popup a.arv-map__popup-cta,
.arv-map__popup a.arv-map__popup-cta:hover,
.arv-map__popup a.arv-map__popup-info:hover {
	text-decoration: none;
}

.arv-map__popup a.arv-map__popup-cta--upcoming,
.arv-map__popup a.arv-map__popup-cta--upcoming:hover {
	color: #fff;
}

.arv-map__popup a.arv-map__popup-cta--live,
.arv-map__popup a.arv-map__popup-cta--results,
.arv-map__popup a.arv-map__popup-cta--live:hover,
.arv-map__popup a.arv-map__popup-cta--results:hover {
	color: #fff;
}

.arv-map__popup a.arv-map__popup-cta--waitlist,
.arv-map__popup a.arv-map__popup-cta--waitlist:hover {
	color: #272727;
}

.arv-map__popup a.arv-map__popup-info,
.arv-map__popup a.arv-map__popup-info:hover {
	color: #272727;
}

@media (max-width: 619px) {
	.arv-map { padding: 2.5rem 0; }
}

/* =================================================== Featured race == */
/* One named race, promoted to a full block wherever an editor drops it,
   independent of where it sorts in Aravaipa Upcoming Races by date. Visual
   language borrowed from the hero (image + scrim + big date/name lockup)
   since the job is the same: stop a scrolling visitor on one race. Phase
   colours borrowed from the calendar and the cards, since it is driven by
   the same arv_upcoming_races_action() they are and has to agree with them
   about what a given phase means. */

.arv-featured {
	--arv-teal: #5bb5a2;
	--arv-teal-deep: #2a5e6b;
	--arv-accent: #ff2a13;
	box-sizing: border-box;
	/* Set explicitly, not left to inherit. This lands in whatever Cornerstone
	   column an editor drops it into, and that column is centred on the live
	   homepage, which centred every line of this block. That is not just a
	   look: the scrim behind the copy is deliberately weighted to the left, so
	   centred text drifted off the dark side of the gradient and sat on top of
	   the bright part of the photo. The calendar and the region map both carry
	   this same declaration for the same reason. */
	text-align: left;
}

.arv-featured *  {
	box-sizing: inherit;
}

.arv-featured--dark {
	color: #fff;
}

.arv-featured--light {
	color: #272727;
}

.arv-featured__panel {
	position: relative;
	padding: 4.5rem 1.5rem;
	background-color: #1d2624;
	background-size: cover;
	/* Biased low: these are desert race photos, where the sky is the empty
	   half and the runners and horizon sit in the lower third. Centring the
	   crop cuts the subject in half on a wide, short panel. */
	background-position: center 60%;
	overflow: hidden;
}

.arv-featured--light .arv-featured__panel {
	background-color: var(--arv-races-card, #f7f7f7);
}

.arv-featured--image .arv-featured__panel {
	background-image: var(--arv-featured-image);
}

/* A pseudo element rather than a background blend, same reasoning as the
   hero's: the overlay opacity control then works identically whether or
   not an image is actually set, rather than needing its own code path for
   the no-image case. */
/* A gradient, not a flat wash. A uniform black veil over a photo dims the
   whole image equally, which costs the picture its light without buying the
   text much contrast where the text actually is. Weighted to the left, where
   the copy sits, so the sky and the runners on the right stay bright and the
   words still have something solid behind them. */
.arv-featured--image .arv-featured__panel::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		100deg,
		rgba(8, 12, 16, 0.92) 0%,
		rgba(8, 12, 16, 0.78) 38%,
		rgba(8, 12, 16, 0.32) 68%,
		rgba(8, 12, 16, 0.15) 100%
	);
	opacity: calc(var(--arv-overlay, 0.55) * 1.6);
}

/* Full bleed. Same technique as the full-width map, and for the same
   reason: 50% minus 50vw is exactly how far this element's container sits
   from the window edge, whatever chain of Cornerstone section/row/column
   produced that container, which a fixed negative margin could not know.
   --arv-sbw corrects for the scrollbar width difference between platforms;
   see the map's own rule for the full reasoning. Declared again here
   rather than shared, since the two elements do not otherwise depend on
   each other and a future change to one should not have to remember the
   other exists. */
.arv-featured--full .arv-featured__panel {
	margin-left: calc(50% - 50vw + (var(--arv-sbw, 0px) / 2));
	margin-right: calc(50% - 50vw + (var(--arv-sbw, 0px) / 2));
}

.arv-featured__inner {
	position: relative;
	max-width: 68rem;
	margin: 0 auto;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 2.5rem 3rem;
}

/* Takes the slack so the card keeps its own width, and can shrink past its
   content's natural width rather than forcing the card to wrap early. */
.arv-featured__main {
	flex: 1 1 22rem;
	min-width: 0;
}

/* The race's own logo, at a size where it reads as a mark rather than as a
   background. Capped by height, not width, so a wide lockup and a squarer
   badge land at the same optical weight, the same rule the region map's
   hover card uses. */
.arv-featured__logo {
	display: block;
	width: auto;
	/* Big enough that the lockup's own internal detail survives. These are
	   illustrated badges with the race name set inside them, not simple
	   wordmarks, so at thumbnail size the type inside them goes to mush and
	   the whole thing reads as a smudge rather than as branding. */
	max-width: min(100%, 30rem);
	max-height: 13rem;
	margin: 0 0 1.25rem;
	object-fit: contain;
	object-position: left center;
	/* Most of these badges are dark artwork on transparent, which is the
	   same trap the Bad Beard logo hit on the map: a dark mark on a dark
	   scrim disappears. A soft dark halo behind it separates the mark from
	   whatever part of the photo happens to sit under it, without putting a
	   visible box around the logo. */
	filter: drop-shadow(0 2px 18px rgba(0, 0, 0, 0.85));
}

/* Kept in the markup, hidden on screen. Every Aravaipa race logo already
   sets the race's name, so showing the heading too prints it twice in two
   typefaces. This keeps one real <h2> in the document for search engines
   and screen readers without the visual duplication. */
.arv-featured__name--sr {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.arv-featured__eyebrow {
	display: inline-block;
	margin: 0 0 1.1rem;
	padding: 0.35rem 0.75rem;
	border: 1px solid var(--arv-teal);
	font-size: var(--arv-fs-label);
	font-weight: 800;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--arv-teal);
}

.arv-featured--light .arv-featured__eyebrow {
	color: var(--arv-teal-deep);
}

.arv-featured__date {
	display: block;
	margin: 0 0 0.5rem;
	font-size: clamp(19px, 2.2vw, 24px);
	font-weight: 800;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.arv-featured__name {
	margin: 0 0 0.6rem;
	font-size: clamp(30px, 5vw, 52px);
	line-height: 1.08;
	font-weight: 800;
}

.arv-featured__detail {
	margin: 0 0 1.5rem;
	max-width: 30rem;
	font-size: var(--arv-fs-lead);
	line-height: 1.5;
	opacity: 0.92;
}

.arv-featured__distances {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin: 0 0 1.75rem;
	padding: 0;
	list-style: none;
}

/* Same amber as a sold-out race's waitlist button and the card's price
   rise note: this site's one colour for "act now, on a real deadline"
   rather than a fresh one invented for this line. A left border rather
   than a filled background, so it reads as a note attached to the CTA
   beneath it rather than as a second button competing with it. */
.arv-featured__deadline {
	margin: 0 0 1.1rem;
	padding: 0.5rem 0 0.5rem 0.85rem;
	border-left: 3px solid #daa520;
	max-width: 26rem;
	font-size: var(--arv-fs-meta);
	font-weight: 600;
	line-height: 1.4;
	color: #ffcf5c;
}

.arv-featured--light .arv-featured__deadline {
	color: #8a6200;
}

.arv-featured__pill {
	padding: 0.3rem 0.7rem;
	border: 1px solid rgba(255, 255, 255, 0.35);
	border-radius: 2px;
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 0.03em;
	text-transform: uppercase;
}

.arv-featured--light .arv-featured__pill {
	border-color: rgba(0, 0, 0, 0.2);
	background: #fff;
}

.arv-featured__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1rem;
}

/* :link and :visited are listed alongside the bare class for the same
   reason the races-list buttons in #68 needed them: a theme's own
   "a:hover { color: ... }" is one element plus one pseudo-class, which
   beats a single class on specificity alone. Without the extra two
   selectors here, hovering the button (or COROS registering the state
   because a page-wide anchor style always applies while a bare click sets
   :active/:visited) swapped this white text for the theme's link colour,
   red on this site, against a background this element was also turning
   red. Both went invisible for exactly as long as the cursor sat on the
   button, which is the one moment someone is deciding whether to click. */
.arv-featured__cta,
.arv-featured__cta:link,
.arv-featured__cta:visited {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
	padding: 0.85rem 1.6rem;
	border: 2px solid var(--arv-accent);
	background: var(--arv-accent);
	color: #fff;
	font-size: var(--arv-fs-btn);
	font-weight: 800;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	text-decoration: none;
	transition: background 0.15s ease, border-color 0.15s ease;
}

/* Same amber for a sold-out race with a waitlist, same teal for something
   informational rather than an offer, as everywhere else this phase set
   appears (the calendar, the map, the cards). One vocabulary of colour for
   "what can I do about this race" across the whole site, not a fourth
   version invented for this element. */
.arv-featured__cta--waitlist,
.arv-featured__cta--waitlist:link,
.arv-featured__cta--waitlist:visited {
	background: #daa520;
	border-color: #daa520;
	color: #272727;
}

.arv-featured__cta--live,
.arv-featured__cta--live:link,
.arv-featured__cta--live:visited,
.arv-featured__cta--results,
.arv-featured__cta--results:link,
.arv-featured__cta--results:visited {
	background: var(--arv-teal-deep);
	border-color: var(--arv-teal-deep);
}

.arv-featured__cta--closed,
.arv-featured__cta--closed:link,
.arv-featured__cta--closed:visited {
	background: transparent;
	border-color: rgba(255, 255, 255, 0.4);
	color: inherit;
	cursor: default;
}

.arv-featured--light .arv-featured__cta--closed {
	border-color: rgba(0, 0, 0, 0.3);
}

/* The arrow is on the button rather than in the label so it survives the
   label changing with the race's phase: Register, Join Waitlist and Live
   Results all get it without three copies of the same character. */
.arv-featured__cta::after {
	content: "\2192";
	transition: transform 0.15s ease;
}

@media (hover: hover) and (pointer: fine) {
	a.arv-featured__cta:hover::after {
		transform: translateX(3px);
	}
}

/* The side card: who runs it, what it costs, what it talks to. Deliberately
   a panel rather than more lines of copy, because it answers a different
   question from the rest of the block ("why sign up" against "what is
   this") and reads faster as a block you can scan than as a paragraph. */
.arv-featured__card {
	flex: 0 1 20rem;
	padding: 1.5rem;
	background: rgba(10, 14, 18, 0.72);
	border: 1px solid rgba(255, 255, 255, 0.16);
	/* Rounded, unlike everything else on this site, and deliberately so. The
	   square corners elsewhere are the brand; this one is standing in for an
	   app, sitting under an app icon, so the rounded rectangle is doing work
	   rather than decorating. */
	border-radius: 14px;
	/* Frosted where the browser supports it, plain translucency where it does
	   not, so the card never becomes an unreadable smear over a busy photo. */
	-webkit-backdrop-filter: blur(10px);
	backdrop-filter: blur(10px);
}

.arv-featured__host {
	display: flex;
	align-items: center;
	gap: 0.7rem;
	color: inherit;
	text-decoration: none;
}

.arv-featured__host-logo {
	flex: 0 0 auto;
	width: 2.5rem;
	height: 2.5rem;
	border-radius: 9px;
	object-fit: cover;
}

.arv-featured__host-label {
	font-size: var(--arv-fs-meta);
	font-weight: 700;
	line-height: 1.25;
}

.arv-featured__price {
	margin: 1.1rem 0 0;
	font-size: var(--arv-fs-heading);
	font-weight: 800;
	line-height: 1.15;
}

/* "$49" is the number someone compares against other races and remembers;
   "+ fees" is the honesty clause that stops it being a lie. Set at the same
   size they compete, and the one confident number this card is built around
   turns into a longer, mushier string. Sized in em rather than rem so it
   tracks whatever the price around it is set at, including the smaller
   mobile size further down. */
.arv-featured__fees {
	font-size: 0.5em;
	font-weight: 700;
	letter-spacing: 0.02em;
	opacity: 0.75;
}

/* The increase note is already small and uppercase, so it wants a nudge
   rather than the big step down the headline price takes. Same treatment
   though, so the before and after still read like for like. */
.arv-featured__price-note .arv-featured__fees {
	font-size: 0.88em;
	opacity: 0.85;
}

/* Amber, the same colour a sold-out race's waitlist button uses. Both are
   "this is still open to you, but not on the terms you might assume", which
   is worth one consistent colour rather than two. */
.arv-featured__price-note {
	display: block;
	margin-top: 0.4rem;
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: #daa520;
}

/* What you actually get, between the price and the syncs, because it
   answers the question the price raises. Chips rather than rows: these are
   four short nouns, and stacking them as full-width list items would make
   the card twice as tall to say the same thing. */
.arv-featured__perks {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4rem;
	margin: 1.1rem 0 0;
	padding: 1.1rem 0 0;
	border-top: 1px solid rgba(255, 255, 255, 0.16);
	list-style: none;
}

.arv-featured__perk {
	padding: 0.3rem 0.6rem;
	font-size: var(--arv-fs-meta);
	font-weight: 700;
	line-height: 1.3;
	background: rgba(255, 255, 255, 0.1);
	border: 1px solid rgba(255, 255, 255, 0.18);
	/* Softened to match the card, but not the full pill an app would use:
	   the square corner is still the brand everywhere else on this page. */
	border-radius: 6px;
}

.arv-featured__syncs {
	margin: 1.1rem 0 0;
	padding: 1.1rem 0 0;
	border-top: 1px solid rgba(255, 255, 255, 0.16);
	list-style: none;
}

.arv-featured__sync {
	display: flex;
	align-items: center;
	gap: 0.55rem;
	font-size: var(--arv-fs-meta);
}

/* Each platform's own mark, on a light chip. Both are brand colours
   (Strava's orange, Coros's red) picked to read on white, and both would
   sit muddy directly on this card's near-black. The chip is what every
   app store does with an icon for the same reason. */
.arv-featured__sync-mark {
	flex: 0 0 auto;
	box-sizing: content-box;
	padding: 4px;
	background: #fff;
	border-radius: 6px;
}

/* Pushed to the far edge so the row reads left to right as "logo, what it
   does, yes this works" rather than burying the tick in the middle. */
.arv-featured__sync .arv-featured__tick {
	margin-left: auto;
}

.arv-featured__sync + .arv-featured__sync {
	margin-top: 0.65rem;
}

.arv-featured__tick {
	flex: 0 0 auto;
	color: var(--arv-teal);
}

/* A second way into the same registration, at the foot of the card. Teal
   rather than the main button's red on purpose: one primary action per
   screen, and this is the same action reached from a different place, not a
   competing one. Full width of the card so it reads as the card's own
   footer rather than a button that happens to be sitting in it. */
/* Same :link/:visited reinforcement as the primary CTA above, and for the
   same reason: this one was going red-on-teal instead of red-on-red, but
   it was the theme's link-hover colour winning either way. */
.arv-featured__card-cta,
.arv-featured__card-cta:link,
.arv-featured__card-cta:visited {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.45rem;
	margin-top: 1.1rem;
	padding: 0.8rem 1rem;
	background: var(--arv-teal);
	color: #fff;
	font-size: var(--arv-fs-btn);
	font-weight: 800;
	letter-spacing: 0.06em;
	line-height: 1.2;
	text-align: center;
	text-transform: uppercase;
	text-decoration: none;
	border-radius: 8px;
}

.arv-featured__card-cta-arrow {
	flex: 0 0 auto;
}

/* Same reinforcement a third time. "Race Info" sits directly on the photo,
   so a hover swap to the theme's red was the most visible of the three:
   white-on-photo turning to a red substring mid-sentence. */
.arv-featured__info,
.arv-featured__info:link,
.arv-featured__info:visited {
	color: inherit;
	font-size: var(--arv-fs-btn);
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	text-decoration: none;
	border-bottom: 1px solid currentColor;
	padding-bottom: 2px;
}

@media (hover: hover) and (pointer: fine) {
	a.arv-featured__cta:hover {
		background: #c61300;
		border-color: #c61300;
	}

	a.arv-featured__cta--waitlist:hover {
		background: #c9971d;
		border-color: #c9971d;
		color: #272727;
	}

	a.arv-featured__cta--live:hover,
	a.arv-featured__cta--results:hover {
		background: #22505b;
		border-color: #22505b;
	}

	a.arv-featured__card-cta:hover {
		background: #22505b;
	}
}

@media (max-width: 619px) {
	.arv-featured__panel {
		padding: 2.25rem 1.25rem 2.5rem;
	}

	/* The scrim above is a left-to-right gradient, tuned for the desktop
	   layout where the copy occupies the left column and the photo is meant
	   to stay bright under the card on the right. Stacked, that assumption
	   inverts: every line of text now runs the full width of the panel, so
	   the bright end of the gradient sits under the right half of each line
	   and the copy loses its backing exactly where the photo is busiest.
	   Vertical instead, so text is legible at any point across the width,
	   with the middle left lightest so the photo is still a photo. */
	.arv-featured--image .arv-featured__panel::before {
		background: linear-gradient(
			180deg,
			rgba(8, 12, 16, 0.88) 0%,
			rgba(8, 12, 16, 0.74) 42%,
			rgba(8, 12, 16, 0.9) 100%
		);
	}

	/* Less dead air above the fold: at this width the logo is the first
	   thing in the panel and does not need desktop's breathing room. It is
	   still the largest single element above the card, so this is where
	   trimming the panel actually buys anything. */
	.arv-featured__logo {
		max-height: 7.5rem;
		margin-bottom: 0.85rem;
	}

	.arv-featured__detail {
		margin-bottom: 1rem;
	}

	.arv-featured__distances {
		margin-bottom: 0.9rem;
	}

	.arv-featured__deadline {
		margin-bottom: 0.9rem;
	}

	/* Two equal columns, not two stacked full-width slabs.
	
	   They were stacked because side by side a solid red block and an
	   underlined text link are two different kinds of thing crushed onto
	   one row: unequal height, unequal weight, and a tap target on the
	   right only as wide as its own text. Making the secondary an outlined
	   button of the same size fixes all three, and once both are real
	   buttons there is no reason to give each the full width of a phone.
	   Two edge-to-edge slabs, plus the card's own button below them, was
	   three of the loudest thing on the screen inside one block. */
	.arv-featured__actions {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: 0.5rem;
	}

	.arv-featured__cta,
	.arv-featured__cta:link,
	.arv-featured__cta:visited,
	.arv-featured__info,
	.arv-featured__info:link,
	.arv-featured__info:visited {
		display: flex;
		align-items: center;
		justify-content: center;
		min-height: 44px;
		padding: 0.6rem 0.5rem;
		font-size: var(--arv-fs-btn);
		letter-spacing: 0.04em;
		text-align: center;
		/* Grid items default to min-width:auto, so a label wider than its
		   1fr track would push the pair out of the panel instead of
		   shrinking into it. */
		min-width: 0;
	}

	/* Promoted from underlined link to outlined button, so the pair reads as
	   primary and secondary rather than as a button next to some text.
	
	   Filled, not just outlined. An outline alone left the label sitting
	   directly on the photograph, and on a phone the panel is short enough
	   that the runners are right behind this button: the word "Race Info"
	   was reading over somebody's white hat. The primary button beside it
	   is solid, so a hollow one against a busy image was the only thing on
	   the block without something behind it. Dark and translucent rather
	   than opaque, so it still reads as the secondary of the pair. */
	.arv-featured__info,
	.arv-featured__info:link,
	.arv-featured__info:visited {
		border: 2px solid rgba(255, 255, 255, 0.5);
		background: rgba(10, 14, 18, 0.55);
		-webkit-backdrop-filter: blur(4px);
		backdrop-filter: blur(4px);
		padding-bottom: 0.6rem;
	}

	/* The border and fill above are white-on-dark, which inverts on the
	   light theme's near-white panel. Everything else in this element
	   adapts through currentColor; these cannot, because a full-strength
	   currentColor border would outshout the primary button next to it. */
	.arv-featured--light .arv-featured__info,
	.arv-featured--light .arv-featured__info:link,
	.arv-featured--light .arv-featured__info:visited {
		border-color: rgba(0, 0, 0, 0.3);
		background: rgba(255, 255, 255, 0.75);
	}

	/* Full width once stacked: a 20rem card floating in a narrower column
	   reads as a stray box rather than as part of the block. */
	.arv-featured__card {
		flex-basis: 100%;
		padding: 1.25rem;
	}

	.arv-featured__price {
		font-size: var(--arv-fs-heading);
	}

	/* The card's own button is the third call to action in this block. It
	   earns its place at the foot of a card someone has just read, but not
	   at the size of the two above it. */
	.arv-featured__card-cta,
	.arv-featured__card-cta:link,
	.arv-featured__card-cta:visited {
		min-height: 44px;
		margin-top: 0.9rem;
		padding: 0.6rem 0.75rem;
		font-size: var(--arv-fs-btn);
	}

	/* The panel's own gutters. 1.25rem on each side of a 390px screen left
	   the content 340px wide, which is why the buttons and the card read as
	   edge-to-edge slabs rather than as elements sitting on a page. */
	.arv-featured__panel {
		padding-left: 1.1rem;
		padding-right: 1.1rem;
	}
}

/* ======================================================== Results == */
/* Every race that has run, and where to read what happened. A table, not
   cards: four columns of the same kind of thing, read across. Same plain
   register as the calendar, hairline rules and type, because this is an
   index rather than a dashboard. */

.arv-results {
	text-align: left;
	--arv-teal: #5bb5a2;
	--arv-teal-deep: #2a5e6b;
	--arv-results-rule: #ebebeb;
	--arv-results-muted: #7a7a7a;
	padding: 2rem 0;
	background: #ffffff;
	color: #272727;
}

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

.arv-results__inner {
	max-width: 68rem;
	margin: 0 auto;
	padding: 0 1.5rem;
}

.arv-results__eyebrow {
	margin: 0 0 0.35rem;
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 1.5px;
	text-transform: uppercase;
	color: var(--arv-accent);
}

.arv-results__heading {
	margin: 0 0 0.5rem;
	font-size: var(--arv-fs-heading);
	font-weight: 700;
	line-height: 1.15;
}

.arv-results__intro {
	margin: 0 0 1.5rem;
	font-size: var(--arv-fs-body);
	line-height: 1.6;
	color: var(--arv-results-muted);
}

.arv-results__empty {
	margin: 1.5rem 0 0;
	font-size: var(--arv-fs-body);
	color: var(--arv-results-muted);
}

/* Only ever scrolls if something forces it wider than the page; the layout
   below is built not to. Here so a long race name on a narrow screen
   degrades to a scroll rather than pushing the whole page sideways. */
.arv-results__scroll {
	margin-top: 1.5rem;
	overflow-x: auto;
}

.arv-results__table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--arv-fs-body);
}

.arv-results__table thead th {
	padding: 0 0 0.6rem;
	border-bottom: 2px solid #272727;
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 1.2px;
	text-transform: uppercase;
	text-align: left;
	white-space: nowrap;
}

/* The three link columns are the same width as each other and only as wide
   as they need to be, so the race name takes whatever is left rather than
   the four columns splitting the table evenly and leaving the names to
   wrap while the links sit in acres of space. */
.arv-results__table thead th:not(:first-child) {
	width: 9.5rem;
}

.arv-results__month th {
	padding: 1.5rem 0 0.5rem;
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 1.5px;
	text-transform: uppercase;
	text-align: left;
	color: var(--arv-results-muted);
}

.arv-results__row > * {
	padding: 0.7rem 0.75rem 0.7rem 0;
	border-bottom: 1px solid var(--arv-results-rule);
	vertical-align: middle;
}

.arv-results__race {
	text-align: left;
	font-weight: 400;
}

.arv-results__name {
	display: block;
	font-size: var(--arv-fs-name);
	font-weight: 700;
	line-height: 1.3;
}

.arv-results__date {
	display: block;
	margin-top: 0.1rem;
	font-size: var(--arv-fs-meta);
	color: var(--arv-results-muted);
}

/* A race that has run but that the scraper has not picked up yet, carrying
   only its live link. Amber, the same colour this site uses everywhere else
   for "true right now, and not for long". */
.arv-results__flag {
	display: inline-block;
	margin-top: 0.35rem;
	padding: 0.15rem 0.45rem;
	background: #daa520;
	color: #272727;
	font-size: var(--arv-fs-label);
	font-weight: 800;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.arv-results__link,
.arv-results__link:link,
.arv-results__link:visited {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 38px;
	/* Two words that are one label. Allowed to wrap, "LIVE RESULTS" broke
	   across two lines inside a box that had been squeezed to 19px wide on
	   the race week block, and the text simply spilled out of it. */
	white-space: nowrap;
	padding: 0.45rem 0.6rem;
	background: var(--arv-teal);
	color: #0d1211;
	font-size: var(--arv-fs-btn);
	font-weight: 800;
	letter-spacing: 0.04em;
	text-align: center;
	text-transform: uppercase;
	text-decoration: none;
	transition: background 0.15s ease;
}

/* Aravaipa's own timing is the primary of the three, and the only one that
   is ours. The two off-site archives are hollow, so the row reads as one
   action and two references rather than three equal buttons. */
.arv-results__link--us,
.arv-results__link--us:link,
.arv-results__link--us:visited,
.arv-results__link--ur,
.arv-results__link--ur:link,
.arv-results__link--ur:visited {
	background: transparent;
	border: 1px solid var(--arv-results-rule);
	color: #272727;
}

.arv-results__cell--empty {
	text-align: center;
}

.arv-results__dash {
	color: #c7c7c7;
}

@media (hover: hover) and (pointer: fine) {
	a.arv-results__week-link:hover {
		text-decoration: underline;
		text-underline-offset: 3px;
	}

	a.arv-results__week-social:hover {
		color: #f2f2f2;
	}

	a.arv-results__week-pill--link:hover {
		background: var(--arv-teal);
		border-color: var(--arv-teal);
		color: #0d1211;
	}

	a.arv-results__link:hover {
		background: #6fc7b4;
	}

	a.arv-results__link--us:hover,
	a.arv-results__link--ur:hover {
		background: #f4f4f4;
		border-color: #c7c7c7;
	}
}

/* Stacked below this. A four-column table on a phone either scrolls
   sideways, which hides the links that are the entire point, or squeezes
   every label onto two lines. Each race becomes a block instead: name and
   date, then the links it actually has, side by side. */
@media (max-width: 619px) {
	.arv-results__inner {
		padding: 0 1.25rem;
	}

	.arv-results__scroll {
		overflow-x: visible;
	}

	.arv-results__table,
	.arv-results__table tbody,
	.arv-results__table tr,
	.arv-results__table td,
	.arv-results__table th {
		display: block;
		width: auto;
	}

	/* The header row is meaningless once the columns are gone: every link
	   already carries its own name. Hidden rather than removed so the table
	   is still a table to a screen reader. */
	.arv-results__table thead {
		position: absolute;
		width: 1px;
		height: 1px;
		margin: -1px;
		overflow: hidden;
		clip: rect(0, 0, 0, 0);
		white-space: nowrap;
	}

	/* Every selector below is scoped through .arv-results__table on purpose.
	   The rule above that flattens the table sets "display: block" via
	   ".arv-results__table tr" and ".arv-results__table td", which is a
	   class plus a type and therefore outranks a bare ".arv-results__row".
	   Written unscoped, the row never became flex and the empty cell never
	   went away: both silently kept the display the flattening rule gave
	   them. Same trap as the races-list buttons in #68.
	
	   Flex rather than grid, so an empty column can be removed entirely and
	   the links that remain share the width between them instead of leaving
	   a hole where the third would have been. */
	.arv-results__table tr.arv-results__row {
		display: flex;
		flex-wrap: wrap;
		gap: 0.45rem;
		padding: 0.9rem 0;
		border-bottom: 1px solid var(--arv-results-rule);
	}

	.arv-results__table .arv-results__row > * {
		padding: 0;
		border-bottom: 0;
	}

	.arv-results__table th.arv-results__race {
		flex: 1 0 100%;
		margin-bottom: 0.15rem;
	}

	.arv-results__table td.arv-results__cell {
		flex: 1 1 0;
		min-width: 0;
	}

	/* Absent, not a dash in a column that no longer exists. */
	.arv-results__table td.arv-results__cell--empty {
		display: none;
	}

}

/* --- Results, grouped by race ------------------------------------------ */
/* The other half of the element: every edition of a race under its own
   name, for someone who knows the race and wants its history. The latest
   edition is always open, because that is the one most people came for and
   a click for it would be a click for nothing. */

.arv-results__search {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.6rem;
	margin-top: 1.5rem;
}

/* Visible, not a placeholder standing in for one. A placeholder disappears
   the moment anyone types, which is exactly when a screen reader user needs
   to know what the box is. */
.arv-results__search-label {
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 1.2px;
	text-transform: uppercase;
}

/* Holds the input and its clear button in one box, so the button can sit
   inside the field rather than beside it. */
.arv-results__search-field {
	position: relative;
	display: flex;
	align-items: center;
	flex: 1 1 16rem;
	min-width: 0;
}

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

/* The native one only appears once there is text, is a small unlabelled
   target, and does not exist at all in Firefox. Ours replaces it, so this
   makes sure there are never two. */
.arv-results__search-input::-webkit-search-cancel-button,
.arv-results__search-input::-webkit-search-decoration {
	-webkit-appearance: none;
	appearance: none;
}

.arv-results__search-clear {
	position: absolute;
	right: 0.35rem;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	padding: 0;
	background: none;
	border: 0;
	color: var(--arv-results-muted);
	cursor: pointer;
}

.arv-results__search-clear[hidden] {
	display: none;
}

.arv-results__search-clear:focus-visible {
	outline: 2px solid var(--arv-teal);
	outline-offset: -2px;
}

.arv-results__search-input {
	flex: 1 1 auto;
	min-width: 0;
	padding: 0.6rem 2.2rem 0.6rem 0.75rem;
	border: 1px solid #d4d4d4;
	border-radius: 0;
	/* 16px. Anything smaller and iOS Safari zooms the whole page in on
	   focus, which is the same trap the calendar's search hit. */
	font-size: var(--arv-fs-input);
	font-family: inherit;
	background: #fff;
	color: inherit;
}

.arv-results__search-input:focus-visible {
	outline: 2px solid var(--arv-teal);
	outline-offset: 1px;
}

.arv-results__count {
	margin: 0;
	font-size: var(--arv-fs-meta);
	color: var(--arv-results-muted);
}

.arv-results__races {
	margin-top: 1.25rem;
	border-top: 1px solid var(--arv-results-rule);
}

/* The month a run of races belongs to. Sticky, because the whole point is
   knowing where in seventy-four races you are, and a heading that scrolls
   away answers that only at the moment you pass it.

   The theme has no fixed chrome of its own, checked rather than assumed, so
   the only thing that can sit over this is the admin bar. WordPress puts its
   height on the document element when it renders one, and the fallback is
   what every logged-out visitor gets. */
.arv-results__month-head {
	position: sticky;
	top: var(--wp-admin--admin-bar--height, 0px);
	z-index: 2;
	margin: 0;
	padding: 0.55rem 0;
	background: #ffffff;
	border-bottom: 2px solid var(--arv-teal);
	font-size: var(--arv-fs-label);
	font-weight: 800;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--arv-teal-deep);
}

.arv-results__month-group + .arv-results__month-group {
	margin-top: 1.75rem;
}

.arv-results__race-group {
	padding: 1rem 0;
	border-bottom: 1px solid var(--arv-results-rule);
}

/* [hidden] needs saying explicitly: the rule above sets display on the same
   element, and an author rule beats the browser's own [hidden] default at
   equal specificity whatever the source order. The calendar shipped this
   exact bug once, where every filter set hidden correctly and nothing
   visibly happened. */
.arv-results__race-group[hidden] {
	display: none;
}

.arv-results__latest {
	display: flex;
	flex-wrap: wrap;
	/* Top rather than centre: the left column is now two lines tall on a
	   race with winners, and centring against it floated the buttons into
	   the middle of the block instead of lining them up with the name. */
	align-items: flex-start;
	justify-content: space-between;
	gap: 0.75rem;
}

/* Name and date on one line, the way the race week block above already
   sets them. They stay separate elements, a heading and a paragraph, so the
   document still says "this race" and "this running of it"; only the layout
   puts them side by side. Baseline alignment rather than centre, because the
   date is much smaller than the name and centring floats it. */
.arv-results__race-head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.1rem 0.6rem;
	/* Takes the space the buttons do not, and no more. Without the basis of
	   zero the winners line below, which is deliberately full width, sets
	   this column's preferred width to the whole row and pushes the buttons
	   onto a line of their own. */
	flex: 1 1 0;
	min-width: 0;
}

/* The winners line belongs under the name, not beside it, so it claims the
   whole row of this column and wraps onto its own line. */
.arv-results__race-head > .arv-results__winners {
	flex: 1 1 100%;
	min-width: 0;
}

.arv-results__race-name {
	margin: 0;
	font-size: var(--arv-fs-name);
	font-weight: 700;
	line-height: 1.3;
}

.arv-results__race-meta {
	margin: 0;
	font-size: var(--arv-fs-body);
	color: var(--arv-results-muted);
}

/* The one number on a row that varies.

   Every other part of a race group is the same shape on all seventy-four of
   them: a name, a date, three buttons. Numbers are the only thing that
   differs from row to row, which is what gives the eye somewhere to land
   while scanning. Muted and small all the same: it is a fact about the race,
   not a claim on attention, and the race name has to stay the loudest thing
   in the group. */
.arv-results__stat {
	font-variant-numeric: tabular-nums;
}

/* The count always rides on a date line, latest edition and older ones
   alike, so it carries its own separator rather than relying on a wrapper. */
.arv-results__edition-date .arv-results__stat,
.arv-results__race-meta .arv-results__stat {
	margin-left: 0.15rem;
	font-weight: 400;
	color: var(--arv-results-muted);
}

.arv-results__edition-date .arv-results__stat::before,
.arv-results__race-meta .arv-results__stat::before {
	content: "\00b7";
	margin-right: 0.35rem;
}

/* The marquee result, one line under the count.

   Flex rather than inline text so a third division wraps as a unit instead
   of splitting a name from its time mid-line. Most events ran men and women
   and fit on one line; Javelina also scores nonbinary and wraps, which is
   the correct behaviour rather than a case to design away. */
.arv-results__winners {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.15rem 0.75rem;
	margin: 0.15rem 0 0;
	font-size: var(--arv-fs-body);
	color: var(--arv-results-muted);
}

/* The distance the headline is about. Set apart from the names, since
   without it "Alex Bustamante 5:49:58" is a time for an unstated race. */
.arv-results__winners-distance {
	font-weight: 700;
	font-size: var(--arv-fs-label);
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--arv-ink, #272727);
}

.arv-results__winner {
	white-space: nowrap;
}

.arv-results__winner-name {
	color: var(--arv-ink, #272727);
}

.arv-results__winner-time {
	font-variant-numeric: tabular-nums;
}

/* Every distance, closed by default. Royal Gorge Groove scores nine of
   them across three divisions, which is the amount of information that has
   to be behind a disclosure: seventy-four of these open at once stops being
   an archive and becomes a results booklet. */
.arv-results__winners-all {
	margin-top: 0.5rem;
}

.arv-results__winners-all[open] {
	margin-bottom: 0.25rem;
	padding: 0.15rem 0.75rem 0.6rem;
	background: #fafafa;
}

.arv-results__winners-all[open] > .arv-results__older-toggle {
	margin-bottom: 0.4rem;
}

.arv-results__winners-all[open] > .arv-results__older-toggle .arv-results__chevron {
	transform: rotate(180deg);
}

.arv-results__winners-scroll {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

.arv-results__winners-table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--arv-fs-meta);
}

/* A winner is a name and a time and never breaks between them. Without this
   the table has permission to shrink instead of scroll, and on a phone it
   took it: "Alex Bustamante 5:49:58" came out as three stacked lines and the
   scroll container it sits in never had anything to scroll. */
.arv-results__winners-table th,
.arv-results__winners-table td {
	white-space: nowrap;
}

.arv-results__winners-table th,
.arv-results__winners-table td {
	padding: 0.3rem 0.75rem 0.3rem 0;
	text-align: left;
	vertical-align: baseline;
}

/* The column heads carry the division, which is the one place it is spelled
   out: on the headline line above, the names do that job and a drawn "Men"
   would be scaffolding around the result. */
.arv-results__winners-table thead th {
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--arv-results-muted);
	border-bottom: 1px solid var(--arv-results-rule);
}

/* The distance is the row's header, not a cell: it names the row the way
   the division names the column. */
.arv-results__winners-table tbody th {
	font-weight: 700;
	white-space: nowrap;
}

.arv-results__winners-table tbody tr + tr th,
.arv-results__winners-table tbody tr + tr td {
	border-top: 1px solid var(--arv-results-rule);
}

.arv-results__winners-table .arv-results__winner-time {
	color: var(--arv-results-muted);
}

/* The years sit quieter than the count they follow: "3 earlier editions" is
   the control, the years are the detail that saves a click. */
.arv-results__older-years {
	margin-left: 0.35rem;
	font-weight: 400;
	color: var(--arv-results-muted);
	font-variant-numeric: tabular-nums;
}

/* Three fixed columns, even though there is no table here. The row is
   right-aligned against the race name, so sizing the buttons to whichever
   links a race happens to have let the block shrink from the left: a race
   with two listings started 119px right of a race with three, and the page
   had a ragged edge running down it. Fixed tracks and an empty slot for a
   missing listing put every button in the same place on every row. */
.arv-results__links {
	display: grid;
	grid-template-columns: repeat(3, 7.75rem);
	gap: 0.45rem;
}

.arv-results__links .arv-results__link {
	width: 100%;
	min-width: 0;
}

/* Holds a column open where a race has no listing. Not a dash and not a
   disabled button: the point is only that the columns line up. */
.arv-results__slot {
	display: block;
}

.arv-results__older {
	margin-top: 0.75rem;
}

.arv-results__older-toggle {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	padding: 0.2rem 0;
	font-size: var(--arv-fs-btn);
	font-weight: 700;
	color: var(--arv-teal-deep);
	cursor: pointer;
}

/* Any display other than list-item drops the browser's own disclosure
   triangle, which is why this needs one of its own; see the matching
   comment in includes/elements/results.php. */
.arv-results__older-toggle::marker,
.arv-results__older-toggle::-webkit-details-marker {
	content: "";
	display: none;
}

.arv-results__chevron {
	flex: 0 0 auto;
	transition: transform 0.15s ease;
}

.arv-results__older[open] > .arv-results__older-toggle .arv-results__chevron {
	transform: rotate(180deg);
}

.arv-results__older-toggle:focus-visible {
	outline: 2px solid var(--arv-teal);
	outline-offset: 2px;
}

/* An open race reads as one unit rather than as its latest edition
   followed by some loose rows. Deliberately not zebra striping the whole
   list: at seventy-four races that is a lot of banding to say something the
   hairline rules already say, and it fights the plain index register this
   shares with the calendar. The tint marks the one thing that is actually a
   group. */
.arv-results__older[open] {
	margin-top: 0.5rem;
	padding: 0.15rem 0.75rem 0.35rem;
	background: #fafafa;
}

.arv-results__older[open] .arv-results__older-toggle {
	margin-bottom: 0.5rem;
}

.arv-results__edition {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 0.6rem;
	padding: 0.55rem 0 0.55rem 1.1rem;
	border-left: 2px solid var(--arv-results-rule);
}

.arv-results__edition-date {
	margin: 0;
	font-size: var(--arv-fs-body);
	font-weight: 700;
}

@media (max-width: 619px) {
	/* 44px, the tap target, not a type size: the scale handles the text. */
	.arv-results__link,
	.arv-results__link:link,
	.arv-results__link:visited {
		min-height: 44px;
	}

	.arv-results__search {
		gap: 0.4rem;
	}

	.arv-results__search-field {
		flex-basis: 100%;
	}

	/* Three columns of names do not fit a phone, and a winners table is the
	   one place on this page where the content genuinely is tabular, so it
	   scrolls rather than being flattened into stacked blocks.

	   The scrolling happens on the wrapper, not on the table. Setting
	   overflow on the <table> itself makes it a block box, which takes away
	   the table layout that is the entire reason the columns line up. */
	.arv-results__winners-all[open] {
		padding-right: 0;
	}

	.arv-results__winners-scroll {
		padding-right: 0.75rem;
	}

	.arv-results__winners-table {
		width: auto;
		min-width: 100%;
	}

	/* The headline's divisions stack rather than wrap mid-name. */
	.arv-results__winners {
		gap: 0.1rem 0.6rem;
	}

	/* Name above, links below, both full width: side by side there is not
	   enough room for three link buttons and a race name that can run to
	   forty characters. */
	.arv-results__latest,
	.arv-results__edition {
		flex-direction: column;
		align-items: stretch;
	}

	/* Three equal columns here too, not flex. Flex sized each button to the
	   row it was in, so a race with two listings got two half-width buttons
	   and the race under it got three at a third each: no two rows lined up
	   down the page. The empty slot costs a gap on a two-listing row and
	   buys alignment on every row, which is the better trade at this width
	   for the same reason it is on desktop. */
	.arv-results__links {
		display: grid;
		grid-template-columns: repeat(3, 1fr);
		width: 100%;
		gap: 0.45rem;
	}

	.arv-results__links .arv-results__link {
		width: 100%;
		min-width: 0;
	}
}

/* --- Results: race week ------------------------------------------------ */
/* The races happening this weekend, above the archive, because during race
   week that is the only thing anyone has come to the page for. Dark, unlike
   everything below it, so it reads as the live thing rather than as the
   first row of the list. */

.arv-results__week {
	margin-top: 1.5rem;
	padding: 1.1rem 1.25rem 1.25rem;
	background: #1d2624;
	color: #f2f2f2;
}

.arv-results__week-eyebrow {
	margin: 0 0 0.5rem;
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 1.5px;
	text-transform: uppercase;
	color: var(--arv-teal);
}

.arv-results__week-list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.arv-results__week-race {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.6rem 1rem;
	padding: 0.9rem 0;
	border-top: 1px solid rgba(255, 255, 255, 0.14);
}

.arv-results__week-logo {
	flex: 0 0 auto;
	width: 44px;
	height: 44px;
	object-fit: contain;
}

.arv-results__week-body {
	flex: 1 1 14rem;
	min-width: 0;
}

/* Name and date on one line where they fit, stacked where they do not.
   Baseline-aligned rather than centred, so the small date sits on the same
   line as the large name instead of floating in the middle of it. */
.arv-results__week-head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.15rem 0.7rem;
}

.arv-results__week-name {
	font-size: var(--arv-fs-name);
	font-weight: 700;
	line-height: 1.3;
}

/* Underlined only on hover: at rest the name is already obviously the
   heading of its row, and a permanent underline on every race turns the
   block into a list of links rather than a list of races. */
.arv-results__week-link,
.arv-results__week-link:link,
.arv-results__week-link:visited {
	color: inherit;
	text-decoration: none;
}

.arv-results__week-link:focus-visible {
	outline: 2px solid var(--arv-teal);
	outline-offset: 2px;
}

.arv-results__week-logo-link {
	display: block;
	flex: 0 0 auto;
}

/* The account that actually covers this race, which is the regional one
   rather than the national feed for most of them. An icon, not a button:
   it is a sidelong offer next to the thing people came for. */
.arv-results__week-social {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	width: 38px;
	height: 38px;
	color: rgba(242, 242, 242, 0.6);
	transition: color 0.15s ease;
}

.arv-results__week-social:focus-visible {
	outline: 2px solid var(--arv-teal);
	outline-offset: 2px;
}

.arv-results__week-distances {
	display: flex;
	flex-wrap: wrap;
	gap: 0.3rem;
	margin-top: 0.35rem;
}

.arv-results__week-pill {
	padding: 0.1rem 0.4rem;
	border: 1px solid rgba(255, 255, 255, 0.28);
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	color: inherit;
}

/* Only the chips that actually go somewhere look like they do. A distance
   the timing board has no id for stays a plain chip rather than a link
   that lands on the wrong results. */
.arv-results__week-pill--link,
.arv-results__week-pill--link:link,
.arv-results__week-pill--link:visited {
	color: inherit;
	text-decoration: none;
	cursor: pointer;
	transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.arv-results__week-pill--link:focus-visible {
	outline: 2px solid var(--arv-teal);
	outline-offset: 2px;
}

/* The state, not the town: enough to tell two races apart at a glance
   without turning the bar into an address book. */
.arv-results__week-place {
	padding: 0.05rem 0.35rem;
	border: 1px solid rgba(255, 255, 255, 0.22);
	font-size: var(--arv-fs-label);
	font-weight: 700;
	letter-spacing: 0.06em;
	color: rgba(242, 242, 242, 0.7);
	white-space: nowrap;
}

.arv-results__week-date {
	font-size: var(--arv-fs-body);
	color: rgba(242, 242, 242, 0.65);
	/* Never broken across lines: "August 29," on one line and "2026" on the
	   next is the worst of both layouts. */
	white-space: nowrap;
}

/* One cell holding all three states, only one of them ever visible, so the
   row does not change width as a race moves from counting down to live to
   finished. */
.arv-results__week-status {
	flex: 0 0 auto;
	min-width: 7.5rem;
	font-size: var(--arv-fs-body);
	font-weight: 700;
}

.arv-results__countdown[hidden],
.arv-results__elapsed[hidden],
.arv-results__live[hidden],
.arv-results__done[hidden] {
	display: none;
}

/* "Starts in" / "Elapsed" sit quieter than the clock beside them: the
   number is the thing being read, the word only says which number it is. */
.arv-results__clock-label {
	font-weight: 400;
	color: rgba(242, 242, 242, 0.55);
}

.arv-results__elapsed {
	color: #6ee7a8;
	font-variant-numeric: tabular-nums;
	font-feature-settings: "tnum";
	letter-spacing: 0.02em;
}

.arv-results__elapsed .arv-results__clock-label {
	color: rgba(110, 231, 168, 0.7);
}

.arv-results__countdown {
	color: rgba(242, 242, 242, 0.85);
	/* Tabular figures, so a ticking clock does not shuffle its own width
	   every second as digits change. */
	font-variant-numeric: tabular-nums;
	font-feature-settings: "tnum";
	letter-spacing: 0.02em;
}

/* Beside the race name rather than in the status cell, so it can sit next
   to the elapsed clock instead of replacing it. */
.arv-results__live {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	margin-left: 0.15rem;
	font-size: var(--arv-fs-label);
	font-weight: 800;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: #6ee7a8;
	white-space: nowrap;
}

.arv-results__done {
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: rgba(242, 242, 242, 0.5);
}

.arv-results__pulse {
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: #3ddc84;
	box-shadow: 0 0 0 0 rgba(61, 220, 132, 0.7);
	animation: arv-results-pulse 1.8s ease-out infinite;
}

@keyframes arv-results-pulse {
	70% { box-shadow: 0 0 0 9px rgba(61, 220, 132, 0); }
	100% { box-shadow: 0 0 0 0 rgba(61, 220, 132, 0); }
}

/* A dot that never stops moving is exactly what this setting exists to
   turn off. The colour still carries the meaning without it. */
@media (prefers-reduced-motion: reduce) {
	.arv-results__pulse {
		animation: none;
	}
}

/* A finished race is still worth reading, but it should not shout as loudly
   as the one happening right now. */
.arv-results__week-race--done .arv-results__week-logo,
.arv-results__week-race--done .arv-results__week-name {
	opacity: 0.75;
}

/* Sized like the archive's buttons rather than stretched, so the two
   sections read as the same site. */
.arv-results__week-race .arv-results__link {
	width: auto;
	min-width: 7.75rem;
}

@media (max-width: 619px) {
	.arv-results__week {
		padding: 1rem 1.1rem 1.1rem;
	}

	.arv-results__week-race {
		align-items: flex-start;
		gap: 0.5rem 0.75rem;
	}

	.arv-results__week-logo {
		width: 36px;
		height: 36px;
	}

	/* Placed, not wrapped. Flow layout gave the two races in this block
	   different shapes: "Black Bear Trail Race" plus its date filled the
	   line, so NH wrapped below it, while the shorter "Rock Hawk" left room
	   for CO to sit inline. Two rows of the same thing, built differently,
	   depending on how long a race happens to be called.

	   It also left the clock starting at the container's edge, under the
	   logo, while the name, date and distances all started past it. Every
	   part of a race now shares one left edge in the second column, and
	   every race is the same shape as the one above it. */
	.arv-results__week-race {
		display: grid;
		grid-template-columns: 36px minmax(0, 1fr) auto;
	}

	.arv-results__week-logo-link {
		grid-area: 1 / 1 / 2 / 2;
	}

	.arv-results__week-body {
		grid-area: 1 / 2 / 2 / 4;
	}

	/* Its own row: the clock, the button and the icon together are wider
	   than the column they would have to share at 390px, and squeezing the
	   clock is what crushed this button to nineteen pixels once before. */
	.arv-results__week-status {
		grid-area: 2 / 2 / 3 / 4;
		min-width: 0;
	}

	.arv-results__week-race .arv-results__link {
		grid-area: 3 / 2 / 4 / 3;
		justify-self: start;
		min-width: 8.5rem;
	}

	/* Name, then date and state beneath it, rather than all three flowing
	   until they run out of room. */
	.arv-results__week-head {
		display: grid;
		grid-template-columns: auto auto minmax(0, 1fr);
		align-items: baseline;
	}

	.arv-results__week-name {
		grid-area: 1 / 1 / 2 / 4;
	}

	.arv-results__week-date {
		grid-area: 2 / 1 / 3 / 2;
	}

	.arv-results__week-place {
		grid-area: 2 / 2 / 3 / 3;
	}

	.arv-results__week-race .arv-results__live {
		grid-area: 2 / 3 / 3 / 4;
		justify-self: start;
	}

	/* Placed like the rest of the row rather than ordered after it. */
	.arv-results__week-social {
		grid-area: 3 / 3 / 4 / 4;
		justify-self: end;
	}
}


/* ---------------------------------------------------------------------
   Aravaipa Live: a branded, indexable page for one race's results.

   The frame is the smaller half of this. An iframe contributes nothing to
   the page around it as far as a search engine is concerned, so the styling
   that matters is on the report underneath: that is the part that is real
   HTML, and the reason this page exists rather than a link to the board.
   --------------------------------------------------------------------- */
/* Full bleed, out of whatever the theme wrapped this in.

   The board is a dark panel that fills its frame, and sitting it inside the
   theme's white content card left a band of white down both sides of a black
   table: on a phone that inset was most of the reason the results were
   cramped, and the card was framing a thing that is already a frame.

   Same breakout the race map uses, and for the same reason it is written
   this way: the element is dropped into a Cornerstone section, row and
   column, each with its own max-width and padding, so undoing this plugin's
   own padding only reaches the edge of the innermost one. Measuring from the
   viewport instead is the only thing that reaches the window. --arv-sbw is
   the scrollbar width, measured in JS, because 100vw counts the scrollbar on
   Windows and Linux but not on macOS's overlay scrollbars. */
.arv-live {
	/* Stated, not inherited. The page template this renders in centres its
	   text, so the bar's date and location line sat centred under a
	   left-aligned title, which read as a mistake because it was one:
	   .arv-results has always stated this and never had the problem. */
	text-align: left;
	margin-left: calc(50% - 50vw + (var(--arv-sbw, 0px) / 2));
	margin-right: calc(50% - 50vw + (var(--arv-sbw, 0px) / 2));
	/* No top padding: the bar is its own dark surface and starts the
	   component, so a gap above it just floats the whole thing. */
	padding: 0 0 1.5rem;
	font-family: Lato, "Helvetica Neue", Helvetica, Arial, sans-serif;
	color: var(--arv-ink, #272727);
}

/* The bar above the board.

   Dark, and flush against the frame with no gap, because the thing it
   introduces is a dark panel: a white heading band floating above it read as
   two unrelated components stacked rather than one. Same family of surface
   as the board's own header, so the seam between our chrome and their app is
   not the first thing the eye lands on.

   Full width like the frame, with its contents held to the content column so
   the race name still lines up with every other heading on the site. */
.arv-live__bar {
	background: #10201f;
	color: #f4f4f4;
}

.arv-live__bar-inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.6rem 1.25rem;
	max-width: 1200px;
	margin: 0 auto;
	padding: 0.9rem 1.25rem;
}

/* Takes the room the clock and the years do not. */
.arv-live__ident {
	flex: 1 1 auto;
	min-width: 0;
}

/* The marker and the title on one line, and the marker keeps its size when
   the title is long enough to wrap. */
.arv-live__headline {
	display: flex;
	align-items: baseline;
	gap: 0.6rem;
	flex-wrap: wrap;
}

/* The live marker reads on the dark bar, where the archive's version was
   built for white. Same green, given a glow so it carries at a glance from
   across a room, which is where a race-day screen usually is. */
/* The [hidden] guard is stated here, not left to the shared rule further up
   the file. That rule is .arv-results__live[hidden], the same two-selector
   weight as .arv-live__bar .arv-results__live below it, and at equal
   specificity the later one wins: giving this a display without saying so
   put a LIVE NOW badge on every page, finished races included. Two classes
   and the attribute settle it wherever either rule sits. */
.arv-live__bar .arv-results__live[hidden] {
	display: none;
}

.arv-live__bar .arv-results__live {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	padding: 0.2rem 0.55rem;
	border: 1px solid rgba(61, 220, 132, 0.45);
	background: rgba(61, 220, 132, 0.12);
	font-size: var(--arv-fs-label);
	font-weight: 800;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: #6bf0a6;
	animation: arv-live-glow 1.8s ease-in-out infinite;
}

@keyframes arv-live-glow {
	0%, 100% { box-shadow: 0 0 0 0 rgba(61, 220, 132, 0); }
	50%      { box-shadow: 0 0 14px 1px rgba(61, 220, 132, 0.35); }
}

/* Same reasoning as the dot this sits around: the colour and the border
   still say "live" with nothing moving. */
@media (prefers-reduced-motion: reduce) {
	.arv-live__bar .arv-results__live {
		animation: none;
	}
}

/* Last in the bar, and the only thing in it that leaves the site, so it is
   set apart rather than sized up. */
.arv-live__social {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
	margin-left: 0.25rem;
	color: rgba(255, 255, 255, 0.72);
	text-decoration: none;
}

.arv-live__social:hover,
.arv-live__social:focus-visible {
	color: #ffffff;
}

.arv-live__title {
	margin: 0;
	font-size: clamp(20px, 2.4vw, 24px);
	font-weight: 700;
	line-height: 1.2;
	color: #fff;
}

/* The year sits with the title rather than under it: "Black Bear Trail Race
   2025" is the name of the thing this page is about, and splitting it makes
   the heading read as though it were about the race in general. */
.arv-live__year {
	color: rgba(244, 244, 244, 0.6);
	font-weight: 400;
}

.arv-live__meta {
	margin: 0.15rem 0 0;
	font-size: var(--arv-fs-meta);
	color: rgba(244, 244, 244, 0.62);
}

/* The clock and its live marker, borrowed wholesale from the race week
   block: same markup, same attributes, same script. A race counts down,
   counts up once it starts and reads Completed after its cutoff, and it does
   that identically here and on the archive because it is the same code
   rather than a second implementation that will drift. */
.arv-live__clock {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	flex: 0 0 auto;
	font-size: var(--arv-fs-body);
	color: #f4f4f4;
}

.arv-live__clock .arv-results__week-status {
	font-variant-numeric: tabular-nums;
}

/* Years as links, because the board has no way to move between them at all.
   Not a select: a dropdown's options are not links, so neither a crawler nor
   a middle click can reach last year's race. Each one loads that year's own
   URL rather than swapping the frame in place, which is the point: a year
   with no address of its own cannot be indexed, shared or linked to. */
.arv-live__years {
	display: flex;
	flex-wrap: wrap;
	gap: 0.3rem;
	flex: 0 0 auto;
}

.arv-live__year-link,
.arv-live__year-link:link,
.arv-live__year-link:visited {
	padding: 0.25rem 0.6rem;
	border: 1px solid rgba(244, 244, 244, 0.28);
	font-size: var(--arv-fs-btn);
	font-weight: 700;
	letter-spacing: 0.02em;
	color: #f4f4f4;
	text-decoration: none;
	font-variant-numeric: tabular-nums;
}

.arv-live__year-link.is-current {
	background: var(--arv-teal, #5bbfa8);
	border-color: var(--arv-teal, #5bbfa8);
	color: #0d1211;
}

/* The words below the frame stay in the content column. */
.arv-live__open {
	max-width: 1200px;
	margin-left: auto;
	margin-right: auto;
	padding-left: 1.25rem;
	padding-right: 1.25rem;
}

/* No side borders: a 1px line against the window edge reads as a rendering
   artefact rather than as a frame. No top border either, because the bar
   above is already a hard edge and a rule between them would draw a line
   through the middle of one component. */
.arv-live__frame {
	border-bottom: 1px solid var(--arv-results-rule, #e2e2e2);
	background: #101314;
}

.arv-live__iframe {
	display: block;
	width: 100%;
	border: 0;
}

.arv-live__open {
	margin: 0.6rem 0 0;
	font-size: var(--arv-fs-body);
}

.arv-live__open-link,
.arv-live__open-link:link,
.arv-live__open-link:visited {
	color: var(--arv-teal-deep, #2a5e6b);
	font-weight: 700;
	text-decoration: none;
}

@media (hover: hover) and (pointer: fine) {
	a.arv-live__year-link:hover {
		border-color: var(--arv-teal, #5bbfa8);
		color: #fff;
	}

	a.arv-live__open-link:hover {
		text-decoration: underline;
		text-underline-offset: 3px;
	}
}

@media (max-width: 619px) {
	.arv-live {
		padding: 1rem 0;
	}

	/* Pixels for the same reason as the results element above: the theme
	   drops the root to 12px at this width, so rem sizes shrink on exactly
	   the device that needs them largest. */
	.arv-live__bar-inner {
		padding: 0.9rem 1rem;
	}


	/* Bigger than the desktop clamp would give at this width, on purpose.
	   The board's own "Black Bear" heading inside the frame is set large, so
	   at the phone sizes this clamped down to, our title read as a caption
	   above their headline: the page looked like it belonged to the embed
	   rather than the other way round. */
	.arv-live__title {
		font-size: 20px;
	}

	.arv-live__year-link,
	.arv-live__year-link:link,
	.arv-live__year-link:visited {
		padding: 0.35rem 0.8rem;
	}

	.arv-live__open {
		padding-left: 1rem;
		padding-right: 1rem;
	}

	/* Placed rather than ordered. On a phone the name takes the full width,
	   so the clock has to drop below it, and flex order alone put the
	   Instagram icon to the LEFT of the clock: the clock was ordered 3 and
	   the icon, having no order of its own, sorted ahead of it at 0. Two
	   columns and four explicit placements say where each thing goes without
	   depending on what every sibling happens to be set to.

	   Name and years on the top row, clock centred under the name with the
	   icon out at the right margin beside it. */
	.arv-live__bar-inner {
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto;
		align-items: center;
	}

	.arv-live__ident {
		grid-area: 1 / 1 / 2 / 2;
	}

	.arv-live__years {
		grid-area: 1 / 2 / 2 / 3;
		justify-self: end;
	}

	/* Left, lined up with the race name above it rather than centred under
	   it. The icon sits in the same row on top of this span, and the
	   max-width is what keeps the two from ever meeting: a clock long enough
	   to reach the icon wraps instead of running under it. */
	.arv-live__clock {
		grid-area: 2 / 1 / 3 / -1;
		justify-self: start;
		max-width: calc(100% - 6rem);
	}

	.arv-live__social {
		grid-area: 2 / 2 / 3 / 3;
		justify-self: end;
	}
}


/* ---------------------------------------------------------------------
   The live results index: every race with a live page, as a dark list.

   Dark for the same reason the bar above each board is: this page is the
   front door to a set of dark timing boards, and a white list of links to
   black pages announces a seam the visitor then walks through. Full bleed,
   same breakout as everything else in this component.
   --------------------------------------------------------------------- */
.arv-live-index {
	text-align: left;
	margin-left: calc(50% - 50vw + (var(--arv-sbw, 0px) / 2));
	margin-right: calc(50% - 50vw + (var(--arv-sbw, 0px) / 2));
	background: #10201f;
	color: #f4f4f4;
	font-family: Lato, "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.arv-live-index__inner {
	max-width: 1200px;
	margin: 0 auto;
	padding: 2rem 1.25rem 2.25rem;
}

.arv-live-index__heading {
	margin: 0;
	text-align: center;
	font-size: clamp(26px, 3.4vw, 34px);
	font-weight: 700;
	line-height: 1.15;
	color: #fff;
}

.arv-live-index__intro {
	margin: 0.4rem auto 0;
	text-align: center;
	font-size: var(--arv-fs-body);
	color: rgba(244, 244, 244, 0.66);
	max-width: 46rem;
}

.arv-live-index__list {
	list-style: none;
	margin: 1.5rem 0 0;
	padding: 0;
}

.arv-live-index__race + .arv-live-index__race {
	border-top: 1px solid rgba(244, 244, 244, 0.12);
}

/* The whole row is the link. A race is one destination, and a linked name
   beside unlinked facts makes the target smaller than the thing it stands
   for, which is worse on a phone than anywhere. */
.arv-live-index__link,
.arv-live-index__link:link,
.arv-live-index__link:visited {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem 1rem;
	padding: 0.9rem 0;
	color: #f4f4f4;
	text-decoration: none;
}

.arv-live-index__logo {
	flex: 0 0 auto;
	width: 44px;
	height: 44px;
	object-fit: contain;
}

.arv-live-index__body {
	display: flex;
	flex-direction: column;
	gap: 0.15rem;
	flex: 1 1 14rem;
	min-width: 0;
}

.arv-live-index__name {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.4rem;
	font-size: var(--arv-fs-name);
	font-weight: 700;
	color: #fff;
}

.arv-live-index__year {
	color: rgba(244, 244, 244, 0.55);
	font-weight: 400;
}

.arv-live-index__meta {
	font-size: var(--arv-fs-body);
	color: rgba(244, 244, 244, 0.62);
}

.arv-live-index__clock {
	flex: 0 0 auto;
	font-size: var(--arv-fs-body);
	font-variant-numeric: tabular-nums;
}

.arv-live-index__go {
	flex: 0 0 auto;
	color: rgba(244, 244, 244, 0.5);
	line-height: 0;
}

/* A race that has finished steps back rather than disappearing: the index
   is also how someone reaches last weekend's results. */
.arv-live-index__race--done .arv-live-index__name {
	color: rgba(244, 244, 244, 0.82);
}

@media (hover: hover) and (pointer: fine) {
	a.arv-live-index__link:hover {
		background: rgba(244, 244, 244, 0.05);
	}

	a.arv-live-index__link:hover .arv-live-index__go {
		color: var(--arv-teal, #5bbfa8);
	}
}

.arv-live-index__link:focus-visible {
	outline: 2px solid var(--arv-teal, #5bbfa8);
	outline-offset: -2px;
}

@media (max-width: 619px) {
	.arv-live-index__inner {
		padding: 1.5rem 1rem 1.75rem;
	}

	/* The chevron is decoration on a row that is already entirely a link,
	   and on a phone it costs a line to keep. */
	.arv-live-index__go {
		display: none;
	}

	.arv-live-index__clock {
		flex: 1 1 100%;
	}
}

/* The footer's own accordion, added by aravaipa-footer.js. This is theme
   content this plugin does not own, so nothing here can lean on the
   --arv-fs-* scale or the teal custom properties: those are declared on
   .arv-results, .arv-live and .arv-live-index, and the footer sits outside
   all three. Sized and coloured to match the widget's own inline styles
   (13px, #272727, #888) rather than this plugin's usual palette. */
@media (max-width: 767px) {
	.arv-footer-accordion {
		/* Stated, not inherited: the page centres its text by default, the
		   same thing that made the live bar's title look centred earlier
		   tonight, and it was reaching this widget's links too. */
		text-align: left;
		border-top: 1px solid rgba(0, 0, 0, 0.08);
	}

	.arv-footer-accordion:first-of-type {
		border-top: none;
	}

	.arv-footer-accordion summary {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 0.75rem;
		padding: 0.65rem 0;
		font-size: 13px;
		letter-spacing: 2px;
		text-transform: uppercase;
		font-weight: 800;
		color: #272727;
		cursor: pointer;
		list-style: none;
	}

	.arv-footer-accordion summary::-webkit-details-marker {
		display: none;
	}

	/* A plain chevron rather than an icon font or an SVG sprite: the footer
	   loads no icon set of its own, and the site's other chevrons live inside
	   elements this widget is not part of. */
	.arv-footer-accordion summary::after {
		content: '';
		width: 7px;
		height: 7px;
		flex: 0 0 auto;
		border-right: 2px solid #aaa;
		border-bottom: 2px solid #aaa;
		transform: rotate(45deg);
		transition: transform 0.15s ease;
	}

	.arv-footer-accordion[open] summary::after {
		transform: rotate(-135deg);
	}

	.arv-footer-accordion a {
		padding: 0.3rem 0;
	}
}
