/*
Theme Name: Five Dot Ranch Hunting & Fishing
Theme URI: https://www.fivedothuntingfishing.com
Author: Five Dot Ranch Hunting & Fishing
Author URI: https://www.fivedothuntingfishing.com
Description: Custom native block theme for Five Dot Ranch Hunting & Fishing, a consolidated Northeastern California hunting and fly-fishing destination. Design tokens live in theme.json; this stylesheet only holds rules theme.json cannot express.
Requires at least: 6.5
Tested up to: 6.5
Requires PHP: 8.0
Version: 0.9.24
License: GNU General Public License v2 or later
License URI: LICENSE
Text Domain: five-dot-hunting-fishing
Tags: block-theme, full-site-editing, custom-colors, custom-menu, translation-ready
*/

/* Fixes a real gap in WordPress core's own CSS: a cover block using the
   default "flow" layout (no explicit "layout" attribute - true of every
   fivedot-feature-cover/small preview card in this theme) gets its direct
   children hit by the global block-spacing rule
   `:where(.is-layout-flow) > * { margin-block: 1.5rem 0 }`. Core resets
   this back to margin:0 for .wp-block-cover__image-background (the photo
   layer) but never does the same for .wp-block-cover__background (the dim
   overlay) or .wp-block-cover__gradient-background - so the overlay was
   rendering ~24px short at the top of every affected cover, leaving a
   lighter, un-dimmed band across the top of the image. Confirmed live
   (2026-08-04) via computed-style inspection: the overlay span's own
   getComputedStyle showed `margin-top: 24px` even though its `top`/`inset`
   were correctly 0. Covers that already set an explicit "layout":
   {"type":"constrained"} (hero, ranch-overview) never hit this, since the
   buggy rule is scoped to .is-layout-flow specifically. */
.wp-block-cover__background,
.wp-block-cover__gradient-background {
	margin: 0;
}

/* Accommodations cards (patterns/accommodations.php / wp_block 350): fixed
   2-up grid that wraps extra cards to their own row, rather than N equal
   columns squeezed into one row - chosen since the page's content column
   is only 760px wide and 3 columns there read as cramped. flex-grow:0 so
   a card holds this same half-width whether it's sharing a row with
   another card or wrapped alone onto the last row by itself - without
   this, flex's default grow behavior would stretch a lone trailing card
   to fill the whole row width, visibly larger than its siblings above it.
   Below 600px (this theme's mobile breakpoint - see mobile-nav.js's own
   MOBILE_BREAKPOINT) each card instead goes full-width, one per row,
   since two side-by-side no longer fits comfortably at that width. */
.fivedot-accommodation-card {
	flex: 0 1 calc(50% - 0.75rem);
	min-width: 280px;
}

@media (max-width: 600px) {
	.fivedot-accommodation-card {
		flex-basis: 100%;
	}
}

/* Smooths object-position changes when assets/js/responsive-focal-image.js
   recomputes a cover image's focal point on window resize - without a
   transition, resizing the window would snap the crop to its new position
   in one instant jump. prefers-reduced-motion turns off both the JS
   recomputation's effective motion and this transition. */
.fivedot-responsive-focal-image {
	transition: object-position 0.3s ease-out;
}

@media (prefers-reduced-motion: reduce) {
	.fivedot-responsive-focal-image {
		transition: none;
	}
}

/* Site-wide button hover/focus feedback. theme.json defines a hover
   background-color change (to rust) on .wp-element-button/.wp-block-button__link,
   but nearly every button on the site sets an explicit color via
   {"backgroundColor":"..."} (rust, forest-green, river-blue, gold,
   weathered-brown), which compiles to a .has-<color>-background-color rule
   with !important - that always wins over the non-!important hover rule,
   so in practice the color never actually changed on hover for any button
   that specifies its own color, which is nearly all of them. A lift +
   shadow avoids fighting that !important entirely, since neither transform
   nor box-shadow is touched by the background-color override, so it works
   uniformly regardless of which color a given button uses. */
.wp-element-button,
.wp-block-button__link {
	transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.wp-element-button:hover,
.wp-block-button__link:hover,
.wp-element-button:focus-visible,
.wp-block-button__link:focus-visible {
	transform: translateY(-2px);
	box-shadow: 0 4px 10px rgba(36, 31, 27, 0.3);
}

@media (prefers-reduced-motion: reduce) {
	.wp-element-button,
	.wp-block-button__link {
		transition: box-shadow 0.15s ease;
	}

	.wp-element-button:hover,
	.wp-block-button__link:hover,
	.wp-element-button:focus-visible,
	.wp-block-button__link:focus-visible {
		transform: none;
	}
}

/* Access License banner body text (patterns/access-license-banner.php) -
   bespoke size between the theme's "small" preset (13px, felt too small
   here) and "medium" (a fluid clamp that maxes out around 20px on desktop,
   too big to fit this sentence on one line within the banner's 70% text
   column) - there's nothing in between in theme.json, so this is its own
   fixed size rather than forcing either preset. */
.fivedot-access-license-banner-text {
	font-size: 1.125rem;
}

/* WordPress's global styles put a margin-block-start (top margin) of 1.5rem
   on every non-first child of a flow/constrained layout container
   (:root :where(.is-layout-flow) > * / .is-layout-constrained > *) -
   setting margin-bottom:0 on the FIRST paragraph (the eyebrow) never
   touched this, since it's a separate top-margin rule applied to the
   SECOND paragraph instead. Overriding margin-block-start directly on that
   second paragraph is what actually closes the gap - kept to desktop only
   for the Seasonal Notice box specifically, at the client's request to
   leave its default (unmodified) mobile spacing alone. */
@media (min-width: 783px) {
	.fivedot-access-license-banner-text-column .fivedot-access-license-banner-text {
		margin-block-start: 0 !important;
	}

	[data-fivedot-view-event="season_availability_view"] p:not(.fivedot-eyebrow) {
		margin-block-start: 0 !important;
	}
}

/* Access License banner columns (patterns/access-license-banner.php) -
   desktop only, at the client's request: on mobile, WordPress's own default
   column-stacking behavior should apply untouched (button below the text,
   full width, same as every other stacked-button section on the site) -
   these custom flex/width overrides are for the desktop side-by-side
   layout specifically and would otherwise fight that default stacking. A
   fixed 70%/30% split reserved far more width for the button column than
   the short "Access License" button actually needs, indirectly starving
   the text column and making the sentence wrap sooner than it needed to.
   Sizing the button column to its own content instead (flex: 0 0 auto)
   and letting the text column claim everything else (flex: 1 1 auto)
   gives the sentence the extra room. !important needed on both: core's
   block-library CSS has
   `.wp-block-columns:not(.is-not-stacked-on-mobile)>.wp-block-column{flex-basis:0;flex-grow:1}`
   - a 3-class-equivalent selector that's more specific than a single custom
   class, so it silently won over plain (non-!important) flex/width rules
   tried here first, no matter what values they set. Same reason the rest
   of this stylesheet's .has-<color>-background-color rules need
   !important to override core button/color styles. */
@media (min-width: 783px) {
	.fivedot-access-license-banner-text-column {
		flex: 1 1 0% !important;
		min-width: 0;
	}

	.fivedot-access-license-banner-button-column {
		flex: 0 0 auto !important;
		width: fit-content !important;
	}

	.fivedot-access-license-banner-columns.wp-block-columns {
		flex-wrap: nowrap;
		column-gap: 2rem;
	}
}

/* The button itself is set to justifyContent:"right" at the block level
   (patterns/access-license-banner.php), which reads fine on desktop where
   it sits at the right edge of its own narrow column, balanced against the
   left-aligned text - but that block attribute isn't scoped to desktop, so
   it also right-floats the button once the column stacks to full width on
   mobile, unlike every other stacked button on the site (left-aligned,
   full width). Overriding back to flex-start below the desktop breakpoint
   matches that convention. */
@media (max-width: 782px) {
	.fivedot-access-license-banner-button-column .wp-block-buttons.is-content-justification-right {
		justify-content: flex-start;
	}
}

/* WordPress adds a default margin-block-start between top-level blocks
   (:where(.wp-site-blocks) > * { margin-block-start: 1.5rem }), which put an
   unwanted gap between the header's gold bottom border and the page content
   below it. Zero it here so the gold line sits flush against the next
   section - each template's own <main> padding (or lack of it, for the hero
   on the front page) controls the actual breathing room instead of this
   external gap. The :where() rule has zero specificity, so a plain ID
   selector overrides it with no !important. */
#main {
	margin-block-start: 0;
}

/* The main-to-footer gap got the same zero-margin treatment at one point,
   but per the business's preference that gap has been restored - it reads
   better with the rest of the site's section rhythm. Set explicitly (rather
   than left to WordPress's own default) since that default wasn't actually
   rendering any visible gap here in practice. */
