/* ==========================================================================
   FOOTER — footer@1.0
   The last surface of every page. Three bands (cap, body, legal), one
   designed band (body), one 12-column grid inside it. Contract:
   skills/footer/SPEC.md + skills/footer/footer.schema.json. Rendered by
   includes/footer/class-footer-renderer.php.

   Structure only, no colour: every colour here is a theme token
   (var(--color-*)), the same discipline assets/css/page-header.css follows —
   what the contract forbids is a pixel or a literal colour in an ENTRY, not
   a token reference in the stylesheet that turns a derived role into one.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Block + content wrapper
   -------------------------------------------------------------------------- */

.plexa-footer {
	display: block;
	width: 100%;
	color: var(--pf-content, var(--color-base-content));
}

/* Tier 1 with a mode of its own (data-theme set -- i.e. not 'inherit') has
   no bg-layers class and nothing else paints it, so it needs to paint its
   own mode's ground directly. `mode: inherit` (no data-theme attribute)
   stays unpainted on purpose: transparent, page-as-surface (SPEC §5's tier
   6 stand-in -- the `surface`/`legal-only` entries). */
.plexa-footer[data-theme] {
	background-color: var(--color-base-100);
}

/* A tier-1 footer with its own mode that ALSO carries bg-layers (fade: top,
   or any other reason a tier-1 footer gets the class) has no data-bg-base to
   paint .bg-layers__base through backgrounds.css's own rules -- without this
   it stays the page's paper colour with dark-mode text sitting on it. Tier 4
   keeps its own tint rule below; this only fills the gap tier 1 leaves. */
.plexa-footer[data-theme].bg-layers:not([data-bg-base]) > .bg-layers__base {
	background: var(--color-base-100);
}

.plexa-footer__content {
	display: block;
	width: 100%;
}

/* --------------------------------------------------------------------------
   Bands — cap and legal are the plain-strip primitive; body is the one
   designed band.
   -------------------------------------------------------------------------- */

.plexa-footer__band {
	position: relative;
	display: block;
	width: 100%;
}

.plexa-footer__inner {
	width: 100%;
	max-width: var(--pf-container, 80rem);
	margin-inline: auto;
	padding-inline: clamp(1rem, 4vw, 2rem);
}

.plexa-footer__band--cap .plexa-footer__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 1rem 1.5rem;
	padding-block: clamp(1.5rem, 3vw, 2.25rem);
}

.plexa-footer__band--body .plexa-footer__inner {
	padding-block: clamp(2.5rem, 5vw, 4rem);
}

.plexa-footer__band--legal .plexa-footer__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 0.5rem 1.5rem;
	padding-block: clamp(1.25rem, 2vw, 1.75rem);
	font-size: var(--text-caption-size, 0.75rem);
}

/* Alignment — meaningful on cap/legal always; on body only when stacked. */
.plexa-footer__band--align-left .plexa-footer__inner    { justify-content: flex-start; text-align: left; }
.plexa-footer__band--align-center .plexa-footer__inner  { justify-content: center; text-align: center; }
.plexa-footer__band--align-right .plexa-footer__inner   { justify-content: flex-end; text-align: right; }
.plexa-footer__band--align-split .plexa-footer__inner   { justify-content: space-between; }

/* --------------------------------------------------------------------------
   Derived: rule budget (invariant 4). At most one hairline across the three
   bands, drawn in the band's own resolved content colour at reduced opacity.
   -------------------------------------------------------------------------- */

.plexa-footer__band--rule-top {
	border-top: 1px solid color-mix(in oklch, var(--pf-content, var(--color-base-content)) 18%, transparent);
}

.plexa-footer__band--rule-bottom {
	border-bottom: 1px solid color-mix(in oklch, var(--pf-content, var(--color-base-content)) 18%, transparent);
}

/* --------------------------------------------------------------------------
   Derived: contrast pairing. Role-paired and automatic, never authored
   (SPEC §7.5). Strips always pair 'base' (mirrors the header's open_strip());
   the body band takes the surface's derived role.
   -------------------------------------------------------------------------- */

.plexa-footer__band--content-base      { --pf-content: var(--color-base-content); }
.plexa-footer__band--content-primary   { --pf-content: var(--color-primary-content); }
.plexa-footer__band--content-secondary { --pf-content: var(--color-secondary-content); }
.plexa-footer__band--content-accent    { --pf-content: var(--color-accent-content); }
.plexa-footer__band--content-neutral   { --pf-content: var(--color-neutral-content); }

