/**
 * Parcel-grid motif.
 *
 * ---------------------------------------------------------------------------
 * WHY THIS EXISTS
 * ---------------------------------------------------------------------------
 * The design system permits exactly one piece of non-wordmark image content:
 *
 *   "simple flat geographic/map-line motifs (thin single-weight lines
 *    suggesting parcel/grid boundaries) used sparingly as background texture
 *    at low opacity - never literal photographic maps."
 *
 * It was used zero times. Every page was four stacked rectangles of flat
 * colour, which is why the site read as generic despite the type, palette and
 * spacing all being correct: there was no visual device anywhere that was not
 * a rectangle. For a firm called Dot Map, a parcel grid with dots at its
 * intersections is the one device the brand actually owns.
 *
 * ---------------------------------------------------------------------------
 * HOW IT STAYS INSIDE THE RULES
 * ---------------------------------------------------------------------------
 * - Thin single-weight lines only. No fills, no gradients inside the motif,
 *   no photography, nothing that reads as a literal map.
 * - Low opacity, and MASKED OFF THE TEXT COLUMN entirely, on whichever axis
 *   the layout is currently using. That second clause is the one that matters
 *   and it is the one this comment used to be missing.
 *
 *   What stood here said the lines were "6% white on navy, which cannot lift
 *   the local luminance enough to matter". Two things were wrong with it.
 *   The number was fiction — the tile strokes #ffffff and the hero layer
 *   carried `opacity: 1`, so the hero rendered as full-strength white graph
 *   paper straight through the lede. And the reasoning was wrong even at the
 *   number it claimed: white at 6% over rgb(26,89,82) gives rgb(39,98,92),
 *   which is L 0.0797 -> 0.1030 and takes ink-200 body copy from 4.80:1 to
 *   4.07:1. A low-alpha WHITE layer lifts luminance far faster than its alpha
 *   suggests, because it is moving toward the top of the curve.
 *
 *   So contrast here is guaranteed by the mask, not by the opacity, and the
 *   guarantee is checked by sampling rendered pixels at fifteen phases of the
 *   cycle rather than by arithmetic on the gradient stops.
 * - Irregular subdivisions rather than a uniform lattice. A perfect grid reads
 *   as graph paper; parcels are what a county GIS layer actually looks like.
 * - Decorative only. Inlined as a data URI on a background, so it is invisible
 *   to assistive technology and carries no semantic weight.
 *
 * @package dotmap
 */

/* ---------------------------------------------------------------------------
 * The tile.
 *
 * 320x320, irregular parcel subdivision, dots at four intersections. Encoded
 * once as a custom property so the hero, the CTA band and any future dark
 * surface share one definition rather than three near-copies.
 * ------------------------------------------------------------------------ */

:root {
	--motif-parcel:
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='320' viewBox='0 0 320 320'%3E%3Cg fill='none' stroke='%23ffffff' stroke-width='1'%3E%3Cpath d='M0 78h320M0 206h320M104 0v320M232 0v320'/%3E%3Cpath d='M104 140h128M168 78v62M0 262h104M52 206v56M232 36h88M276 0v36M232 262h88M276 206v56'/%3E%3C/g%3E%3Cg fill='%23ffffff'%3E%3Ccircle cx='104' cy='78' r='2.5'/%3E%3Ccircle cx='232' cy='206' r='2.5'/%3E%3Ccircle cx='168' cy='140' r='2.5'/%3E%3Ccircle cx='52' cy='262' r='2.5'/%3E%3C/g%3E%3C/svg%3E");
}

/* ---------------------------------------------------------------------------
 * Hero.
 *
 * The motif rides in a ::before rather than a second background-image on the
 * container itself, because the container's background-image is already the
 * drifting gradient and the two would fight over background-size and the
 * animation. A separate layer also lets the motif fade toward the text column
 * so it never sits directly behind the headline.
 * ------------------------------------------------------------------------ */

body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child {
	position: relative;
	isolation: isolate;
}