footer.wp-block-template-part {
	margin-block-start: 1.5rem;
}

/* Skip link - visible on keyboard focus only, for keyboard navigation. */
.skip-link {
	position: absolute;
	left: -9999px;
	top: auto;
	width: 1px;
	height: 1px;
	overflow: hidden;
	z-index: 100000;
}

.skip-link:focus {
	left: 0.5rem;
	top: 0.5rem;
	width: auto;
	height: auto;
	padding: 0.75rem 1.25rem;
	background: var(--wp--preset--color--forest-green);
	color: var(--wp--preset--color--white);
	border-radius: 2px;
}

/* Visually hidden but still available to assistive tech - unlike .skip-link
   above, this never reveals itself on focus. For form legends, table
   captions, etc. where a heading is needed for screen readers but would be
   visually redundant. Standard WordPress core implementation. */
.screen-reader-text {
	border: 0;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}

/* Visible focus states for keyboard navigation, kept consistent across
   native blocks that don't already render one. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
.wp-block-button__link:focus-visible {
	outline: 3px solid var(--wp--preset--color--rust);
	outline-offset: 2px;
}

/* Draft-content marker used throughout placeholder copy and patterns. */
.fivedot-draft-notice {
	border-left: 4px solid var(--wp--preset--color--rust);
	background: var(--wp--preset--color--mist);
	padding: 1rem 1.25rem;
	font-size: var(--wp--preset--font-size--small);
}

/* Native HTML reservation-inquiry form styling (see patterns/contact-inquiry.php). */
.fivedot-form label {
	display: block;
	font-weight: 600;
	margin-bottom: 0.35rem;
}

.fivedot-form input[type="text"],
.fivedot-form input[type="email"],
.fivedot-form input[type="tel"],
.fivedot-form input[type="date"],
.fivedot-form select,
.fivedot-form textarea {
	width: 100%;
	padding: 0.65rem 0.75rem;
	border: 1px solid var(--wp--preset--color--weathered-brown);
	border-radius: 2px;
	background: var(--wp--preset--color--white);
	font-family: inherit;
	font-size: var(--wp--preset--font-size--medium);
	box-sizing: border-box;
}

.fivedot-form fieldset {
	border: none;
	padding: 0;
	margin: 0 0 1.25rem;
}

.fivedot-form .fivedot-form-row {
	margin-bottom: 1.25rem;
}

.fivedot-form .fivedot-form-checkbox {
	display: flex;
	align-items: flex-start;
	gap: 0.6rem;
}

.fivedot-form .fivedot-form-checkbox label {
	font-weight: 400;
}

.fivedot-form-notice {
	padding: 1rem 1.25rem;
	border-radius: 2px;
	margin-bottom: 1.5rem;
	font-size: var(--wp--preset--font-size--medium);
}

.fivedot-form-notice.is-success {
	background: #e4ede4;
	border-left: 4px solid var(--wp--preset--color--forest-green);
}

.fivedot-form-notice.is-error {
	background: #f5e4de;
	border-left: 4px solid var(--wp--preset--color--rust);
}

/* Small uppercase tracked label, used above headlines/section titles for a
   structured, badge-like rhythm (echoes the crest logo's banner text). */
.fivedot-eyebrow {
	display: block;
	font-size: var(--wp--preset--font-size--small);
	text-transform: uppercase;
	letter-spacing: 0.14em;
	font-weight: 600;
}

/* Muted trailing annotation after a phone number/link, e.g. "(payment
   questions)" or "(ask for Brian)" on the Contact page - smaller and
   regular-weight so it reads as a quiet clarification, not part of the
   bold label. */
.fivedot-note {
	font-size: 0.85em;
	font-weight: 400;
	color: var(--wp--preset--color--weathered-brown);
}

/* Expand All / Collapse All controls on the FAQ page (see
   assets/js/faq-toggle.js) - styled as plain text links rather than real
   buttons, since visually they're just a pair of inline actions next to
   each section heading, not a primary call to action. */
.fivedot-faq-controls {
	margin: 0.25rem 0 1.25rem;
	font-size: var(--wp--preset--font-size--small);
}

.fivedot-faq-controls button {
	background: none;
	border: none;
	padding: 0;
	margin: 0;
	font: inherit;
	color: var(--wp--preset--color--river-blue);
	cursor: pointer;
	text-decoration: underline;
}

.fivedot-faq-controls button:hover,
.fivedot-faq-controls button:focus-visible {
	color: var(--wp--preset--color--rust);
}

.fivedot-faq-controls .fivedot-faq-controls-sep {
	color: var(--wp--preset--color--weathered-brown);
	margin: 0 0.5rem;
}

/* Section title with a short centered gold rule beneath - the theme's one
   recurring "crest" motif, used sparingly on major section headings only. */
.fivedot-section-title {
	text-align: center;
	position: relative;
	padding-bottom: 1rem;
	margin-bottom: 1.5rem;
}

.fivedot-section-title::after {
	content: "";
	position: absolute;
	bottom: 0;
	left: 50%;
	transform: translateX(-50%);
	width: 64px;
	height: 3px;
	background: var(--wp--preset--color--gold);
}

/* "Featured Hunting Opportunities" / "Featured Fishing Experiences" -
   whether these wrap to a second line at a given width depends on each
   word's own natural glyph widths, so at some viewport widths one wraps
   and the other doesn't, reading as inconsistent even though both headings
   are meant to look the same. A forced break point (invisible/inert on
   desktop, since neither needs to wrap there at full width) guarantees
   both always break at the same word on mobile, regardless of font
   metrics. */
.fivedot-mobile-break {
	display: none;
}

@media (max-width: 782px) {
	.fivedot-mobile-break {
		display: inline;
	}
}

/* Homepage mission statement - a lead sentence in the heading font instead
   of plain body copy, so it reads as a considered editorial line rather
   than a wall of default black paragraph text. */
.fivedot-intro-lead {
	font-family: var(--wp--preset--font-family--callout);
	font-weight: 400;
	letter-spacing: 0.01em;
	color: var(--wp--preset--color--weathered-brown);
	line-height: 1.3;
}

/* Feature-card treatment: gold top edge + a soft lift on hover. Applied to
   the group wrapping a card's text content (see patterns/feature-cards-*). */
.fivedot-card {
	border-top: 3px solid var(--wp--preset--color--gold);
	box-shadow: 0 1px 3px rgba(36, 31, 27, 0.08);
	transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.fivedot-card:hover {
	transform: translateY(-2px);
	box-shadow: 0 6px 16px rgba(36, 31, 27, 0.12);
}

/* Compact "In This Section" cards on the Hunting/Fishing landing pages -
   reuses .fivedot-card's gold-top-border/hover-lift treatment at smaller
   padding, with the card's own heading doubling as its link (no separate
   "read more" needed for a 1-line description). */
.fivedot-mini-card h3 {
	margin: 0 0 0.4rem;
	font-size: var(--wp--preset--font-size--medium);
}

.fivedot-mini-card h3 a {
	color: inherit;
	text-decoration: none;
}

.fivedot-mini-card h3 a:hover,
.fivedot-mini-card h3 a:focus-visible {
	text-decoration: underline;
}

.fivedot-mini-card p {
	margin: 0;
}

/* Equal card heights on desktop regardless of description length - the
   outer .wp-block-columns row already stretches its column children to
   match the tallest one (flex's default align-items:stretch, since this
   row sets no verticalAlignment to override it); this just carries that
   stretched height down into the actual card box, which otherwise only
   takes its own content's height. Skipped on mobile, where columns stack
   full-width instead of sitting side by side, so matching heights doesn't
   apply/matter there. */
@media (min-width: 783px) {
	.fivedot-mini-card-row .wp-block-column {
		display: flex;
	}

	.fivedot-mini-card-row .wp-block-column .fivedot-mini-card {
		flex: 1;
	}
}

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

	.fivedot-card:hover {
		transform: none;
	}
}

/* On mobile, columns stack to full width and a fixed 220px min-height would
   crop the hunting triptych image (see patterns/feature-cards-hunting-fishing.php)
   - most of three side-by-side animal photos would be cut off. Switching to
   an aspect-ratio matching the triptych's own (1400x513) lets the whole
   image show at whatever width the column actually is, no cropping.
   The fishing card shares the same class/ratio so both cards stay the same
   height, even though the trout-scales photo itself doesn't need the full
   frame shown - both min-height AND aspect-ratio need !important, since the
   cover block writes BOTH as inline styles (min-height:220px, and -
   easy to miss - aspect-ratio:unset, added by core even when no aspect
   ratio was ever chosen in the editor), and inline styles win over an
   external stylesheet rule regardless of specificity. */
@media (max-width: 782px) {
	.fivedot-feature-cover {
		min-height: 0 !important;
		aspect-ratio: 1400 / 513 !important;
	}
}