/* --------------------------------------------------------------------------
   Surface — tier 1 (flat) needs nothing; tiers 2/2f/5 paint entirely through
   the shared bg-layers system (assets/css/shared/backgrounds/backgrounds.css)
   via the data-bg-* attributes the renderer emits on <footer>. Tier 3's mesh
   and tier 4's tint are declared here, exactly mirroring page-header.css's
   own tier 3/4 rules, just scoped to .plexa-footer instead of a band.
   -------------------------------------------------------------------------- */

.plexa-footer[data-bg-mesh="custom"] > .bg-layers__base::before {
	content: "";
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	background:
		radial-gradient(ellipse 80% 60% at 20% 30%, var(--mesh-color-1, color-mix(in oklch, var(--color-primary) 60%, transparent)), transparent 70%),
		radial-gradient(ellipse 60% 80% at 80% 20%, var(--mesh-color-2, color-mix(in oklch, color-mix(in oklch, var(--color-primary) 65%, var(--color-primary-content)) 38%, transparent)), transparent 70%),
		radial-gradient(ellipse 70% 50% at 50% 80%, var(--mesh-color-3, color-mix(in oklch, color-mix(in oklch, var(--color-primary) 40%, var(--color-base-100)) 28%, transparent)), transparent 70%),
		radial-gradient(ellipse 90% 90% at 50% 50%, var(--mesh-color-4, var(--color-base-100)), transparent);
	animation: none;
	will-change: auto;
}

/* Painted on the CHILD base layer, not the parent <footer> element.
   assets/css/shared/backgrounds/backgrounds.css forces
   `footer.bg-layers { background-color: transparent !important }` (so a
   real fixed/pattern/image effect always shows through cleanly), which also
   defeats any background-color put on .plexa-footer itself once bg-layers
   is present -- a tint rule scoped to .plexa-footer--tint-* alone silently
   lost that fight (dev5 /footer-gallery/02-columns/, /06-mega/: tier-4 dots
   rendered with no ground, so dark-mode text sat invisible on the page's
   own light paper). .bg-layers__base is a plain child element the forcing
   rule never touches, so painting it there sidesteps the fight entirely --
   the same reason tier 2f's fixed effects and tier 5's image, which paint
   through that same child via backgrounds.css's own [data-bg-base=*] rules,
   were never affected. */
.plexa-footer--tint-base-200  > .bg-layers__base { background: var(--color-base-200); }
.plexa-footer--tint-base-300  > .bg-layers__base { background: var(--color-base-300); }
.plexa-footer--tint-primary   > .bg-layers__base { background: var(--color-primary); }
.plexa-footer--tint-secondary > .bg-layers__base { background: var(--color-secondary); }
.plexa-footer--tint-accent    > .bg-layers__base { background: var(--color-accent); }
.plexa-footer--tint-neutral   > .bg-layers__base { background: var(--color-neutral); }
.plexa-footer--tint-none      > .bg-layers__base { background: transparent; }

/* --------------------------------------------------------------------------
   Body band: stacked layout — one centered column.
   -------------------------------------------------------------------------- */

.plexa-footer__stack {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 1.25rem;
	text-align: center;
}

.plexa-footer__stack--align-left   { align-items: flex-start; text-align: left; }
.plexa-footer__stack--align-right  { align-items: flex-end; text-align: right; }

/* --------------------------------------------------------------------------
   Body band: the 12-column grid (columns | split | mega). Spans are DERIVED
   (Plexa_Footer_Renderer::derive_column_spans()) and arrive as a data
   attribute per column — never authored, never a class per span count beyond
   this fixed 1-12 table.
   -------------------------------------------------------------------------- */

.plexa-footer__grid {
	display: grid;
	grid-template-columns: repeat(12, 1fr);
	gap: 2rem 1.5rem;
	align-items: start;
}

.plexa-footer__col { min-width: 0; }

.plexa-footer__col[data-span="1"]  { grid-column: span 1; }
.plexa-footer__col[data-span="2"]  { grid-column: span 2; }
.plexa-footer__col[data-span="3"]  { grid-column: span 3; }
.plexa-footer__col[data-span="4"]  { grid-column: span 4; }
.plexa-footer__col[data-span="5"]  { grid-column: span 5; }
.plexa-footer__col[data-span="6"]  { grid-column: span 6; }
.plexa-footer__col[data-span="7"]  { grid-column: span 7; }
.plexa-footer__col[data-span="8"]  { grid-column: span 8; }
.plexa-footer__col[data-span="9"]  { grid-column: span 9; }
.plexa-footer__col[data-span="10"] { grid-column: span 10; }
.plexa-footer__col[data-span="11"] { grid-column: span 11; }
.plexa-footer__col[data-span="12"] { grid-column: span 12; }