body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	pointer-events: none;
	/*
	 * THE SCRIM IS GONE, AND THE GRID WAS NEVER AT THE OPACITY THIS FILE
	 * CLAIMED.
	 *
	 * What used to be here was two layers in one declaration: the parcel grid
	 * and a navy wash running 0.95 alpha over the text column. The comment
	 * above it said the lines were "6% white on navy, which cannot lift the
	 * local luminance enough to matter". They were not. The tile strokes
	 * `%23ffffff` at full opacity, this element carried `opacity: 1`, and the
	 * only place 6% appeared was in the CTA band and footer rules further
	 * down. Rendered at 1440 the hero was pure-white graph paper drawn
	 * straight through the lede: white lines crossing grey body copy, four
	 * dots sitting inside the heading. It is the single ugliest thing in the
	 * before/after pair and it was invisible to every static check because the
	 * number the reviewer was checking against lived in a comment.
	 *
	 * Now: no wash at all — layer 2 in layout.css is MASKED off the text
	 * column rather than veiled, so nothing needs covering — and the grid runs
	 * at the 0.10 this file always said it did, faded out before it reaches
	 * the words. It is texture on the colour field, which is what the design
	 * system permits ("thin single-weight lines ... sparingly as background
	 * texture at low opacity"), not a layer over the type.
	 */
	background-image: var(--motif-parcel);
	background-size: 320px 320px;
	background-position: right -40px top -40px;
	background-repeat: repeat;
	opacity: 0.10;
	/*
	 * Faded off the text column on the same axis as layer 2's mask, and
	 * starting at the SAME 56%.
	 *
	 * The first cut started the fade at 40%, on the reasoning that the grid is
	 * only 10% white and arriving before the colour would soften the handoff.
	 * Measured, that was wrong in a way worth writing down: at 55% of the band
	 * the mask is 57% open, so 0.057 alpha of WHITE was landing on the last
	 * 40px of the lede's box. White at any alpha raises luminance fast —
	 * rgb(26,89,82) became rgb(39,98,92), L 0.0797 -> 0.1030 — and it dragged
	 * the lede's worst-case contrast from 4.80:1 to 4.07:1, under AA.
	 *
	 * A 10% decorative layer looked far too faint to matter. It was not, and
	 * nothing but sampling the rendered pixels would have caught it: the
	 * declaration is unremarkable and the contrast maths, done against the
	 * gradient stops alone, comes out clean.
	 */
	-webkit-mask-image: linear-gradient(90deg, transparent 0%, transparent 56%, #000 76%, #000 100%);
	mask-image: linear-gradient(90deg, transparent 0%, transparent 56%, #000 76%, #000 100%);
}

@media (max-width: 899px) {
	/*
	 * ROTATE WITH THE LAYOUT, exactly as layer 2's mask does in layout.css.
	 *
	 * This mask was horizontal at every width. Below 900px the hero's columns
	 * stack and the text goes full-bleed, so "the right 44% of the band" stops
	 * meaning "the part with no text in it" and starts meaning "the right-hand
	 * half of every line of copy". Measured at 390px: white grid lines at
	 * 0.10 landing on the lede, worst-case contrast 3.85:1.
	 *
	 * A mask expressed against one axis is only a contrast guarantee while the
	 * layout keeps that axis. Both masks now turn at the same breakpoint.
	 */
	body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child::before {
		-webkit-mask-image: linear-gradient(180deg, transparent 0%, transparent 64%, #000 84%, #000 100%);
		mask-image: linear-gradient(180deg, transparent 0%, transparent 64%, #000 84%, #000 100%);
	}
}


/* ---------------------------------------------------------------------------
 * CTA band
 *
 * NOT ON /contact/. The selector is positional -- "the last top-level
 * container" -- which is the CTA band on every page that HAS one. Contact
 * deliberately has none, because it is the destination; it has exactly two
 * containers, hero and content, so `:nth-last-child(1)` matched the CONTENT
 * section and painted the form area with the band's gradient. Excluding the
 * contact body class is the fix; a positional selector cannot tell the
 * difference on its own. — the same device, quieter, mirrored.
 *
 * Mirroring the origin stops the two dark bands on a page looking like the
 * same tile stamped twice.
 * ------------------------------------------------------------------------ */



/* ---------------------------------------------------------------------------
 * Reduced motion changes nothing here — the motif does not move. It is
 * deliberately static texture, not an animated background.
 *
 * Forced-colors mode DOES need it gone: a decorative line grid competes with
 * the system palette and carries no information worth keeping.
 * ------------------------------------------------------------------------ */

@media (forced-colors: active) {
	body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child::before,
}


/* ---------------------------------------------------------------------------
 * THE HERO PARCEL PANEL
 *
 * REBUILT. The previous version had two defects that together explain why the
 * operator saw no movement:
 *
 *   1. The panel a visitor actually LOOKS AT had `animation-name: none`. The
 *      only layer drifting was the full-bleed ::before at opacity 0.06, moving
 *      2.13 px/s -- invisible by construction. The visible element was static.
 *   2. `opacity: 0.34` on the panel created a stacking context that dimmed
 *      everything inside it, including the marker dot. The dot rendered
 *      rgb(42,99,92) instead of teal-300 rgb(95,199,183), and its pulse ring
 *      peaked at 0.102 alpha.
 *
 * Now the opacity lives on the GRID LAYER ONLY (::before), so the dot and the
 * traversing line render at full strength.
 *
 * Structure:
 *   panel          -> the traversing survey line (background-position)
 *   panel::before  -> the parcel grid, dimmed
 *   panel::after   -> the marker dot, full strength, pulsing
 * ------------------------------------------------------------------------ */

body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con:empty,
body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con > .e-con:nth-child(2):last-child {
	position: relative;
	overflow: hidden;
	/*
	 * A single 1px teal line crossing the panel. This is the one piece of
	 * motion a visitor will actually register: a hard edge travelling against
	 * a static grid. The gradient roll fails precisely because it has no edge
	 * -- every transition in it is a 267px soft ramp with nothing for motion
	 * detection to lock onto.
	 */
	background-image: linear-gradient(
		90deg,
		transparent 0%,
		transparent 49.6%,
		rgb(95 199 183 / 0.55) 49.9%,
		rgb(95 199 183 / 0.55) 50.1%,
		transparent 50.4%,
		transparent 100%
	);
	background-size: 240% 100%;
	background-repeat: no-repeat;
	background-position: 140% 0;
}

body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con:empty::before,
body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con > .e-con:nth-child(2):last-child::before {
	content: "";
	position: absolute;
	inset: 0;
	background-image: var(--motif-parcel);
	background-size: 200px 200px;
	background-position: center;
	background-repeat: repeat;
	/*
	 * 0.34 was tuned against a near-black ground. The panel now sits on the
	 * brightest part of layer 2 -- teal-300 at its peak -- where white lines
	 * at that strength stop reading as a survey grid and start reading as a
	 * haze over the colour. 0.20 keeps the lines legible against both ends
	 * of the cycle.
	 */
	opacity: 0.20;
	pointer-events: none;
}

/*
 * The marker. Full strength now -- it is no longer inside a 0.34 wrapper.
 */
body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con:empty::after,
body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con > .e-con:nth-child(2):last-child::after {
	content: "";
	position: absolute;
	left: 34%;
	bottom: 38%;
	width: 9px;
	height: 9px;
	border-radius: var(--radius-pill);
	background-color: var(--teal-300);
	pointer-events: none;
}

/* --- The traverse -------------------------------------------------------
 *
 * Travels across in the first 60% of the cycle, then rests off-canvas. A
 * continuous sweep reads as a scanner and gets annoying fast; a pass followed
 * by a pause reads as a survey line and stays calm.
 * ---------------------------------------------------------------------- */

@keyframes dm-panel-traverse {
	0%   { background-position: 140% 0; }
	60%  { background-position: -40% 0; }
	100% { background-position: -40% 0; }
}

html.dm-motion-ready body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con:empty,
html.dm-motion-ready body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con > .e-con:nth-child(2):last-child {
	animation: dm-panel-traverse 19s var(--ease-standard) infinite;
}

@keyframes dm-marker-pulse {
	0%   { box-shadow: 0 0 0 0 rgb(95 199 183 / 0.45); }
	70%  { box-shadow: 0 0 0 20px rgb(95 199 183 / 0); }
	100% { box-shadow: 0 0 0 0 rgb(95 199 183 / 0); }
}

html.dm-motion-ready body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con:empty::after,
html.dm-motion-ready body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con > .e-con:nth-child(2):last-child::after {
	animation: dm-marker-pulse 4.5s var(--ease-out) infinite;
}

@media (max-width: 767px) {
	body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con:empty::before,
	body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con > .e-con:nth-child(2):last-child::before {
		opacity: 0.22;
		background-size: 150px 150px;
	}
}

/*
 * DEGRADE, DO NOT DELETE.
 *
 * `background-image: none` used to be in this block. Under reduced motion it
 * deleted the survey line AND, paired with the same declaration on the hero in
 * layout.css, left a visitor with that setting looking at flat navy with no
 * trace that the design has a colour field at all. Reduced motion means stop
 * moving it. Forced colours is the only state where removing the image is
 * right, because the system palette replaces the author's ground outright.
 */
@media (prefers-reduced-motion: reduce) {html:not(.dm-motion-opt-in) body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con:empty,
	html:not(.dm-motion-opt-in) body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con > .e-con:nth-child(2):last-child,
	html:not(.dm-motion-opt-in) body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con:empty::after,
	html:not(.dm-motion-opt-in) body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con > .e-con:nth-child(2):last-child::after {
		animation: none;
	}
}

@media (forced-colors: active) {
	body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con:empty,
	body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con > .e-con:nth-child(2):last-child,
	body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con:empty::after,
	body.dm-page .elementor:not(.elementor-location-header):not(.elementor-location-footer) > .e-con:first-child .e-con > .e-con:nth-child(2):last-child::after {
		animation: none;
		background-image: none;
	}
}

/* ---------------------------------------------------------------------------
 * CARD INDEX
 *
 * No CSS needed. The index is a real widget emitted by card_index() in the
 * generator -- a teal mono numeral above the card title -- so it is styled
 * through Elementor's own per-element CSS like any other heading.
 *
 * An earlier draft of this file added a hairline "corner bracket" here. It was
 * removed before shipping: the first rule set `position: relative` on every
 * pair of sibling headings site-wide for no visual effect, and the second only
 * added padding. Both were no-ops dressed as design. The numeral alone does
 * the job the bracket was meant to do.
 * ------------------------------------------------------------------------ */


/* ---------------------------------------------------------------------------
 * MARKER PULSE -- defined once, further up.
 *
 * A SECOND @keyframes dm-marker-pulse used to sit here with different
 * values (18px/0.30 against the first copy's 20px/0.45) plus a second copy
 * of the gated rule. Duplicate @keyframes do not merge: the last one in
 * source order wins outright, so the pulse everyone was reading at the top
 * of this file was not the pulse the browser ran. Removed rather than
 * reconciled -- one definition, one place.
 * ------------------------------------------------------------------------ */


/* ---------------------------------------------------------------------------
 * THE FIELD CASCADES TO EVERY DARK SURFACE
 *
 * The site has three dark surfaces and, until now, three unrelated treatments:
 *   hero      rolling gradient + parcel grid
 *   CTA band  flat navy-800, no gradient, no motion
 *   footer    flat navy-950, no motif at all
 *
 * That is the other half of "the gradient is not cascading" -- it wasn't. The
 * same field now runs through all three, slowing as it goes down the page so
 * the hero stays the loudest surface.
 *
 * SAFE TO ANIMATE OUTSIDE THE HERO only because hero.js now puts
 * .dm-motion-paused on <html> rather than on the hero element. Before that
 * change, hero.contains(ctaBand) === false meant a loop down here would have
 * been unreachable by the pause control -- WCAG 2.2.2 broken by adding polish.
 * ------------------------------------------------------------------------ */



/* The footer takes the grid, static. A third moving surface would be noise. */
.dm-page .dm-site-footer {
	position: relative;
	isolation: isolate;
}

.dm-page .dm-site-footer::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image: var(--motif-parcel);
	background-size: 320px 320px;
	background-position: right -80px center;
	background-repeat: repeat;
	opacity: 0.05;
	-webkit-mask-image: linear-gradient(90deg, transparent 0%, transparent 45%, #000 88%);
	mask-image: linear-gradient(90deg, transparent 0%, transparent 45%, #000 88%);
	pointer-events: none;
}

@media (forced-colors: active) {
	.dm-page .dm-site-footer::before {
		display: none;
	}
}


/* ===========================================================================
 * FLOATING SURVEY MARKS
 *
 * Fourteen map-line marks drifting up through the hero band across five depth
 * tiers. Shapes, tier assignments and every measured number are in
 * assets/js/float.js; this file moves them and applies the depth.
 *
 * ---------------------------------------------------------------------------
 * THE THREE THINGS THAT WERE WRONG, AND THE THREE RULES THAT FIX THEM
 * ---------------------------------------------------------------------------
 *
 * 1. THEY WERE FILLED, NOT STROKED.
 *
 *    float.js sets `fill="none"` on the <svg>. A presentation attribute has
 *    ZERO specificity -- lower than any stylesheet rule -- so it lost to
 *    base.css's `body.dm-page svg { fill: currentColor }` (0,2,1), which then
 *    inherited down to every path and circle. Computed fill on a mark was
 *    rgb(95 199 183), not `none`.
 *
 *    Every mark was therefore rendering as a solid silhouette: the pin a
 *    teardrop blob, the parcel a filled pentagon, the reticle a filled disc
 *    with four stray ticks. The one clue visible at size was that the
 *    reticle's ticks -- an open path enclosing no area -- drew correctly while
 *    its ring did not.
 *
 *    `fill: none` below is a real declaration and wins. Do not move it back to
 *    the attribute.
 *
 * 2. THE AURORA WAS PAINTED OVER THEM.
 *
 *    `.dm-float`, the hero's `::before` and the hero's `::after` all sat at
 *    z-index -1 in the same stacking context. Among equal z-index siblings
 *    paint order is tree order, and a `::after` is by definition the last
 *    child -- so the saturated aurora painted ON TOP of the marks.
 *
 *    The aurora is opaque wherever its own mask is opaque, which is from 76%
 *    of the band rightward. So the marks were not merely dim out there, they
 *    were covered. Measured on the live band: they were only ever visible
 *    between x=798 and x=1084 of a 1425px band, fading the whole way.
 *
 *    layout.css now puts the aurora at z-index -2. Paint order is background
 *    gradient, aurora, marks, content.
 *
 * 3. THEY WERE TEAL ON TEAL.
 *
 *    The mark colour was --teal-300 (#5fc7b7), which is one of the aurora's
 *    own stops. As the gradient sweeps to its bright band the mark and the
 *    ground converge. Computed across the sweep at the shipped 0.20 alpha:
 *
 *        ground rgb(31 87 91)     contrast 1.366   delta 22/255
 *        ground rgb(51 109 124)   contrast 1.266   delta 18/255
 *        ground rgb(70 139 152)   contrast 1.150   delta 12/255
 *        ground rgb(78 159 162)   contrast 1.092   delta  8/255
 *        ground rgb(86 179 172)   contrast 1.043   delta  4/255
 *
 *    A 4/255 difference is not visible. And because the mask confines the
 *    marks to the right half, they were being held precisely in the zone where
 *    their own colour disappeared.
 *
 *    The colour is now --ink-0. White is the one hue in the kit that keeps its
 *    distance from every stop in a gradient made of teals and navies, so the
 *    delta stays inside a 2.5x band across the whole sweep instead of
 *    collapsing by 5.5x. Per-tier floor on the brightest ground is 1.110.
 *
 * ---------------------------------------------------------------------------
 * WHY translate3d AND NOT `bottom`
 * ---------------------------------------------------------------------------
 * The reference pen animates `bottom` from -100vh to 150vh. That is a layout
 * property: every frame invalidates layout and repaints the whole band. These
 * translate instead, which the compositor runs on the GPU. The visual result
 * is identical.
 * ======================================================================== */

@keyframes dm-float-rise {
	from {
		transform: translate3d(0, 18vh, 0) rotate(var(--dm-f-from, 0deg));
		opacity: 0;
	}
	12% {
		opacity: 1;
	}
	86% {
		opacity: 1;
	}
	to {
		transform: translate3d(0, -120vh, 0) rotate(var(--dm-f-to, -320deg));
		opacity: 0;
	}
}

body.dm-page .dm-float {
	position: absolute;
	inset: 0;
	/*
	 * -1 keeps the layer behind all hero content, which lives at z-index auto.
	 * It now beats the aurora because layout.css drops that to -2 -- see note 2
	 * above. Both numbers have to move together; changing one alone puts the
	 * marks back under the gradient.
	 */
	z-index: -1;
	overflow: hidden;
	pointer-events: none;
	color: var(--ink-0);
	/*
	 * Matched to the aurora's mask exactly: transparent until 56%, 0.35 at
	 * 66%, solid from 76%. It used to start fading in at 50% and reach full
	 * strength at 68%, which allowed up to 0.27 alpha of a mark to reach the
	 * last glyphs of the lede (measured: the lede's box ends at 54.9% of the
	 * band at 1440). Now no mark ink of any kind reaches any text.
	 */
	-webkit-mask-image: linear-gradient(
		90deg,
		transparent 0%,
		transparent 56%,
		rgb(0 0 0 / 0.35) 66%,
		#000 76%,
		#000 100%
	);
	mask-image: linear-gradient(
		90deg,
		transparent 0%,
		transparent 56%,
		rgb(0 0 0 / 0.35) 66%,
		#000 76%,
		#000 100%
	);
}

body.dm-page .dm-float__item {
	position: absolute;
	bottom: 0;
	display: block;
	width: var(--dm-f-px, 53px);
	height: var(--dm-f-px, 53px);
	/*
	 * `left` in float.js is the mark's CENTRE. Pulling it back half its own
	 * width is what makes that true, and it is why a 110px mark can sit at 88%
	 * without hanging off the band -- which the previous edge-anchored
	 * placement did, permanently slicing the rightmost mark in half.
	 */
	margin-left: calc(var(--dm-f-px, 53px) / -2);
	opacity: 0;
	/*
	 * THE DEPTH OF FIELD. Near and far both go soft; the focal tier is the
	 * only one at blur 0. Pre-compensated alphas are in float.js -- blur dims
	 * a stroke as well as spreading it, so the two values are chosen as a pair
	 * and neither can be adjusted alone.
	 */
	filter: blur(var(--dm-f-blur, 0px));
	will-change: transform, opacity;
}

html.dm-motion-ready body.dm-page .dm-float__item {
	animation-name: dm-float-rise;
	animation-timing-function: linear;
	animation-iteration-count: infinite;
}

body.dm-page .dm-float__item svg {
	display: block;
	width: 100%;
	height: 100%;
	opacity: var(--dm-f-alpha, 0.17);
}

/*
 * Applied to the SHAPES, not the <svg> root, for two separate reasons.
 *
 * `fill` -- see note 1 in the block comment. base.css sets it on
 * `body.dm-page svg` and it inherits, so overriding the root alone is not
 * enough to stop it reaching the children.
 *
 * `vector-effect` -- it does not reliably inherit from the root element to its
 * children, so setting it as an attribute on <svg> leaves the strokes scaling
 * in some engines. This is the declaration that lets each depth tier carry an
 * explicit screen-pixel line weight regardless of the mark's rendered size,
 * so depth reads as weight and softness rather than as a mark thinning itself
 * out of existence.
 */
body.dm-page .dm-float__item svg path,
body.dm-page .dm-float__item svg circle {
	fill: none;
	stroke: currentColor;
	stroke-width: var(--dm-f-stroke, 1.6);
	stroke-linecap: round;
	stroke-linejoin: round;
	vector-effect: non-scaling-stroke;
}

@media (max-width: 899px) {
	/*
	 * Dropped on phones. The columns stack there, so the mask can no longer
	 * keep the marks off the copy, and this is the viewport where the extra
	 * compositing is least welcome.
	 */
	body.dm-page .dm-float {
		display: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	/*
	 * Static, not deleted: the marks still sit in the band as texture, they
	 * simply stop travelling. Consistent with how the gradient degrades.
	 */
	html:not(.dm-motion-opt-in) body.dm-page .dm-float__item {
		animation: none;
		opacity: 1;
	}
}

@media (forced-colors: active) {
	body.dm-page .dm-float {
		display: none;
	}
}


/* ---------------------------------------------------------------------------
 * THE CTA BAND'S POSITIONAL STYLING IS GONE. DO NOT PUT IT BACK.
 *
 * It was `.elementor > .e-con:nth-last-child(1)` -- "style the last container,
 * which is the CTA band on every page that has one". That premise has now
 * failed twice:
 *
 *   1. Contact has no CTA band, so the rule painted its FORM section with the
 *      band's gradient. Patched by excluding `.dm-page-contact` -- a patch
 *      that only worked because there happened to be exactly one exception.
 *   2. The operator moved the CTA band into an Elementor Theme Builder footer
 *      template. Every page's last container is now an ordinary content
 *      section, so the rule painted a dark gradient behind `What we do`,
 *      `Types of Work` and `What we value` -- each of which sets ink-900
 *      headings, giving near-black text on navy at about 1.3:1. Measured on
 *      the live site 2026-10-17.
 *
 * A positional selector cannot know what it is selecting. The CTA band keeps
 * the flat --navy-800 it already carries as an Elementor setting in
 * `cta_band()`, which is on-brand, travels with the template wherever the
 * operator moves it, and cannot land on the wrong element.
 *
 * To give a CTA band the gradient again, set it on that container in Elementor
 * -- that is where the band now lives and where the operator controls it.
 * ------------------------------------------------------------------------ */