/* Contact page - the logo fills what would otherwise be empty space beside
   the short address/phone/email block on desktop (see the two-column
   layout in post content). Below core's own column-stacking breakpoint
   (782px) the columns stack vertically instead, so the logo would just
   sit redundantly below the same contact info rather than beside it - and
   the header already shows this exact logo on every page - so it's
   dropped entirely on mobile rather than kept as a stacked duplicate. */
@media (max-width: 782px) {
	.fivedot-contact-logo-column {
		display: none;
	}
}

.fivedot-contact-logo-column {
	padding-left: 1.5rem;
}

/* Belt-and-suspenders against the logo ever outgrowing its (narrower,
   36%-width) column and pushing into the text column beside it - the
   image's own width/height attributes should already size it correctly,
   but this guarantees it regardless of viewport width between the mobile
   breakpoint above and whatever the column actually measures. */
.fivedot-contact-logo-column img {
	max-width: 100%;
	height: auto;
}

/* Homepage "Featured Fishing Experiences" section band - a light blue tint
   (not in theme.json's palette, since it's a one-off decorative band color
   rather than a semantic content color that should show up in the block
   editor's color picker), used instead of the "Featured Hunting
   Opportunities" band's mist background so the two homepage sections read
   as visually distinct at a glance. Lightness/weight roughly matches mist
   (#E7E2D4) on purpose - same visual "loudness", just blue-toned instead
   of tan-toned - derived from the site's own river-blue (#3F6B84, already
   fishing's accent color everywhere else: buttons, card borders) blended
   toward white. */
.fivedot-fishing-band {
	background-color: #E8EDF0;
}

/* Featured hunting/fishing galleries: a Query Loop block whose post-template
   is forced into a horizontally-scrolling, snap-to track (2 cards visible at
   a time on desktop) with arrow buttons on either side. The `!important`s
   override WordPress's own generated inline stylesheet for the query block's
   "columns" display mode (`.is-flex-container.columns-N > li{width:...}`),
   which otherwise wins on specificity and would keep the cards wrapping to a
   new line instead of scrolling. gallery-scroll.js drives the arrow clicks
   and hides an arrow once there's nothing further to scroll to in that
   direction - this is the one place a Query Loop can't do what's needed on
   its own (no native "carousel" display mode exists for it). */
.fivedot-gallery {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}

.fivedot-gallery-track {
	flex: 1 1 auto;
	min-width: 0;
}

.fivedot-gallery-track .wp-block-post-template {
	display: flex !important;
	flex-wrap: nowrap !important;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	gap: 1.5rem !important;
	margin: 0 !important;
	padding: 0.25rem 0.25rem 1rem;
	scroll-behavior: smooth;
	/* Tells the browser this element only handles horizontal touch panning,
	   so a finger-drag that's mostly-but-not-perfectly horizontal locks to
	   scrolling the track instead of also scrolling the page vertically at
	   the same time. The image-carousel variant (.fivedot-gallery-track--images
	   below) already had this; this variant was just missing it. */
	touch-action: pan-x;
}