.plexa-footer__col--identity-row { grid-column: 1 / -1; }

@media (max-width: 47.999rem) {
	/* One column on a phone, whatever the derived span was. */
	.plexa-footer__grid { grid-template-columns: 1fr; gap: 1.75rem; }
	.plexa-footer__col  { grid-column: auto !important; }
}

/* --------------------------------------------------------------------------
   Slot 1 — identity
   -------------------------------------------------------------------------- */

.plexa-footer__identity {
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
}

.plexa-footer__identity img,
.plexa-footer__identity .custom-logo {
	max-height: 2.5rem;
	width: auto;
}

.plexa-footer__site-name {
	font-size: var(--text-h4-size, 1.25rem);
	font-weight: 700;
	color: var(--pf-content, var(--color-base-content));
	text-decoration: none;
}

.plexa-footer__blurb {
	margin: 0;
	max-width: 34ch;
	font-size: var(--text-small-size, 0.875rem);
	line-height: 1.6;
	opacity: 0.75;
}

.plexa-footer__stack .plexa-footer__blurb { max-width: 46ch; margin-inline: auto; }

/* --------------------------------------------------------------------------
   Slot 2 — nav groups. Headings are always h2 (SPEC §6, invariant 2).
   -------------------------------------------------------------------------- */

.plexa-footer__nav-group {
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
}

.plexa-footer__group-heading {
	margin: 0;
	font-size: var(--text-caption-size, 0.75rem);
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	opacity: 0.7;
}

.plexa-footer__nav-list {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: var(--text-small-size, 0.875rem);
}

.plexa-footer__nav-list a {
	color: var(--pf-content, var(--color-base-content));
	text-decoration: none;
	opacity: 0.7;
}

.plexa-footer__nav-list a:hover,
.plexa-footer__nav-list a:focus-visible {
	opacity: 1;
}

/* --------------------------------------------------------------------------
   Slot 3 — contact
   -------------------------------------------------------------------------- */

.plexa-footer__contact-list {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: var(--text-small-size, 0.875rem);
}

.plexa-footer__contact-link {
	color: var(--pf-content, var(--color-base-content));
	text-decoration: none;
	opacity: 0.8;
}

.plexa-footer__contact-link:hover,
.plexa-footer__contact-link:focus-visible {
	opacity: 1;
}

.plexa-footer__contact-text { opacity: 0.8; white-space: pre-line; }

.plexa-footer__contact-with-map {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	gap: 1rem 1.5rem;
}

/* --------------------------------------------------------------------------
   Media — map-beside-contact (SPEC §4; a card, not a raster static map —
   see class-footer-parts.php's docblock).
   -------------------------------------------------------------------------- */

.plexa-footer__map {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	padding: 0.5rem 0.875rem;
	border-radius: var(--radius-field, 0.5rem);
	border: 1px solid color-mix(in oklch, var(--pf-content, var(--color-base-content)) 20%, transparent);
	color: var(--pf-content, var(--color-base-content));
	font-size: var(--text-small-size, 0.875rem);
	text-decoration: none;
	opacity: 0.85;
}

.plexa-footer__map:hover,
.plexa-footer__map:focus-visible { opacity: 1; }

.plexa-footer__map-pin { width: 1rem; height: 1rem; flex: 0 0 auto; }

/* --------------------------------------------------------------------------
   Slot 4 — social
   -------------------------------------------------------------------------- */

.plexa-footer__social {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem 1rem;
	margin-block-start: 0.25rem;
}

.plexa-footer__social-link {
	display: inline-flex;
	font-size: 1.25rem;
	color: var(--pf-content, var(--color-base-content));
	text-decoration: none;
	opacity: 0.7;
}

.plexa-footer__social-link:hover,
.plexa-footer__social-link:focus-visible {
	opacity: 1;
}

/* --------------------------------------------------------------------------
   Slot 5 — action (cta | newsletter). Cap or body, exactly one home.
   -------------------------------------------------------------------------- */

.plexa-footer__cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0.625rem 1.5rem;
	border-radius: var(--radius-field, 0.5rem);
	font-size: var(--text-small-size, 0.875rem);
	font-weight: 600;
	text-decoration: none;
	background-color: var(--color-primary);
	color: var(--color-primary-content);
}

.plexa-footer__cta:hover,
.plexa-footer__cta:focus-visible { filter: brightness(1.08); }

.plexa-footer__band--cap .plexa-footer__cta {
	background-color: var(--pf-content, var(--color-base-content));
	color: var(--color-base-100);
}

