/*
Theme Name: Art Division
Theme URI: https://artdivision.co.uk
Author: Art Division
Author URI: https://artdivision.co.uk
Description: A lightweight WordPress theme for Art Division.
Version: 1.0.350
Requires at least: 6.0
Tested up to: 6.7
Requires PHP: 8.0
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: art-division
Tags: minimal, lightweight, blog, portfolio
*/

/* === Reset === */
*, *::before, *::after {
	box-sizing: border-box;
}

/* === Variables === */
:root {
	--color-primary: #1a1a2e;
	--color-bg: #ffffff;
	--color-surface: #f8f8f8;
	--color-title: #111111;
	--color-eyebrow: #1a1a2e;
	--color-text: #111111;
	--color-muted: #666666;
	--color-accent: #1a1a2e;
	--color-accent-hover: #16213e;
	--color-border: #e0e0e0;
	--color-alternate: #f5f5f5;
	--color-navbar-bg: #ffffff;
	--color-navbar-link: #666666;
	--color-navbar-link-hover: #111111;
	--color-navbar-transparent-link: #ffffff;
	--color-navbar-transparent-link-hover: #cccccc;
	--color-menu-bg: #ffffff;
	--color-menu-link: #111111;
	--color-menu-link-hover: #1a1a2e;
	--color-menu-overlay: rgba(0,0,0,0.6);
	--color-btn-primary-text: #ffffff;
	--color-btn-primary-border: #1a1a2e;
	--color-btn-primary-bg: #1a1a2e;
	--color-btn-primary-text-hover: #ffffff;
	--color-btn-primary-border-hover: #16213e;
	--color-btn-primary-bg-hover: #16213e;
	--color-btn-secondary-text: #ffffff;
	--color-btn-secondary-border: #666666;
	--color-btn-secondary-bg: #666666;
	--color-btn-secondary-text-hover: #ffffff;
	--color-btn-secondary-border-hover: #1a1a2e;
	--color-btn-secondary-bg-hover: #1a1a2e;
	--color-btn-outline-text: #1a1a2e;
	--color-btn-outline-border: #1a1a2e;
	--color-btn-outline-text-hover: #ffffff;
	--color-btn-outline-border-hover: #1a1a2e;
	--color-btn-outline-bg-hover: #1a1a2e;
	--btn-font-weight: 400;
	--btn-text-transform: none;
	--color-footer-bg: #333333;
	--color-footer-heading: #ffffff;
	--color-footer-text: #ffffff;
	--color-footer-link: #ffffff;
	--color-footer-link-hover: #b1c6ff;
	--color-footer-top-bg: #333333;
	--color-footer-top-heading: #ffffff;
	--color-footer-top-text: #ffffff;
	--color-footer-top-link: #ffffff;
	--color-footer-top-link-hover: #b1c6ff;
	--color-footer-bottom-bg: #333333;
	--color-footer-bottom-heading: #ffffff;
	--color-footer-bottom-text: #ffffff;
	--color-footer-bottom-link: #ffffff;
	--color-footer-bottom-link-hover: #b1c6ff;
	--color-footer-info-bg: #ffffff;
	--color-footer-info-text: #666666;
	--color-footer-info-link: #666666;
	--color-footer-info-link-hover: #b1c6ff;
	--font-base: 'Inter', system-ui, -apple-system, sans-serif;
	--font-base-weight: 400;
	--font-heading: var(--font-base);
	--font-heading-weight: normal;
	--font-heading-style: normal;
	--font-heading-transform: none;
	--font-mono: 'JetBrains Mono', 'Fira Code', monospace;
	--text-base: 1rem;
	--text-sm: 0.875rem;
	--text-lg: 1.125rem;
	--text-xl: 1.5rem;
	--text-2xl: 2rem;
	--text-3xl: 2.75rem;
	--line-height-body: 1.6;
	--line-height-heading: 1.2;
	--art-radius: 0;
	--art-radius-round: 0;
	--art-max-width: 1562px;
	--art-navbar-max-width: 1562px;
	--art-site-max-width: 2560px;
	--spacing: 1.5rem;
}

/* --art- prefixed aliases for the plugin-facing custom property contract
   documented in .github/copilot-instructions.md (Colours / Type scale /
   Spacing). This theme's own TODO list still calls for renaming the vars
   above in place; until that happens, these aliases let art-division-*
   plugins (Page Modules etc.) read live theme values — including the fluid
   clamp() overrides art_division_visual_language_css() writes for the type
   scale — without waiting on that rename. Delete once the rename lands. */
:root {
	--art-color-primary: var(--color-primary);
	--art-color-bg: var(--color-bg);
	--art-color-surface: var(--color-surface);
	--art-color-title: var(--color-title);
	--art-color-eyebrow: var(--color-eyebrow);
	--art-color-text: var(--color-text);
	--art-color-muted: var(--color-muted);
	--art-color-accent: var(--color-accent);
	--art-color-accent-hover: var(--color-accent-hover);
	--art-color-border: var(--color-border);
	--art-color-alternate: var(--color-alternate);
	/* Auto-derived by art_division_readable_text_color() (theme-settings.php)
	   from --color-primary/--color-accent - whichever of white/dark text
	   contrasts better against that colour, so plugins rendering text on top
	   of an admin-chosen background (e.g. Property Modules' active
	   department tab) stay readable without a per-client override, however
	   light or dark that colour is picked. No var()-only fallback needed
	   here since the PHP side always emits both when the source colour
	   resolves - see art_division_visual_language_css(). */
	--art-color-on-primary: var(--color-on-primary, #ffffff);
	--art-color-on-accent: var(--color-on-accent, #ffffff);
	/* No dedicated "active" colour in the theme's own style settings - the
	   accent colour reads as the natural choice for an active/selected state
	   (e.g. Property Modules' active department tab), so alias it rather
	   than leaving plugins to fall back to their own hardcoded colour. */
	--art-color-dept-active: var(--color-accent);
	--art-font-base: var(--font-base);
	--art-font-heading: var(--font-heading);
	--art-text-sm: var(--text-sm);
	--art-text-base: var(--text-base);
	--art-text-lg: var(--text-lg);
	--art-text-xl: var(--text-xl);
	--art-text-2xl: var(--text-2xl);
	--art-text-3xl: var(--text-3xl);
	--art-line-height-body: var(--line-height-body);
	--art-line-height-heading: var(--line-height-heading);
	--art-spacing: var(--spacing);
}

/* === Base === */
html {
	font-size: 16px;
	scroll-behavior: smooth;
	/* Reserves the scrollbar's track permanently so clientWidth never changes
	   when body.menu-is-open sets overflow: hidden — without this, anything
	   sized against the viewport directly (a position: fixed sticky header,
	   the slide-in nav panel) shifts by the scrollbar's width when it
	   disappears, since the body padding-right compensation in main.js only
	   reaches normal in-flow content. */
	scrollbar-gutter: stable;
}

body {
	background-color: var(--color-bg);
	color: var(--color-text);
	font-family: var(--font-base);
	font-size: var(--text-base);
	font-weight: var(--font-base-weight);
	line-height: var(--line-height-body);
	-webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
	font-family: var(--font-heading);
	font-weight: var(--font-heading-weight);
	font-style: var(--font-heading-style);
	text-transform: var(--font-heading-transform);
	line-height: var(--line-height-heading);
}

h2, .is-h2 {
	color: var(--color-title);
}

/* Subheadings in running text sit with the text they introduce: more space
   above (after the previous paragraph or list) than below. Without this the
   browser's equal 1em above and below left each heading floating midway.
   :where() keeps these at zero specificity, so any component or module that
   sets its own heading margins with a class still wins. */
:where(h2, h3, h4, h5, h6) {
	margin-bottom: 0.6em;
}

:where(p, ul, ol, dl, blockquote, table, figure, pre) + :where(h2, h3, h4, h5, h6) {
	margin-top: 1.6em;
}

:where(h2, h3, h4, h5, h6) + :where(p, ul, ol, dl) {
	margin-top: 0;
}

a {
	color: var(--color-accent);
	text-decoration: none;
}

a:hover {
	color: var(--color-accent-hover);
	text-decoration: underline;
}

img {
	max-width: 100%;
	height: auto;
	display: block;
}

/* === Layout === */
.site {
	display: flex;
	flex-direction: column;
	margin-left: auto;
	margin-right: auto;
	max-width: var(--art-site-max-width);
	min-height: 100vh;
}

.site-content {
	flex: 1;
}

.container {
	max-width: var(--art-max-width);
	margin: 0 auto;
	padding: 0 15px;
}

/* === Header === */
.site-header {
	background-color: var(--color-navbar-bg);
	padding: 1rem 0;
}

/* === Sticky Navbar === */
/* position: sticky by default - the header reserves its own height in
   normal document flow natively, with no JS-computed #content padding
   needed for it at all. Only overridden to position: fixed below for the
   two cases sticky genuinely can't do: autohide (sticky keeps its reserved
   space even while transformed off-screen, leaving a gap) and Transparent
   Navbar on (needs to reserve zero space so the page can flow up behind it
   - sticky always reserves its space while in flow; independent of whether
   a hero itself is actually present, see the inline script below). Both
   .navbar-autohide and .hero-nav-transparent are server-side body classes
   (see functions.php's body_class filters), so this never has to wait on
   JS to know which positioning a given page needs. */
.navbar-sticky .site-header {
	position: sticky;
	/* --art-topbar-height is 0px unless an .art-topbar element is present AND
	   currently visible (e.g. Art Division Areas We Cover's Area Top Bar) -
	   see the inline script below and the .art-topbar rules further down.
	   Pushes the header down to sit below the topbar instead of underneath
	   it, and JS zeroes it back out once the topbar auto-hides on scroll so
	   the header slides up to fill the gap. */
	top: var(--art-topbar-height, 0px);
	left: 0;
	right: 0;
	z-index: 1000;
	background-color: var(--color-navbar-bg);
	transition: background-color 0.3s ease, border-color 0.3s ease, transform 0.3s ease, opacity 0.3s ease, top 0.3s ease;
}

/* .art-navbar-force-fixed: a generic escape hatch for "this page wants the
   fixed header behaviour without the transparent/overlay look" - unlike
   .hero-nav-transparent (which also zeroes out #content's top padding so
   the page flows up behind it), this only changes position. The theme adds
   it to property pages (art_division_navbar_body_classes() in
   functions.php), which structurally can never carry the Hero Sidebar's own
   Transparent Navbar toggle; a child theme can add it anywhere else. See the matching
   needsFixed/needsFixedHeader checks in this file's inline header script
   and main.js's updateOffset(). */
.navbar-sticky.navbar-autohide .site-header,
.navbar-sticky.hero-nav-transparent .site-header,
.navbar-sticky.art-navbar-force-fixed .site-header {
	position: fixed;
}

/* === Above-header bar (e.g. Areas We Cover's Area Top Bar) ===
   A generic convention, not specific to any one plugin: any element with
   this class renders as a fixed bar pinned above the sticky header. Plugins
   opt in by adding this class alongside their own BEM class. Auto-hides once
   the page is scrolled away from the very top (see main.js) - unlike the
   header's own .is-hidden, which is direction-based, this is purely
   position-based: visible at scrollY 0, hidden otherwise. */
.navbar-sticky .art-topbar {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 1001;
	transition: transform 0.3s ease;
}

.navbar-sticky .art-topbar.is-hidden {
	transform: translateY(-100%);
}

/* === Transparent Navbar (hero option) === */
.hero-nav-transparent .site-header {
	background-color: transparent;
	/* Same specificity (2 classes) as .navbar-sticky .site-header's own
	   transition list, and this rule comes later in the cascade - the
	   `transition` shorthand doesn't merge across rules, so whichever one
	   wins replaces the whole list. Repeating the full list here (not just
	   background-color) keeps top easing consistent instead of snapping
	   instantly the moment .is-scrolled is removed at the top of the page. */
	transition: background-color 0.3s ease, border-color 0.3s ease, transform 0.3s ease, opacity 0.3s ease, top 0.3s ease;
}

.hero-nav-transparent .site-header.is-scrolled {
	background-color: var(--color-navbar-bg);
}

.navbar-sticky .site-header.is-hidden {
	transform: translateY(-100%);
}

/* Fixed positioning ignores the margin-top the WP admin bar adds to <html>,
   so a logged-in visitor sees a fixed header (and topbar, which is always
   fixed) pinned under the admin bar instead of below it. Offset to match
   the admin bar's own height/breakpoint - the header's offset stacks on top
   of the topbar's own height, same as the unauthenticated
   var(--art-topbar-height, 0px) above. Only scoped to the fixed-header
   cases (autohide / hero-nav-transparent) - the default sticky header sits
   correctly in normal flow already and would get an extra unwanted 32px
   here otherwise. */
body.admin-bar.navbar-sticky.navbar-autohide .site-header,
body.admin-bar.navbar-sticky.hero-nav-transparent .site-header {
	top: calc(32px + var(--art-topbar-height, 0px));
}

body.admin-bar.navbar-sticky .art-topbar {
	top: 32px;
}

@media screen and (max-width: 782px) {
	body.admin-bar.navbar-sticky.navbar-autohide .site-header,
	body.admin-bar.navbar-sticky.hero-nav-transparent .site-header {
		top: calc(46px + var(--art-topbar-height, 0px));
	}

	body.admin-bar.navbar-sticky .art-topbar {
		top: 46px;
	}
}

/* Content offset for sticky header.
   --art-header-offset is set by an inline script immediately after the header
   HTML so the value is available before #content is first painted - no CLS. */
body.navbar-sticky #content {
	padding-top: var(--art-header-offset, 0px);
}

/* A full-width Page Modules Hero is printed before #content, beside the
   header - so with the header fixed (Hide on Scroll) and no Transparent
   Navbar, the header covered the top of the hero, and the space reserved
   for it opened up below the hero instead. The space goes above the hero. */
body.navbar-sticky:not(.hero-nav-transparent) .site-header ~ .art-pm-hero {
	margin-top: var(--art-header-offset, 0px);
}

body.navbar-sticky:not(.hero-nav-transparent) .site-header ~ .art-pm-hero ~ #content {
	padding-top: 0;
}