.fivedot-gallery-track .wp-block-post-template > li {
	flex: none !important;
	width: calc(50% - 0.75rem) !important;
	scroll-snap-align: start;
	border-top: 3px solid var(--wp--preset--color--gold);
	box-shadow: 0 1px 3px rgba(36, 31, 27, 0.08);
	transition: transform 0.15s ease, box-shadow 0.15s ease;
	background: var(--wp--preset--color--white, #fff);
	display: flex;
	flex-direction: column;
}

/* The text panel (mist background) grows to fill whatever height the card
   was stretched to match its tallest sibling - otherwise a shorter card's
   spare height shows as a plain white gap below the mist-colored text. */
.fivedot-gallery-track .wp-block-post-template > li > .wp-block-group {
	flex: 1 1 auto;
}

.fivedot-gallery-track .wp-block-post-template > li:hover {
	transform: translateY(-2px);
	box-shadow: 0 6px 16px rgba(36, 31, 27, 0.14);
}

/* A single result shouldn't sit at half-width with empty space beside it -
   let it fill the track instead. Nothing to scroll to either way, so the
   arrows already auto-hide via gallery-scroll.js's maxScroll check. */
.fivedot-gallery-track .wp-block-post-template > li:only-child {
	width: 100% !important;
}

/* Homepage Featured Hunting Opportunities specifically: only 1 fivedot_hunt
   post remains published (Deer & Antelope) after Waterfowl/Pheasant &
   Chukar were drafted. Without this override the generic :only-child rule
   above stretches the lone card to 100% width - and since its image is
   aspect-ratio-locked rather than a fixed height, the image grows taller
   right along with it. Capping this specific instance back to the same
   width a 2-up card would have keeps the image at its originally-designed
   crop/height instead of needing a new one, and centers it so it doesn't
   sit stranded at the track's left edge with empty space beside it. Scoped
   to the homepage only (see the fivedot-gallery--homepage-hunting class in
   front-page.html) - the Hunting page's own "Current Opportunities"
   section (fivedot-gallery--hunting-offerings) isn't directly stacked
   above a visually similar section, so its lone card can stay full-width. */
.fivedot-gallery--homepage-hunting .fivedot-gallery-track .wp-block-post-template > li:only-child {
	width: calc(50% - 0.75rem) !important;
}

.fivedot-gallery--homepage-hunting .fivedot-gallery-track .wp-block-post-template:has(> li:only-child) {
	justify-content: center;
}

.fivedot-gallery-track .wp-block-post-template img {
	display: block;
	width: 100%;
	aspect-ratio: 3 / 2;
	object-fit: cover;
}

/* Static-image carousel variant (see patterns/fishing-photo-carousel.php) -
   same scroll/arrow mechanism as the Query Loop galleries above, but the
   track itself is the flex/scroll container instead of a nested
   .wp-block-post-template, since there's no query block involved.

   Unlike the card galleries, these images are never cropped: the track has
   a fixed height and each photo is width:auto, so it keeps its natural
   aspect ratio and just fills that height - landscape, portrait, and
   ultra-wide panoramas all display in full. The scrollbar itself is hidden
   (scrollbar-width/::-webkit-scrollbar) since the arrow buttons are the
   intended way to navigate; native touch/trackpad scrolling still works. */
.fivedot-gallery-track.fivedot-gallery-track--images {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	overflow-x: auto;
	gap: 1rem;
	margin: 0;
	padding: 0;
	height: clamp(240px, 26vw, 420px);
	scroll-behavior: smooth;
	scrollbar-width: none;
	-ms-overflow-style: none;
	-webkit-overflow-scrolling: touch;
	touch-action: pan-x;
}

.fivedot-gallery-track--images::-webkit-scrollbar {
	display: none;
}

.fivedot-gallery-track--images {
	cursor: grab;
}

.fivedot-gallery-track--images.is-dragging {
	cursor: grabbing;
	scroll-behavior: auto;
	user-select: none;
}

.fivedot-gallery-track--images img {
	-webkit-user-drag: none;
	user-select: none;
}

/* Full-bleed carousel variant (fishing-photo-carousel.php): the track runs
   completely edge-to-edge (like the homepage Ranch section's cover image),
   so the arrows can't sit beside it as flex siblings the way the card
   galleries' inline arrows do - they float on top of the image instead,
   near the left/right edges. This is scoped to --carousel specifically so
   it doesn't change the Featured Hunting/Fishing card galleries above. */
.fivedot-gallery--carousel {
	position: relative;
	display: block;
}

.fivedot-gallery--carousel .fivedot-gallery-arrow {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 1;
	background: rgba(243, 234, 216, 0.85);
}

.fivedot-gallery--carousel .fivedot-gallery-arrow--prev {
	left: 1rem;
}

.fivedot-gallery--carousel .fivedot-gallery-arrow--next {
	right: 1rem;
}

/* "View More" is its own card-like slide at the end of the track (after the
   last photo) rather than a button overlaid on top of the images - it used
   to sit absolutely-positioned over the photos at partial opacity so it
   wouldn't compete with them visually, but that opacity trick meant its
   default (non-hover) state failed color-contrast, since the effective
   rendered color was the button color blended with whatever photo sat
   behind it. A solid, fully-opaque card needs no such blending, so there's
   nothing for contrast to fail. Matches the site's other cards (gold top
   border) so it reads as "one more card" ending the row rather than a
   dead end. */
.fivedot-gallery-viewmore {
	position: relative;
	z-index: 2;
	flex: none;
	width: clamp(150px, 13vw, 200px);
	height: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0.6rem;
	background: var(--wp--preset--color--white, #fff);
	border-top: 3px solid var(--wp--preset--color--gold);
	color: var(--wp--preset--color--forest-green);
	text-decoration: none;
	text-align: center;
	font-weight: 600;
	font-size: var(--wp--preset--font-size--small);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	transition: background 0.15s ease;
}

.fivedot-gallery-viewmore:hover,
.fivedot-gallery-viewmore:focus-visible {
	background: var(--wp--preset--color--mist);
}

.fivedot-gallery-viewmore:hover .fivedot-gallery-viewmore-label,
.fivedot-gallery-viewmore:focus-visible .fivedot-gallery-viewmore-label {
	text-decoration: underline;
}

.fivedot-gallery-viewmore-arrow svg {
	display: block;
}

/* "Offerings" card carousels - the same scroll/arrow/card mechanism as the
   homepage's Featured Hunting/Fishing galleries above, reused on the
   Hunting and Fishing pages themselves (Current Opportunities / Fishing
   Offerings) so they don't need their own separate JS or markup pattern.
   Deliberately restyled (mist card background instead of white, and a
   page-matching accent color on the top border instead of gold) so these
   don't read as a duplicate of the homepage section - a visitor who
   scrolled past one already recognizes the pattern but sees it's "their
   own" version on this page. */
.fivedot-gallery--hunting-offerings .fivedot-gallery-track .wp-block-post-template > li {
	background: var(--wp--preset--color--mist);
	border-top-color: var(--wp--preset--color--forest-green);
}

.fivedot-gallery--fishing-offerings .fivedot-gallery-track .wp-block-post-template > li {
	background: var(--wp--preset--color--mist);
	border-top-color: var(--wp--preset--color--river-blue);
}

.fivedot-gallery--hunting-offerings .fivedot-gallery-track .wp-block-post-template > li > .wp-block-group,
.fivedot-gallery--fishing-offerings .fivedot-gallery-track .wp-block-post-template > li > .wp-block-group {
	background: transparent;
}

/* Single Hunting Opportunity / Fishing Offering pages (single-fivedot_hunt.html,
   single-fivedot_fish.html) - badges for the species/availability taxonomy
   terms, and a colored closing CTA band matching each post type's accent
   color (forest-green for hunting, river-blue for fishing, same convention
   as their buttons elsewhere on the site). */
.fivedot-offering-meta {
	gap: 0.5rem 0.75rem;
	align-items: center;
}

.fivedot-offering-meta .wp-block-post-terms {
	margin: 0;
}

/* :not(.wp-block-post-terms__separator) matters here - core's Post Terms
   block wraps its own ", " separator in a <span> too when a taxonomy has
   more than one term (e.g. "Antelope, Mule Deer"), which would otherwise
   get boxed into its own little pill right along with the real terms. */
.fivedot-offering-meta .wp-block-post-terms span:not(.wp-block-post-terms__separator) {
	display: inline-block;
	background: var(--wp--preset--color--mist);
	color: var(--wp--preset--color--weathered-brown);
	border-radius: 999px;
	padding: 0.2rem 0.85rem;
	font-size: 0.8rem;
	text-decoration: none;
}

.fivedot-offering-featured img {
	border-radius: 4px;
}

.fivedot-offering-cta {
	margin-top: 2.5rem;
	padding: 2rem 1.5rem;
	border-radius: 4px;
	text-align: center;
}

.fivedot-offering-cta.is-hunting {
	background: var(--wp--preset--color--forest-green);
}

.fivedot-offering-cta.is-fishing {
	background: var(--wp--preset--color--river-blue);
}

.fivedot-offering-cta h2 {
	margin-top: 0;
}

/* Stat-highlight grid - used on the Deer & Antelope Hunts offering page to
   surface the state PLM program's scale (properties/counties/acreage)
   at a glance, rather than burying the numbers in prose. Generic enough
   to reuse anywhere else a handful of standout figures need the same
   treatment. */
.fivedot-stat-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 1rem;
	margin: 1.5rem 0 2rem;
}

.fivedot-stat {
	display: flex;
	flex-direction: column;
	background: var(--wp--preset--color--mist);
	border-top: 3px solid var(--wp--preset--color--gold);
	border-radius: 4px;
	padding: 1.25rem 0.75rem;
	text-align: center;
}

/* A fixed-height "number zone" (rather than letting each number's own
   font-size determine its row height) is what actually keeps every label
   below it lined up across all 4 cells, and keeps the smaller --compact
   number (a "375-270,000" range doesn't fit the others' larger size)
   vertically centered against the big numbers next to it instead of
   sitting flush at the top of a shorter line. */
.fivedot-stat-number {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 2.3rem;
	font-family: var(--wp--preset--font-family--heading, inherit);
	font-size: 1.9rem;
	font-weight: 700;
	color: var(--wp--preset--color--forest-green);
	line-height: 1.1;
}

.fivedot-stat-number--compact {
	font-size: 1.15rem;
}

.fivedot-stat-label {
	display: block;
	margin-top: 0.35rem;
	font-size: 0.8rem;
	color: var(--wp--preset--color--weathered-brown);
}

@media (max-width: 600px) {
	.fivedot-stat-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

/* This full-bleed carousel is the last block in the Fishing page's
   post-content, which sits inside page.html's <main> - and that <main> adds
   a flat 4rem of bottom padding on every interior page. On the homepage,
   the last section's own --section-gap bottom padding is what you're
   actually seeing "below" it - the footer itself butts up almost directly
   against that section (they're separated only by the footer's own ~1.5rem
   internal top spacing, not by extra page gap). Since this carousel has no
   background band to hold that breathing room inside itself (see the
   .fivedot-carousel-section padding-bottom:0 in the pattern), the honest
   match for "the same gap as the homepage" is to cancel <main>'s flat 4rem
   entirely, so the photo's own edge sits that same ~1.5rem from the footer
   instead of stacking blank page background on top of it.

   !important is required: WordPress's own core stylesheet ships
   `.is-layout-constrained > :last-child { margin-block-end: 0; }`, which is
   two selector components (higher specificity than a single class here) and
   would otherwise silently zero this out, since post-content is itself a
   constrained-layout container and this section is its last child. */
.is-layout-constrained > .fivedot-carousel-section {
	margin-block-end: -4rem !important;
}

.fivedot-gallery-track--images .fivedot-gallery-photo {
	position: relative;
	flex: none;
	width: auto;
	height: 100%;
	margin: 0;
	overflow: hidden;
}

.fivedot-gallery-track--images .fivedot-gallery-photo img {
	display: block;
	width: auto;
	height: 100%;
	max-width: none;
}

/* Caption shown on hover/keyboard-focus only, anchored to the bottom edge -
   an unobtrusive way to surface each photo's alt text without permanent
   on-image clutter. */
.fivedot-gallery-photo-caption {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	margin: 0;
	padding: 1.5rem 1rem 0.6rem;
	background: linear-gradient(to top, rgba(27, 42, 61, 0.85), rgba(27, 42, 61, 0));
	color: var(--wp--preset--color--white);
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.3;
	opacity: 0;
	transform: translateY(6px);
	transition: opacity 0.15s ease, transform 0.15s ease;
	pointer-events: none;
}

.fivedot-gallery-photo:hover .fivedot-gallery-photo-caption,
.fivedot-gallery-photo:focus-within .fivedot-gallery-photo-caption {
	opacity: 1;
	transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
	.fivedot-gallery-photo-caption {
		transition: none;
	}
}

.fivedot-gallery-arrow {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.5rem;
	height: 2.5rem;
	border-radius: 999px;
	border: 1px solid var(--wp--preset--color--gold);
	background: var(--wp--preset--color--parchment);
	color: var(--wp--preset--color--charcoal);
	cursor: pointer;
	padding: 0;
	transition: background 0.15s ease, color 0.15s ease;
}

.fivedot-gallery-arrow:hover,
.fivedot-gallery-arrow:focus-visible {
	background: var(--wp--preset--color--gold);
}

.fivedot-gallery-arrow[hidden] {
	display: none;
}

@media (max-width: 782px) {
	/* One full card at a time on mobile for the Featured Hunting/Fishing
	   Query Loop galleries (not the full-bleed photo carousel, which
	   already goes edge-to-edge and hides its own arrows on mobile below). */
	.fivedot-gallery:not(.fivedot-gallery--carousel) .fivedot-gallery-track .wp-block-post-template > li {
		width: 100% !important;
	}

	/* Reserve constant space for both arrows regardless of whether either
	   is actually visible at the current scroll position. The arrows are
	   flex siblings of the track (see .fivedot-gallery above) - letting a
	   hidden one collapse via display:none let the track grow to fill that
	   freed space, resizing every card and visibly "bouncing" the section
	   (and the page under it) each time an arrow's visibility changed as
	   you scrolled. Swapping to visibility keeps the box in layout so nothing
	   resizes, just fades the arrow itself in/out of view. */
	.fivedot-gallery:not(.fivedot-gallery--carousel) .fivedot-gallery-arrow[hidden] {
		display: flex;
		visibility: hidden;
		pointer-events: none;
	}

	/* On touch-sized screens the full-bleed photo carousel is swipe-driven
	   instead of arrow-driven - overflow-x: auto already lets a finger drag
	   through the track natively, so the arrow buttons (a desktop
	   hover/click affordance) are just hidden rather than reworked. */
	.fivedot-gallery--carousel .fivedot-gallery-arrow {
		display: none;
	}

	.fivedot-gallery-track.fivedot-gallery-track--images {
		height: clamp(200px, 58vw, 320px);
	}
}

@media (prefers-reduced-motion: reduce) {
	.fivedot-gallery-track .wp-block-post-template,
	.fivedot-gallery-track--images {
		scroll-behavior: auto;
	}

	.fivedot-gallery-track .wp-block-post-template > li {
		transition: none;
	}
}

/* Collage photo grid for the Photos subpages (see
   fivedot_render_photo_gallery() in inc/gallery-render.php).
   grid-template-columns' auto-fill/minmax (rather than a fixed column
   count) lets the browser pick however many columns actually fit, so this
   needs no manual breakpoints - same responsive density as the
   column-width masonry layout this replaced. Deliberately does NOT crop
   or force a fixed aspect ratio - the img rule's width:auto +
   max-width/max-height combination lets the browser pick whichever bound
   actually binds (a wide photo settles at the column's full width; an
   unusually tall one settles narrower than the column, capped by height,
   rather than ever cropping). Clicking a photo opens
   assets/js/photo-modal.js's lightbox.

   CSS Grid rather than a CSS multi-column layout specifically because
   Gallery Order (Fivedot_Media_Galleries::get_gallery_images(), sorted
   before this ever reaches the browser) needs to read left-to-right,
   top-to-bottom, the way a Gallery Order number implies "priority" - 1st,
   2nd, 3rd down the page. Multi-column fills column-major: it always
   completes the entire first column top-to-bottom before starting the
   second, so with 2+ columns the 2nd-highest-ordered photo would land at
   the TOP of column 2, underneath lower-priority photos still filling out
   column 1 - not the reading order Gallery Order is meant to express.
   Grid's default flow is row-major (1st top-left, 2nd top of the next
   column over, 3rd starts the second row), which matches. The one
   tradeoff: each grid row sizes to its tallest photo (a shorter neighbor
   in the same row leaves a gap below it) rather than columns packing
   tightly Pinterest-style - an acceptable trade for ordering that
   actually reads as ordered. */
.fivedot-photo-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
	gap: 1.5rem;
}

.fivedot-photo-grid-item {
	display: block;
	width: 100%;
	padding: 0;
	background: none;
	border: none;
	border-top: 3px solid var(--wp--preset--color--gold);
	box-shadow: 0 1px 3px rgba(36, 31, 27, 0.08);
	transition: transform 0.15s ease, box-shadow 0.15s ease;
	text-align: center;
	cursor: zoom-in;
	font: inherit;
}

.fivedot-photo-grid-item:hover,
.fivedot-photo-grid-item:focus-visible {
	transform: translateY(-2px);
	box-shadow: 0 6px 16px rgba(36, 31, 27, 0.14);
}

.fivedot-photo-grid-item img {
	display: block;
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: 560px;
	margin: 0 auto;
}

@media (max-width: 480px) {
	.fivedot-photo-grid-item img {
		max-height: 420px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.fivedot-photo-grid-item {
		transition: none;
	}
}

/* Lightbox modal (assets/js/photo-modal.js) - one instance, built lazily
   and reused for whichever .fivedot-photo-grid was clicked.

   The image is centered on the *whole* frame by default, ignoring the
   info bar entirely (so it can also extend up behind the close button/
   arrows, which stay clickable/visible above it via z-index - deliberately
   tight frame padding here, since those controls are the actual minimum
   clearance now, not the padding). That's correct as long as there's
   enough vertical room. assets/js/photo-modal.js's adjustForCaption()
   measures after each image loads (and on resize) and only steps in with
   an inline max-height + top-alignment override when the centered image
   would actually run under the info bar - e.g. a tall photo on a short
   landscape-mobile viewport - rather than always reserving that space
   whether or not it's needed. */
/* Single source of truth for the modal image/embed's clearance on every
   side, so the frame's padding (and .fivedot-photo-modal-info's inset)
   can never drift out of sync with the arrows' actual position/size again
   - it happened once already when the frame padding was tightened without
   recalculating this. --fivedot-arrow-offset/-size must match the values
   used below on .fivedot-photo-modal-arrow. --fivedot-top-clearance is
   small by default (the close button/arrows float over the image via
   z-index, which is fine) but gets raised whenever the WordPress admin bar
   is present, since that's a real opaque bar the image must not render
   underneath - see the body.admin-bar rules.

   Declared on :root, not .fivedot-photo-modal itself: .fivedot-video-modal
   (a separate top-level element, not a descendant of .fivedot-photo-modal)
   reuses these same arrow/info/caption classes for its own close button,
   arrows, and caption, and needs the same variables to resolve - a
   custom property only inherits through the DOM tree it's declared on. */
:root {
	--fivedot-arrow-offset: 2rem;
	--fivedot-arrow-size: 3rem;
	--fivedot-arrow-gap: 0.5rem;
	--fivedot-side-clearance: calc(var(--fivedot-arrow-offset) + var(--fivedot-arrow-size) + var(--fivedot-arrow-gap));
	--fivedot-top-clearance: 1rem;
}

.fivedot-photo-modal {
	position: fixed;
	inset: 0;
	z-index: 1000;
}

.fivedot-photo-modal[hidden] {
	display: none;
}

.fivedot-photo-modal-backdrop {
	position: absolute;
	inset: 0;
	background: rgba(27, 42, 61, 0.92);
}

.fivedot-photo-modal-frame {
	position: absolute;
	inset: 0;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--fivedot-top-clearance) var(--fivedot-side-clearance) 1.25rem;
	cursor: zoom-out;
}

.fivedot-photo-modal-img {
	display: block;
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
	cursor: default;
}

.fivedot-photo-modal-info {
	position: absolute;
	left: var(--fivedot-side-clearance);
	right: var(--fivedot-side-clearance);
	bottom: 1.25rem;
	z-index: 1;
	text-align: center;
}

.fivedot-photo-modal-caption {
	color: var(--wp--preset--color--white);
	margin: 0;
	font-size: var(--wp--preset--font-size--small);
	/* Without this, mobile Safari's automatic text-size-adjust boosts small
	   text based on how wide the viewport is relative to the content - so
	   the exact same fixed (non-fluid, see theme.json) 0.875rem preset
	   renders visibly larger in landscape than portrait on the same phone. */
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
}

.fivedot-photo-modal-caption[hidden] {
	display: none;
}

.fivedot-photo-modal-counter {
	color: var(--wp--preset--color--mist);
	margin: 0.5rem 0 0;
	font-size: var(--wp--preset--font-size--small);
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
}

.fivedot-photo-modal-counter[hidden] {
	display: none;
}

.fivedot-photo-modal-close,
.fivedot-photo-modal-arrow {
	position: absolute;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	border-radius: 999px;
	border: 1px solid rgba(243, 234, 216, 0.5);
	background: rgba(27, 42, 61, 0.6);
	color: var(--wp--preset--color--parchment);
	cursor: pointer;
	transition: background 0.15s ease;
}

.fivedot-photo-modal-close:hover,
.fivedot-photo-modal-close:focus-visible,
.fivedot-photo-modal-arrow:hover,
.fivedot-photo-modal-arrow:focus-visible {
	background: rgba(201, 162, 39, 0.85);
	color: var(--wp--preset--color--charcoal);
}

.fivedot-photo-modal-close {
	top: 1rem;
	right: 1rem;
	width: 2.75rem;
	height: 2.75rem;
	padding: 0;
}

/* The logged-in WordPress admin bar is fixed at the very top of the
   viewport with a higher z-index than anything a theme can reasonably
   use, so without this the close button (and, via --fivedot-top-clearance,
   the image itself) sits half-hidden underneath it for any logged-in
   editor. Matches WP core's own admin-bar height breakpoint (32px desktop,
   46px at 782px and below). */
body.admin-bar {
	--fivedot-top-clearance: calc(32px + 1rem);
}

body.admin-bar .fivedot-photo-modal-close {
	top: calc(32px + 1rem);
}

@media (max-width: 782px) {
	body.admin-bar {
		--fivedot-top-clearance: calc(46px + 1rem);
	}

	body.admin-bar .fivedot-photo-modal-close {
		top: calc(46px + 1rem);
	}
}

.fivedot-photo-modal-arrow {
	top: 50%;
	transform: translateY(-50%);
	width: var(--fivedot-arrow-size);
	height: var(--fivedot-arrow-size);
	padding: 0;
}

/* Invisible "grace halo" - extends the clickable area well past the visible
   circle, without changing its appearance. Now that clicking the modal
   background closes it, a click that narrowly misses the arrow would
   otherwise fall through to that background handler and close the modal
   instead of advancing - this makes near-misses still count as hitting
   the arrow. */
.fivedot-photo-modal-arrow::after {
	content: '';
	position: absolute;
	inset: -0.85rem;
}

.fivedot-photo-modal-arrow--prev {
	left: var(--fivedot-arrow-offset);
}

.fivedot-photo-modal-arrow--next {
	right: var(--fivedot-arrow-offset);
}

.fivedot-photo-modal-arrow[hidden] {
	display: none;
}

body.fivedot-modal-open {
	overflow: hidden;
}

@media (max-width: 600px) {
	/* Just the arrow geometry needs to change here - .fivedot-photo-modal-
	   frame's padding and .fivedot-photo-modal-info's inset (and their
	   .fivedot-video-modal equivalents) all derive from --fivedot-side-
	   clearance already, so updating these two variables keeps everything
	   else in sync automatically. */
	:root {
		--fivedot-arrow-offset: 1rem;
		--fivedot-arrow-size: 2.5rem;
	}
}

/* Short/landscape-mobile viewports specifically (a landscape phone is wide,
   so the max-width query above doesn't catch it, but very short) - claw
   back a little more of the already-limited height. Top clearance and side
   clearance (arrows, admin bar) are left alone here - they're not just
   cosmetic padding, so they don't shrink just because the viewport is
   short. */
@media (max-height: 500px) {
	.fivedot-photo-modal-frame {
		padding-bottom: 0.75rem;
	}
}

/* Click-to-play video grid (assets/js/video-modal.js, inc/video-embed.php) -
   same card language as .fivedot-photo-grid-item (gold top border, hover
   lift) but laid out as a proper grid rather than a masonry column set,
   since every thumbnail shares the same 16:9 shape. The first available
   video renders full-width above this grid (.fivedot-video-featured) -
   see below. */
.fivedot-video-gallery-wrap > .fivedot-video-featured {
	margin-bottom: 1.5rem;
}

.fivedot-video-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 1.5rem;
}