.plexa-footer__newsletter {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	width: 100%;
	max-width: 26rem;
}

.plexa-footer__newsletter-label {
	font-size: var(--text-caption-size, 0.75rem);
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	opacity: 0.8;
}

.plexa-footer__newsletter-row {
	display: flex;
	gap: 0.5rem;
}

.plexa-footer__newsletter-input {
	flex: 1 1 auto;
	min-width: 0;
	padding: 0.5rem 0.75rem;
	border-radius: var(--radius-field, 0.5rem);
	border: 1px solid color-mix(in oklch, var(--pf-content, var(--color-base-content)) 25%, transparent);
	background: color-mix(in oklch, var(--color-base-100) 92%, transparent);
	color: var(--color-base-content);
	font-size: var(--text-small-size, 0.875rem);
}

.plexa-footer__newsletter-submit {
	flex: 0 0 auto;
	padding: 0.5rem 1.25rem;
	border: 0;
	border-radius: var(--radius-field, 0.5rem);
	background-color: var(--pf-content, var(--color-base-content));
	color: var(--color-base-100);
	font-size: var(--text-small-size, 0.875rem);
	font-weight: 600;
	cursor: pointer;
}

.plexa-footer__group--action { margin-block-start: 0.5rem; }
.plexa-footer__col--action   { margin-block-start: 0.5rem; }

/* --------------------------------------------------------------------------
   Slot 6 — legal (band B). Copyright always renders (invariant 1); small
   text, low-alpha links (invariant 9).
   -------------------------------------------------------------------------- */

.plexa-footer__group {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 0.5rem 1.25rem;
}

.plexa-footer__copyright,
.plexa-footer__credit { opacity: 0.7; }

.plexa-footer__legal-nav {
	display: flex;
	flex-wrap: wrap;
	gap: 0.375rem 1rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.plexa-footer__legal-nav a {
	color: var(--pf-content, var(--color-base-content));
	text-decoration: none;
	opacity: 0.7;
}

.plexa-footer__legal-nav a:hover,
.plexa-footer__legal-nav a:focus-visible {
	opacity: 1;
}

/* --------------------------------------------------------------------------
   Local hover-underline (DESIGN.md "the voice, in CSS terms"): hvr-underline-
   from-left re-implemented at 250ms so the footer never depends on
   hover-effects.css being loaded on a page that carries one.
   -------------------------------------------------------------------------- */

.plexa-footer__nav-list a,
.plexa-footer__contact-link,
.plexa-footer__legal-nav a,
.plexa-footer__social-link,
.plexa-footer__nav-group .plexa-footer__nav-terminal,
.plexa-footer__statement-link {
	position: relative;
	display: inline-block;
}

.plexa-footer__nav-list a::after,
.plexa-footer__contact-link::after,
.plexa-footer__legal-nav a::after,
.plexa-footer__social-link::after,
.plexa-footer__nav-group .plexa-footer__nav-terminal::after,
.plexa-footer__statement-link::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: -0.15em;
	height: 1px;
	background: currentColor;
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 250ms ease-out;
}

.plexa-footer__nav-list a:hover::after,
.plexa-footer__nav-list a:focus-visible::after,
.plexa-footer__contact-link:hover::after,
.plexa-footer__contact-link:focus-visible::after,
.plexa-footer__legal-nav a:hover::after,
.plexa-footer__legal-nav a:focus-visible::after,
.plexa-footer__social-link:hover::after,
.plexa-footer__social-link:focus-visible::after,
.plexa-footer__nav-group .plexa-footer__nav-terminal:hover::after,
.plexa-footer__nav-group .plexa-footer__nav-terminal:focus-visible::after,
.plexa-footer__statement-link:hover::after,
.plexa-footer__statement-link:focus-visible::after {
	transform: scaleX(1);
}

/* Social icons carry no visible underline (they are icons, not text) — the
   shared rule above still gives them the positioning context they need for
   nothing else; opacity alone marks their hover/focus state. */
.plexa-footer__social-link::after { content: none; }

/* --------------------------------------------------------------------------
   Focus — every link and control in the footer, one rule (DESIGN.md).
   -------------------------------------------------------------------------- */