.site-header .container {
	max-width: var(--art-navbar-max-width, 1562px);
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 1rem;
}

.site-branding a {
	font-size: var(--text-xl);
	letter-spacing: -0.02em;
	color: var(--color-text);
	text-decoration: none;
    display: inline-block;	
}

.site-branding .tagline {
	font-size: var(--text-sm);
	color: var(--color-muted);
	margin-top: 0.125rem;
}

/* === Navigation === */
.main-navigation ul {
	list-style: none;
	display: flex;
	gap: 1.5rem;
}

.main-navigation a {
	font-size: var(--text-sm);
	color: var(--color-muted);
	text-decoration: none;
	transition: color 0.2s;
}

.main-navigation a:hover,
.main-navigation .current-menu-item > a {
	color: var(--color-text);
}

/* === Posts === */
.posts-list {
	display: flex;
	flex-direction: column;
	gap: 2.5rem;
}

.post-card {
	padding-bottom: 2.5rem;
}

.post-meta {
	font-size: var(--text-sm);
	color: var(--color-muted);
	margin-bottom: 0.5rem;
}

.post-meta__updated {
	margin-left: 0.5em;
}

.post-title {
	font-family: var(--font-heading);
	font-size: var(--text-xl);
	letter-spacing: -0.02em;
	margin-bottom: 0.75rem;
}

.post-title a {
	color: var(--color-text);
	text-decoration: none;
}

.post-title a:hover {
	color: var(--color-accent);
}

.post-excerpt {
	color: var(--color-muted);
	margin-bottom: 1rem;
}

.read-more {
	font-size: var(--text-sm);
	color: var(--color-accent);
}

/* === Single Post === */

/* Qualified with the main element (not just .single-post) because
   WordPress's own body_class() adds "single-post" to <body> on every
   single blog post - unrelated to the single-post class this theme also
   puts on <main>. Since <body> is an ancestor of the ENTIRE page, a bare
   ".single-post .container" selector was also matching the header's own
   internal .container (used for its nav row), pushing that down and
   making the header render taller on post pages specifically. */
main.single-post .container {
	padding-top: 2.5rem;
}

/* --art-sticky-clearance: shared `top` offset for this template's sticky
   columns (.single-post-sidebar, .art-toc-wrap below). Deliberately NOT
   --art-header-offset - that var is 0 for the default position:sticky
   header by design (see its own doc comment: #content sits right after it
   in flow and needs no extra padding there), which is the wrong semantic
   here - a sticky column still needs to clear the header's real visual
   height to avoid sticking underneath it, regardless of whether the header
   itself is sticky or fixed. --art-header-height is never zeroed for
   exactly this kind of consumer. Mirrors the site's own admin-bar-aware
   header offset pattern (32px / 46px below 782px) since this account for
   the WP admin bar too, unlike --art-header-offset. */
:root {
	--art-sticky-clearance: calc(var(--art-header-height, 0px) + var(--art-topbar-height, 0px) + 2rem);
}

body.admin-bar {
	--art-sticky-clearance: calc(32px + var(--art-header-height, 0px) + var(--art-topbar-height, 0px) + 2rem);
}

@media screen and (max-width: 782px) {
	body.admin-bar {
		--art-sticky-clearance: calc(46px + var(--art-header-height, 0px) + var(--art-topbar-height, 0px) + 2rem);
	}
}

.single-post-layout {
	display: flex;
	flex-direction: column;
	gap: 2rem;
}

.single-post-layout__main {
	min-width: 0;
}

/* === Single Post — Content Row (article + sidebar) ===
   Below 1200px: stacked flex column, article capped/centred on its own.
   From 1200px: a 3-column grid with the article as a FIXED 750px centre
   column, flanked by two equal minmax(300px, 1fr) tracks - because both
   side tracks share the exact same track definition, they always render
   at the same pixel width as each other (regardless of what does or
   doesn't occupy them), which keeps the article on the page's true centre
   axis at all times. The sidebar (always present, a real widget area - see
   inc/post-sidebar.php) fills the right track; the Table of Contents, when
   enabled, fills the left one once it becomes a row member at 1500px+ (see
   the "Single Post — Table of Contents" section) - an unoccupied side
   track just renders as empty space, which is what keeps the article fixed
   whether the TOC is showing or not, rather than the article's own centre
   shifting to accommodate it. */
.single-post-content-row {
	display: flex;
	flex-direction: column;
	gap: 2rem;
}

.single-post-content-row__article {
	min-width: 0;
	max-width: 750px;
	margin: 0 auto;
}

@media (min-width: 1200px) {
	.single-post-content-row {
		display: grid;
		grid-template-columns: minmax(300px, 1fr) 750px minmax(300px, 1fr);
		column-gap: 3rem;
		align-items: start;
	}

	.single-post-content-row__article {
		grid-column: 2;
		grid-row: 1;
		max-width: none;
		margin: 0;
	}

	.single-post-sidebar {
		grid-column: 3;
		grid-row: 1;
		position: sticky;
		top: var(--art-sticky-clearance);
	}
}

/* === Single Post — Breadcrumbs === */
.art-breadcrumbs {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem;
	margin-bottom: 0.75rem;
	font-size: var(--text-sm);
	color: var(--color-muted);
}

.art-breadcrumbs__list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.4rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.art-breadcrumbs__item:not(:last-child)::after {
	content: "\203A";
	margin-left: 0.4rem;
	color: var(--color-muted);
}

.art-breadcrumbs__item a {
	color: var(--color-muted);
	text-decoration: none;
}

.art-breadcrumbs__item a:hover {
	color: var(--color-accent);
}

.art-breadcrumbs--page {
	margin-bottom: 0;
	padding-block: 0.75rem;
}

.art-breadcrumbs__item [aria-current="page"] {
	color: var(--color-text);
}

.art-breadcrumbs__read-time::before {
	content: "|";
	margin-right: 0.5rem;
	color: var(--color-muted);
}

.single-post .post-header {
	margin-bottom: 2rem;
}

.single-post .post-title {
	font-size: var(--post-title-size, var(--text-3xl));
	margin-bottom: 1rem;
}

/* .single-post-sidebar--share-only renders instead of the normal widget
   sidebar when 'sidebar-1' has no widgets (see
   art_division_render_post_sidebar() in inc/post-sidebar.php) - still a
   .single-post-sidebar, so it gets the exact same sticky right-hand-track
   positioning as the real sidebar (see the Content Row rules above), just
   with the Share block unboxed and restyled as a plain icon row instead of
   the sidebar's boxed circular row. Below 1200px the sidebar is a full-width
   block stacked under the article (see the Content Row rules above), so the
   icons stay in the same horizontal row .art-post-share uses by default;
   only from 1200px, once this becomes the narrow sticky side column, do they
   switch to a vertical stack. */
.single-post-sidebar--share-only .art-post-share {
	align-items: center;
	gap: 0.5rem;
	padding: 0 15px;
}

.single-post-sidebar--share-only .art-post-share__link {
	border: 0;
	width: auto;
	height: auto;
	color: var(--color-muted);
}

.single-post-sidebar--share-only .art-post-share__link svg {
	width: 24px;
	height: 24px;
}

@media (min-width: 1200px) {
	.single-post-sidebar--share-only .art-post-share {
		flex-direction: column;
		padding: 0;
	}

	.single-post-sidebar--share-only .art-post-share__icons {
		flex-direction: column;
	}
}

/* === Single Post — Header Meta Card === */
.post-header-meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem;
	font-size: var(--text-sm);
	color: var(--color-muted);
}

.post-header-meta__avatar img {
	display: block;
	border-radius: 50%;
	width: 40px;
	height: 40px;
}

.post-header-meta__by a {
	color: var(--color-text);
	font-weight: 600;
	text-decoration: underline;
}

.post-header-meta__divider {
	color: var(--color-border);
}

.post-header-meta__date {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
}

/* === Single Post — Share ===
   Renders inside the sidebar's share box (see
   art_division_render_post_share() in inc/social-share.php) - circular
   outline buttons in a horizontal row. */
.art-post-share {
	display: flex;
	align-items: center;
	gap: 0.6rem;
}

.art-post-share__label {
	font-size: var(--text-sm);
	color: var(--color-muted);
}

.art-post-share__icons {
	display: flex;
	gap: 0.5rem;
}

.art-post-share__link {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	border: 1px solid var(--color-border);
	border-radius: 50%;
	color: var(--color-text);
	transition: color 0.15s ease, border-color 0.15s ease;
}

.art-post-share__link:hover {
	color: var(--color-accent);
	border-color: var(--color-accent);
}

.art-post-share__link svg {
	width: 16px;
	height: 16px;
}

/* === Single Post — Sidebar ===
   The 'sidebar-1' widget area (editable via Appearance → Widgets, seeded
   with a real Search + Categories widget the first time it's empty - see
   art_division_seed_sidebar1_widgets() in inc/post-sidebar.php) + the
   Share row. .widget below is every widget's own wrapper (see
   before_widget/before_title in art_division_widgets_init()); the rest of
   this section styles WordPress core's own Search/Categories widget markup
   to match that box look, since - unlike an earlier hardcoded fallback -
   these are real widgets and can be freely removed/replaced/reordered, so
   whatever a client actually adds needs to look consistent, not just these
   two. Stacks below the article until 1200px, see the Content Row rules
   above for the sticky right-hand column it becomes from there. */
.single-post-sidebar {
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
}

.single-post-sidebar__box,
.single-post-sidebar .widget {
	border: 1px solid var(--color-border);
	border-radius: var(--art-radius, 0);
	padding: 1.25rem;
}

.single-post-sidebar .widget-title {
	font-family: var(--font-heading);
	font-size: var(--text-lg);
	margin: 0 0 0.75rem;
}

.single-post-sidebar .search-form {
	display: flex;
	gap: 0.5rem;
}

.single-post-sidebar .search-form .search-field {
	flex: 1 1 auto;
	min-width: 0;
	border: 1px solid var(--color-border);
	border-radius: var(--art-radius, 0);
	padding: 0.5rem 0.75rem;
}

.single-post-sidebar .search-form .search-submit {
	border: 1px solid var(--color-border);
	border-radius: var(--art-radius, 0);
	background: var(--color-accent);
	color: var(--color-on-accent, #fff);
	padding: 0.5rem 1rem;
	cursor: pointer;
}

.single-post-sidebar .widget ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}

.single-post-sidebar .widget ul a {
	color: var(--color-text);
	text-decoration: none;
	font-size: var(--text-sm);
}

.single-post-sidebar .widget ul a:hover {
	color: var(--color-accent);
}

.single-post-sidebar__box--share {
	text-align: center;
}

/* === Single Post — Author Bio === */
.post-author-bio {
	display: flex;
	gap: 1.25rem;
	margin-top: 2.5rem;
	padding-top: 2rem;
	border-top: 1px solid var(--color-border);
}

.post-author-bio__avatar img {
	display: block;
	border-radius: 50%;
	width: 80px;
	height: 80px;
}

.post-author-bio__body {
	min-width: 0;
	flex: 1;
}

.post-author-bio__name {
	font-family: var(--font-heading);
	font-size: var(--text-lg);
	margin: 0 0 0.5rem;
}

.post-author-bio__name a {
	color: var(--color-text);
	text-decoration: none;
}