@media (max-width: 600px) {
	.fivedot-video-grid {
		grid-template-columns: 1fr;
	}
}

.fivedot-video-grid-item {
	position: relative;
	display: block;
	width: 100%;
	padding: 0;
	margin: 0;
	background: none;
	border: none;
	border-top: 3px solid var(--wp--preset--color--gold);
	box-shadow: 0 1px 3px rgba(36, 31, 27, 0.08);
	transition: transform 0.15s ease, box-shadow 0.15s ease;
	text-align: left;
	cursor: pointer;
	font: inherit;
	overflow: hidden;
}

.fivedot-video-grid-item:hover,
.fivedot-video-grid-item:focus-visible {
	transform: translateY(-2px);
	box-shadow: 0 6px 16px rgba(36, 31, 27, 0.14);
}

.fivedot-video-grid-item img {
	display: block;
	width: 100%;
	/* The HTML height="360" attribute (needed so the browser can reserve
	   layout space before the image loads) otherwise wins as the box's
	   only explicit height, since aspect-ratio only computes a dimension
	   that's actually auto - without this, the image renders at a fixed
	   360px tall regardless of width, ignoring aspect-ratio entirely. */
	height: auto;
	aspect-ratio: 16 / 9;
	object-fit: cover;
}

.fivedot-video-grid-play {
	position: absolute;
	top: calc(50% - 0.85rem);
	left: 50%;
	transform: translateX(-50%);
	width: 3.25rem;
	height: 3.25rem;
	border-radius: 999px;
	background: rgba(27, 42, 61, 0.75);
	color: var(--wp--preset--color--parchment);
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background 0.15s ease, color 0.15s ease;
}