.plexa-footer a:focus-visible,
.plexa-footer button:focus-visible,
.plexa-footer input:focus-visible {
	outline: 2px solid var(--color-primary);
	outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   Identity — display: wordmark | big-type | statement (logo is unchanged,
   above). big-type and statement are DECORATIVE (aria-hidden / a plain
   sentence); neither is ever a heading (SPEC §6, invariant 2).
   -------------------------------------------------------------------------- */

.plexa-footer__wordmark {
	display: inline-block;
	font-family: var(--font-heading, inherit);
	font-size: 2rem;
	font-weight: 700;
	line-height: 1.1;
	color: var(--pf-content, var(--color-base-content));
	text-decoration: none;
}

.plexa-footer__big-type {
	margin: 0;
	max-width: 100%;
	font-family: var(--font-heading, inherit);
	font-size: clamp(2.5rem, 7vw, 6.5rem);
	font-weight: 800;
	letter-spacing: -0.03em;
	line-height: 0.9;
	white-space: normal;
	text-wrap: balance;
	overflow-wrap: anywhere;
	color: color-mix(in oklch, var(--pf-content, var(--color-base-content)) 12%, transparent);
}

.plexa-footer__big-type--solid {
	color: var(--pf-content, var(--color-base-content));
}

.plexa-footer__statement {
	margin: 0;
	max-width: 28ch;
	font-family: var(--font-heading, inherit);
	font-size: clamp(1.75rem, 5vw, 3.25rem);
	line-height: 1.05;
	letter-spacing: -0.02em;
}

.plexa-footer__stack .plexa-footer__statement { max-width: 36ch; margin-inline: auto; }

.plexa-footer__statement-meta {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.5rem 1.5rem;
	margin-block-start: 1.25rem;
	padding-block-start: 0.75rem;
	border-top: 1px solid color-mix(in oklch, var(--pf-content, var(--color-base-content)) 10%, transparent);
	font-size: var(--text-small-size, 0.875rem);
}

.plexa-footer__statement-link {
	color: var(--pf-content, var(--color-base-content));
	text-decoration: none;
	opacity: 0.85;
}

.plexa-footer__statement-link:hover,
.plexa-footer__statement-link:focus-visible { opacity: 1; }

/* --------------------------------------------------------------------------
   Nav — terminal link (DESIGN.md: last item, accent).
   -------------------------------------------------------------------------- */

.plexa-footer__nav-group .plexa-footer__nav-terminal {
	font-weight: 600;
	color: var(--color-primary);
	opacity: 1;
	text-decoration: none;
}

/* --------------------------------------------------------------------------
   Contact — badges (quiet chips) and the `cards` layout (location grid).
   -------------------------------------------------------------------------- */

.plexa-footer__badges {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin-block-start: 0.75rem;
}

.plexa-footer__badge {
	display: inline-flex;
	align-items: center;
	gap: 0.375rem;
	padding: 0.375rem 0.75rem;
	border: 1px solid color-mix(in oklch, var(--pf-content, var(--color-base-content)) 20%, transparent);
	border-radius: var(--radius-field, 999px);
	font-size: var(--text-caption-size, 0.75rem);
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

.plexa-footer__badge-label { opacity: 0.6; }
.plexa-footer__badge-value { font-weight: 600; }
.plexa-footer__badge-star { color: var(--pf-content, var(--color-base-content)); }

.plexa-footer__contact-cards {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
	gap: 1rem;
	margin-block-start: 0.75rem;
}

.plexa-footer__contact-card {
	border: 1px solid color-mix(in oklch, var(--pf-content, var(--color-base-content)) 15%, transparent);
	border-radius: var(--radius-box, 0.75rem);
	padding: 1.25rem;
}

.plexa-footer__contact-card-label {
	display: block;
	margin-block-end: 0.5rem;
	font-size: var(--text-caption-size, 0.75rem);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	opacity: 0.6;
}

.plexa-footer__contact-card-value {
	font-size: var(--text-small-size, 0.875rem);
}

/* --------------------------------------------------------------------------
   Cap — marquee (Ft8, adapted) and headline (CTA band).
   -------------------------------------------------------------------------- */

.plexa-footer__marquee {
	overflow: hidden;
	width: 100%;
}

.plexa-footer__marquee-track {
	display: flex;
	width: max-content;
	white-space: nowrap;
	animation: plexa-footer-marquee 40s linear infinite;
}

.plexa-footer__marquee:hover .plexa-footer__marquee-track,
.plexa-footer__marquee:focus-within .plexa-footer__marquee-track {
	animation-play-state: paused;
}

.plexa-footer__marquee-group {
	font-family: var(--font-heading, inherit);
	font-weight: 700;
	letter-spacing: 0.06em;
	font-size: clamp(1rem, 2.5vw, 1.5rem);
	padding-inline-end: 1.5rem;
}

@keyframes plexa-footer-marquee {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}

.plexa-footer__headline-band {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 1rem 1.5rem;
	width: 100%;
}

.plexa-footer__headline {
	margin: 0;
	font-family: var(--font-heading, inherit);
	font-size: clamp(1.5rem, 3vw, 2.25rem);
	font-weight: 700;
}

.plexa-footer__headline-actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1rem 1.5rem;
}

.plexa-footer__headline-phone {
	font-family: var(--font-heading, inherit);
	font-weight: 700;
	color: var(--pf-content, var(--color-base-content));
	text-decoration: none;
}

@media (min-width: 64rem) {
	.plexa-footer__headline-band { flex-wrap: nowrap; justify-content: space-between; }
}

/* --------------------------------------------------------------------------
   Legal — back_to_top.
   -------------------------------------------------------------------------- */

.plexa-footer__back-to-top {
	margin-inline-start: auto;
	color: var(--pf-content, var(--color-base-content));
	text-decoration: none;
	opacity: 0.75;
}

.plexa-footer__back-to-top:hover,
.plexa-footer__back-to-top:focus-visible { opacity: 1; }

/* JS-free smooth scroll for the bare `href="#"` link, scoped so no other
   page gains it just because it happens to carry a footer with no back-link. */
html:has(.plexa-footer__back-to-top) {
	scroll-behavior: smooth;
}

/* --------------------------------------------------------------------------
   Surface — fade: top (the page-bleed device, tiers 1 and 2). Sits above the
   base/pattern/overlay layers, below bg-layers__content.
   -------------------------------------------------------------------------- */

.bg-layers__fade {
	position: absolute;
	inset: 0;
	background: linear-gradient(to bottom, var(--bg-ground, var(--color-base-200)) 0, transparent 8rem);
	pointer-events: none;
}

/* --------------------------------------------------------------------------
   Reduced motion (DESIGN.md): no transitions, no marquee.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	.plexa-footer__nav-list a::after,
	.plexa-footer__contact-link::after,
	.plexa-footer__legal-nav a::after,
	.plexa-footer__nav-group .plexa-footer__nav-terminal::after,
	.plexa-footer__statement-link::after {
		transition: none;
	}
	html:has(.plexa-footer__back-to-top) {
		scroll-behavior: auto;
	}
	.plexa-footer__marquee-track {
		animation: none;
	}
	.plexa-footer__marquee {
		overflow: visible;
	}
	.plexa-footer__marquee-track {
		flex-wrap: wrap;
		width: auto;
		white-space: normal;
	}
	.plexa-footer__marquee-group:nth-child(n+2) {
		display: none;
	}
}

/* ==========================================================================
   FOOTER — parts library (footer@2.0), Plexa_Default_Footer
   Rendered by includes/parts/footers/class-default-footer.php +
   includes/parts/bars/class-bar.php + class-footer-bar.php. Distinct from
   the footer@1.0 `.plexa-footer` rules above — do not merge the two: the
   parts-library footer is bar/column driven (`.plexa-footer-bar`, `.bar`,
   `.grid`), not the band/slot markup footer@1.0 renders.

   Fixes docs/superpowers/plans/2026-09-12-footer-render-fixes.md task B:
   daisyUI's built `[data-theme]{background-color:var(--root-bg)}` paints
   every bar opaque over the footer's own effect layer (backgrounds.css);
   spacing was doubled between the wrapper, the bar margin/padding and
   `.bar-item`'s own margin (now zeroed by task A in class-part.php /
   class-bar.php / class-footer-bar.php). No colour here: tokens and
   color-mix of tokens only (skills/footer/DESIGN.md "the voice, in CSS
   terms").
   ========================================================================== */

/* Bars whose mode matches the footer's get `plexa-footer-bar--clear`
   (task A, class-footer-bar.php) so daisyUI's `[data-theme]` background
   doesn't hide the footer's own gradient/pattern layer underneath.
   Specificity 0,2,0 beats `[data-theme]`'s 0,1,0. */
.plexa-default-footer .plexa-footer-bar--clear {
	background-color: transparent;
}

/* Legal bar tint — a faint content-tinted ground so the legal strip reads
   as a distinct band even when the hairline above it is hard to see over a
   dark or gradient ground. Must win over `--clear` (same rule, higher
   specificity than the single-class `--clear` selector above; the combined
   selector below covers a bar that is both `--clear` and `height: xs`). */
.plexa-default-footer .plexa-footer-bar.bar--height-xs,
.plexa-default-footer .plexa-footer-bar--clear.bar--height-xs {
	background-color: color-mix(in oklch, var(--color-base-content) 4%, transparent);
}

/* Bars-between hairline — `.plexa-footer-bar`'s own border-bottom is
   registered at 10% in class-default-footer.php (not ours to edit); raise
   it to 15% here so it reads over dark/gradient grounds. */
.plexa-default-footer .plexa-footer-bar {
	border-bottom-color: color-mix(in oklch, var(--color-base-content) 15%, transparent);
}

/* Top join hairline — the seam between the footer and whatever sits above
   it. Raised from 10% to 15% for the same reason as the bars-between
   hairline above. */
.plexa-default-footer {
	border-top: 1px solid color-mix(in oklch, var(--color-base-content) 15%, transparent);
}

/* Bar padding, replacing the bar's own zeroed padding (task A) and beating
   the `py-8` utility class Plexa_Bar adds for `position: center`
   (utility 0,1,0; this rule 0,2,0 — wins without !important). */
.plexa-default-footer .plexa-footer-bar {
	padding-block: clamp(2rem, 3.5vw, 3rem);
}

.plexa-default-footer .plexa-footer-bar.bar--height-xs {
	padding-block: 1rem;
}

.plexa-default-footer .plexa-footer-bar.bar--height-sm {
	padding-block: clamp(1.25rem, 2.5vw, 2rem);
}

/* Grid gap of the bar's own column grid only (contained layout wraps it in
   `.container`, full layout does not) — never a component's inner grid. */
.plexa-default-footer .plexa-footer-bar > .container > .grid,
.plexa-default-footer .plexa-footer-bar > .grid {
	column-gap: 2.5rem;
	row-gap: 1.25rem;
}

/* Below Tailwind's md (48rem) every footer column is col-span-12, so the
   column gap only adds width: 11 gaps x 2.5rem = 27.5rem, wider than a
   phone, and the grid overflowed the viewport (clipped buttons and legal
   links on the right). Zero it there; row-gap keeps the stacked rhythm. */
@media (max-width: 47.999rem) {
	.plexa-default-footer .plexa-footer-bar > .container > .grid,
	.plexa-default-footer .plexa-footer-bar > .grid {
		column-gap: 0;
	}
}

/* A column with `cols_sm: 6` (footer research FG7) sits two-up below 768:
   two link lists share a row. The phone grid's column gap is zero (above),
   so give it back only where a column actually sits half-width, or the two
   lists touch. 1.5rem x 11 gaps still fits a 288px (320 viewport) grid. */
@media (max-width: 47.999rem) {
	.plexa-default-footer .plexa-footer-bar .grid:has(> .col-span-6:not(.col-span-12)) {
		column-gap: 1.5rem;
	}
}

/* Footer headings (footer research FG2, SPEC §6): a column heading is an h2
   in the document outline and the same small size as every other footer
   heading; the Footer_Bar's own id-scoped rule sizes h3 only. */
.plexa-default-footer h2,
.plexa-default-footer .nav-links-heading {
	font-size: var(--text-size-base, 1rem);
	font-weight: 600;
	line-height: 1.5;
	margin: 0 0 0.5rem;
}

/* A horizontal Nav_Links (FG3) in the legal strip: the links sit on one
   baseline, each with a 24px-tall target (FB-A5) at the strip's 12px. On a
   phone the component's own CSS makes it 44px (class-nav-links-component.php,
   site pack finding 12). */
.plexa-default-footer .bar--height-xs .nav-links-link {
	display: inline-flex;
	align-items: center;
	min-height: 24px;
}
.plexa-default-footer .bar--height-xs .nav-links-item {
	margin-bottom: 0;
}

/* Belt-and-braces top alignment for column content (task A already
   defaults bars/columns to top-aligned; this holds it even if a column's
   own flex settings drift). */
.plexa-default-footer .plexa-footer-bar > .container > .grid > [class*="col-span-"],
.plexa-default-footer .plexa-footer-bar > .grid > [class*="col-span-"] {
	justify-content: flex-start;
}

/* Legal strip typography. */
.plexa-default-footer .bar--height-xs {
	font-size: var(--text-xs, 0.75rem);
}

/* Newsletter, preset inline (class-newsletter-component.php): wrapper is
   `.newsletter.flex.items-center.gap-4`, form is
   `.newsletter__form.flex.gap-2.flex-1` holding the input and button, and
   the promise line is `.newsletter__description` (rendered after the form
   for this preset). Below 40rem the input+button row no longer fits beside
   the heading label, so wrap everything to one column and let the input
   and the promise line each claim a full row. */
@media (max-width: 40rem) {
	.plexa-default-footer .newsletter {
		flex-wrap: wrap;
	}
	.plexa-default-footer .newsletter__form {
		flex-wrap: wrap;
	}
	.plexa-default-footer .newsletter__form .newsletter__input {
		flex: 1 1 100%;
		min-width: 0;
	}
	.plexa-default-footer .newsletter__description {
		flex: 1 1 100%;
		width: 100%;
	}
}

/* Border effect, top edge only. A footer bar with `border_effect` renders a
   `.bg-layers__border` overlay div (class-part.php render_border_effect_layer());
   for the gradient techniques (assets/css/borders/base.css) that overlay's
   ::before paints a ring by masking out its own content-box from its
   border-box, with the ring's width set by `padding: var(--border-fx-width)`
   on all four sides. Giving that padding top-only leaves border-box and
   content-box coincident on the other three sides, so the mask cancels out
   there and only the top strip remains visible — a wraparound frame doesn't
   read as a footer accent. */
.plexa-default-footer .plexa-footer-bar .bg-layers__border[class*="border-fx-gradient"]::before {
	padding: var(--border-fx-width, 2px) 0 0;
}

/* --------------------------------------------------------------------------
   Footer review round 1 (2026-09-28) — one contact-row treatment, links that
   look like links, the link row on the container edge, the newsletter band
   heading, and the phone's left-aligned rows. Footer-scoped: the headers
   carry the same Contact_Group and Hours presets and stay as approved.
   -------------------------------------------------------------------------- */

/* #2 One contact row: every icon — call, email, area, address, directions,
   hours — is the accent colour in a fixed box, so the text beside it starts
   on one edge whatever the glyph's own width (the address text sat at 118px,
   the call text at 122px). One gap for every icon row; the row sits on its
   first baseline, so a wrapping value keeps its icon on the first line. */
.plexa-default-footer .contact-group i,
.plexa-default-footer .hours i {
	color: var(--color-primary);
	flex: none;
	width: 1.25em;
	text-align: center;
	line-height: inherit;
}
.plexa-default-footer .contact-group__item:not(.flex-col),
.plexa-default-footer .hours.flex:not(.flex-col) {
	align-items: baseline;
	column-gap: 0.625rem;
}

/* #3 An inline row's label keeps one line ("Service area:" wrapped into a
   two-line label column on a 412 phone); the value wraps beside it. */
.plexa-default-footer .contact-group__label {
	white-space: nowrap;
	flex: none;
}
.plexa-default-footer .contact-group__item > .contact-group__value {
	min-width: 0;
}

/* #4 A contact value that is a link ("Call (256) 555-0141", "Get
   directions") is styled as the footer's links, the nav links' treatment. */
.plexa-default-footer .contact-group__content > a.contact-group__value {
	color: var(--color-primary);
	text-decoration: none;
}

/* A contact value that is a link, inline or stacked (the directory's
   Call/Email rows), is a 44x44 target at least (site pack finding 12: 28px
   at 412): an invisible box centred on the link, never smaller than it;
   nothing moves. */
.plexa-default-footer a.contact-group__value {
	position: relative;
}
.plexa-default-footer a.contact-group__value::before {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 100%;
	height: 100%;
	min-width: 2.75rem;
	min-height: 2.75rem;
	translate: -50% -50%;
}
.plexa-default-footer .contact-group__content > a.contact-group__value:hover,
.plexa-default-footer .contact-group__content > a.contact-group__value:focus-visible {
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

/* #5 A right-aligned column's link row ends on the container edge, and a
   row that wraps wraps from the right. */
.plexa-default-footer .items-end .nav-links-nav--horizontal .nav-links-list {
	justify-content: flex-end;
}

/* #7 The newsletter band's heading is the band's heading, on the footer
   heading scale, not a 16px column label. */
.plexa-default-footer .footer-signup-bar .text-block h2 {
	font-size: var(--text-size-xl, 1.25rem);
	font-weight: 700;
	line-height: 1.3;
}
@media (min-width: 64rem) {
	.plexa-default-footer .footer-signup-bar .text-block h2 {
		font-size: var(--text-size-2xl, 1.5rem);
	}
}

/* #5, #8 Below 768 every column stacks full width, so a right-aligned column
   (the legal links, the page-link row) reads left, on the copyright's and the
   wordmark's edge. Desktop keeps copyright left, links right. */
@media (max-width: 47.999rem) {
	.plexa-default-footer .plexa-footer-bar .grid > .items-end {
		align-items: flex-start;
	}
	.plexa-default-footer .plexa-footer-bar .grid > .items-end > .bar-item.justify-end {
		justify-content: flex-start;
	}
	.plexa-default-footer .items-end .nav-links-nav--horizontal .nav-links-list {
		justify-content: flex-start;
	}
}