.post-author-bio__text {
	margin: 0;
	color: var(--color-muted);
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.post-author-bio__text.is-expanded {
	display: block;
	-webkit-line-clamp: unset;
	overflow: visible;
}

.post-author-bio__toggle {
	background: none;
	border: 0;
	padding: 0;
	margin-top: 0.35rem;
	color: var(--color-accent);
	font-size: var(--text-sm);
	cursor: pointer;
}

.post-author-bio__follow {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	margin: 1rem 0 0;
	font-size: var(--text-sm);
	color: var(--color-muted);
}

.post-author-bio__follow-link {
	display: inline-flex;
	color: var(--color-text);
}

.post-author-bio__follow-link:hover {
	color: var(--color-accent);
}

.post-author-bio__follow-link svg {
	width: 16px;
	height: 16px;
}

/* === Single Post — Adjacent Nav === */
.single-post-adjacent-nav {
	display: flex;
	flex-direction: column;
	gap: 1rem;
	margin-top: 2rem;
}

@media (min-width: 640px) {
	.single-post-adjacent-nav {
		flex-direction: row;
	}
}

.single-post-adjacent-nav__card {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	flex: 1 1 0;
	border: 1px solid var(--color-border);
	border-radius: var(--art-radius, 0);
	padding: 1rem 1.25rem;
	text-decoration: none;
	color: var(--color-text);
}

.single-post-adjacent-nav__card--next {
	justify-content: space-between;
}

.single-post-adjacent-nav__icon {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	width: 32px;
	height: 32px;
	border-radius: 50%;
	background: var(--color-accent);
	color: #fff;
}

.single-post-adjacent-nav__body {
	min-width: 0;
	display: flex;
	flex-direction: column;
}

.single-post-adjacent-nav__label {
	font-size: var(--text-sm);
	color: var(--color-muted);
}

.single-post-adjacent-nav__title {
	font-weight: 600;
}

.single-post-adjacent-nav__card:hover .single-post-adjacent-nav__title {
	color: var(--color-accent);
}

/* === Single Post — Related Posts ===
   .art-pm-module__blog-cards/.art-pm-module__blog-card* are Art Division
   Page Modules' own classes (see art_division_page_modules_render_blog_card(),
   reused here so the cards look identical to a Blog module card - only this
   section's own heading/spacing is styled here. */
.single-post-related {
	margin-top: 3rem;
	padding-top: 2rem;
	border-top: 1px solid var(--color-border);
}

.single-post-related__title {
	font-family: var(--font-heading);
	font-size: var(--text-2xl);
	margin: 0 0 1.5rem;
}

/* === Single Post — Table of Contents ===
   single.php places .art-toc-wrap as the FIRST child of
   .single-post-content-row (before the article), not as a separate
   sidebar-level element - positioning/behaviour differs entirely by
   breakpoint via CSS only:
     - <768px:  normal flow. order:3 (see below) puts it after the article/
       sidebar, stacked at the bottom, matching pre-sidebar behaviour.
     - >=768px: detached floating panel anchored to the viewport edge -
       DOM/flex order is irrelevant here since position:fixed removes it
       from flow entirely.
     - >=1500px: a genuine grid item in .single-post-content-row's left
       track (grid-column: 1), sticky, sharing that row's height with the
       sidebar (NOT including Related Posts below the row) so both stop
       being sticky at the same scroll point. Because the row's two side
       tracks are always equally sized regardless of what occupies them
       (see the "Single Post — Content Row" section), the article's own
       centre never moves whether the TOC is showing or not - unlike an
       earlier attempt that centred the TOC+article+sidebar row as one
       combined unit, which left the article's centre shifting depending on
       whether the TOC was present. */

.art-toc-wrap {
	order: 3;
}

.art-toc__toggle {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.75rem;
	width: 100%;
	padding: 0.875rem 1.25rem;
	background: var(--color-accent);
	color: #fff;
	border: 0;
	border-radius: var(--art-radius, 0);
	font-size: var(--text-sm);
	font-weight: 600;
	cursor: pointer;
}

.art-toc {
	background: var(--color-alternate);
	padding: 1.5rem;
	margin-top: 0.5rem;
}

.art-toc-wrap.is-collapsed .art-toc {
	display: none;
}

.art-toc__title {
	font-family: var(--font-heading);
	font-size: var(--text-lg);
	margin: 0 0 1rem;
}

.art-toc__list {
	display: flex;
	flex-direction: column;
	gap: 0.6rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.art-toc__link {
	border-left: 2px solid transparent;
	color: var(--color-text);
	display: block;
	font-size: var(--text-sm);
	padding-left: 0.75rem;
	text-decoration: none;
	transition: color 0.15s ease, border-color 0.15s ease;
}

.art-toc__link:hover {
	color: var(--color-accent);
}

.art-toc__link.is-active {
	border-left-color: var(--color-accent);
	color: var(--color-accent);
	font-weight: 600;
}

/* Mobile: the bar's home stays at the bottom of the article (order: 3
   above), but position: sticky pins it to the bottom of the screen while
   the reader is anywhere above that home, and it settles back into place
   once they scroll down to it - sticky keeps its space in the flow, so
   nothing jumps. table-of-contents.js adds .is-floating while it's pinned
   and .is-revealed once the post title has scrolled away; until then a
   pinned bar is slid off the bottom of the screen, so it animates in as
   reading starts. --art-toc-float-bottom lifts it clear of anything else
   docked to the bottom of the screen (e.g. a chat widget's button). */
@media (max-width: 767.98px) {
	.art-toc-wrap {
		bottom: var(--art-toc-float-bottom, 0.75rem);
		position: sticky;
		z-index: 40;
	}

	/* Slide/fade lives on the children, not .art-toc-wrap itself, so the
	   wrap's own box (which the JS measures to detect pinning) never moves.
	   .is-float-ready (added by the JS after its first check) keeps the bar
	   from visibly fading out on page load. */
	.art-toc-wrap.is-float-ready > * {
		transition: opacity 0.3s ease, transform 0.3s ease, visibility 0s;
	}

	.art-toc-wrap.is-floating .art-toc__toggle,
	.art-toc-wrap.is-floating .art-toc {
		box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
	}

	.art-toc-wrap.is-floating .art-toc {
		max-height: min(60vh, 420px);
		overflow-y: auto;
	}

	.art-toc-wrap.is-floating:not(.is-revealed) {
		pointer-events: none;
	}

	.art-toc-wrap.is-floating:not(.is-revealed) > * {
		opacity: 0;
		transform: translateY(calc(100% + var(--art-toc-float-bottom, 0.75rem)));
		visibility: hidden;
	}

	.art-toc-wrap.is-float-ready.is-floating:not(.is-revealed) > * {
		transition: opacity 0.3s ease, transform 0.3s ease, visibility 0s linear 0.3s;
	}
}

@media (max-width: 767.98px) and (prefers-reduced-motion: reduce) {
	.art-toc-wrap.is-float-ready > *,
	.art-toc-wrap.is-float-ready.is-floating:not(.is-revealed) > * {
		transition: none;
	}
}

/* Tablet: floating side panel, detached from document flow. */
@media (min-width: 768px) {
	.art-toc-wrap {
		bottom: 1.5rem;
		max-width: calc(100vw - 3rem);
		position: fixed;
		right: 1.5rem;
		width: 280px;
		z-index: 40;
	}

	.art-toc-wrap .art-toc {
		box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
		max-height: min(60vh, 420px);
		overflow-y: auto;
	}
}

/* Desktop: TOC becomes a real grid item in .single-post-content-row's left
   track (grid-column: 1), sticky, hugging the article's edge via
   justify-self: end - the track itself stays the same width (empty or
   not), so this never affects the article's own position. See the
   "Single Post — Content Row" section for the symmetric-track rationale. */
@media (min-width: 1500px) {
	.art-toc-wrap {
		bottom: auto;
		grid-column: 1;
		grid-row: 1;
		justify-self: end;
		max-width: none;
		position: sticky;
		right: auto;
		top: var(--art-sticky-clearance);
		width: 240px;
		z-index: auto;
	}

	.art-toc-wrap .art-toc {
		box-shadow: none;
		display: block !important;
		max-height: none;
		overflow: visible;
	}

	.art-toc__toggle {
		display: none;
	}
}


/* :not(.art-bcta__title) on h2 excludes Blog CTAs' injected title, same
   reasoning as the font-size override below - it keeps its own fixed
   margin (Art Division Blog CTAs' art-division-blog-ctas.css) regardless
   of this generic post-content heading rule. Previously only the font-size
   rule carried this exclusion - this margin rule was still winning via its
   own higher specificity (.post-content h2 beats a bare .art-bcta__title),
   leaking a 2rem top margin into the CTA title that its own margin:0 could
   never override. */
.post-content h1,
.post-content h2:not(.art-bcta__title),
.post-content h3,
.post-content h4 {
	font-family: var(--font-heading);
	letter-spacing: -0.02em;
	margin: 2rem 0 0.75rem;
}

.post-content h2 { font-size: var(--text-2xl); }
.post-content h3 { font-size: var(--text-xl); }
.post-content h4 { font-size: var(--text-lg); }

/* .post-content is shared with page-blocks.php, page-saved-search.php and
   template-parts/content-page.php - these two overrides are scoped to
   .single-post so the blog article's H2/H3 can be sized independently of
   those other templates, which stay on the shared --text-2xl/--text-xl.
   :not(.art-bcta__title) excludes Blog CTAs' injected h2 (the_content
   filter - see Art Division Blog CTAs' class-art-division-blog-ctas-injector.php),
   which keeps its own fixed styling regardless of this setting. */
.single-post .post-content h2:not(.art-bcta__title) { font-size: var(--post-h2-size, var(--text-2xl)); }
.single-post .post-content h3 { font-size: var(--post-h3-size, var(--text-xl)); }

.post-content p,
.post-content ul,
.post-content ol,
.post-content blockquote,
.post-content pre {
	margin-bottom: 1.25rem;
}

.post-content ul,
.post-content ol {
	padding-left: 1.5rem;
}

.post-content blockquote {
	border-left: 3px solid var(--color-accent);
	padding: 0.5rem 0 0.5rem 1.25rem;
	color: var(--color-muted);
	font-style: italic;
}

.post-content pre {
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: var(--art-radius, 0);
	padding: 1rem 1.25rem;
	overflow-x: auto;
	font-family: var(--font-mono);
	font-size: var(--text-sm);
}

.post-content code {
	font-family: var(--font-mono);
	font-size: 0.9em;
	background: var(--color-surface);
	padding: 0.1em 0.35em;
	border-radius: 3px;
}

.post-content pre code {
	background: none;
	padding: 0;
}

/* FAQ accordion - the exact markup Content Generator's "Generate FAQs"
   feature emits (see Art Division Content Generator), also read by the
   Schema plugin for JSON-LD. Toggle behaviour lives in main.js.
   .wp-block-art-division-faq is Art Division Blocks' AD FAQ block - it
   emits the same schema-faq/-section/-question/-answer class names
   alongside its own art-blocks-faq-* ones specifically to plug into this
   same accordion, so it's included on every rule here rather than given
   a separate copy of this block. */
.schema-faq.wp-block-yoast-faq-block,
.schema-faq.wp-block-art-division-faq {
	margin: 20px 0;
}

.schema-faq.wp-block-yoast-faq-block .schema-faq-section,
.schema-faq.wp-block-art-division-faq .schema-faq-section {
	margin-bottom: 10px;
}

.schema-faq.wp-block-yoast-faq-block .schema-faq-section:last-child,
.schema-faq.wp-block-art-division-faq .schema-faq-section:last-child {
	margin-bottom: 0;
}

.schema-faq.wp-block-yoast-faq-block .schema-faq-question,
.schema-faq.wp-block-art-division-faq .schema-faq-question {
	display: block;
	cursor: pointer;
	padding: 1em 4em 1em 1.25em;
	background: var(--color-alternate);
	position: relative;
	font-size: var(--text-lg);
	color: var(--color-text);
	/* Yoast's/Content Generator's markup wraps the question in <strong>,
	   which has no default margin, so this was never needed until AD FAQ
	   (Art Division Blocks) started using a heading tag here for proper
	   heading semantics - headings carry a browser default margin that
	   otherwise pushed each question/answer pair further apart than the
	   10px .schema-faq-section gap intends. */
	margin: 0;
	/* Explicit normal weight, not just "no override" - both <strong>
	   (Yoast's/Content Generator's markup) and h1-h6 (AD FAQ's markup) are
	   bold by browser default, so removing a weight rule here entirely
	   would make the question bolder, not lighter. */
	font-weight: normal;
}

.schema-faq.wp-block-yoast-faq-block .schema-faq-question::after,
.schema-faq.wp-block-art-division-faq .schema-faq-question::after {
	content: "+";
	position: absolute;
	top: 50%;
	right: 1em;
	transform: translateY(-50%);
	line-height: 1;
	font-weight: 600;
	font-size: 38px;
	color: var(--color-accent);
}

.schema-faq.wp-block-yoast-faq-block .schema-faq-section.active .schema-faq-question::after,
.schema-faq.wp-block-art-division-faq .schema-faq-section.active .schema-faq-question::after {
	content: "-";
}

/* margin-top (not the section's own margin-bottom) is what creates the
   visible gap between the question bar and its answer panel while open -
   it still applies at height: 0 when closed, so it doubles as the closed-
   state row spacing without a separate rule.

   This element carries NO padding of its own and only ever transitions
   height - box-sizing: border-box can't shrink height below the element's
   own padding (confirmed live via DevTools: the content area clamped to
   zero, but the box still stayed 36px tall, exactly its padding-top +
   padding-bottom), and transitioning padding alongside height to work
   around that caused its own visible jerk (each animated property fires
   its own transitionend, racing the one that flips height to auto). The
   actual padding/background live on .schema-faq-answer-inner, an unclipped
   wrapper main.js injects around this element's content on init - height
   just reveals more or less of that fixed-size inner box, so nothing about
   its own box model ever has to move. */
.schema-faq.wp-block-yoast-faq-block .schema-faq-answer,
.schema-faq.wp-block-art-division-faq .schema-faq-answer {
	height: 0;
	overflow: hidden;
	margin: 8px 0 0;
	transition: height 0.4s ease;
}

.schema-faq.wp-block-yoast-faq-block .schema-faq-answer-inner,
.schema-faq.wp-block-art-division-faq .schema-faq-answer-inner {
	padding: 1em 1.25em;
	background: var(--color-bg);
}

/* === Site Policy (Privacy Policy / Terms & Conditions / Cookie Policy) === */
.page-template-page-site-policy main {
	margin: 0 auto;
	max-width: var(--art-pm-content-max-width);
}

/* Dedicated typography for long-form legal text, applied via the Site Policy
   page template (page-site-policy.php). A neutral sans stack is used
   deliberately instead of --font-base, distinct from the brand typeface, for
   a plain, formal legal-document read. */
.art-site-policy h2,
.art-site-policy h3,
.art-site-policy h4,
.art-site-policy h5,
.art-site-policy h6 {
	color: var(--color-title);
	font-family: Arial, Helvetica, sans-serif;
	text-transform: capitalize;
}

.art-site-policy h2 {
	font-size: 1.25rem;
	line-height: 1.25;
}

.art-site-policy h3 {
	font-size: var(--text-lg);
	line-height: 1.25;
}

.art-site-policy p,
.art-site-policy li,
.art-site-policy td,
.art-site-policy th {
	font-family: Arial, Helvetica, sans-serif;
	font-size: var(--text-base);
}

.art-site-policy li a,
.art-site-policy p a {
	font-family: Arial, Helvetica, sans-serif;
	font-size: var(--text-base);
	text-decoration: underline;
}

.art-site-policy ul {
	list-style-position: outside;
	padding-bottom: 1.25rem;
}

.art-site-policy table ul {
	padding-left: 0;
}

/* Numbered clause references, e.g. "1.2.3" — nested <ol> counters. */
.art-site-policy ol {
	counter-reset: item;
}

.art-site-policy ol > li {
	counter-increment: item;
}

.art-site-policy ol ol > li {
	display: block;
}

.art-site-policy ol ol > li::before {
	content: counters(item, ".") ". ";
	margin-left: -20px;
}

/* === Author Archive ===
   .art-pm-module__blog-cards/.art-pm-module__blog-card* are Art Division
   Page Modules' own classes (see art_division_page_modules_render_blog_card(),
   reused here for both the featured latest-post card and the "More
   articles" grid so both look identical to a Blog module card - only the
   column count/sizing modifiers below are this theme's own. */
.author-page__bio {
	display: flex;
	gap: 1.5rem;
	align-items: flex-start;
	border: 1px solid var(--color-border);
	border-radius: var(--art-radius, 0);
	padding: 1.75rem;
	margin-bottom: 2.5rem;
}

.author-page__bio-avatar img {
	display: block;
	border-radius: 50%;
	width: 80px;
	height: 80px;
}

.author-page__bio-body {
	min-width: 0;
}

.author-page__bio-name {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 0.6rem;
	font-family: var(--font-heading);
	font-size: var(--text-lg);
	font-weight: 600;
	margin: 0 0 0.75rem;
}

.author-page__bio-follow-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.75rem;
	height: 1.75rem;
	border: 1px solid var(--color-border);
	border-radius: 50%;
	color: var(--color-accent);
}

.author-page__bio-follow-link:hover {
	background: var(--color-accent);
	color: var(--color-on-accent, #fff);
}

.author-page__bio-follow-link svg {
	width: 14px;
	height: 14px;
}

.author-page__bio-text {
	margin: 0;
	color: var(--color-muted);
}

.author-page__highlight {
	display: grid;
	gap: 2rem;
	margin-bottom: 3rem;
}

@media (min-width: 1024px) {
	.author-page__highlight {
		grid-template-columns: 2fr 1fr;
		align-items: start;
	}
}

.author-page__feature.art-pm-module__blog-cards {
	grid-template-columns: 1fr;
}

.author-page__feature .art-pm-module__blog-title {
	font-size: var(--text-xl);
}

.author-page__recommended {
	border: 1px solid var(--color-border);
	border-radius: var(--art-radius, 0);
	padding: 1.5rem;
}

.author-page__recommended-title {
	font-family: var(--font-heading);
	font-size: var(--text-lg);
	margin: 0 0 1rem;
	padding-bottom: 0.75rem;
	border-bottom: 1px solid var(--color-border);
}

.author-page__recommended-empty {
	color: var(--color-muted);
	font-size: var(--text-sm);
	margin: 0;
}

.author-page__recommended-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 1rem;
}

.author-page__recommended-item {
	display: flex;
	gap: 0.75rem;
}

.author-page__recommended-thumb {
	display: block;
	flex-shrink: 0;
}

.author-page__recommended-thumb-img {
	display: block;
	width: 64px;
	height: 64px;
	object-fit: cover;
	border-radius: var(--art-radius, 0);
}

.author-page__recommended-body {
	min-width: 0;
	display: flex;
	flex-direction: column;
}

.author-page__recommended-name a {
	color: var(--color-text);
	font-weight: 600;
	text-decoration: none;
}

.author-page__recommended-name a:hover {
	color: var(--color-accent);
}

.author-page__recommended-bio {
	color: var(--color-muted);
	font-size: var(--text-sm);
	margin-top: 0.15rem;
}

.author-page__grid-title {
	font-family: var(--font-heading);
	font-size: var(--text-2xl);
	margin: 0 0 1.5rem;
}

.author-page__grid.art-pm-module__blog-cards {
	grid-template-columns: repeat(4, minmax(0, 1fr));
}

@media (max-width: 1200px) {
	.author-page__grid.art-pm-module__blog-cards {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (max-width: 1023px) {
	.author-page__grid.art-pm-module__blog-cards {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 767px) {
	.author-page__bio {
		flex-direction: column;
	}

	.author-page__grid.art-pm-module__blog-cards {
		grid-template-columns: 1fr;
	}
}

/* === Page === */
.page-title {
	font-family: var(--font-heading);
	font-size: var(--text-2xl);
	letter-spacing: -0.02em;
	margin-bottom: 1.5rem;
}

/* === Pagination === */
.pagination {
	display: flex;
	gap: 0.5rem;
	margin-top: 3rem;
	justify-content: center;
}

.pagination a,
.pagination span {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.25rem;
	height: 2.25rem;
	padding: 0 0.5rem;
	border: 1px solid var(--color-border);
	border-radius: var(--art-radius, 0);
	font-size: var(--text-sm);
	color: var(--color-text);
	text-decoration: none;
	transition: background 0.2s;
}

.pagination a:hover,
.pagination .current {
	background: var(--color-accent);
	border-color: var(--color-accent);
	color: #fff;
}

/* === Footer === */
.site-footer {
	background-color: var(--color-footer-bg);
}

.site-footer h1,
.site-footer h2,
.site-footer h3,
.site-footer h4,
.site-footer h5,
.site-footer h6 {
	color: var(--color-footer-heading);
}

.site-footer p,
.site-footer li,
.site-footer dd,
.site-footer dt {
	color: var(--color-footer-text);
	font-size: var(--text-base);
}

.site-footer a {
	color: var(--color-footer-link);
}

.site-footer a:hover {
	color: var(--color-footer-link-hover);
}

.site-footer .widget_nav_menu ul {
	list-style: none;
	padding-left: 0;
}

/* Above Page — full-width before #page wrapper */
.widget-area--above-page {
	width: 100%;
}

/* Above Footer — full-width between #content and footer */
.widget-area--above-footer {
	width: 100%;
}

/* Footer Top — spans the full footer width, above columns */
.widget-area--footer-top {
	background-color: var(--color-footer-top-bg);
	padding: 2rem 0;
}

.widget-area--footer-top h1,
.widget-area--footer-top h2,
.widget-area--footer-top h3,
.widget-area--footer-top h4,
.widget-area--footer-top h5,
.widget-area--footer-top h6 {
	color: var(--color-footer-top-heading);
}

.widget-area--footer-top p,
.widget-area--footer-top li,
.widget-area--footer-top dd,
.widget-area--footer-top dt {
	color: var(--color-footer-top-text);
}

.widget-area--footer-top a {
	color: var(--color-footer-top-link);
}

.widget-area--footer-top a:hover {
	color: var(--color-footer-top-link-hover);
}

/* Footer — multi-column widget grid */
.widget-area--footer {
	padding: 3rem 0;
}

.widget-area--footer .container {
	display: grid;
	gap: 2rem;
	grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

.widget-area--footer .widget {
	margin-bottom: 0;
}

/* Below the width where the auto-fit grid above collapses to a single
   column, footer widget columns stack vertically instead of sitting side
   by side. A Nav Menu widget with a blank Title falls back to a screen-
   reader-only heading using the menu's own name (see
   art_division_nav_menu_widget_title_fallback() in functions.php) - never
   shown to sighted users. That's fine side by side, where the columns'
   own left-edge alignment is enough to read as separate groups, but once
   stacked the invisible <h2> still carries the browser's default heading
   margin even with zero visible content, leaving an unlabelled dead gap
   between each stacked list instead of a proper section break. Un-hide
   the fallback text here instead of just zeroing that margin - it's a
   real, meaningful label (the actual menu name), just never surfaced
   visually until now. */
@media (max-width: 480px) {
	.widget-area--footer .widget-title {
		font-size: var(--text-base);
		margin: 0 0 0.75rem;
	}

	.widget-area--footer .widget-title .screen-reader-text {
		clip: auto;
		height: auto;
		overflow: visible;
		position: static;
		width: auto;
	}
}

/* Footer Bottom — below the main footer widget columns */
.widget-area--footer-bottom {
	background-color: var(--color-footer-bottom-bg);
	padding: 2rem 0;
}

.widget-area--footer-bottom h1,
.widget-area--footer-bottom h2,
.widget-area--footer-bottom h3,
.widget-area--footer-bottom h4,
.widget-area--footer-bottom h5,
.widget-area--footer-bottom h6 {
	color: var(--color-footer-bottom-heading);
}

.widget-area--footer-bottom p,
.widget-area--footer-bottom li,
.widget-area--footer-bottom dd,
.widget-area--footer-bottom dt {
	color: var(--color-footer-bottom-text);
}

.widget-area--footer-bottom a {
	color: var(--color-footer-bottom-link);
}

.widget-area--footer-bottom a:hover {
	color: var(--color-footer-bottom-link-hover);
}

/* Footer Info — legal/credit bar below Footer Bottom (Copyright, Navigation,
   Art Division credit blocks); widgets/blocks placed here lay out as a
   wrapping row. */
.widget-area--footer-info {
	background-color: var(--color-footer-info-bg);
	padding: 1.5rem 0;
}

.widget-area--footer-info .widget {
	margin-bottom: 0;
}

.widget-area--footer-info .widgettitle,
.widget-area--footer-info .widget-title {
	margin: 0;
}

.widget-area--footer-info p,
.widget-area--footer-info li,
.widget-area--footer-info dd,
.widget-area--footer-info dt {
	color: var(--color-footer-info-text);
	font-size: var(--text-sm);
}

.widget-area--footer-info a {
	color: var(--color-footer-info-link);
}

.widget-area--footer-info a:hover {
	color: var(--color-footer-info-link-hover);
}

.widget-area--footer-info .widget_nav_menu ul {
	display: flex;
	flex-wrap: wrap;
	margin: 0;
}

.widget-area--footer-info .widget_nav_menu ul li + li::before {
	content: "|";
	margin: 0 0.5rem;
}

/* Footer Accordion — collapsible menu section above the footer, built from
   up to four registered nav menu locations (Footer Nav 1-4). The trigger bar
   and panel backgrounds are full-bleed (no .container on the button/nav
   itself); their content is wrapped in .container so it lines up with the
   rest of the site's max content width while the background spans edge to
   edge. Uses a grid-template-rows 0fr/1fr transition so it animates
   smoothly; the panel's inner padding lives on its last child (not the
   content wrapper itself) to avoid bottom-padding bleed while collapsed. */
.art-footer-accordion-area {
	width: 100%;
}

.art-footer-accordion__trigger {
	display: block;
	width: 100%;
	padding: 0;
	background-color: var(--color-surface);
	border: none;
	font: inherit;
	color: var(--color-text);
	cursor: pointer;
	text-align: left;
}

.art-footer-accordion__trigger-inner {
	display: flex;
	align-items: center;
	justify-content: flex-start;
	gap: 0.75rem;
	padding-top: 1rem;
	padding-bottom: 1rem;
}

.art-footer-accordion__title {
	font-size: var(--text-sm);
}

.art-footer-accordion__trigger-inner::after {
	content: '';
	flex-shrink: 0;
	width: 0.5em;
	height: 0.5em;
	border-right: 2px solid currentColor;
	border-top: 2px solid currentColor;
	transform: rotate(135deg);
	transition: transform 0.3s ease;
}

.art-footer-accordion__trigger[aria-expanded="true"] .art-footer-accordion__trigger-inner::after {
	transform: rotate(-45deg);
}

.art-footer-accordion__panel {
	display: grid;
	grid-template-rows: 0fr;
	overflow: hidden;
	transition: grid-template-rows 0.3s ease;
}

.art-footer-accordion__trigger[aria-expanded="true"] + .art-footer-accordion__panel {
	grid-template-rows: 1fr;
}

.art-footer-accordion__content {
	min-height: 0;
	overflow: hidden;
}

.art-footer-accordion__content > .container {
	padding-top: 1.5rem;
	padding-bottom: 1.5rem;
}

.art-footer-accordion__columns {
	display: flex;
	flex-wrap: wrap;
	justify-content: flex-start;
	gap: 1.5rem 3rem;
}

.art-footer-accordion__column {
	flex: 0 1 240px;
}

.art-footer-accordion__menu {
	list-style: none;
	margin: 0;
	padding: 0;
}

.art-footer-accordion__menu li {
	margin: 0 0 0.5rem;
}

.art-footer-accordion__menu li:last-child {
	margin-bottom: 0;
}

.art-footer-accordion__menu a {
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	color: var(--color-text);
	text-decoration: none;
}

.art-footer-accordion__menu a:hover {
	color: var(--color-accent);
}

.art-footer-accordion__menu a::before {
	content: '';
	flex-shrink: 0;
	width: 0.4em;
	height: 0.4em;
	border-right: 1.5px solid currentColor;
	border-top: 1.5px solid currentColor;
	transform: rotate(45deg);
}

/* === Utilities === */

/* Boxed text callout — inserted via the "boxed" Quicktags button added to
   every WYSIWYG editor's Text-mode toolbar (see functions.php), wrapping
   the selection in <div class="art-boxed-text">. Neutral default so it
   looks reasonable on every site out of the box; child themes override the
   background/radius to match their own branding. */
.art-boxed-text {
	background: var(--color-alternate);
	border-radius: var(--art-radius, 0);
	padding: 1.5rem 2rem;
}

.art-boxed-text > *:first-child {
	margin-top: 0;
}

.art-boxed-text > *:last-child {
	margin-bottom: 0;
}

/* Checklist — swaps a list's bullets for a checkmark icon. Two markup shapes
   both need to match: the Text-mode Quicktags button (functions.php) wraps a
   selected <ul> in <div class="art-checklist">, while the Visual-mode
   TinyMCE button puts the class straight on the <ul> itself - hence both
   ".art-checklist ul" (descendant) and "ul.art-checklist" (self) below.
   Uses mask-image with background-color:
   currentColor rather than background-image with a baked-in fill, so the
   checkmark always matches whatever text colour is in effect - inherited
   from --color-text by default, but also automatically follows a `color`
   override on an ancestor (e.g. white text on a dark callout box), with no
   extra rule needed. */
.art-checklist ul,
ul.art-checklist {
	list-style: none;
	padding: 0 0 0 15px;
}

.art-checklist li {
	line-height: 1.5;
	margin-bottom: 1rem;
	padding-left: 1.5rem;
	position: relative;
}

.art-checklist li:last-child {
	margin-bottom: 0;
}

.art-checklist li::before {
	background-color: currentColor;
	content: "";
	height: 14px;
	left: 0;
	position: absolute;
	top: 0.38em;
	width: 14px;
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 640'%3E%3Cpath d='M530.8 134.1C545.1 144.5 548.3 164.5 537.9 178.8L281.9 530.8C276.4 538.4 267.9 543.1 258.5 543.9C249.1 544.7 240 541.2 233.4 534.6L105.4 406.6C92.9 394.1 92.9 373.8 105.4 361.3C117.9 348.8 138.2 348.8 150.7 361.3L252.2 462.8L486.2 141.1C496.6 126.8 516.6 123.6 530.9 134z'/%3E%3C/svg%3E");
	-webkit-mask-repeat: no-repeat;
	-webkit-mask-size: contain;
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 640'%3E%3Cpath d='M530.8 134.1C545.1 144.5 548.3 164.5 537.9 178.8L281.9 530.8C276.4 538.4 267.9 543.1 258.5 543.9C249.1 544.7 240 541.2 233.4 534.6L105.4 406.6C92.9 394.1 92.9 373.8 105.4 361.3C117.9 348.8 138.2 348.8 150.7 361.3L252.2 462.8L486.2 141.1C496.6 126.8 516.6 123.6 530.9 134z'/%3E%3C/svg%3E");
	mask-repeat: no-repeat;
	mask-size: contain;
}

.screen-reader-text {
	clip: rect(1px, 1px, 1px, 1px);
	position: absolute;
	overflow: hidden;
	height: 1px;
	width: 1px;
	word-wrap: normal !important;
}

.screen-reader-text:focus {
	background-color: var(--color-bg);
	border: 1.5px solid var(--color-accent);
	border-radius: var(--art-radius, 0);
	clip: auto !important;
	color: var(--color-text);
	display: block;
	font-size: var(--text-sm);
	font-weight: 700;
	height: auto;
	left: 5px;
	line-height: normal;
	padding: 0.75em 1.25em;
	text-decoration: none;
	top: 5px;
	width: auto;
	z-index: 100000;
}

/* === Responsive === */
/* --text-3xl / --text-2xl scale fluidly via clamp() (see
   art_division_fluid_type_scale() in inc/theme-settings.php) instead of a
   fixed override at this breakpoint. */
@media (max-width: 640px) {
	.site-header .container {
		flex-direction: column;
		align-items: flex-start;
	}

	/* Keep header row when hamburger toggle is present */
	.site-header.has-hamburger .container {
		flex-direction: row;
		align-items: center;
	}

	.main-navigation ul {
		flex-wrap: wrap;
		gap: 1rem;
	}
}

/* === Hamburger Toggle Button === */
.hamburger-toggle {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 5px;
	background: none;
	border: none;
	cursor: pointer;
	padding: 6px;
	position: relative;
	z-index: 1000;
	flex-shrink: 0;
}

.hamburger-toggle span {
	display: block;
	width: 24px;
	height: 2px;
	background-color: var(--color-navbar-link);
	border-radius: 2px;
	transition: transform 0.3s ease, opacity 0.3s ease, background-color 0.2s;
	transform-origin: center;
}

.hamburger-toggle:hover span,
.hamburger-toggle:focus-visible span {
	background-color: var(--color-navbar-link-hover);
}

.hero-nav-transparent .hamburger-toggle span {
	background-color: var(--color-navbar-transparent-link);
}

.hero-nav-transparent .hamburger-toggle:hover span,
.hero-nav-transparent .hamburger-toggle:focus-visible span {
	background-color: var(--color-navbar-transparent-link-hover);
}

.hamburger-toggle.is-open span:nth-child(1) {
	transform: translateY(7px) rotate(45deg);
}

.hamburger-toggle.is-open span:nth-child(2) {
	opacity: 0;
	transform: scaleX(0);
}

.hamburger-toggle.is-open span:nth-child(3) {
	transform: translateY(-7px) rotate(-45deg);
}

/* === Menu Overlay === */
.menu-overlay {
	position: fixed;
	inset: 0;
	background: rgba(0, 0, 0, 0.5);
	/* Above .site-header's own 1000 (see .navbar-sticky .site-header) so the
	   backdrop actually dims the header too instead of leaving it showing
	   through on top of the overlay. */
	z-index: 1001;
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.3s ease;
}

.menu-overlay.is-active {
	opacity: 1;
	pointer-events: auto;
}

/* === Navigation Panel – Common === */
/* Top-anchored (not centred): submenu expansion then only pushes content
   downward — a vertically centred menu re-centres on every expand, so
   items above the open submenu drift upward while it animates. */
.main-navigation[class*="nav-slide-"] {
	position: fixed;
	/* Above .site-header's own 1000 and .menu-overlay's 1001 (see
	   .navbar-sticky .site-header and .menu-overlay) - otherwise the header
	   renders on top of this panel instead of being covered by it while the
	   menu is open. */
	z-index: 1002;
	background-color: var(--color-menu-bg);
	background-size: cover;
	background-position: center;
	overflow-y: auto;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: flex-start;
	padding-top: 5rem;
	isolation: isolate;
}

/* Background Image overlay (Theme Styles > Menu) — the ::before rule only
   exists when a background image is set (see art_division_menu_bg_image_css()).
   isolation: isolate above keeps this negative z-index inside the panel's own
   stacking context: below the panel's content, above its background image,
   without repositioning any child (the close button is position: absolute). */
.main-navigation[class*="nav-slide-"]::before {
	z-index: -1;
}

.main-navigation[class*="nav-slide-"] .primary-menu {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.9rem;
	list-style: none;
	padding: 0 2rem;
}

.main-navigation[class*="nav-slide-"] .primary-menu a {
	font-size: var(--text-base);
	color: var(--color-menu-link);
	text-decoration: none;
	transition: color 0.2s;
}

.main-navigation[class*="nav-slide-"] .primary-menu a:hover,
.main-navigation[class*="nav-slide-"] .current-menu-item > a {
	color: var(--color-menu-link-hover);
}

/* Submenus — WP's core Walker gives each parent item a plain nested
   <ul class="sub-menu"> with no toggle affordance; main.js injects a
   .submenu-toggle button after the parent link and toggles .is-open on the
   parent <li>, driving a grid-template-rows 0fr/1fr transition — the same
   technique the footer accordion uses, applied here to a two-row grid
   (label row + collapsible row) so the whole <ul> collapses as one single
   grid item, rather than trying to collapse each of its <li> individually. */
.main-navigation[class*="nav-slide-"] .menu-item-has-children {
	display: grid;
	grid-template-columns: auto auto;
	grid-template-rows: auto 0fr;
	justify-content: center;
	width: 100%;
	transition: grid-template-rows 0.3s ease;
}

.main-navigation[class*="nav-slide-"] .menu-item-has-children.is-open {
	grid-template-rows: auto 1fr;
}

.main-navigation.nav-slide-right-quarter .menu-item-has-children,
.main-navigation.nav-slide-left-quarter .menu-item-has-children {
	justify-content: start;
}

.main-navigation[class*="nav-slide-"] .menu-item-has-children > a {
	grid-column: 1;
	grid-row: 1;
}

.main-navigation[class*="nav-slide-"] .submenu-toggle {
	grid-column: 2;
	grid-row: 1;
	align-self: center;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.5rem;
	height: 1.5rem;
	margin-left: 0.5rem;
	padding: 0;
	border: none;
	background: none;
	color: var(--color-menu-link);
	cursor: pointer;
	vertical-align: middle;
}

.main-navigation[class*="nav-slide-"] .submenu-toggle::after {
	content: '';
	width: 0.5em;
	height: 0.5em;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: rotate(45deg);
	transition: transform 0.3s ease;
}

.main-navigation[class*="nav-slide-"] .submenu-toggle[aria-expanded="true"]::after {
	transform: rotate(-135deg);
}

/* display + flex-direction defeat the desktop-nav `.main-navigation ul`
   flex-row rule further up; align-self: stretch (not the li's default
   centring) so the <ul> takes the collapsed row's 0 height rather than its
   own content height, which would spill out of the row in both directions.
   Spacing matches the top-level .primary-menu gap: gap between children plus
   a first-child margin (clipped while collapsed — padding on the <ul> itself
   would render even at 0 height) for the step down from the parent label. */
.main-navigation[class*="nav-slide-"] .sub-menu {
	grid-column: 1 / -1;
	grid-row: 2;
	display: flex;
	flex-direction: column;
	gap: 0.9rem;
	align-self: stretch;
	overflow: hidden;
	min-height: 0;
	list-style: none;
	margin: 0;
	padding: 0;
	width: 100%;
}

.main-navigation[class*="nav-slide-"] .sub-menu li:first-child {
	margin-top: 0.9rem;
}

.main-navigation[class*="nav-slide-"] .sub-menu a {
	display: block;
}

/* Quarter-screen panels: left-align items */
.main-navigation.nav-slide-right-quarter,
.main-navigation.nav-slide-left-quarter {
	align-items: flex-start;
	justify-content: flex-start;
	padding-top: 5rem;
}

.main-navigation.nav-slide-right-quarter .primary-menu,
.main-navigation.nav-slide-left-quarter .primary-menu {
	align-items: flex-start;
}

/* === Slide In from Right – Full Screen === */
.main-navigation.nav-slide-right-full {
	top: 0;
	right: 0;
	width: 100vw;
	height: 100vh;
	transform: translateX(100%);
	transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

.main-navigation.nav-slide-right-full.is-open {
	transform: translateX(0);
}

/* === Slide In from Right – Quarter Screen === */
.main-navigation.nav-slide-right-quarter {
	top: 0;
	right: 0;
	width: 25vw;
	min-width: 280px;
	height: 100vh;
	transform: translateX(100%);
	transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
	box-shadow: -4px 0 24px rgba(0, 0, 0, 0.12);
}

.main-navigation.nav-slide-right-quarter.is-open {
	transform: translateX(0);
}

/* === Slide In from Left – Full Screen === */
.main-navigation.nav-slide-left-full {
	top: 0;
	left: 0;
	width: 100vw;
	height: 100vh;
	transform: translateX(-100%);
	transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

.main-navigation.nav-slide-left-full.is-open {
	transform: translateX(0);
}

/* === Slide In from Left – Quarter Screen === */
.main-navigation.nav-slide-left-quarter {
	top: 0;
	left: 0;
	width: 25vw;
	min-width: 280px;
	height: 100vh;
	transform: translateX(-100%);
	transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
	box-shadow: 4px 0 24px rgba(0, 0, 0, 0.12);
}

.main-navigation.nav-slide-left-quarter.is-open {
	transform: translateX(0);
}

/* === Slide Down – Full Screen === */
.main-navigation.nav-slide-down-full {
	top: 0;
	left: 0;
	width: 100vw;
	height: 100vh;
	transform: translateY(-100%);
	transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

.main-navigation.nav-slide-down-full.is-open {
	transform: translateY(0);
}

/* === Body scroll lock when menu is open === */
body.menu-is-open {
	overflow: hidden;
}

/* While a slide-in panel is open, the header's own hamburger button is
   hidden (visibility, not display, so it keeps its layout space and the
   header never reflows) in favour of .nav-panel-close below, which lives
   inside the panel and is positioned independently of the header. */
body.menu-is-open .hamburger-toggle {
	visibility: hidden;
}

/* Close control built into the slide-in panel itself. */
.nav-panel-close {
	position: absolute;
	top: 1.5rem;
	right: 1.5rem;
	width: 36px;
	height: 36px;
	background: none;
	border: none;
	cursor: pointer;
	padding: 0;
}

.nav-panel-close span {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 24px;
	height: 2px;
	background-color: var(--color-menu-link);
	border-radius: 2px;
	transition: background-color 0.2s;
}

.nav-panel-close span:nth-child(1) {
	transform: translate(-50%, -50%) rotate(45deg);
}

.nav-panel-close span:nth-child(2) {
	transform: translate(-50%, -50%) rotate(-45deg);
}

.nav-panel-close:hover span,
.nav-panel-close:focus-visible span {
	background-color: var(--color-menu-link-hover);
}

/* Left-side panels: keep the close button on the side it slides from. */
.main-navigation.nav-slide-left-quarter .nav-panel-close,
.main-navigation.nav-slide-left-full .nav-panel-close {
	right: auto;
	left: 1.5rem;
}

/* =========================================================
   Header Layout: Logo Left, Primary Menu Right
   ========================================================= */

.header-layout-left .container {
	display: flex;
	align-items: center;
	gap: 2rem;
	flex-wrap: nowrap;
}

.header-layout-left .site-branding {
	flex: 1;
}

/* Inline primary nav (desktop) */
.header-layout-left .header-nav-primary .primary-menu {
	list-style: none;
	display: flex;
	flex: 1;
	gap: 1.5rem;
	flex-wrap: wrap;
	margin: 0;
	padding: 0;
}

.header-layout-left .header-nav-primary .primary-menu a {
	font-size: var(--text-sm);
	color: var(--color-navbar-link);
	text-decoration: none;
	transition: color 0.2s;
}

.header-layout-left .header-nav-primary .primary-menu a:hover,
.header-layout-left .header-nav-primary .current-menu-item > a {
	color: var(--color-navbar-link-hover);
}

.hero-nav-transparent .header-nav-primary .primary-menu a {
	color: var(--color-navbar-transparent-link);
}

.hero-nav-transparent .header-nav-primary .primary-menu a:hover,
.hero-nav-transparent .header-nav-primary .current-menu-item > a {
	color: var(--color-navbar-transparent-link-hover);
}

/* Hamburger toggle hidden on desktop for left layout */
.header-layout-left .hamburger-toggle {
	display: none;
}

/* =========================================================
   Header Layout: Logo Centred, Left & Right Menus
   ========================================================= */

.header-layout-centred .container {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	gap: 1.5rem;
}

.header-layout-centred .header-nav-left {
	justify-self: start;
}

.header-layout-centred .site-branding {
	text-align: center;
}

/* Right group occupies the 3rd 1fr column — flex row, right-aligned */
.header-layout-centred .header-right-group {
	align-items: center;
	display: flex;
	gap: 1rem;
	justify-content: flex-end;
	justify-self: end;
}

.header-layout-centred .header-nav ul {
	list-style: none;
	display: flex;
	gap: 1.5rem;
	flex-wrap: wrap;
	margin: 0;
	padding: 0;
}

.header-layout-centred .header-nav a {
	font-size: var(--text-base, 1rem);
	color: var(--color-navbar-link);
	text-decoration: none;
	transition: color 0.2s;
}

.header-layout-centred .header-nav a:hover,
.header-layout-centred .header-nav .current-menu-item > a {
	color: var(--color-navbar-link-hover);
}

.hero-nav-transparent .header-nav a {
	color: var(--color-navbar-transparent-link);
}

.hero-nav-transparent .header-nav a:hover,
.hero-nav-transparent .header-nav .current-menu-item > a {
	color: var(--color-navbar-transparent-link-hover);
}

/* Hamburger toggle hidden on desktop for centred layout */
.header-layout-centred .hamburger-toggle {
	display: none;
}

/* =========================================================
   Header Nav Icons
   ========================================================= */

.header-nav-icons {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	flex-shrink: 0;
}

/* min-width/min-height: an icon-only link/button was only as big as its
   1.25rem (20px) icon, under the 24x24px minimum touch target (WCAG 2.2
   2.5.8, Lighthouse "target-size") - flagged on Oakmans' header Property
   Search button, which also sat flush against the logo link. 1.5rem adds
   2px around the icon, so the header doesn't visibly change; icons with a
   visible label are already wider than this. */
.nav-icon-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 1.5rem;
	min-width: 1.5rem;
	gap: 0.5rem;
	color: var(--color-navbar-link);
	text-decoration: none;
	transition: color 0.2s;
	line-height: 1;
}

.nav-icon-link:hover,
.nav-icon-link:focus-visible {
	color: var(--color-navbar-link-hover);
}

.hero-nav-transparent .nav-icon-link {
	color: var(--color-navbar-transparent-link);
}

.hero-nav-transparent .nav-icon-link:hover,
.hero-nav-transparent .nav-icon-link:focus-visible {
	color: var(--color-navbar-transparent-link-hover);
}

.hero-nav-transparent .art-btn--navbar {
	background-color: var(--color-btn-navbar-transparent-bg, #ffffff);
	border-color: var(--color-btn-navbar-transparent-border, #ffffff);
	color: var(--color-btn-navbar-transparent-text, #1a1a2e);
}

.hero-nav-transparent .art-btn--navbar:hover,
.hero-nav-transparent .art-btn--navbar:focus-visible {
	background-color: var(--color-btn-navbar-transparent-bg-hover, #f0f0f0);
	border-color: var(--color-btn-navbar-transparent-border-hover, #f0f0f0);
	color: var(--color-btn-navbar-transparent-text-hover, #1a1a2e);
}

.nav-icon-link svg {
	display: block;
	width: 1.25rem;
	height: 1.25rem;
}
.nav-icon-link svg path {
	fill: currentColor;
}

/* .art-btn's display: inline-block would otherwise beat this rule (it's
   declared later in the file at equal specificity), leaving the icon
   left-aligned in the button's padding instead of centred. */
.nav-icon-link.art-btn--navbar {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
}

.nav-btn-text {
	font-size: var(--text-base, 1rem);
	line-height: 1.25;
	white-space: nowrap;
}

/* hamburger-desktop: show panel menu on desktop alongside the inline nav */
.hamburger-desktop .header-layout-left .hamburger-toggle,
.hamburger-desktop .header-layout-centred .hamburger-toggle {
	display: flex;
}

/* The hamburger toggle doesn't participate in the centred grid on desktop */
/* (#site-navigation is position:fixed via nav-slide-* and is already out of flow) */

/* === Hamburger Icon Position: Left ===
   Static (not viewport-scoped) so it applies whenever the toggle is
   visible - the mobile breakpoint or Hamburger Menu on Desktop, both of
   which are independent of this setting. */

/* header-layout-left: the toggle is already a flat flex child of
   .container, so a simple order flip is enough. */
.hamburger-position-left .header-layout-left .hamburger-toggle {
	order: -1;
}

/* header-layout-centred: the toggle is nested inside .header-right-group
   so it can sit in the desktop grid's 3rd column; reordering it there
   would only move it within that group, not to the header's true left
   edge, so pull it out of flow instead and pin it to the left. The
   gutter for the absolutely-positioned toggle (2.25rem = its own width)
   is reserved on .header-nav-left itself, not on .container - padding
   the container instead would shift its whole padding box (and the
   centred grid's 1fr columns) off the standard var(--spacing) edge that
   the rest of the site's containers use, so the header content stopped
   lining up with the page below it. */
.hamburger-position-left .header-layout-centred .container {
	position: relative;
}

.hamburger-position-left .header-layout-centred .header-nav-left {
	padding-left: 2.25rem;
}

.hamburger-position-left .header-layout-centred .hamburger-toggle {
	position: absolute;
	left: var(--spacing);
	top: 50%;
	transform: translateY(-50%);
}

/* =========================================================
   Responsive mobile collapse — both new header layouts
   Breakpoint: configurable via Theme Settings > Navigation >
   Mobile Menu Breakpoint (default 768px); the @media rule itself
   is generated in inc/theme-settings.php
   (art_division_nav_breakpoint_css) since plain CSS can't read
   a PHP option, and inlined after this stylesheet.
   Logo left + hamburger right; inline menus hidden.
   ========================================================= */

/* =========================================================
   Responsive logos — desktop default
   ========================================================= */

/* Show desktop logo, hide mobile logo above the breakpoint */
.logo-mobile {
	display: none;
}

.logo-desktop {
	display: block;
}

/* =========================================================
   Fixed logos
   ========================================================= */

/* Fixed logos are hidden until the header enters the scrolled state */
.logo-fixed {
	display: none;
}

/* When header is scrolled: reveal fixed logos, hide default logos */
.site-header.is-scrolled .logo-fixed {
	display: block;
}

.site-header.is-scrolled .logo-default {
	display: none;
}

/* Responsive split for fixed logos when both desktop and mobile variants are
   set — @media rule generated in inc/theme-settings.php, see note above. */

/* When transparent nav is off the header is always solid, so show the fixed
   logo from the start without waiting for is-scrolled */
body:not(.hero-nav-transparent) .site-header .logo-fixed {
	display: block;
}

body:not(.hero-nav-transparent) .site-header .logo-default {
	display: none;
}

/* Raw SVG logo (Theme Settings > "Logo SVG" option) is pasted markup with
   whatever width/height its own designer gave it - every real site needs to
   size it deliberately in its own child theme anyway (logos vary too much
   for one shared default to fit them all), so no fallback cap is imposed
   here; an unsized paste renders at its own intrinsic size until a child
   theme sets one.
   Raw SVG logo also has no separate small scroll variant like the
   uploaded-image logos above, so it shrinks in place on scroll instead.
   transform:scale is used rather than width/height so the grid's auto-sized
   logo column doesn't change size and shift the flanking nav columns as the
   header scrolls. */
.custom-logo-link svg {
	transition: transform 0.3s ease;
}

/* =========================================================
   Art Button — shared CTA button component
   art-btn              base class on every CTA button / form wrapper
   art-btn--primary     primary filled button
   art-btn--secondary   secondary filled button
   art-btn--navbar      header nav icon rendered as a filled button
   art-btn--outline     transparent fill, coloured border/text, fills solid on hover
   art-btn--link        plain text link, no button chrome
   art-btn-style-*      body class that applies a hover animation style
                        (does not apply to art-btn--link)
   art-btn-shape-rounded  body class that forces buttons to a pill shape,
                          overriding the site-wide --art-radius setting
   ========================================================= */

.art-btn {
	border: 2px solid transparent;
	/* --art-btn-radius: Button Corner Amount (buttons only); unset = follow
	   the site-wide --art-radius. */
	border-radius: var(--art-btn-radius, var(--art-radius, 0));
	cursor: pointer;
	display: inline-block;
	/* Browsers give <button> its own default font (usually Arial/system-ui)
	   via the UA stylesheet, which - unlike every other element - doesn't
	   inherit automatically; a .art-btn built on <a> or <input> never hit
	   this, only <button>. */
	font-family: inherit;
	font-size: var(--text-base, 1rem);
	font-weight: var(--btn-font-weight, 400);
	line-height: 1.25;
	min-height: 44px;
	min-width: 44px;
	overflow: hidden;
	padding: 0.75rem 1.5rem;
	position: relative;
	text-align: center;
	text-decoration: none;
	text-transform: var(--btn-text-transform, none);
	transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
	vertical-align: middle;
	z-index: 0;
}

.art-btn-shape-rounded .art-btn {
	border-radius: 9999px;
}

/* Button Corner Amount on buttons that set their own corners - Gravity
   Forms' Submit/Next/Previous and the cookie banner. Only when the amount
   is set (body.art-btn-radius-custom), so other sites keep those plugins'
   own corners. !important: Gravity Forms sets its corners per form. */
.art-btn-radius-custom .gform_wrapper .gform_button,
.art-btn-radius-custom .gform_wrapper .gform_next_button,
.art-btn-radius-custom .gform_wrapper .gform_previous_button,
.art-btn-radius-custom .adcc-btn {
	border-radius: var(--art-btn-radius) !important;
}

.art-btn:focus-visible {
	outline: 2px solid var(--color-btn-primary-bg, #1a1a2e);
	outline-offset: 2px;
}

.art-btn--primary {
	background-color: var(--color-btn-primary-bg, #1a1a2e);
	border-color: var(--color-btn-primary-border, #1a1a2e);
	color: var(--color-btn-primary-text, #ffffff);
}

.art-btn--primary:hover,
.art-btn--primary:focus-visible {
	background-color: var(--color-btn-primary-bg-hover, #16213e);
	border-color: var(--color-btn-primary-border-hover, #16213e);
	color: var(--color-btn-primary-text-hover, #ffffff);
	text-decoration: none;
}

.art-btn--secondary {
	background-color: var(--color-btn-secondary-bg, #666666);
	border-color: var(--color-btn-secondary-border, #666666);
	color: var(--color-btn-secondary-text, #ffffff);
}

.art-btn--secondary:hover,
.art-btn--secondary:focus-visible {
	background-color: var(--color-btn-secondary-bg-hover, #1a1a2e);
	border-color: var(--color-btn-secondary-border-hover, #1a1a2e);
	color: var(--color-btn-secondary-text-hover, #ffffff);
	text-decoration: none;
}

.art-btn--navbar {
	background-color: var(--color-btn-navbar-bg, #1a1a2e);
	border-color: var(--color-btn-navbar-border, #1a1a2e);
	color: var(--color-btn-navbar-text, #ffffff);
}

.art-btn--navbar:hover,
.art-btn--navbar:focus-visible {
	background-color: var(--color-btn-navbar-bg-hover, #16213e);
	border-color: var(--color-btn-navbar-border-hover, #16213e);
	color: var(--color-btn-navbar-text-hover, #ffffff);
	text-decoration: none;
}

.art-btn--outline {
	background-color: transparent;
	border-color: var(--color-btn-outline-border, #1a1a2e);
	color: var(--color-btn-outline-text, #1a1a2e);
}

.art-btn--outline:hover,
.art-btn--outline:focus-visible {
	background-color: var(--color-btn-outline-bg-hover, #1a1a2e);
	border-color: var(--color-btn-outline-border-hover, #1a1a2e);
	color: var(--color-btn-outline-text-hover, #ffffff);
	text-decoration: none;
}

.art-btn--link {
	background-color: transparent;
	border-color: transparent;
	color: var(--color-btn-primary-bg, #1a1a2e);
	min-height: 0;
	min-width: 0;
	padding: 0;
	text-decoration: underline;
}

.art-btn--link:hover,
.art-btn--link:focus-visible {
	background-color: transparent;
	border-color: transparent;
	color: var(--color-btn-primary-bg-hover, #16213e);
	text-decoration: underline;
}

/* ── Button style: Fade (default — colour opacity transition) ─── */
.art-btn-style-fade .art-btn:not(.art-btn--link) { transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease; }

/* ── Button style: Slide In (background sweeps in from left) ──── */
.art-btn-style-slide-in .art-btn:not(.art-btn--link)::before {
	content: '';
	position: absolute;
	inset: 0;
	background-color: currentColor;
	opacity: 0.15;
	transform: translateX(-101%);
	transition: transform 0.3s ease;
	z-index: -1;
}
.art-btn-style-slide-in .art-btn:not(.art-btn--link):hover::before,
.art-btn-style-slide-in .art-btn:not(.art-btn--link):focus-visible::before { transform: translateX(0); }

/* ── Button style: Slide Up (background sweeps in from bottom) ── */
.art-btn-style-slide-up .art-btn:not(.art-btn--link)::before {
	content: '';
	position: absolute;
	inset: 0;
	background-color: currentColor;
	opacity: 0.15;
	transform: translateY(101%);
	transition: transform 0.3s ease;
	z-index: -1;
}
.art-btn-style-slide-up .art-btn:not(.art-btn--link):hover::before,
.art-btn-style-slide-up .art-btn:not(.art-btn--link):focus-visible::before { transform: translateY(0); }

/* ── Button style: Grow (subtle scale on hover) ─────────────── */
.art-btn-style-grow .art-btn:not(.art-btn--link) { transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease, transform 0.2s ease; }
.art-btn-style-grow .art-btn:not(.art-btn--link):hover,
.art-btn-style-grow .art-btn:not(.art-btn--link):focus-visible { transform: scale(1.05); }

/* ── Button style: Glow (box-shadow pulse on hover) ─────────── */
.art-btn-style-glow .art-btn:not(.art-btn--link) { transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease, box-shadow 0.3s ease; }
.art-btn-style-glow .art-btn--primary:hover,
.art-btn-style-glow .art-btn--primary:focus-visible { box-shadow: 0 0 0 4px var(--color-btn-primary-bg, #1a1a2e), 0 0 16px 4px var(--color-btn-primary-bg, #1a1a2e); }
.art-btn-style-glow .art-btn--secondary:hover,
.art-btn-style-glow .art-btn--secondary:focus-visible { box-shadow: 0 0 0 4px var(--color-btn-secondary-bg, #666666), 0 0 16px 4px var(--color-btn-secondary-bg, #666666); }
.art-btn-style-glow .art-btn--navbar:hover,
.art-btn-style-glow .art-btn--navbar:focus-visible { box-shadow: 0 0 0 4px var(--color-btn-navbar-bg, #1a1a2e), 0 0 16px 4px var(--color-btn-navbar-bg, #1a1a2e); }
.art-btn-style-glow .art-btn--outline:hover,
.art-btn-style-glow .art-btn--outline:focus-visible { box-shadow: 0 0 0 4px var(--color-btn-outline-border, #1a1a2e), 0 0 16px 4px var(--color-btn-outline-border, #1a1a2e); }

/* ── Button style: Sweep (diagonal wipe from bottom-left) ───── */
.art-btn-style-sweep .art-btn:not(.art-btn--link)::before {
	content: '';
	position: absolute;
	inset: 0;
	background-color: currentColor;
	opacity: 0.12;
	transform: skewX(-20deg) translateX(-110%);
	transition: transform 0.35s ease;
	z-index: -1;
}
.art-btn-style-sweep .art-btn:not(.art-btn--link):hover::before,
.art-btn-style-sweep .art-btn:not(.art-btn--link):focus-visible::before { transform: skewX(-20deg) translateX(0); }

/* =========================================================
   Gravity Forms — Floating Label style
   Body class: art-forms-style-floating-label (set from the Forms
   tab in Theme Settings, only shown when art-division-page-modules
   and Gravity Forms are both active).

   main.js flags eligible single-input fields (text, textarea, email,
   number, phone, website, select, post title/tags) with
   [data-art-floating-label] and toggles .is-floated once the field
   has a value. Complex multi-input fields (name, address, date, time,
   checkboxes, radio, consent, etc.) are left untouched.
   ========================================================= */

.art-forms-style-floating-label .gform_wrapper [data-art-floating-label] {
	position: relative;
}

.art-forms-style-floating-label .gform_wrapper [data-art-floating-label] :is(input, textarea, select) {
	padding-block-end: 0.5rem;
	padding-block-start: 1.5rem;
}

.art-forms-style-floating-label .gform_wrapper [data-art-floating-label] .gfield_label {
	color: var(--color-muted, #666666);
	left: 1rem;
	margin: 0;
	pointer-events: none;
	position: absolute;
	top: 1rem;
	transform-origin: left top;
	transition: transform 0.15s ease, color 0.15s ease;
	z-index: 1;
}

.art-forms-style-floating-label .gform_wrapper [data-art-floating-label].is-floated .gfield_label,
.art-forms-style-floating-label .gform_wrapper [data-art-floating-label]:focus-within .gfield_label {
	transform: translateY(-0.85rem) scale(0.8);
}

.art-forms-style-floating-label .gform_wrapper [data-art-floating-label]:focus-within .gfield_label {
	color: var(--color-accent, #1a1a2e);
}

/* =========================================================
   Gravity Forms — required-fields legend, screen-reader only
   Site-wide, not gated behind a toggle. Targets .gform_required_legend
   specifically rather than its .gform_heading wrapper, since that
   wrapper can also hold a form's Title/Description when those are
   enabled - hiding the whole wrapper would hide those too. Same clip
   technique as .screen-reader-text above, without the :focus-reveal
   variant since this paragraph never receives focus.
   ========================================================= */
.gform_required_legend {
	clip: rect(1px, 1px, 1px, 1px);
	position: absolute;
	overflow: hidden;
	height: 1px;
	width: 1px;
	word-wrap: normal !important;
}

/* =========================================================
   Gravity Forms — required-field asterisk matches the label colour
   Orbital defaults --gf-ctrl-label-color-req to var(--gf-color-danger),
   so the "*" on required fields reads red regardless of the label's own
   colour. Re-pointing it at --gf-ctrl-label-color-primary instead makes
   it always track whatever the label colour actually is - GF's own
   default, or the Label Text swatch on Theme Styles > Gravity Forms if
   that's been customised. A structural re-link, not a new brand colour
   choice, so it's unconditional (not gated behind Enable Colour
   Overrides) - same unscoped + !important requirement as the admin-tab
   overrides (see [[project_gform_specificity_important_requirement]]).
   ========================================================= */
.gform-theme--framework,
.gform-theme--api {
	--gf-ctrl-label-color-req: var(--gf-ctrl-label-color-primary) !important;
}

/* =========================================================
   Gravity Forms — privacy statement text size
   ========================================================= */
.form-privacy-statement {
	font-size: var(--text-sm);
}

/* =========================================================
   On Scroll Navbar Colours
   Applied when .is-scrolled is added to .site-header.
   Fixed Navbar colours apply to both states — these rules
   override transparent-navbar colour declarations above.
   ========================================================= */

.site-header.is-scrolled {
	background-color: var(--color-navbar-bg);
}

.site-header.header-layout-left.is-scrolled .header-nav-primary .primary-menu a,
.site-header.header-layout-centred.is-scrolled .header-nav a {
	color: var(--color-navbar-link);
}

.site-header.header-layout-left.is-scrolled .header-nav-primary .primary-menu a:hover,
.site-header.header-layout-left.is-scrolled .header-nav-primary .current-menu-item > a,
.site-header.header-layout-centred.is-scrolled .header-nav a:hover,
.site-header.header-layout-centred.is-scrolled .header-nav .current-menu-item > a {
	color: var(--color-navbar-link-hover);
}

.site-header.is-scrolled .hamburger-toggle span {
	background-color: var(--color-navbar-link);
}

.site-header.is-scrolled .hamburger-toggle:hover span,
.site-header.is-scrolled .hamburger-toggle:focus-visible span {
	background-color: var(--color-navbar-link-hover);
}

.site-header.is-scrolled .nav-icon-link {
	color: var(--color-navbar-link);
}

.site-header.is-scrolled .nav-icon-link:hover,
.site-header.is-scrolled .nav-icon-link:focus-visible {
	color: var(--color-navbar-link-hover);
}

.site-header.is-scrolled .art-btn--navbar {
	background-color: var(--color-btn-navbar-bg, #1a1a2e);
	border-color: var(--color-btn-navbar-border, #1a1a2e);
	color: var(--color-btn-navbar-text, #ffffff);
}

.site-header.is-scrolled .art-btn--navbar:hover,
.site-header.is-scrolled .art-btn--navbar:focus-visible {
	background-color: var(--color-btn-navbar-bg-hover, #16213e);
	border-color: var(--color-btn-navbar-border-hover, #16213e);
	color: var(--color-btn-navbar-text-hover, #ffffff);
}

/* ── Property Search Overlay ─────────────────────────────────────────────────
   Rendered by Art Division Property Modules when two or more departments are
   active. Triggered by .nav-icon-link--property-search button in the header.
   ─────────────────────────────────────────────────────────────────────────── */

.nav-icon-link--property-search {
	background: none;
	border: none;
	cursor: pointer;
	padding: 0;
}

.art-nav-property-search {
	inset: 0;
	overscroll-behavior: contain;
	position: fixed;
	z-index: 99999;
}

.art-nav-property-search[hidden] {
	display: none;
}

/* Must stay position:fixed, not absolute - .art-nav-property-search--wizard
   (a modifier on this same fixed, inset:0 element) is the one that actually
   scrolls (overflow-y:auto) once a wizard's content exceeds 100vh. An
   absolutely-positioned child scrolls along with its containing block's
   content, unlike fixed, which stays pinned to the viewport regardless of
   any ancestor's scroll - so with position:absolute here, scrolling past a
   tall wizard step scrolled the backdrop away with it, leaving a gap that
   revealed the real page underneath. */
.art-nav-property-search__backdrop {
	background: rgba(0, 0, 0, 0.6);
	inset: 0;
	opacity: 0;
	position: fixed;
	transition: opacity 0.1s ease;
}

/* Fades in/out together with the panel below for the centered (default)
   popup style; the --fullscreen variant fades its whole container instead
   (see .art-nav-property-search--fullscreen further down), so its backdrop
   is forced back to a static opacity: 1 there. */
.art-nav-property-search.is-open:not(.art-nav-property-search--fullscreen) .art-nav-property-search__backdrop {
	opacity: 1;
	transition: opacity 0.22s ease;
}

.art-nav-property-search__panel {
	background: var(--color-bg, #ffffff);
	box-shadow: 0 8px 48px rgba(0, 0, 0, 0.18);
	left: 50%;
	max-height: 90vh;
	max-width: 640px;
	opacity: 0;
	overflow-y: auto;
	padding: 2.5rem;
	position: absolute;
	top: 50%;
	/* Closing state's duration - deliberately quicker than opening's below,
	   matching the shared dialog.art-modal pattern this mirrors. */
	transform: translate(-50%, -50%) scale(0.96);
	transition: opacity 0.1s ease, transform 0.1s ease;
	width: 90%;
}

.art-nav-property-search.is-open:not(.art-nav-property-search--fullscreen) .art-nav-property-search__panel {
	opacity: 1;
	transform: translate(-50%, -50%) scale(1);
	transition: opacity 0.22s ease, transform 0.22s ease;
}

.art-nav-property-search__close {
	background: none;
	border: none;
	color: var(--color-text, #111111);
	cursor: pointer;
	line-height: 1;
	padding: 4px;
	position: absolute;
	right: 1.25rem;
	top: 1.25rem;
}

.art-nav-property-search__close:focus-visible {
	outline: 2px solid var(--color-accent, #1a1a2e);
	outline-offset: 2px;
}

.art-nav-property-search__close svg {
	display: block;
	height: 24px;
	width: 24px;
}

.art-nav-property-search__inner {
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
}

.art-nav-property-search__label {
	display: block;
	font-size: var(--text-sm, 0.875rem);
	margin-bottom: 0.5rem;
}

.art-nav-property-search__input {
	background: var(--color-bg, #ffffff);
	border: 1px solid var(--color-border, #e0e0e0);
	border-radius: var(--art-radius, 0);
	font-family: inherit;
	font-size: var(--text-base, 1rem);
	padding: 0.75rem 1rem;
	width: 100%;
}

.art-nav-property-search__input:focus {
	border-color: var(--color-accent, #1a1a2e);
	outline: 2px solid var(--color-accent, #1a1a2e);
	outline-offset: 2px;
}

.art-nav-property-search__departments {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
}

.art-nav-property-search__dept-btn {
	background-color: var(--color-btn-primary-bg, #1a1a2e);
	border: 1px solid var(--color-btn-primary-border, #1a1a2e);
	border-radius: var(--art-radius, 0);
	color: var(--color-btn-primary-text, #ffffff);
	flex: 1;
	font-size: var(--text-sm, 0.875rem);
	min-width: 140px;
	padding: 0.75rem 1.5rem;
	text-align: center;
	text-decoration: none;
	transition: background-color 0.15s ease, border-color 0.15s ease;
}

.art-nav-property-search__dept-btn:hover,
.art-nav-property-search__dept-btn:focus-visible {
	background-color: var(--color-btn-primary-bg-hover, #16213e);
	border-color: var(--color-btn-primary-border-hover, #16213e);
	color: var(--color-btn-primary-text-hover, #ffffff);
	text-decoration: none;
}

.art-nav-property-search__dept-btn:focus-visible {
	outline: 2px solid var(--color-accent, #1a1a2e);
	outline-offset: 2px;
}

/* `overflow: hidden` alone doesn't reliably stop touch/rubber-band scrolling
   of the page behind the fixed overlay on iOS Safari/Android WebViews - it
   only blocks the scrollbar-driven kind. Pinning body itself to `position:
   fixed` at its current scroll offset (see main.js's openOverlay(), which
   sets `top`) genuinely removes it from the scrollable area; left/right: 0
   is required since a fixed element no longer inherits the viewport width
   from its normal block-level flow. */
body.property-search-overlay-open {
	left: 0;
	overflow: hidden;
	position: fixed;
	right: 0;
}

/* Full screen overlay variant - background image/colour are set inline as the
   --art-nav-search-bg-image / --art-nav-search-bg-color custom properties via
   the "Property Search Popup Background" admin setting. Unlike the centred
   dialog, content sits directly over the backdrop image with no card/box -
   the heading (normally screen-reader-only) and the input/department row
   are shown inline, side by side, similar to a hero search bar. Animates in
   from the top of the page; main.js toggles the .is-open class a frame
   after the [hidden] attribute is removed so the transition has an initial
   state to animate from. */
.art-nav-property-search--fullscreen {
	align-items: center;
	display: flex;
	justify-content: center;
	opacity: 0;
	transform: translateY(-100%);
	transition: opacity 0.3s ease, transform 0.4s ease;
}

/* transform: none, not translateY(0): any transform value (even a zero
   one) makes this element the containing block for its position:fixed
   descendants, so the fixed backdrop above scrolled away with a tall
   wizard step and revealed the page underneath. none still animates from
   the closed translateY(-100%) state. */
.art-nav-property-search--fullscreen.is-open {
	opacity: 1;
	transform: none;
}

.art-nav-property-search--fullscreen .art-nav-property-search__backdrop {
	background-color: var(--art-nav-search-bg-color, var(--color-bg, #ffffff));
	background-image: var(--art-nav-search-bg-image, none);
	background-position: center;
	background-size: cover;
	/* This variant fades its whole container in/out (below) rather than the
	   backdrop individually, so the backdrop itself just stays visible. */
	opacity: 1;
}

/* Dark scrim over the backdrop so the white heading/input stay legible
   regardless of the admin-chosen background image or colour. */
.art-nav-property-search--fullscreen .art-nav-property-search__backdrop::after {
	background: linear-gradient(180deg, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.3));
	content: "";
	inset: 0;
	position: absolute;
}

.art-nav-property-search--fullscreen .art-nav-property-search__panel {
	background: transparent;
	box-shadow: none;
	left: auto;
	margin: 0;
	max-height: none;
	max-width: 1100px;
	/* This variant fades/slides its whole container in/out (above) rather
	   than the panel individually, so the panel itself just stays visible. */
	opacity: 1;
	overflow: visible;
	padding: 0 1.5rem;
	position: relative;
	top: auto;
	transform: none;
	width: 92%;
}

.art-nav-property-search--fullscreen .art-nav-property-search__close {
	color: #ffffff;
	filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.6));
}

.art-nav-property-search--fullscreen #art-nav-property-search-heading {
	clip: auto;
	color: #ffffff;
	filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.5));
	font-size: clamp(1.75rem, 4vw, 2.75rem);
	height: auto;
	margin: 0 0 1.5rem;
	overflow: visible;
	position: static;
	width: auto;
}

.art-nav-property-search--fullscreen .art-nav-property-search__inner {
	flex-direction: row;
	flex-wrap: wrap;
}

.art-nav-property-search--fullscreen .art-nav-property-search__inner > div:first-child {
	flex: 1 1 260px;
}

.art-nav-property-search--fullscreen .art-nav-property-search__label {
	clip: rect(1px, 1px, 1px, 1px);
	height: 1px;
	overflow: hidden;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}

.art-nav-property-search--fullscreen .art-nav-property-search__departments {
	flex: 2 1 420px;
}

@media (prefers-reduced-motion: reduce) {
	.art-nav-property-search--fullscreen {
		transform: none;
		transition: opacity 0.15s ease;
	}

	.art-nav-property-search__panel,
	.art-nav-property-search__backdrop {
		transition: none;
	}
}

@media (max-width: 480px) {
	/* Panel keeps the same centered dialog + scale animation as every other
	   width now (base .art-nav-property-search__panel rule above) - this
	   used to switch it to a bottom sheet (top:auto/bottom:0 + slide-up
	   transform) below 480px, but that's been dropped in favour of staying
	   centered at every screen size. max-width:100% is still useful this
	   narrow, so that part's kept via the padding/width tweak below. */
	.art-nav-property-search__panel {
		padding: 2rem 1.25rem;
		max-width: calc(100% - 2rem);
	}

	.art-nav-property-search--fullscreen .art-nav-property-search__panel {
		bottom: auto;
		padding: 0 1.25rem;
	}

	.art-nav-property-search--fullscreen .art-nav-property-search__inner {
		flex-direction: column;
	}
}

/* ── Shared modal (dialog.art-modal) ──────────────────────────────────────────
   Ported from the Art Division Blocks plugin's assets/css/modal.css, the
   origin of this pattern (also duplicated into Repeatables and Page
   Modules). Powers the Floating Form Button below. */

dialog.art-modal {
	background: var(--art-color-bg, #ffffff);
	border: none;
	border-radius: var(--art-radius, 0);
	box-shadow: 0 8px 40px rgba(0, 0, 0, 0.2);
	max-width: min(600px, calc(100vw - 2rem));
	padding: 0;
	width: 100%;
}

/* The open/close animation (opacity+transform) and scroll clipping
   (max-height/overflow-y) live on .art-modal__inner, NOT the <dialog>
   element itself. `transform` on an ancestor makes it the containing block
   for any `position: fixed` descendant (e.g. a Google Places Autocomplete
   .pac-container an address field appends inside the dialog) - paired with
   overflow-y:auto that then clips/mispositions that dropdown against the
   dialog's own box instead of the viewport. Keeping <dialog> itself
   transform-free avoids creating that containing block at all. Also fixes
   a cross-plugin collision: this dialog often carries a second class too
   (e.g. Page Modules' art-pm-module__form-modal), whose own CSS targets
   the same element at equal specificity - whichever plugin's stylesheet
   happened to load last was winning and silently reintroducing this bug
   regardless of which single copy got fixed, so every copy needs it. */
dialog.art-modal .art-modal__inner {
	max-height: 90dvh;
	opacity: 0;
	overflow-y: auto;
	scrollbar-color: var(--art-color-accent, #999999) transparent;
	scrollbar-width: thin;
	transform: translateY(16px) scale(0.96);
	/* Closing state's duration - deliberately quicker than opening's below,
	   a slow fade-out on dismiss reads as sluggish rather than smooth. */
	transition: opacity 0.1s ease, transform 0.1s ease;
}

/* Firefox picks up thin/coloured scrollbars from scrollbar-color above;
   Chromium/Safari need the ::-webkit- pseudo-elements instead. */
dialog.art-modal .art-modal__inner::-webkit-scrollbar {
	width: 8px;
}

dialog.art-modal .art-modal__inner::-webkit-scrollbar-track {
	background: transparent;
}

dialog.art-modal .art-modal__inner::-webkit-scrollbar-thumb {
	background-color: var(--art-color-accent, #999999);
	border-radius: 9999px;
}

/* Locks the underlying page's own scrollbar while a modal is open (toggled
   by main.js) - without this, opening a modal left two scrollbars visible
   (the page's and the dialog's own), and the page behind could still be
   wheel-scrolled despite the dialog being modal/inert. */
body.art-modal-locked {
	overflow: hidden;
}

/* The page root too: when <html> has its own overflow set (e.g. Page
   Modules' slide animations clip it sideways), it - not body - scrolls the
   page, so locking body alone let it keep scrolling behind any popup. */
html:has(body.art-modal-locked) {
	overflow: hidden;
}

dialog.art-modal.art-modal--visible .art-modal__inner {
	opacity: 1;
	transform: translateY(0) scale(1);
	transition: opacity 0.22s ease, transform 0.22s ease;
}

dialog.art-modal::backdrop {
	backdrop-filter: blur(2px);
	background: rgba(0, 0, 0, 0.5);
	opacity: 0;
	transition: opacity 0.1s ease;
}

dialog.art-modal.art-modal--visible::backdrop {
	opacity: 1;
	transition: opacity 0.22s ease;
}

@media (prefers-reduced-motion: reduce) {
	dialog.art-modal .art-modal__inner,
	dialog.art-modal::backdrop {
		transition: none;
	}
}

.art-modal__inner {
	padding: 2rem;
	position: relative;
}

.art-modal__close {
	background: transparent;
	border: none;
	color: var(--art-color-text, #111111);
	cursor: pointer;
	font-size: 1.5rem;
	line-height: 1;
	min-height: 44px;
	min-width: 44px;
	padding: 0.5rem;
	position: absolute;
	right: 1rem;
	top: 1rem;
}

.art-modal__close:focus-visible {
	border-radius: var(--art-radius, 0);
	outline: 2px solid var(--art-color-accent, #1a1a2e);
	outline-offset: 2px;
}

.art-modal__content {
	padding-top: 1rem;
	text-align: left;
}

/* ── Floating Form Button ──────────────────────────────────────────────────── */
/* Flush against whichever viewport edge is chosen (no gap), so only the
   corners on the far side from that edge get a slight radius - and only
   when the site's own Rounded Corners setting is on (--art-radius is 0
   otherwise). The edge touching the side of the site always stays square. */

.art-fab-btn {
	align-items: center;
	background: var(--art-fab-bg, var(--art-color-accent, #1a1a2e));
	border: none;
	box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
	color: var(--art-fab-icon, #ffffff);
	cursor: pointer;
	display: flex;
	height: 56px;
	justify-content: center;
	padding: 0;
	position: fixed;
	transition: transform 0.2s ease, box-shadow 0.2s ease;
	width: 56px;
	z-index: 9998;
}

.art-fab-btn:hover {
	box-shadow: 0 6px 16px rgba(0, 0, 0, 0.32);
	transform: scale(1.05);
}

.art-fab-btn:focus-visible {
	outline: 2px solid var(--art-color-accent, #1a1a2e);
	outline-offset: 2px;
}

.art-fab-btn__icon {
	display: block;
	height: 28px;
	width: 28px;
}

.art-fab-btn--left {
	border-radius: 0 var(--art-radius, 0) var(--art-radius, 0) 0;
	left: 0;
}

.art-fab-btn--right {
	border-radius: var(--art-radius, 0) 0 0 var(--art-radius, 0);
	right: 0;
}

.art-fab-btn--top {
	top: 25vh;
}

.art-fab-btn--middle {
	top: 50%;
	transform: translateY(-50%);
}

.art-fab-btn--middle:hover {
	transform: translateY(-50%) scale(1.05);
}

.art-fab-btn--bottom {
	bottom: 28px;
}

/* ── Floating Form Button: slide out on hover/focus to reveal the label ──────
   Deliberately does NOT animate the button's own width: the base rule above
   sets a hard `width: 56px`, and width wins over max-width whenever width
   already satisfies it, so `width: auto` here lets the button's own box
   follow its flex content instead - it grows in sync for free as the label
   reveals. Equal left/right padding reproduces the plain button's
   centred-icon look at rest (icon 28px + 14px padding each side = 56px).

   The label's reveal uses the CSS Grid 0fr->1fr track trick rather than a
   max-width transition: a max-width transition animates towards a guessed
   target (e.g. 280px) that's almost always wider than the actual label
   text, so the text finishes revealing long before the transition's
   duration elapses and the motion reads as a jumpy "pop" rather than a
   smooth reveal. A grid track sized in fr units interpolates smoothly
   between 0 and the CONTENT'S OWN width regardless of how long the label
   text actually is, so the reveal speed is always consistent. The nested
   .art-fab-btn__label-text span is what actually gets clipped as the track
   collapses (grid/flex items need min-width:0 to shrink below their content
   size) and is also where the translateX slide-in lives, direction-aware
   per side so the text visibly slides in from the screen edge rather than
   just fading in place. */

.art-fab-btn--hover-label {
	justify-content: flex-start;
	overflow: hidden;
	padding: 0 14px;
	transition: box-shadow 0.2s ease;
	width: auto;
}

.art-fab-btn--hover-label .art-fab-btn__icon {
	flex-shrink: 0;
}

.art-fab-btn--hover-label .art-fab-btn__label {
	display: grid;
	grid-template-columns: 0fr;
	margin: 0;
	transition: grid-template-columns 0.3s ease, margin 0.3s ease;
}

.art-fab-btn--hover-label:hover .art-fab-btn__label,
.art-fab-btn--hover-label:focus-visible .art-fab-btn__label {
	grid-template-columns: 1fr;
	margin: 0 8px;
}

.art-fab-btn__label-text {
	display: block;
	font-size: var(--art-text-sm, 0.875rem);
	min-width: 0;
	opacity: 0;
	overflow: hidden;
	transition: opacity 0.25s ease, transform 0.3s ease;
	white-space: nowrap;
}

.art-fab-btn--hover-label.art-fab-btn--left .art-fab-btn__label-text {
	transform: translateX(-10px);
}

.art-fab-btn--hover-label.art-fab-btn--right .art-fab-btn__label-text {
	transform: translateX(10px);
}

.art-fab-btn--hover-label:hover .art-fab-btn__label-text,
.art-fab-btn--hover-label:focus-visible .art-fab-btn__label-text {
	opacity: 1;
	transform: translateX(0);
}

@media (prefers-reduced-motion: reduce) {
	.art-fab-btn--hover-label .art-fab-btn__label,
	.art-fab-btn__label-text {
		transition: none;
	}
}

/* ── Map Appearance ────────────────────────────────────────────────────────── */
/* Theme Settings → Map → Map Appearance (inc/map-appearance.php). Every
   appearance keeps the standard OpenStreetMap tiles and only filters Leaflet's
   tile pane - markers, popups, controls and attribution sit in sibling panes,
   so they keep their own colours. Standard adds no classes, so no filter.

   The preset values below are the single place to tune each appearance.
   Child themes override a preset everywhere by redefining its variable on
   :root, or one map type by setting --art-map-tile-filter on its classes.

   Art Division maps: the Art Maps block and Page Modules' Map, Contact Us and
   Branch Finder maps add art-map--styled art-map--{appearance} to their own
   Leaflet container. PropertyHive's Leaflet maps (Map Search results and the
   [property_map] single-property map) are styled from the body classes,
   scoped to PropertyHive's own map containers only. */
/* Greyscale: fully monochrome, with contrast nudged up so water and land stay
   distinct and labels stay crisp once colour no longer separates them.
   Muted: OSM's road-atlas colours at under half strength, slightly lifted and
   flattened - still recognisably OSM, just quieter.
   Soft: desaturate first, then sepia, so the warmth lands as one even cream/
   stone tone rather than tinting OSM's own colours; lower contrast softens
   lines and text. (Sepia before saturate would drain the warmth again.) */
:root {
	--art-map-filter-greyscale: grayscale(1) brightness(1.03) contrast(1.06);
	--art-map-filter-muted: saturate(0.45) brightness(1.04) contrast(0.92);
	--art-map-filter-soft: saturate(0.5) sepia(0.3) brightness(1.03) contrast(0.88);
}

.art-map--greyscale,
.art-map-appearance--greyscale .propertyhive-map-canvas,
.art-map-appearance--greyscale [id^="property_map_canvas"] {
	--art-map-tile-filter: var(--art-map-filter-greyscale);
}

.art-map--muted,
.art-map-appearance--muted .propertyhive-map-canvas,
.art-map-appearance--muted [id^="property_map_canvas"] {
	--art-map-tile-filter: var(--art-map-filter-muted);
}

.art-map--soft,
.art-map-appearance--soft .propertyhive-map-canvas,
.art-map-appearance--soft [id^="property_map_canvas"] {
	--art-map-tile-filter: var(--art-map-filter-soft);
}

.art-map--styled .leaflet-tile-pane,
.art-map-appearance .propertyhive-map-canvas .leaflet-tile-pane,
.art-map-appearance [id^="property_map_canvas"] .leaflet-tile-pane {
	filter: var(--art-map-tile-filter);
}