.fivedot-video-grid-item:hover .fivedot-video-grid-play,
.fivedot-video-grid-item:focus-visible .fivedot-video-grid-play {
	background: rgba(201, 162, 39, 0.9);
	color: var(--wp--preset--color--charcoal);
}

.fivedot-video-grid-title {
	display: block;
	padding: 0.6rem 0.85rem 0.75rem;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--charcoal);
	/* One line only - a wrapped second line would make this card taller
	   than its row partner, offsetting everything below it. Long titles
	   truncate with an ellipsis instead. */
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* Featured video - the same card treatment as .fivedot-video-grid-item,
   scaled up and capped at roughly the width of a standard embedded player
   (matching the fixed-width iframe used for the Round Valley Reservoir
   page's own embed) rather than stretching to the full wide-container
   width on large screens. */
.fivedot-video-featured {
	position: relative;
	display: block;
	width: 100%;
	max-width: 800px;
	margin-left: auto;
	margin-right: auto;
	padding: 0;
	background: none;
	border: none;
	border-top: 3px solid var(--wp--preset--color--gold);
	box-shadow: 0 1px 3px rgba(36, 31, 27, 0.08);
	transition: transform 0.15s ease, box-shadow 0.15s ease;
	text-align: left;
	cursor: pointer;
	font: inherit;
	overflow: hidden;
}

.fivedot-video-featured:hover,
.fivedot-video-featured:focus-visible {
	transform: translateY(-2px);
	box-shadow: 0 6px 16px rgba(36, 31, 27, 0.14);
}

.fivedot-video-featured img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
	object-fit: cover;
}

.fivedot-video-featured-play {
	position: absolute;
	top: calc(50% - 1.15rem);
	left: 50%;
	transform: translateX(-50%);
	width: 4.5rem;
	height: 4.5rem;
	border-radius: 999px;
	background: rgba(27, 42, 61, 0.75);
	color: var(--wp--preset--color--parchment);
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background 0.15s ease, color 0.15s ease;
}

.fivedot-video-featured:hover .fivedot-video-featured-play,
.fivedot-video-featured:focus-visible .fivedot-video-featured-play {
	background: rgba(201, 162, 39, 0.9);
	color: var(--wp--preset--color--charcoal);
}

.fivedot-video-featured-title {
	display: block;
	padding: 0.85rem 1rem 1rem;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--charcoal);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

@media (prefers-reduced-motion: reduce) {
	.fivedot-video-grid-item,
	.fivedot-video-featured {
		transition: none;
	}
}

/* Video modal (assets/js/video-modal.js) - reuses .fivedot-photo-modal's
   backdrop/close/arrow/caption styling (identical look, no JS coupling
   beyond a shared class name each script queries within its own modal
   root), swapping only the centered-image frame for a responsive 16:9
   embed frame.

   Centered on the full frame by default, same as the photo modal - see
   the comment near .fivedot-photo-modal-frame. adjustForCaption() in
   video-modal.js only steps in (narrowing the embed - its height always
   follows its width via aspect-ratio, so "shrinking to fit" means
   computing a narrower width from the available height) when the centered
   embed would actually overlap the caption bar, e.g. a wide landscape-
   mobile viewport making the 16:9 embed tall enough to reach it. */
.fivedot-video-modal {
	position: fixed;
	inset: 0;
	z-index: 1000;
}

.fivedot-video-modal[hidden] {
	display: none;
}

.fivedot-video-modal-frame {
	position: absolute;
	inset: 0;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	/* Horizontal clearance matches the arrows' actual footprint, and top
	   clearance is admin-bar-aware, same as .fivedot-photo-modal-frame -
	   see the --fivedot-side-clearance/-top-clearance definitions and
	   comment near .fivedot-photo-modal. */
	padding: var(--fivedot-top-clearance) var(--fivedot-side-clearance) 1.25rem;
	cursor: zoom-out;
}

.fivedot-video-modal-embed {
	position: relative;
	width: min(100%, 1100px);
	aspect-ratio: 16 / 9;
	box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
	cursor: default;
}

.fivedot-video-modal-embed iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
}

/* Adobe Sign esignWidget embed (Access License) - the widget itself isn't
   responsive-height, so this just gives it a tall, bordered frame that's
   consistent with the rest of the site's card language.

   The widget's own embed mode ("sized container," per Adobe's docs - the
   mode you get by fixing a width/height on the iframe rather than letting
   it take the full window) doesn't support a fit-width view parameter, and
   its default zoom level renders the document wider than the iframe,
   forcing a horizontal scrollbar INSIDE the frame (confirmed by manually
   clicking the widget's own zoom-out control, which removes it). Since we
   can't pass a "start zoomed out" parameter, .fivedot-access-license-scale
   fakes the same effect from the outside: it's rendered 25% larger than
   its visible box in both dimensions, then scaled back down by the inverse
   (0.8), which shrinks the widget's own too-wide layout right along with
   it - the horizontal scrollbar disappears because the content itself no
   longer needs one, not because we're hiding an existing one.

   height + max-height on the outer .embed element (rather than the iframe
   itself, now that the iframe's real height is governed by the scale
   wrapper) caps how tall the frame gets on a short mobile viewport -
   without it, a phone would have to scroll the whole page for over 1000px
   just to clear the widget, AND separately scroll inside it, which felt
   broken. The widget's own internal vertical scroll for a long document is
   fine and expected; this only bounds how much of the *page* it eats. */
.fivedot-access-license-embed {
	border: 1px solid var(--wp--preset--color--mist);
	border-top: 3px solid var(--wp--preset--color--gold);
	margin: 1.5rem 0;
	height: 1100px;
	max-height: 75vh;
	overflow: hidden;
	position: relative;
}

.fivedot-access-license-scale {
	width: 125%;
	height: 125%;
	transform: scale(0.8);
	transform-origin: 0 0;
}

.fivedot-access-license-scale iframe {
	display: block;
	width: 100%;
	height: 100%;
	border: none;
}

@media (max-width: 600px) {
	.fivedot-access-license-embed {
		height: 1300px;
		max-height: 70vh;
	}
}

/* Fallback for the embedded Adobe Sign widget above - a plain link to the
   same form in its own tab, in case the iframe fails to render for a given
   visitor's browser/network. */
.fivedot-access-license-fallback {
	font-size: 0.9rem;
	color: var(--wp--preset--color--weathered-brown);
	margin: 0.5rem 0 1.5rem;
}

/* Responsive 16:9 wrapper for embedded videos (e.g. the Round Valley
   Reservoir YouTube video) built as a wp:html block with the same
   markup/classes WordPress core's own embed block uses - defined here
   rather than relying on core's embed CSS, since that stylesheet only
   auto-loads when a real core/embed block is detected in the content, and
   this needs to render correctly regardless of network-dependent oEmbed
   lookups. */
.wp-block-embed.wp-has-aspect-ratio .wp-block-embed__wrapper {
	position: relative;
	padding-top: 56.25%;
}

.wp-block-embed.wp-has-aspect-ratio .wp-block-embed__wrapper iframe {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	border: none;
}

/* Generic themed section divider - a small icon centered between two gold
   rules, echoing the cartridge-icon divider used in the footer contact line
   for the same kind of subtle thematic touch. Shared structure across
   sections; only the icon differs - a fly for fishing pages
   (fishing-fly-icon.svg), a mule deer for hunting pages
   (hunting-mule-deer-icon.svg), etc. */
.fivedot-icon-divider {
	display: flex;
	align-items: center;
	gap: 1.25rem;
	margin: 2.5rem 0;
	color: var(--wp--preset--color--gold);
}

.fivedot-icon-divider::before,
.fivedot-icon-divider::after {
	content: "";
	flex: 1 1 auto;
	height: 1px;
	background: var(--wp--preset--color--gold);
}

.fivedot-icon-divider-icon {
	flex: 0 0 auto;
	display: flex;
}

.fivedot-icon-divider-icon img {
	display: block;
	width: 34px;
	height: 34px;
}

/* Table styling. NOTE: this intentionally lives here, not in theme.json's
   per-block "css" property - WordPress only outputs that property for
   visitors with the edit_css capability (see WP_Theme_JSON::remove_insecure_properties()),
   so anonymous front-end visitors would never see it. */
.wp-block-table table {
	border-collapse: collapse;
	width: 100%;
}

.wp-block-table th,
.wp-block-table td {
	border: 1px solid var(--wp--preset--color--mist);
	padding: 0.75rem 1rem;
}

.wp-block-table thead th {
	background-color: var(--wp--preset--color--navy);
	color: var(--wp--preset--color--white);
	border-bottom: 3px solid var(--wp--preset--color--gold);
	font-weight: 600;
}

.wp-block-table tbody tr:nth-child(odd) {
	background-color: var(--wp--preset--color--mist);
}

/* Header logo - the central focal point of the nav row, so it's sized
   noticeably larger than a typical corner logo; scales down on narrow
   viewports so it never overwhelms the nav links beside it. */
.fivedot-site-logo {
	max-height: 128px;
	width: auto;
	display: block;
	margin: 0 auto;
}

@media (max-width: 900px) {
	.fivedot-site-logo {
		max-height: 90px;
	}
}

@media (max-width: 600px) {
	.fivedot-site-logo {
		max-height: 70px;
	}
}

/* Header nav row: plain semantic markup (not core/navigation) for full
   control over wrapping and the mobile presentation - see header.html.
   Desktop/tablet: a 3-column grid (nav-left | logo | nav-right); each nav
   is its own flex container free to wrap to a second line independently as
   the viewport narrows, well before anything collapses to the hamburger. */
.fivedot-header-nav-wrap {
	position: relative;
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	column-gap: 1.5rem;
}

.fivedot-header-logo {
	display: flex;
	justify-content: center;
}

.fivedot-header-logo a {
	display: flex;
	flex-direction: column;
	align-items: center;
	/* The browser's default underline for <a> is what actually needed
	   suppressing here, not .fivedot-header-sitename's own text-decoration
	   (a descendant can't turn off a line an ancestor is already drawing
	   through it - only the element carrying the underline in the first
	   place can). Never visible before since an <img> alone doesn't render
	   one either way, but became visible once real text sat inside the
	   same link. */
	text-decoration: none;
}

/* On mobile the logo shrinks small enough (see .fivedot-site-logo's
   max-width:70px breakpoint below) that its wordmark isn't legible, so a
   visitor landing on an inner page (not the homepage, where the page title
   itself confirms it) may not be able to tell whose site they're on. Hidden
   above the phone breakpoint, where the logo is large enough to read on its
   own - see .fivedot-header-sitename's re-enabling rule further down. The
   <a>'s own aria-label already covers this same text for screen readers, so
   this being a plain visual <span> (not a heading or duplicate link) avoids
   announcing the site name twice. */
.fivedot-header-sitename {
	display: none;
}

.fivedot-nav ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem 1.75rem;
}

.fivedot-nav-left ul {
	justify-content: flex-start;
}

.fivedot-nav-right ul {
	justify-content: flex-end;
}

.fivedot-nav > ul > li {
	position: relative;
}

.fivedot-nav a {
	display: inline-block;
	font-weight: 700;
	font-size: 1.0625rem;
	color: var(--wp--preset--color--charcoal);
	text-decoration: none;
	padding: 0.5rem 0.1rem;
	line-height: 1.2;
}

.fivedot-nav > ul > li > a:hover,
.fivedot-nav > ul > li > a:focus-visible {
	color: var(--wp--preset--color--rust);
}

/* Small caret after items with a dropdown, to signal there's more. */
.fivedot-nav li.has-submenu > a::after {
	content: "";
	display: inline-block;
	width: 0.35em;
	height: 0.35em;
	margin-left: 0.4em;
	margin-bottom: 0.15em;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: rotate(45deg);
	vertical-align: middle;
}

/* Desktop/tablet submenu dropdowns - plain CSS hover/focus, no JS needed.
   display: block deliberately overrides the display: flex/flex-wrap that
   .fivedot-nav ul (above) sets for the top-level horizontal bar - without
   this, the dropdown's own <li>s inherited that flex-row/wrap behavior too,
   so each one only sized to its own text instead of stretching to the
   dropdown's full width. That's what made the hover background only as
   wide as the item's own label except on the single widest item, which
   happened to already match the dropdown's shrink-to-fit width. */
/* left: 50% + translateX(-50%) centers the dropdown under its parent nav
   item, regardless of which is wider - the trigger link or the dropdown
   itself (min-width: 230px, or wider still once it's sized to its widest
   item - see .fivedot-nav .submenu a). translateX is combined with the
   existing translateY slide-in in one transform, since the hover/focus
   rule below has to override translateY without losing the centering. */
.fivedot-nav .submenu {
	display: block;
	list-style: none;
	margin: 0;
	padding: 0.5rem 0;
	position: absolute;
	top: 100%;
	left: 50%;
	min-width: 230px;
	background: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--mist);
	border-top: 3px solid var(--wp--preset--color--gold);
	box-shadow: 0 10px 24px rgba(36, 31, 27, 0.14);
	z-index: 30;
	opacity: 0;
	visibility: hidden;
	transform: translateX(-50%) translateY(4px);
	transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
}

.fivedot-nav li.has-submenu:hover > .submenu,
.fivedot-nav li.has-submenu:focus-within > .submenu {
	opacity: 1;
	visibility: visible;
	transform: translateX(-50%) translateY(0);
}

.fivedot-nav .submenu a {
	display: block;
	padding: 0.65rem 1.15rem;
	font-size: 0.95rem;
	font-weight: 600;
	text-align: center;
	white-space: nowrap;
}

.fivedot-nav .submenu a:hover,
.fivedot-nav .submenu a:focus-visible {
	background: var(--wp--preset--color--mist);
	color: var(--wp--preset--color--rust);
}

@media (prefers-reduced-motion: reduce) {
	.fivedot-nav .submenu {
		transition: none;
	}
}

/* Mobile hamburger toggle - hidden until the phone breakpoint, then shown
   centered below the logo per the single-column mobile layout below. */
.fivedot-mobile-toggle {
	display: none;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	padding: 0;
	margin: 0.25rem 0 0;
	background: transparent;
	border: none;
	cursor: pointer;
}

.fivedot-hamburger-icon {
	position: relative;
	width: 30px;
	height: 22px;
	display: inline-block;
}

.fivedot-hamburger-icon span {
	position: absolute;
	left: 0;
	width: 100%;
	height: 3px;
	border-radius: 2px;
	background: var(--wp--preset--color--forest-green);
	transition: transform 0.25s ease, opacity 0.2s ease, top 0.25s ease;
}

.fivedot-hamburger-icon span:nth-child(1) { top: 0; }
.fivedot-hamburger-icon span:nth-child(2) { top: 9.5px; }
.fivedot-hamburger-icon span:nth-child(3) { top: 19px; }

.fivedot-mobile-toggle[aria-expanded="true"] .fivedot-hamburger-icon span:nth-child(1) {
	top: 9.5px;
	transform: rotate(45deg);
}

.fivedot-mobile-toggle[aria-expanded="true"] .fivedot-hamburger-icon span:nth-child(2) {
	opacity: 0;
}

.fivedot-mobile-toggle[aria-expanded="true"] .fivedot-hamburger-icon span:nth-child(3) {
	top: 9.5px;
	transform: rotate(-45deg);
}

@media (prefers-reduced-motion: reduce) {
	.fivedot-hamburger-icon span {
		transition: none;
	}
}

/* Mobile dropdown panel - anchored below the hamburger button, not a
   full-screen overlay. Hidden by default; JS toggles .is-open. */
.fivedot-mobile-menu {
	display: none;
}

.fivedot-mobile-menu.is-open {
	display: block;
	position: absolute;
	top: 100%;
	left: 1.25rem;
	right: 1.25rem;
	margin-top: 0.5rem;
	background: var(--wp--preset--color--navy);
	border: 1px solid var(--wp--preset--color--gold);
	border-radius: 4px;
	box-shadow: 0 14px 32px rgba(0, 0, 0, 0.28);
	z-index: 50;
	max-height: 70vh;
	overflow-y: auto;
}

.fivedot-mobile-menu ul {
	list-style: none;
	margin: 0;
	padding: 0.4rem 0;
}

.fivedot-mobile-menu li {
	border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

.fivedot-mobile-menu li:last-child {
	border-bottom: none;
}

.fivedot-mobile-menu a {
	display: block;
	padding: 0.9rem 1.5rem;
	font-weight: 700;
	font-size: 1rem;
	color: var(--wp--preset--color--white);
	text-decoration: none;
}

.fivedot-mobile-menu a:hover,
.fivedot-mobile-menu a:focus-visible {
	background: rgba(255, 255, 255, 0.08);
	color: var(--wp--preset--color--gold);
}

.fivedot-mobile-menu ul ul {
	padding: 0 0 0.4rem;
}

.fivedot-mobile-menu ul ul a {
	padding-left: 2.5rem;
	font-weight: 500;
	font-size: 0.9rem;
	color: rgba(255, 255, 255, 0.85);
}

/* Phone breakpoint: stack logo above a single centered hamburger, hide the
   two inline nav groups entirely in favor of the dropdown panel. Above this
   width, nav-left/nav-right simply wrap to a second line as needed - see
   .fivedot-nav ul's flex-wrap above, which handles that with no extra rules. */
@media (max-width: 600px) {
	.fivedot-header-nav-wrap {
		grid-template-columns: 1fr;
		justify-items: center;
		row-gap: 0.25rem;
	}

	.fivedot-nav-left,
	.fivedot-nav-right {
		display: none;
	}

	.fivedot-header-sitename {
		display: block;
		margin-top: 0.35rem;
		max-width: 260px;
		font-family: var(--wp--preset--font-family--heading);
		font-size: 0.8rem;
		font-weight: 700;
		letter-spacing: 0.04em;
		text-transform: uppercase;
		text-align: center;
		color: var(--wp--preset--color--charcoal);
	}

	.fivedot-mobile-toggle {
		display: flex;
	}

	/* Only one topbar item remains once the desktop-only one is hidden below -
	   center it rather than leaving it stranded at the left edge. */
	.fivedot-topbar {
		justify-content: center;
		text-align: center;
	}

	/* "Five Dot Ranch Hunting & Fishing" - redundant with the header logo's
	   own sitename (.fivedot-header-sitename, shown just below the nav row
	   at this same breakpoint), so it's desktop-only; mobile shows just the
	   "Northeastern California..." tagline here. */
	.fivedot-topbar-desktop-only {
		display: none;
	}
}

/* Top info bar above the main nav row. */
.fivedot-topbar {
	flex-wrap: wrap;
	row-gap: 0.35rem;
}

.fivedot-topbar a {
	color: var(--wp--preset--color--white);
}

/* Footer: single centered info column (name, tagline, contact line) plus two
   link rows that spread edge-to-edge across the wide (1200px) footer width,
   collapsing to a single "Back to top" link on mobile instead of a long
   stacked list. */
.fivedot-footer-name {
	margin: 0;
	text-align: center;
	font-family: var(--wp--preset--font-family--heading);
	font-size: 1.15rem;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--white);
}

.fivedot-footer-tagline {
	margin: 0.35rem 0 0;
	text-align: center;
	font-size: var(--wp--preset--font-size--small);
	color: rgba(255, 255, 255, 0.75);
}

/* Centered, with the bullet's own padding providing the gap between items -
   same spacing feel as the copyright line below, which uses a single
   inline paragraph rather than a flex row. space-between was only correct
   when this held 5 items (address, dot, phone, dot, email); with the phone
   removed, only one dot remains and space-between would strand it in the
   dead center of the full-width row, stretching the address/email gap. */
.fivedot-footer-contact {
	display: flex;
	justify-content: center;
	align-items: baseline;
	flex-wrap: wrap;
	margin: 1.25rem 0 0;
	font-size: var(--wp--preset--font-size--small);
}

.fivedot-footer-contact a {
	color: var(--wp--preset--color--white);
	text-decoration: none;
}

.fivedot-footer-contact a:hover,
.fivedot-footer-contact a:focus-visible {
	color: var(--wp--preset--color--gold);
}

.fivedot-footer-dot {
	display: inline-flex;
	align-items: center;
	padding: 0 0.6rem;
	color: var(--wp--preset--color--gold);
}

.fivedot-footer-dot svg {
	display: block;
	width: 1.6rem;
	height: auto;
}

/* Divider between the contact block and the Explore/Policies link sections -
   the footer reads as one dense block without it, so this echoes the gold
   rule already used above the copyright line. */
.fivedot-footer-divider {
	width: 100%;
	height: 1px;
	border: none;
	background: rgba(201, 162, 39, 0.35);
	margin: 2rem 0 0;
}

/* Generous gap before each heading (clear separation between sections),
   tight gap from a heading down to its own list of links. */
.fivedot-footer-section {
	margin-top: 2.5rem;
	text-align: center;
}

.fivedot-footer-heading {
	margin: 0 0 0.4rem;
	color: var(--wp--preset--color--gold);
}

.fivedot-footer-links {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	width: 100%;
}

.fivedot-footer-links a {
	color: var(--wp--preset--color--white);
	text-decoration: none;
	font-weight: 600;
}

.fivedot-footer-links a:hover,
.fivedot-footer-links a:focus-visible {
	color: var(--wp--preset--color--gold);
}

.fivedot-footer-back-to-top {
	display: none;
	color: var(--wp--preset--color--white);
	text-decoration: underline;
}

.fivedot-footer-back-to-top:hover,
.fivedot-footer-back-to-top:focus-visible {
	color: var(--wp--preset--color--gold);
}

.fivedot-footer-credit-link {
	color: var(--wp--preset--color--white);
}

.fivedot-footer-credit-link:hover,
.fivedot-footer-credit-link:focus-visible {
	color: var(--wp--preset--color--gold);
}

@media (max-width: 600px) {
	.fivedot-footer-contact {
		flex-direction: column;
		align-items: center;
		gap: 0.5rem;
	}

	.fivedot-footer-dot {
		display: none;
	}

	.fivedot-footer-heading,
	.fivedot-footer-links {
		display: none;
	}

	/* Nothing left to show in this section once its heading and link list
	   are hidden, so drop it entirely instead of leaving a blank gap. */
	.fivedot-footer-section--explore {
		display: none;
	}

	.fivedot-footer-section--policies {
		margin-top: 1.5rem;
	}

	.fivedot-footer-back-to-top {
		display: inline-block;
		margin-top: 0.5rem;
	}
}

/* Respect reduced-motion preferences; the theme has no decorative motion
   by default, this guards against any added later. */
@media (prefers-reduced-motion: reduce) {
	* {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}
}
