/* =====================================================================
   MMCall Design System — Industrial layer
   design-system.css

   The industrial design language. It is ADDITIVE and does NOT modify
   the base file: load design-core.css first, then this file. Its :root
   token block (§1) is the committed default — no wrapper attribute is
   needed; the look applies to every page that loads these stylesheets.

   What it changes vs the base primitives:
   - Palette: red-forward (brand red as the action color) on graphite
     neutrals — no purple/indigo. Reads like a hardware/tool brand.
   - Type: Barlow Semi Condensed headings (utilitarian) + Inter body +
     IBM Plex Mono for specs.
   - Shape: tighter radii and squared, uppercase buttons.
   It also ADDS the section patterns the base guide was missing, taken
   from the current live site: full-bleed cover hero, impact timeline,
   objection/answer rows, light stat cards, case-study carousel,
   numbered instant-quote, and the minimal (per-solution) footer.
   All new classes use the dx- prefix; existing ds- components are reused.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1. INDUSTRIAL THEME TOKENS  (:root — the committed default)
   --------------------------------------------------------------------- */
:root {
	--font-head: "Barlow Semi Condensed", system-ui, sans-serif;
	--font-body: "Inter", system-ui, sans-serif;
	--font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
	--head-weight: 700;
	--head-tracking: -0.005em;

	/* Tighter, more engineered radii */
	--radius-sm: 4px;
	--radius:    8px;
	--radius-lg: 12px;

	--bg:        #ffffff;
	--bg-subtle: #f3f5f8;
	--surface:   #ffffff;
	--ink:       #14181f;
	--ink-soft:  #525a67;
	/* Same hue and saturation as the original #8a93a1, darkened to the lightest
	   value that still clears WCAG AA on both --bg and --bg-subtle: 5.09:1 on
	   white, 4.66:1 on #f3f5f8. #8a93a1 was 3.10:1 and 2.84:1. */
	--ink-faint: #656f7e;
	--border:    #e3e7ee;
	--border-strong: #ccd3dd;

	--accent:      #de1d23;   /* brand red = the action color */
	--accent-ink:  #ffffff;
	--accent-soft: #fdeced;
	--accent-hover:#b8161b;

	--brand-red: #de1d23;
	--signal-amber: #f5a524;

	--band-bg:   #14181f;     /* graphite, not navy */
	--band-ink:  #eef1f6;
	--band-ink-soft: #99a2b1;
	--band-accent: #ff5a5f;

	--shadow-sm: 0 1px 2px rgba(20,24,31,.07), 0 2px 6px rgba(20,24,31,.05);
	--shadow:    0 6px 16px rgba(20,24,31,.09), 0 16px 36px rgba(20,24,31,.07);
	--shadow-lg: 0 22px 56px rgba(20,24,31,.16);

	--hero-bg: linear-gradient(165deg, #14181f 0%, #232a35 100%);
	--hero-ink: #f4f6fa;
	--hero-ink-soft: #aab2c0;
}

/* Squared, uppercase, utilitarian buttons */
.ds-btn {
	border-radius: var(--radius-sm);
	text-transform: uppercase;
	letter-spacing: 0.05em;
	font-weight: 700;
}
.ds-btn--ghost { text-transform: none; letter-spacing: 0; }

/* Slightly tighter, flatter cards to match the engineered feel */
.ds-card,
.ds-price,
.ds-case { border-radius: var(--radius); }

/* ---------------------------------------------------------------------
   2. FULL-BLEED COVER HERO  (background photo + logo + copy/media split)
   Mirrors the current site's signature hero.
   ---------------------------------------------------------------------
   Asset reality drives this component: the backdrop photos are 900x600 and
   the product cut-outs 585x235, so neither survives being scaled up to fill
   a 1440-wide hero. The photo is therefore demoted to atmosphere (dimmed,
   desaturated, slightly defocused) and the cut-out is capped at its native
   width on a lit panel rather than stretched to the column. */
.dx-hero-cover {
	position: relative;
	display: flex;
	align-items: center;
	overflow: hidden;
	color: #fff;
	min-height: clamp(30rem, 24rem + 18vw, 41rem);
	padding: clamp(2.5rem, 2rem + 3vw, 4rem) 0 clamp(3rem, 2.4rem + 3vw, 4.5rem);
	background:
		radial-gradient(115% 95% at 76% 28%, rgba(56,70,92,.5) 0%, transparent 62%),
		linear-gradient(158deg, #181e28 0%, #11151c 55%, #0b0e14 100%);
}
/* Fine machined texture, so a hero with no backdrop photo still reads as a
   surface rather than a flat dark block. */
.dx-hero-cover::before {
	content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
	background: repeating-linear-gradient(-45deg, rgba(255,255,255,.02) 0 1px, transparent 1px 8px);
}
.dx-hero-cover::after {
	content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
	background: linear-gradient(180deg, rgba(11,14,20,.3) 0%, rgba(11,14,20,.6) 100%);
}
.dx-hero-cover > *:not(.dx-hero-cover__bg) { position: relative; z-index: 2; width: 100%; }
/* Same logo size and gap as .dx-syshero, so the two hero types open on one
   rhythm; the old clamp put 44px under a 34px logo, which read as a stranded
   mark rather than the top of the copy block. */
.dx-hero-cover__logo { margin-bottom: var(--sp-5); }
.dx-hero-cover__logo img { height: 40px; width: auto; }
/* Copy leads, media follows. Every page authors the media column first (it
   predates this layout), so it is ordered across instead of being moved in
   each page's markup. */
.dx-hero-cover__grid {
	display: grid;
	grid-template-columns: 1.12fr 0.88fr;
	gap: clamp(2rem, 1rem + 3vw, 4rem);
	align-items: center;
}
.dx-hero-cover__grid > *:first-child { order: 2; }
@media (max-width: 900px) {
	.dx-hero-cover { min-height: 0; }
	.dx-hero-cover__grid { grid-template-columns: 1fr; gap: var(--sp-6); }
}
/* The global h1 scale is built for full-width headings; in a half-width hero
   column it forces every product name onto three lines and strands words such
   as the "&" in "Deaf & Hard of Hearing". This scale keeps the same weight and
   fits the measure. No character cap either, for the same reason. */
.dx-hero-cover h1 { color: #fff; font-size: clamp(2.2rem, 1.5rem + 2.6vw, 3.35rem); }
.dx-hero-cover .ds-lead { color: rgba(255,255,255,.84); max-width: 46ch; }
/* The kicker takes the .dx-syshero__eyebrow treatment: mono, lighter and tighter
   to the headline. The stock .ds-eyebrow is the body font at 700 with 16px under
   it, which on a dark hero competes with the h1 instead of introducing it. */
.dx-hero-cover .ds-eyebrow {
	display: block;
	font-family: var(--font-mono);
	font-size: 0.72rem;
	font-weight: 600;
	letter-spacing: 0.16em;
	color: var(--band-accent);
	margin-bottom: var(--sp-3);
}
/* Side by side: two stacked full-width buttons in a 320px column read as a
   form, and push the trust line below the fold on a laptop. */
.dx-hero-cover__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.dx-hero-cover__actions .ds-btn { width: auto; }
@media (max-width: 420px) { .dx-hero-cover__actions .ds-btn { width: 100%; } }
.dx-hero-cover .ds-trustline { margin-top: var(--sp-5); color: rgba(255,255,255,.72); font-size: var(--fs-small); }
.dx-hero-cover .ds-btn--secondary { color: #fff; border-color: rgba(255,255,255,.45); }
.dx-hero-cover .ds-btn--secondary:hover { border-color: #fff; background: rgba(255,255,255,.08); }
/* The media column holds either a product still or a video embed, so both
   share one frame and only their contents differ. */
.dx-hero-cover__shot,
.dx-hero-cover__media,
.dx-hero-cover__grid .dx-video { border-radius: var(--radius-lg); }
.dx-hero-cover__media {
	aspect-ratio: 16 / 10;
	background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.16);
	display: flex; align-items: center; justify-content: center; color: rgba(255,255,255,.6);
	font-family: var(--font-mono); font-size: 0.8rem; gap: 0.5rem;
	box-shadow: 0 26px 60px rgba(0,0,0,.5);
}
.dx-hero-cover__media svg { width: 46px; height: 46px; fill: rgba(255,255,255,.85); }
/* A matte ring reads as a bezel around the player; the stock border token is
   tuned for light surfaces and shows up as a grey hairline on the dark hero. */
.dx-hero-cover__grid .dx-video {
	border-color: rgba(255,255,255,.14);
	background: #0a0d13;
	box-shadow: 0 0 0 10px rgba(255,255,255,.04), 0 30px 70px rgba(0,0,0,.55);
}
/* Product still: the cut-out is lit on a glass panel and capped at its native
   585px, which grounds it instead of leaving it pasted on the photo. */
.dx-hero-cover__shot {
	position: relative;
	display: flex; align-items: center; justify-content: center;
	min-height: clamp(12rem, 9rem + 8vw, 15rem);
	padding: clamp(1.5rem, 1rem + 2vw, 2.25rem);
	overflow: hidden;
	border: 1px solid rgba(255,255,255,.2);
	/* Tinted rather than clear glass: a purely translucent panel picks up
	   whatever bright patch of the photo sits behind it. */
	background:
		linear-gradient(155deg, rgba(255,255,255,.14) 0%, rgba(255,255,255,.04) 58%, rgba(255,255,255,.08) 100%),
		rgba(11,15,21,.42);
	backdrop-filter: blur(14px) saturate(1.1);
	box-shadow: 0 30px 70px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.16);
}
.dx-hero-cover__shot::before {
	content: ""; position: absolute; inset: 0;
	background: radial-gradient(66% 56% at 50% 44%, rgba(255,255,255,.2) 0%, transparent 72%);
}
.dx-hero-cover__shot img {
	position: relative;
	display: block; width: 100%; max-width: 585px; height: auto;
	filter: drop-shadow(0 16px 24px rgba(0,0,0,.55));
}
@media (max-width: 900px) { .dx-hero-cover__shot { min-height: 0; } }
/* Real background media on the cover hero (production pages) */
.dx-hero-cover--media { background: #0b0e14; }
/* The photos are busy and light in places, so a flat scrim leaves the
   headline sitting on whatever happens to be there. This weights the dimming
   toward the copy side and lets the media side keep some of the scene. */
.dx-hero-cover--media::after {
	background:
		linear-gradient(90deg, rgba(9,12,17,.88) 0%, rgba(9,12,17,.74) 34%, rgba(9,12,17,.44) 66%, rgba(9,12,17,.38) 100%),
		linear-gradient(180deg, rgba(9,12,17,.55) 0%, rgba(9,12,17,.34) 45%, rgba(9,12,17,.68) 100%),
		radial-gradient(125% 95% at 68% 42%, transparent 34%, rgba(6,8,12,.55) 100%);
}
.dx-hero-cover__bg { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.dx-hero-cover__bg img, .dx-hero-cover__bg video {
	position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block;
	/* A 900x600 source stretched over a 1440-wide hero shows its upscale, so a
	   slight defocus turns that into depth of field; the scale hides the blur
	   feathering at the edges. */
	filter: saturate(.6) contrast(1.04) brightness(.92) blur(3px);
	transform: scale(1.06);
}
.dx-hero-cover .dx-hero-badge { display: inline-block; background: #16a34a; color: #fff; font-weight: 700; font-size: 0.8rem; letter-spacing: 0.02em; padding: 0.4rem 0.9rem; border-radius: var(--radius-sm); margin: 0.25rem 0 1.1rem; }
.dx-hero-cover p.dx-hero-cover__sub { color: rgba(255,255,255,.72); }
.dx-hero-cover__note { margin: var(--sp-4) 0 0; color: rgba(255,255,255,.72); font-size: var(--fs-small); }

/* ---------------------------------------------------------------------
   3. IMPACT / COST TIMELINE
   --------------------------------------------------------------------- */
/* Step count is set per instance with --dx-tl-n so a timeline can end on its
   own decision step instead of trailing off into a separate box. */
.dx-timeline { position: relative; display: grid; grid-template-columns: repeat(var(--dx-tl-n, 4), 1fr); gap: var(--sp-4); }
.dx-timeline::before { content: ""; position: absolute; top: 27px; left: 12%; right: 12%; height: 2px; background: var(--border-strong); }
@media (max-width: 720px) { .dx-timeline { grid-template-columns: 1fr 1fr; } .dx-timeline::before { display: none; } }
.dx-tl { text-align: center; }
.dx-tl__dot {
	position: relative; z-index: 1;
	width: 56px; height: 56px; margin: 0 auto var(--sp-3);
	border-radius: 50%; background: var(--surface); border: 2px solid var(--accent);
	color: var(--accent); display: flex; align-items: center; justify-content: center;
	font-family: var(--font-mono); font-weight: 700;
}
/* A step index in the dot says nothing when the time pill below already carries
   the sequence, so the dot takes an icon instead on timelines of clock times. */
.dx-tl__dot svg { width: 24px; height: 24px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* The elapsed time is what makes this a timeline rather than four cards, so it
   leads each step in full contrast instead of sitting under it as a caption. */
.dx-tl__t {
	display: inline-block; font-family: var(--font-mono); font-size: 0.78rem; font-weight: 700;
	letter-spacing: .02em; color: var(--ink); background: var(--bg-subtle);
	border-radius: var(--radius-pill); padding: 0.2rem 0.7rem;
}
.dx-tl :is(h3, h4) { margin: 0.5rem 0 0.2rem; }
.dx-tl p { margin: 0; color: var(--ink-soft); font-size: var(--fs-small); }
.dx-tl--end .dx-tl__dot { background: var(--accent); border-color: var(--accent); color: var(--accent-ink, #fff); }
.dx-tl--end .dx-tl__t { background: var(--accent); color: var(--accent-ink, #fff); }
.dx-cost {
	margin-top: var(--sp-6); text-align: center;
	background: var(--accent-soft); border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
	border-radius: var(--radius); padding: var(--sp-5);
}
.dx-cost strong { display: block; font-family: var(--font-head); font-weight: 800; font-size: var(--fs-h2); color: var(--accent); line-height: 1; }
.dx-cost span { color: var(--ink-soft); }

/* ---------------------------------------------------------------------
   3b. PHASED PATH  (grouped steps, for anything that risks reading long)
   ---------------------------------------------------------------------
   Use instead of the timeline above when the sequence has more than about
   four steps. A flat run gets counted before it is read, and a long count
   makes something free sound like a project; three named phases read as
   three things, and each band says how light its phase is before anyone
   works through the stops. Keep two stops per card so the three stay the
   same height, which is what makes this read as a plan rather than a list.
   Numbering runs continuously across the cards. */
.dx-phases { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-4); counter-reset: dxphase; }
.dx-phase { display: flex; flex-direction: column; background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius); overflow: hidden; }
.dx-phase__band { background: var(--bg-subtle); border-bottom: 1px solid var(--border); padding: var(--sp-4) var(--sp-5); }
.dx-phase__n { font-family: var(--font-mono); font-size: 0.68rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); }
/* Level-agnostic so the card can nest under whatever heading precedes it. */
/* line-height is pinned because these titles were h4, and the base h3 rule uses
   a tighter one. */
.dx-phase__band :is(h2, h3, h4, h5) { font-size: 1.15rem; line-height: 1.3; margin: 0.1rem 0 0.15rem; }
.dx-phase__band p { margin: 0; font-size: var(--fs-small); color: var(--ink-faint); }
.dx-phase__stops { list-style: none; margin: 0; padding: var(--sp-5); display: flex; flex-direction: column; gap: var(--sp-5); }
.dx-phase__stops li { display: flex; gap: var(--sp-3); counter-increment: dxphase; }
.dx-phase__stops li::before {
	content: counter(dxphase); flex: none;
	width: 1.9rem; height: 1.9rem; border-radius: 50%; background: var(--ink); color: var(--surface);
	font-family: var(--font-mono); font-size: 0.8rem; font-weight: 700;
	display: flex; align-items: center; justify-content: center;
}
.dx-phase__stops li > div { min-width: 0; }
.dx-phase__when { font-size: 0.7rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); font-weight: 700; margin-bottom: 0.1rem; }
/* These were h5, which falls outside the base h1-h4 rule and so rendered in the
   body font at the browser's default bold. Promoting them to h4 for the outline
   pulled in the display font; pinned back so the level change is invisible. */
.dx-phase__stops :is(h3, h4, h5, h6) { margin: 0 0 0.2rem; font-size: 1rem; font-family: var(--font-body); font-weight: 700; letter-spacing: normal; line-height: inherit; }
.dx-phase__stops p { margin: 0; color: var(--ink-soft); font-size: var(--fs-small); }
/* The last phase is the decision, so it carries the accent the way the
   timeline's final step does. */
.dx-phase--end { border-color: var(--accent); }
.dx-phase--end .dx-phase__band { background: var(--accent-soft); border-bottom-color: color-mix(in srgb, var(--accent) 30%, transparent); }
/* The only place --ink-faint lands on the tinted panel, where it is 4.46:1 and
   just misses AA. Scoped here rather than darkening the token further, which
   would flatten it into --ink-soft on the other 494 nodes. */
.dx-phase--end .dx-phase__band p { color: var(--ink-soft); }
.dx-phase--end .dx-phase__stops li.is-end::before { background: var(--accent); color: var(--accent-ink, #fff); }
@media (max-width: 900px) { .dx-phases { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------------
   4. LIGHT STAT CARD (big number on white)
   --------------------------------------------------------------------- */
.dx-statcard { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--sp-6); box-shadow: var(--shadow-sm); }
.dx-statcard__n { font-family: var(--font-head); font-weight: 800; font-size: clamp(2.4rem, 1.7rem + 2.4vw, 3.4rem); color: var(--accent); line-height: 1; letter-spacing: -0.02em; }
.dx-statcard :is(h3, h4) { margin: var(--sp-3) 0 var(--sp-2); }
.dx-statcard p { margin: 0; color: var(--ink-soft); font-size: var(--fs-small); }

/* ---------------------------------------------------------------------
   5. OBJECTION / ANSWER ROWS
   --------------------------------------------------------------------- */
.dx-objection { display: grid; grid-template-columns: 1fr 1.5fr; gap: var(--sp-6); align-items: start; padding: var(--sp-5) 0; border-bottom: 1px solid var(--border); }
@media (max-width: 720px) { .dx-objection { grid-template-columns: 1fr; gap: var(--sp-3); } }
.dx-objection__q { border-left: 3px solid var(--accent); padding-left: var(--sp-4); font-family: var(--font-head); font-weight: 700; font-size: var(--fs-h4); color: var(--ink); }
.dx-objection__a { margin: 0; color: var(--ink-soft); }

/* ---------------------------------------------------------------------
   6. HORIZONTAL CASE-STUDY / LOGO CAROUSEL (scroll-snap, no JS)
   --------------------------------------------------------------------- */
.dx-carousel { display: flex; gap: var(--sp-5); overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: var(--sp-4); }
.dx-carousel > * { flex: 0 0 clamp(260px, 70vw, 340px); scroll-snap-align: start; }
.dx-carousel::-webkit-scrollbar { height: 8px; }
.dx-carousel::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 999px; }
.dx-carousel::-webkit-scrollbar-track { background: var(--bg-subtle); border-radius: 999px; }
.dx-logostrip { display: flex; gap: var(--sp-5); overflow-x: auto; align-items: center; padding-bottom: var(--sp-3); }
.dx-logostrip > .ds-logo { flex: 0 0 160px; }

/* Continuous auto-scrolling logo marquee (5+ logos). Each cell stacks up to
   3 logos so the wall reads as MANY logos across 3 lines (an impressive
   "trusted by" effect). The track scrolls forever with a linear CSS
   animation and the container edges are masked so logos fade in/out
   instead of hard-cutting — a true marquee, never a clipped card.
   mix-blend-mode blends the logos' white PNG backgrounds into the band. */
.ds-logomarquee {
	width: 100%;
	overflow: hidden;
	-webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
	mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
}
.ds-logomarquee__track {
	display: flex;
	width: max-content;
	animation: ds-marquee 55s linear infinite;
}
.ds-logomarquee:hover .ds-logomarquee__track { animation-play-state: paused; }
.ds-logomarquee__cell {
	flex: 0 0 auto;
	width: 220px;
	padding: 0 var(--sp-5);
	display: flex; flex-direction: column; align-items: center; justify-content: center;
	gap: var(--sp-6);
}
.ds-logomarquee__cell img {
	max-width: 100%; max-height: 60px; width: auto; height: auto;
	object-fit: contain;
	opacity: 0.9;
	mix-blend-mode: multiply;
}
@keyframes ds-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (max-width: 767px) { .ds-logomarquee__cell { width: 150px; gap: var(--sp-5); } }
@media (prefers-reduced-motion: reduce) { .ds-logomarquee__track { animation: none; } }

/* Flickity list cells must not render a list marker */
.slider ul.slides { list-style: none; margin: 0; padding: 0; }
.slider ul.slides > li { list-style: none; }
/* Case-study carousel cells (Flickity): whole cards, comfortable gutter */
/* Vertical padding gives each card room for its box-shadow inside the
   Flickity viewport (overflow:hidden). Without it the viewport height equals
   the card height and the shadow is sliced off top/bottom — the card reads
   as "cut". */
.case-studies-carousel .slide { width: 50%; padding: 16px 12px; }
@media (max-width: 767px) { .case-studies-carousel .slide { width: 86%; } }
/* Size the real Flickity cells (the <li>) directly, so cell width never
   depends on the JS-added `.slide` class. If a stale/older site-ds.js inits
   the carousel but skips adding `.slide`, cells would fall back to natural
   width and a 3rd card would peek in behind the arrow — this prevents that.
   Direct-child selectors only, to avoid touching the page-dots <li> or any
   nested list inside a card. `ul.slides > li` = pre-init DOM; after Flickity
   moves the cells, `.flickity-slider > li` = post-init DOM. */
.case-studies-carousel ul.slides > li,
.case-studies-carousel .flickity-slider > li { width: 50%; box-sizing: border-box; }
@media (max-width: 767px) {
	.case-studies-carousel ul.slides > li,
	.case-studies-carousel .flickity-slider > li { width: 86%; }
}
/* Inset the carousel on desktop so the prev/next arrows sit in a clear side
   lane instead of on top of the edge cards. Mobile hides arrows and shows a
   single card, so no inset there. */
@media (min-width: 768px) { .case-studies-carousel ul.slides { padding: 0 56px; } }
/* Cards inside a carousel must not lift on hover — the scroll/viewport clips
   the movement and shadow, cutting the card off. Keep shadow + border only. */
.slider .ds-card:hover, .slider .cs-card:hover,
.dx-carousel .ds-card:hover, .dx-carousel .cs-card:hover { transform: none; }

/* --- 6b. FLICKITY CONTROLS (visible arrows + dots below cards) ------- */
.flickity-prev-next-button {
	width: 46px; height: 46px;
	background: var(--surface);
	border: 1px solid var(--border-strong);
	box-shadow: var(--shadow);
	opacity: 1;
	transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}
.flickity-prev-next-button:hover {
	background: var(--accent);
	border-color: var(--accent);
	box-shadow: var(--shadow-lg);
}
.flickity-prev-next-button .arrow { fill: var(--ink); }
.flickity-prev-next-button:hover .arrow { fill: var(--accent-ink); }
.flickity-prev-next-button:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent); }
.flickity-prev-next-button:disabled { opacity: 0; pointer-events: none; }
.flickity-prev-next-button.previous { left: 8px; }
.flickity-prev-next-button.next { right: 8px; }
/* On phones the cells are wide (1-2 up) so an edge arrow sits on top of a
   logo/card. Hide arrows there and rely on swipe/drag (+ dots where shown). */
@media (max-width: 767px) {
.flickity-prev-next-button { display: none; }
}
/* dots flow below the cards instead of overlapping them */
.flickity-page-dots { position: static; width: 100%; margin-top: var(--sp-5); }
.flickity-page-dots .dot {
	width: 8px; height: 8px; margin: 0 5px;
	background: var(--border-strong); opacity: 1;
	transition: background 0.15s ease, transform 0.15s ease;
}
.flickity-page-dots .dot.is-selected { background: var(--accent); transform: scale(1.35); }

/* ---------------------------------------------------------------------
   7. NUMBERED INSTANT-QUOTE
   --------------------------------------------------------------------- */
.dx-q { display: flex; gap: var(--sp-4); align-items: center; padding: var(--sp-4) 0; border-bottom: 1px solid var(--border); }
.dx-q:last-of-type { border-bottom: 0; }
.dx-q__n { flex: 0 0 34px; width: 34px; height: 34px; border-radius: 50%; background: var(--accent); color: #fff; display: flex; align-items: center; justify-content: center; font-family: var(--font-mono); font-weight: 700; }
.dx-q__body { flex: 1; }
.dx-q__body .ds-label { margin-bottom: var(--sp-2); }
/* Quote radio group (segmented pills) */
.ds-radios { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.ds-radio { cursor: pointer; margin: 0; }
.ds-radio input { position: absolute; opacity: 0; width: 0; height: 0; }
.ds-radio span { display: inline-block; padding: 0.5rem 1.05rem; border: 1.5px solid var(--border); border-radius: var(--radius-sm); font-weight: 600; font-size: var(--fs-small); color: var(--ink); transition: border-color .12s ease, background .12s ease, color .12s ease; }
.ds-radio input:checked + span { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.ds-radio input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Below ~600px the pills wrap ragged — a 4-option row breaks one per line while a
   6-option row breaks 2+2+2 — so the group goes 2-up and every cell stays even.
   Stretch the label + flex-center the span so a 1-line option matches a 2-line neighbor. */
@media (max-width: 600px) {
	.ds-radios { display: grid; grid-template-columns: 1fr 1fr; align-items: stretch; }
	.ds-radio { display: flex; min-width: 0; }
	.ds-radio span {
		display: flex; flex: 1; align-items: center; justify-content: center;
		text-align: center; width: 100%; box-sizing: border-box;
	}
}
/* Toggled by custom.js when a form shows its validation or success message. */
.ds-hidden { display: none !important; }
.ds-btn.disabled, .modal-trigger.disabled { opacity: 0.55; cursor: not-allowed; }
ul.bullets { padding-left: 1.25rem; margin: var(--sp-3) 0 0; }
ul.bullets li { margin-bottom: 0.35rem; color: var(--ink-soft); }
/* Cons / negative list (paired with .dx-checks pros) */
.dx-cons { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--sp-3); }
.dx-cons li { display: flex; gap: var(--sp-3); align-items: flex-start; color: var(--ink-soft); }
.dx-cons li::before { content: "\2013"; color: var(--ink-faint); font-weight: 700; flex: 0 0 auto; }
/* Implementation example: floor-plan image + product accordion side by side */
.dx-impl-grid { display: grid; grid-template-columns: 1.5fr 1fr; gap: var(--sp-6); align-items: start; }
@media (max-width: 768px) { .dx-impl-grid { grid-template-columns: 1fr; } }
/* Implementation list (floor-plan products as a DS accordion with thumbnails) */
.dx-implist summary { justify-content: flex-start; font-size: var(--fs-body); gap: var(--sp-3); padding: var(--sp-4) 0; }
.dx-implist summary > span { flex: 1; }
.dx-implist__thumb { flex: 0 0 auto; display: inline-flex; }
.dx-implist__thumb img { width: 46px; height: 46px; object-fit: contain; border-radius: var(--radius-sm); background: var(--surface); border: 1px solid var(--border); padding: 4px; }

/* ---------------------------------------------------------------------
   8. MINIMAL FOOTER  (per-solution: About + HQ, no cross-links)
   --------------------------------------------------------------------- */
.dx-footer { background: #14181f; color: #e7e9ee; padding: var(--sp-8) 0 var(--sp-5); }
.dx-footer__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-7); }
@media (max-width: 720px) { .dx-footer__grid { grid-template-columns: 1fr; gap: var(--sp-6); } }
/* Selects on the class, not the tag, so the heading level can follow the
   document outline without the footer changing size. */
/* font-weight and line-height are pinned to the values the h6 inherited before
   the level changed, so the footer renders identically. */
.dx-footer__h { font-family: var(--font-head); text-transform: uppercase; letter-spacing: 0.12em; font-size: 0.85rem; font-weight: 700; line-height: inherit; color: #aeb6c2; margin: 0 0 var(--sp-4); }
.dx-footer p { color: #aeb6c2; }
/* Higher specificity so these beat the base a:not(.ds-btn) accent rule */
.dx-footer a:not(.ds-btn) { color: #aeb6c2; }
.dx-footer a:not(.ds-btn):hover { color: #fff; }
.dx-footer__social a:not(.ds-btn) { display: inline-flex; color: #fff; opacity: 0.85; }
.dx-footer__social a:not(.ds-btn):hover { opacity: 1; }
.dx-footer__map { height: 150px; border-radius: var(--radius); border: 1px solid rgba(255,255,255,.14); background: repeating-linear-gradient(-45deg, rgba(255,255,255,.05) 0 16px, rgba(255,255,255,.02) 16px 32px); display: flex; align-items: center; justify-content: center; color: #8a93a1; font-family: var(--font-mono); font-size: 0.75rem; margin-bottom: var(--sp-3); }
.dx-footer__lower { margin-top: var(--sp-7); padding-top: var(--sp-5); border-top: 1px solid rgba(255,255,255,.12); display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--sp-3); font-size: var(--fs-small); color: #aeb6c2; }

/* =====================================================================
   9. EXPANDED ELEMENT LIBRARY
   Equivalents for the remaining patterns used across the live pages.
   ===================================================================== */

/* --- 9a. Framed video / media embed -------------------------------- */
.dx-video { position: relative; aspect-ratio: 16 / 9; border-radius: var(--radius); overflow: hidden; background: #0f141d; border: 1px solid var(--border); display: flex; align-items: center; justify-content: center; }
.dx-video__play { width: 66px; height: 66px; border-radius: 50%; background: var(--accent); display: flex; align-items: center; justify-content: center; box-shadow: 0 0 0 10px rgba(222,29,35,.18); }
.dx-video__play svg { width: 26px; height: 26px; fill: #fff; margin-left: 3px; }
.dx-video__cap { position: absolute; bottom: 10px; left: 12px; font-family: var(--font-mono); font-size: 0.7rem; color: rgba(255,255,255,.5); text-transform: uppercase; letter-spacing: 0.1em; }
.dx-video iframe, .dx-video > video { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* --- 9b. Testimonials grid card ------------------------------------ */
.dx-tcard { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--sp-6); box-shadow: var(--shadow-sm); height: 100%; display: flex; flex-direction: column; }
.dx-tcard__q { font-size: var(--fs-lead); line-height: 1.5; color: var(--ink); margin: 0 0 var(--sp-5); flex: 1; }
.dx-tcard__who { display: flex; align-items: center; gap: var(--sp-3); }
.dx-tcard__av { width: 46px; height: 46px; flex: 0 0 46px; border-radius: 50%; background: var(--accent-soft); color: var(--accent); display: flex; align-items: center; justify-content: center; font-family: var(--font-head); font-weight: 700; }
.dx-tcard__n { font-weight: 700; }
.dx-tcard__t { color: var(--ink-faint); font-size: var(--fs-small); }

/* --- 9c. Problem + cost accordion ---------------------------------- */
.dx-pain details { border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: var(--sp-3); background: var(--surface); overflow: hidden; }
.dx-pain summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-4) var(--sp-5); }
.dx-pain summary::-webkit-details-marker { display: none; }
.dx-pain__ic { width: 40px; height: 40px; flex: 0 0 40px; border-radius: 8px; background: var(--bg-subtle); display: flex; align-items: center; justify-content: center; font-size: 1.2rem; }
.dx-pain__t { flex: 1; font-family: var(--font-head); font-weight: 700; }
.dx-pain__cost { font-family: var(--font-mono); font-weight: 700; color: var(--accent); background: var(--accent-soft); border-radius: 999px; padding: 0.2em 0.7em; font-size: 0.85rem; white-space: nowrap; }
.dx-pain summary::after { content: "+"; margin-left: var(--sp-2); color: var(--accent); font-family: var(--font-mono); font-size: 1.2rem; }
.dx-pain details[open] summary::after { content: "\2013"; }
.dx-pain__body { padding: 0 var(--sp-5) var(--sp-5); color: var(--ink-soft); }
.dx-pain blockquote { border-left: 3px solid var(--accent); margin: 0; padding-left: var(--sp-4); font-style: italic; }

/* --- 9d. Before / after two-column --------------------------------- */
.dx-vs { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-5); }
@media (max-width: 720px) { .dx-vs { grid-template-columns: 1fr; } }
.dx-vs__col { border: 1px solid var(--border); border-radius: var(--radius); padding: var(--sp-6); background: var(--surface); }
.dx-vs__col--bad { border-top: 4px solid var(--ink-faint); }
.dx-vs__col--good { border-top: 4px solid #16a34a; }
.dx-vs ul { list-style: none; padding: 0; margin: var(--sp-4) 0 0; }
.dx-vs li { padding: 0.4rem 0 0.4rem 1.7rem; position: relative; color: var(--ink-soft); }
.dx-vs__col--bad li::before { content: "\2715"; position: absolute; left: 0; color: var(--ink-faint); font-weight: 700; }
.dx-vs__col--good li::before { content: "\2713"; position: absolute; left: 0; color: #16a34a; font-weight: 700; }

/* --- 9e. ROI / big-number callout (use inside .ds-band) ------------ */
.dx-roi { text-align: center; }
.dx-roi__num { font-family: var(--font-head); font-weight: 800; font-size: clamp(3rem, 2rem + 5vw, 5.5rem); line-height: 1; color: var(--band-accent); letter-spacing: -0.03em; }
.dx-roi p { max-width: 54ch; margin: var(--sp-4) auto 0; color: var(--band-ink-soft); }

/* --- 9f. App / message-log window mock ----------------------------- */
.dx-window { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--surface); box-shadow: var(--shadow-sm); }
/* Windows chrome, not mac: the software is a Windows desktop app, so the title
   leads and the minimise / maximise / close cluster sits at the right, the same
   way .dx-compose__bar does — the two mocks often share a page. */
.dx-window__bar { display: flex; align-items: center; gap: var(--sp-2); padding: 0.7rem 1rem; background: var(--bg-subtle); border-bottom: 1px solid var(--border); }
.dx-window__bar .ttl { margin-right: auto; font-size: var(--fs-small); font-weight: 600; color: var(--ink); letter-spacing: .02em; }
.dx-window__bar .win { display: flex; align-items: center; gap: 14px; color: var(--ink-soft); }
.dx-window__bar .win b { font-weight: 400; font-size: 13px; line-height: 1; }
.dx-window table { width: 100%; border-collapse: collapse; font-size: var(--fs-small); }
.dx-window td, .dx-window th { text-align: left; padding: 0.7rem 1rem; border-bottom: 1px solid var(--border); }
.dx-window th { font-family: var(--font-head); }
.dx-window .time { font-family: var(--font-mono); color: var(--ink-faint); white-space: nowrap; }
/* Status bar. Two children read as a label and an action, one at each end —
   without this they butt together, since both are inline. */
.dx-window__foot { display: flex; justify-content: space-between; gap: var(--sp-4); padding: 0.7rem 1rem; font-family: var(--font-mono); font-size: 0.75rem; color: var(--ink-soft); background: var(--bg-subtle); }

/* --- 9g. Icon process flow with arrows ----------------------------- */
.dx-flow { display: flex; align-items: stretch; gap: var(--sp-3); flex-wrap: wrap; }
.dx-flow__step { flex: 1 1 150px; text-align: center; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--sp-5) var(--sp-4); }
.dx-flow__ic { width: 52px; height: 52px; border-radius: 12px; margin: 0 auto var(--sp-3); background: var(--accent-soft); color: var(--accent); display: flex; align-items: center; justify-content: center; }
.dx-flow__ic svg { width: 26px; height: 26px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.dx-flow__step :is(h3, h4) { margin: 0 0 0.2rem; }
.dx-flow__step p { margin: 0; font-size: var(--fs-small); color: var(--ink-soft); }
.dx-flow__arw { display: flex; align-items: center; color: var(--ink-faint); font-size: 1.3rem; }
@media (max-width: 760px) { .dx-flow { flex-direction: column; } .dx-flow__arw { justify-content: center; transform: rotate(90deg); } }

/* --- 9h. Alternating feature band ---------------------------------- */
.dx-feature { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-8); align-items: center; }
/* minmax(0, 1fr) rather than 1fr: a plain 1fr track refuses to go below the
   min-content width of what it holds, so one wide table inside a feature pushed
   the whole page sideways on a phone. */
@media (max-width: 820px) { .dx-feature { grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); } }

/* --- 9h2. Step-art stage ------------------------------------------- *
 * For the transparent product cut-outs in images/how_it_works (550x240)
 * and the hero cut-outs. A bordered light panel frames empty space around
 * them and the hardware reads as pasted on, so the panel goes graphite —
 * the --band-bg family, a step lighter through the middle so it has a
 * light source — and the image casts a shadow of its own silhouette,
 * which is what actually gives it depth. Opaque photos do not belong in
 * here; frame those instead. */
.dx-stage {
	position: relative; overflow: hidden;
	display: flex; align-items: center; justify-content: center;
	padding: var(--sp-6); border-radius: var(--radius-lg);
	background:
		radial-gradient(62% 58% at 78% 84%, rgba(255,90,95,.20) 0%, rgba(255,90,95,0) 68%),
		radial-gradient(78% 72% at 42% 34%, #1e2532 0%, #161c26 58%, #10151d 100%);
	box-shadow: inset 0 1px 0 rgba(255,255,255,.07);
}
.dx-stage img {
	position: relative; z-index: 1;
	display: block; width: 100%; max-width: 550px; height: auto;
	filter: drop-shadow(0 16px 26px rgba(0,0,0,.55));
	/* Several cut-outs run off their own edge — a forearm, a hand — which on a
	   dark panel ends on a hard line. Feathering the outer few percent on the
	   sides and the bottom hides the cut and leaves art that sits clear of the
	   edges untouched. Where mask-composite is unsupported the two gradients
	   add up to no mask at all, which is the old behaviour. */
	-webkit-mask-image: linear-gradient(90deg, transparent 0, #000 4%, #000 96%, transparent 100%),
	                    linear-gradient(180deg, #000 0, #000 90%, transparent 100%);
	        mask-image: linear-gradient(90deg, transparent 0, #000 4%, #000 96%, transparent 100%),
	                    linear-gradient(180deg, #000 0, #000 90%, transparent 100%);
	-webkit-mask-composite: source-in;
	        mask-composite: intersect;
}
/* Oversized step number, behind the art. */
.dx-stage__n {
	position: absolute; top: -.16em; left: .05em; z-index: 0;
	font-size: 7rem; font-weight: 800; line-height: 1;
	color: #fff; opacity: .07; pointer-events: none; user-select: none;
}
@media (max-width: 820px) {
	.dx-stage { padding: var(--sp-5); }
	.dx-stage__n { font-size: 5rem; }
}

/* --- 9i. Green checkmark list -------------------------------------- */
.dx-checks { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--sp-3); }
.dx-checks--2 { grid-template-columns: 1fr 1fr; }
@media (max-width: 640px) { .dx-checks--2 { grid-template-columns: 1fr; } }
.dx-checks li { display: flex; gap: var(--sp-3); align-items: flex-start; color: var(--ink-soft); }
.dx-checks svg { flex: 0 0 22px; width: 22px; height: 22px; color: #16a34a; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; margin-top: 2px; }

/* --- 9j. Three-up guarantee / promise ------------------------------ */
.dx-promise { text-align: center; }
.dx-promise__ic { width: 56px; height: 56px; margin: 0 auto var(--sp-4); border-radius: 50%; background: var(--accent-soft); color: var(--accent); display: flex; align-items: center; justify-content: center; }
.dx-promise__ic svg { width: 28px; height: 28px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.dx-promise p { color: var(--ink-soft); margin: var(--sp-2) 0 0; }

/* --- 9j-b. Accent-top card (top rule + icon beside heading) -------- */
.dx-topcard { background: var(--surface); border: 1px solid var(--border); border-top: 3px solid var(--accent); border-radius: var(--radius); padding: var(--sp-6); box-shadow: var(--shadow-sm); }
.dx-topcard__hd { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-1); }
.dx-topcard__ic { width: 30px; height: 30px; flex: 0 0 auto; color: var(--accent); }
.dx-topcard__ic svg { width: 100%; height: 100%; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.dx-topcard :is(h3, h4) { margin: 0; }
.dx-topcard p { color: var(--ink-soft); margin: var(--sp-2) 0 0; font-size: var(--fs-small); }

/* --- 9j-c. Compose panel (software "send a message" UI mock) ------- */
/* Accent defaults to the theme; override --compose-accent to match a
   specific product's board colour (e.g. the medical board blue). */
.dx-compose { --compose-accent: var(--accent); --compose-accent-soft: var(--accent-soft); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; max-width: 440px; }
.dx-compose__bar { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-3) var(--sp-4); background: var(--surface); color: var(--ink); border-bottom: 1px solid var(--border); font-size: var(--fs-small); font-weight: 600; }
.dx-compose__bar .t { margin-right: auto; letter-spacing: .02em; }
.dx-compose__win { display: flex; align-items: center; gap: 14px; color: var(--ink-soft); font-weight: 400; }
.dx-compose__win b { font-weight: 400; font-size: 13px; line-height: 1; }
.dx-compose__bd { padding: var(--sp-5); }
.dx-compose__lbl { display: block; font-size: 0.72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: var(--sp-2); }
.dx-compose__input { width: 100%; border: 1px solid var(--border-strong); border-radius: 10px; padding: var(--sp-3) var(--sp-4); font: inherit; color: var(--ink); background: var(--surface); resize: none; }
.dx-compose__input:focus { outline: none; border-color: var(--compose-accent); box-shadow: 0 0 0 3px var(--compose-accent-soft); }
.dx-compose__to { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin: var(--sp-4) 0 var(--sp-5); }
.dx-compose__chip { border: 1px solid var(--border-strong); border-radius: var(--radius-pill); padding: 0.35rem 0.8rem; font-size: 0.82rem; font-weight: 600; cursor: pointer; background: var(--surface); color: var(--ink-soft); }
.dx-compose__chip.is-on { background: var(--compose-accent-soft); border-color: var(--compose-accent); color: var(--compose-accent); }
.dx-compose__send { display: inline-flex; align-items: center; gap: var(--sp-2); border: 0; border-radius: 10px; background: var(--compose-accent); color: #fff; font: inherit; font-weight: 700; padding: var(--sp-3) var(--sp-5); cursor: pointer; }
.dx-compose__send:hover { filter: brightness(.93); }

/* --- 9j-d. Kit split (included core parts vs optional add-ons) ----- */
/* Two panels side by side: "every system includes" vs "add if you want",
   each a list of thumbnail + name + blurb, plus a setup reassurance strip. */
.dx-kit { display: grid; grid-template-columns: 1.45fr 1fr; gap: var(--sp-6); align-items: start; }
.dx-kit__panel { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); padding: var(--sp-6); }
.dx-kit__panel--opt { background: var(--bg-subtle); border-style: dashed; }
.dx-kit__hd { display: flex; align-items: baseline; gap: var(--sp-3); margin: 0 0 var(--sp-4); padding-bottom: var(--sp-3); border-bottom: 1px solid var(--border); }
.dx-kit__hd h3 { margin: 0; font-size: var(--fs-h4); }
.dx-kit__hd span { font-size: var(--fs-small); color: var(--ink-soft); }
.dx-kit__item { display: flex; gap: var(--sp-4); padding: var(--sp-5) 0; border-top: 1px solid var(--border); }
.dx-kit__hd + .dx-kit__item { border-top: 0; padding-top: 0; }
.dx-kit__item:last-child { padding-bottom: 0; }
.dx-kit__thumb { width: 112px; height: 112px; flex: none; background: #fff; border: 1px solid var(--border); border-radius: 12px; overflow: hidden; display: block; }
.dx-kit__thumb--zoom { cursor: zoom-in; }
.dx-kit__thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }
.dx-kit__tag { display: inline-block; font-family: var(--font-mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--accent); margin-bottom: 4px; }
/* The two or three parts a system cannot be built without, on a panel whose
   heading says "what most plants start with". A pill rather than more words on
   the tag: appended to the tag as plain text, "· required" read as one phrase
   with the role beside it instead of as a status. */
.dx-kit__req { display: inline-block; margin-left: 8px; vertical-align: 1px; font-size: 10px; font-weight: 600; letter-spacing: .07em; padding: 1px 7px; border-radius: 999px; background: var(--accent-soft); color: var(--accent); border: 1px solid rgba(222,29,35,.26); }
.dx-kit__item :is(h3, h4) { margin: 0 0 4px; font-size: var(--fs-body); }
.dx-kit__item p { margin: 0; color: var(--ink-soft); font-size: var(--fs-small); }
.dx-kit__setup { display: flex; gap: var(--sp-4); align-items: center; background: var(--bg-subtle); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--sp-5); margin-top: var(--sp-6); }
.dx-kit__setup-ic { width: 42px; height: 42px; flex: none; border-radius: 12px; background: var(--accent-soft); color: var(--accent); display: flex; align-items: center; justify-content: center; }
.dx-kit__setup-ic svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.dx-kit__setup p { margin: 0; color: var(--ink-soft); font-size: var(--fs-small); }
.dx-kit__setup strong { color: var(--ink); }
/* A folded detail table, attached to whatever it describes. Used for per-item
   specifications in dx-kit and for the network answer in dx-objection.

   Folded so a section stays readable to someone who does not care, but
   attached to the thing in question, which is the part burying the same table
   in the FAQ got wrong: there it was one row of ten, with nothing at the point
   of the question to say it existed. Forced open for print, so a page saved to
   PDF carries the numbers. */
.dx-fold { margin-top: var(--sp-3); }
.dx-fold > summary { cursor: pointer; display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: 11px; letter-spacing: .07em; text-transform: uppercase; color: var(--accent); list-style: none; }
.dx-fold > summary::-webkit-details-marker { display: none; }
.dx-fold > summary::after { content: ''; width: 6px; height: 6px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); transition: transform .15s ease; }
.dx-fold[open] > summary::after { transform: translateY(1px) rotate(-135deg); }
.dx-fold table { width: 100%; border-collapse: collapse; margin-top: var(--sp-3); }
.dx-fold th, .dx-fold td { text-align: left; font-size: 12px; line-height: 1.6; padding: 4px 0; border-bottom: 1px solid var(--border); vertical-align: top; }
.dx-fold tr:last-child :is(th, td) { border-bottom: 0; }
.dx-fold th { font-weight: 400; color: var(--ink-faint); padding-right: var(--sp-4); }
.dx-fold td { font-family: var(--font-mono); color: var(--ink); text-align: right; }
/* In a phone-width kit column the two spec columns need more room than they have,
   and the table pushed past the viewport. Stacked, the label reads above its
   value and the table can be as narrow as the column it sits in. */
@media (max-width: 480px) {
	.dx-fold :is(table, tbody, tr, th, td) { display: block; }
	.dx-fold tr { border-bottom: 1px solid var(--border); padding: 4px 0; }
	.dx-fold tr:last-child { border-bottom: 0; }
	.dx-fold :is(th, td) { border-bottom: 0; padding: 0; }
	.dx-fold td { text-align: left; }
}
/* minmax(0, 1fr) so the single column cannot be widened past the container by
   the spec table's own minimum width. */
@media (max-width: 760px) { .dx-kit { grid-template-columns: minmax(0, 1fr); } }

/* --- 9k. Lead-capture modal (static demo) -------------------------- */
.dx-modal-stage { border: 1px solid var(--border); border-radius: var(--radius); background: repeating-linear-gradient(-45deg, #e7ebf1 0 18px, #eef1f6 18px 36px); padding: var(--sp-7) var(--sp-5); display: flex; justify-content: center; }
.dx-modal { position: relative; width: 100%; max-width: 520px; background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow-lg); padding: var(--sp-6); }
.dx-modal__close { position: absolute; top: 12px; right: 16px; color: var(--ink-faint); font-size: 1.4rem; line-height: 1; text-decoration: none; }
.dx-modal h3 { margin: 0 0 var(--sp-4); }
.dx-modal hr { border: 0; border-top: 1px solid var(--border); margin: var(--sp-4) 0; }
/* Live modal overlay — reuses the Stack .modal-* contract, toggled by site-ds.js */
.modal-instance .modal-container { display: none; }
.modal-container.is-open { display: flex; position: fixed; inset: 0; z-index: 1100; align-items: flex-start; justify-content: center; overflow-y: auto; padding: var(--sp-6) var(--sp-4); background: rgba(20, 24, 31, 0.55); animation: dxModalIn 0.2s ease; }
.modal-container.is-open .modal-content { position: relative; width: 100%; max-width: 560px; margin: auto; background: var(--surface); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); }
.modal-content .ds-modal-box { padding: var(--sp-6); }
/* The button reset keeps this looking exactly as it did when it was a div; it is a
   button now so it can be reached by keyboard and carry an accessible name. */
.modal-close { position: absolute; top: 10px; right: 14px; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; cursor: pointer; color: var(--ink-faint); border-radius: var(--radius-sm); -webkit-appearance: none; appearance: none; background: none; border: 0; padding: 0; margin: 0; font: inherit; }
.modal-close:hover { color: var(--ink); background: var(--bg-subtle); }
.modal-close::before { content: "\00d7"; font-size: 1.7rem; line-height: 1; }
body.dx-modal-open { overflow: hidden; }
@keyframes dxModalIn { from { opacity: 0; } to { opacity: 1; } }

/* --- 9l. Alert banners --------------------------------------------- */
.dx-alert { border-radius: var(--radius-sm); padding: 0.8rem 1.1rem; font-size: var(--fs-small); border: 1px solid; display: flex; gap: 0.6rem; align-items: center; margin-bottom: var(--sp-3); }
.dx-alert--ok { background: #eaf7ef; border-color: #b7e4c7; color: #1a7f43; }
.dx-alert--err { background: var(--accent-soft); border-color: #f3b6b8; color: var(--accent-hover); }
.dx-alert svg { flex: 0 0 18px; width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }

/* --- 9m. Commerce: product card + price ---------------------------- */
.dx-product { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow-sm); display: flex; flex-direction: column; transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
.dx-product:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.dx-product .ds-photo { border: 0; border-radius: 0; min-height: 0; aspect-ratio: 1 / 1; }
.dx-product__body { padding: var(--sp-5); display: flex; flex-direction: column; gap: var(--sp-2); flex: 1; }
.dx-product__name { font-family: var(--font-head); font-weight: 700; }
.dx-product__price { font-family: var(--font-head); font-weight: 800; font-size: var(--fs-h4); }
.dx-product__price s { color: var(--ink-faint); font-weight: 500; font-size: 0.78em; margin-left: 0.4em; }
.dx-product .ds-btn { margin-top: auto; }

/* --- 9n. Commerce: trust badge tiles ------------------------------- */
/* Flex rather than grid: a partial last row (5 tiles, 4 tiles...) centres itself. */
.dx-badges { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-4); }
.dx-badges > * { flex: 0 1 calc((100% - 2 * var(--sp-4)) / 3); }
@media (max-width: 720px) { .dx-badges > * { flex-basis: calc((100% - var(--sp-4)) / 2); } }
.dx-badge-tile { text-align: center; border: 1px solid var(--border); border-radius: var(--radius); padding: var(--sp-5) var(--sp-4); background: var(--surface); }
.dx-badge-tile__ic { width: 44px; height: 44px; margin: 0 auto var(--sp-3); color: var(--accent); display: flex; align-items: center; justify-content: center; }
.dx-badge-tile__ic svg { width: 28px; height: 28px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.dx-badge-tile strong { display: block; font-family: var(--font-head); }
.dx-badge-tile span { font-size: var(--fs-small); color: var(--ink-soft); }

/* --- 9o. Commerce: cart button / FAB ------------------------------- */
.dx-fab { display: inline-flex; align-items: center; gap: 0.5rem; background: var(--ink); color: #fff; border-radius: 999px; padding: 0.7rem 1.1rem; font-family: var(--font-head); font-weight: 700; }
.dx-fab svg { width: 20px; height: 20px; stroke: currentColor; fill: none; stroke-width: 2; }
.dx-fab__badge { background: var(--accent); color: #fff; border-radius: 999px; min-width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; font-size: 0.75rem; font-family: var(--font-mono); padding: 0 0.35em; }

/* --- 9p. Geo-redirect notification pill ---------------------------- */
/* One row: the sentence and the way out. The height used to come from the escape hatch,
   which was a full sentence set on its own block and wrapped to two lines, making a 140px
   card out of what is really one line of text. */
.dx-notice { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-3); max-width: 820px; background: var(--surface); border: 1px solid var(--border); border-left: 4px solid var(--accent); border-radius: var(--radius); box-shadow: var(--shadow); padding: 0.8rem var(--sp-4); }
.dx-notice__msg { flex: 1 1 200px; margin: 0; }
.dx-notice__stay { flex: none; margin-left: auto; white-space: nowrap; font-size: var(--fs-small); font-weight: 600; color: var(--ink-soft); text-decoration: none; border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0.35rem 0.75rem; }
.dx-notice__stay:hover { background: var(--bg-subtle); color: var(--ink); }
/* Live geo-redirect notice (top_menu.php): fixed top-centre, hidden until custom.js reveals it.
   Centred on auto margins rather than a translate, so the entry animation keeps the transform
   to itself and the two never fight. */
.notification.dx-notice { position: fixed; top: 1rem; left: 0; right: 0; margin: 0 auto; width: max-content; max-width: min(820px, calc(100vw - 1.5rem)); z-index: 1000; animation: dxNoticeIn 0.35s ease; }
.notification.dx-notice.hidden { display: none; }
@keyframes dxNoticeIn { from { opacity: 0; transform: translateY(-12px); } to { opacity: 1; transform: translateY(0); } }
/* No phone fits this on one line, and letting the parts wrap where they fall left the button
   dangling in the bottom-right corner. The sentence takes the full width and the button
   becomes a full-width tap target under it. */
@media (max-width: 640px) {
	.notification.dx-notice { left: 0.75rem; right: 0.75rem; top: 0.75rem; margin: 0; width: auto; max-width: none; gap: var(--sp-3); padding: 0.75rem 0.9rem; }
	.notification.dx-notice .dx-notice__msg { flex: 1 1 100%; font-size: 0.95rem; }
	.notification.dx-notice .dx-notice__stay { width: 100%; margin-left: 0; text-align: center; padding: 0.5rem 0.75rem; }
}

/* --- 9q. Integration scenario builder (static) --------------------- */
.dx-builder { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--sp-6); }
.dx-builder__line { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; font-family: var(--font-head); font-weight: 700; font-size: var(--fs-h4); }
.dx-builder__line .ds-select { width: auto; min-width: 220px; }
.dx-builder__result { margin-top: var(--sp-5); padding: var(--sp-4) var(--sp-5); border-radius: var(--radius); background: var(--bg-subtle); display: flex; gap: 0.6rem; align-items: center; color: var(--ink-soft); }
.dx-builder__result .ck { color: #16a34a; font-weight: 700; }
.dx-builder__snippet { margin-top: var(--sp-4); font-family: var(--font-mono); font-size: 0.78rem; line-height: 1.7; background: #14181f; color: #e6e9ee; border-radius: var(--radius); padding: var(--sp-4) var(--sp-5); overflow-x: auto; }
.dx-builder__snippet .m { color: #ff8f93; }
.dx-builder__snippet .v { color: #7ee0a1; }

/* --- 9r. Integration hero: "systems you run" + signal ripple ------- */
.dx-syshero { background: var(--band-bg); color: var(--band-ink); text-align: center; padding: var(--sp-8) 0 var(--sp-9); }
.dx-syshero__logo { margin-bottom: var(--sp-5); }
.dx-syshero__logo img { height: 40px; width: auto; margin: 0 auto; }
.dx-syshero__eyebrow { display: block; font-family: var(--font-mono); font-size: 0.72rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--band-accent); margin-bottom: var(--sp-3); }
.dx-syshero h1 { color: #fff; margin: 0; }
.dx-syshero__lead { color: var(--band-ink-soft); max-width: 680px; margin: var(--sp-4) auto 0; font-size: var(--fs-lead); }
.dx-syshero__note { color: var(--band-ink-soft); margin: var(--sp-4) 0 0; font-size: var(--fs-small); }
.dx-syshero .ds-btn--secondary { color: #fff; border-color: rgba(255,255,255,.45); }
.dx-syshero .ds-btn--secondary:hover { border-color: #fff; background: rgba(255,255,255,.08); }

.dx-sysbox { display: inline-block; border: 1px solid rgba(255,255,255,.14); border-radius: var(--radius); background: rgba(255,255,255,.04); overflow: hidden; max-width: 800px; margin-top: var(--sp-6); }
.dx-sysbox__hd { background: rgba(255,255,255,.06); font-family: var(--font-mono); font-size: 0.72rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: #e3ecf4; padding: 0.7rem 1.1rem; border-bottom: 1px solid rgba(255,255,255,.12); }
.dx-sysbox__bd { padding: var(--sp-4) var(--sp-5); }
.dx-sysbox__chips { display: flex; gap: 0.6rem; flex-wrap: wrap; justify-content: center; }
.dx-chip { font-family: var(--font-mono); font-size: 0.8rem; font-weight: 600; border-radius: 6px; padding: 0.4em 0.8em; background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.16); color: #dbe4ee; }

.dx-wave { position: relative; height: 66px; margin: var(--sp-2) 0 0; }
.dx-wave__src { position: absolute; left: 50%; top: 0; transform: translateX(-50%); width: 12px; height: 12px; border-radius: 50%; background: var(--band-accent); animation: dxPulse 2.4s ease-out infinite; }
.dx-wave__arc { position: absolute; left: 50%; top: 6px; width: 240px; height: 64px; transform: translateX(-50%) scale(.12); transform-origin: top center; border: 2px solid var(--band-accent); border-top: none; border-radius: 0 0 300px 300px; opacity: 0; animation: dxRipple 2.4s ease-out infinite; }
.dx-wave__arc.a1 { animation-delay: 0s; }
.dx-wave__arc.a2 { animation-delay: 0.8s; }
.dx-wave__arc.a3 { animation-delay: 1.6s; }
@keyframes dxRipple { 0% { transform: translateX(-50%) scale(.12); opacity: .85; } 70% { opacity: .22; } 100% { transform: translateX(-50%) scale(1); opacity: 0; } }
@keyframes dxPulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(222,29,35,.5); } 50% { box-shadow: 0 0 16px 3px rgba(222,29,35,.9); } }
@media (prefers-reduced-motion: reduce) {
	.dx-wave__arc { animation: none; transform: translateX(-50%) scale(1); }
	.dx-wave__arc.a1 { opacity: .6; } .dx-wave__arc.a2 { opacity: .38; } .dx-wave__arc.a3 { opacity: .2; }
	.dx-wave__src { animation: none; box-shadow: 0 0 12px rgba(222,29,35,.7); }
}

.dx-suite { display: flex; justify-content: center; gap: var(--sp-4); flex-wrap: wrap; margin: var(--sp-2) 0 var(--sp-6); }
.dx-dev { background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.12); border-radius: var(--radius); padding: var(--sp-4) var(--sp-4) var(--sp-3); width: 190px; }
.dx-dev .ds-photo { border: 0; min-height: 0; aspect-ratio: 4 / 3; margin-bottom: 0.6rem; background: rgba(255,255,255,.05); }
.dx-dev .ds-photo svg, .dx-dev .ds-photo .ds-photo__tag, .dx-dev .ds-photo .ds-photo__cap { color: rgba(255,255,255,.42); }
.dx-dev__n { font-family: var(--font-head); font-size: 0.95rem; font-weight: 700; color: #fff; }
.dx-dev__d { font-size: 0.78rem; color: var(--band-ink-soft); margin-top: 0.15rem; }

/* --- 9s. Interactive floor map — markers positioned in code -------- */
/* Replaces the old baked-in JPG: drop the facility floor plan behind
   .dx-floormap__map and place each .dx-pin with an inline left/top %.  */
.dx-floormap { display: grid; grid-template-columns: 1.55fr 1fr; gap: var(--sp-6); align-items: start; }
@media (max-width: 820px) { .dx-floormap { grid-template-columns: 1fr; } }

.dx-floormap__map {
	position: relative; aspect-ratio: 400 / 260; border: 1px solid var(--border);
	border-radius: var(--radius); overflow: hidden; background-color: #fff;
	background-image: linear-gradient(var(--border) 1px, transparent 1px), linear-gradient(90deg, var(--border) 1px, transparent 1px);
	background-size: 26px 26px; box-shadow: var(--shadow-sm);
}
.dx-floormap__plan { position: absolute; inset: 0; width: 100%; height: 100%; }
.dx-floormap__plan .wall { fill: none; stroke: #c3ccd8; stroke-width: 2; stroke-linecap: round; }
.dx-floormap__plan .rlbl { fill: #a7b1bf; font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.08em; text-transform: uppercase; }
.dx-floormap__tag { position: absolute; left: 10px; bottom: 10px; z-index: 2; font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); background: rgba(255,255,255,.85); border: 1px solid var(--border); border-radius: 5px; padding: 0.2em 0.5em; }

.dx-pin {
	position: absolute; transform: translate(-50%, -50%); z-index: 3;
	width: 30px; height: 30px; border-radius: 50%; cursor: pointer; padding: 0;
	background: var(--accent); color: #fff; border: 2px solid #fff; line-height: 1;
	font-family: var(--font-mono); font-weight: 600; font-size: 0.85rem;
	display: grid; place-items: center;
	box-shadow: 0 3px 10px -2px rgba(222,29,35,.55);
	transition: transform 0.15s ease, box-shadow 0.2s ease;
}
.dx-pin:hover, .dx-pin:focus-visible { transform: translate(-50%, -50%) scale(1.18); }
/* Dark ring rather than var(--accent): the pin is already accent-red, so a red
   outline would be invisible. Offset puts it outside the pin's white border,
   which keeps it legible over any floor-plan image. */
.dx-pin:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; }
.dx-pin.is-active { z-index: 4; animation: dxPinPulse 1.8s ease-out infinite; }
@keyframes dxPinPulse {
	0%, 100% { box-shadow: 0 4px 14px -2px rgba(222,29,35,.6), 0 0 0 5px rgba(222,29,35,.22); }
	50%      { box-shadow: 0 4px 14px -2px rgba(222,29,35,.6), 0 0 0 12px rgba(222,29,35,0); }
}

.dx-floormap__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.dx-fp { display: flex; gap: 0.85rem; align-items: flex-start; padding: 0.8rem 0.9rem; border: 1px solid var(--border); border-left: 3px solid transparent; border-radius: var(--radius); background: var(--surface); cursor: pointer; transition: background 0.15s ease, border-color 0.15s ease; }
.dx-fp:hover { background: var(--bg-subtle); }
.dx-fp:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.dx-fp.is-active { border-left-color: var(--accent); background: var(--accent-soft); }
.dx-fp__n { flex: 0 0 26px; width: 26px; height: 26px; border-radius: 50%; background: var(--ink); color: #fff; font-family: var(--font-mono); font-weight: 600; font-size: 0.82rem; display: grid; place-items: center; margin-top: 1px; }
.dx-fp.is-active .dx-fp__n { background: var(--accent); }
.dx-fp__body :is(h3, h4) { margin: 0 0 0.15rem; font-size: 1rem; }
.dx-fp__body p { margin: 0; color: var(--ink-soft); font-size: 0.88rem; }
@media (prefers-reduced-motion: reduce) { .dx-pin.is-active { animation: none; box-shadow: 0 4px 14px -2px rgba(222,29,35,.6), 0 0 0 6px rgba(222,29,35,.22); } }

/* --- 9t. Proof stat band — 4 big numbers on a dark band ----------- */
.dx-proofband { position: relative; overflow: hidden; }
.dx-proofband > .ds-container { position: relative; z-index: 1; }
.dx-proofband::before { content: ""; position: absolute; inset: 0; z-index: 0; background-image: repeating-linear-gradient(135deg, rgba(255,255,255,.03) 0 2px, transparent 2px 22px); }
.dx-proofstats { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-5); margin-top: var(--sp-7); }
@media (max-width: 720px) { .dx-proofstats { grid-template-columns: repeat(2, 1fr); gap: var(--sp-7) var(--sp-4); } }
.dx-proofstat { position: relative; text-align: center; padding: 0 0.5rem; }
@media (min-width: 721px) { .dx-proofstat + .dx-proofstat::before { content: ""; position: absolute; left: calc(var(--sp-5) / -2); top: 14%; bottom: 14%; width: 1px; background: rgba(255,255,255,.12); } }
.dx-proofstat__n { font-family: var(--font-head); font-weight: 800; font-size: clamp(2.4rem, 1.6rem + 3vw, 3.4rem); line-height: 1; color: #fff; letter-spacing: -0.02em; }
.dx-proofstat__l { color: var(--band-ink-soft); font-size: 0.9rem; margin-top: 0.6rem; }

/* --- 9u. Interactive scenario builder (trigger -> action) --------- */
.dx-scenario { max-width: 1000px; margin: 0 auto; }
.dx-scenario__wt { display: flex; align-items: stretch; gap: var(--sp-4); }
.dx-scenario__when { flex: 0 0 42%; max-width: 42%; }
.dx-scenario__then { flex: 1 1 0; }
.dx-scenario__arrow { flex: 0 0 40px; display: flex; align-items: center; justify-content: center; color: var(--accent); font-size: 1.7rem; }
@media (max-width: 760px) {
	.dx-scenario__wt { flex-direction: column; }
	.dx-scenario__when, .dx-scenario__then { flex-basis: auto; max-width: none; }
	.dx-scenario__arrow { transform: rotate(90deg); padding: 0.4rem 0; }
}
.dx-scenario__card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--sp-5); height: 100%; box-shadow: var(--shadow-sm); }
.dx-scenario__lbl { display: flex; align-items: center; gap: 0.5rem; font-family: var(--font-mono); font-size: 0.72rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: var(--sp-4); }
.dx-scenario__num { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 50%; background: var(--accent); color: #fff; font-size: 0.7rem; font-weight: 700; flex: 0 0 20px; }

.dx-trig { display: flex; align-items: center; gap: 0.7rem; padding: 0.6rem 0.75rem; border: 1.5px solid var(--border); border-radius: var(--radius); margin-bottom: 0.5rem; cursor: pointer; transition: border-color 0.12s ease, background 0.12s ease; }
.dx-trig:hover { border-color: #c9d3df; }
.dx-trig.is-sel { border-color: var(--accent); background: var(--accent-soft); }
.dx-trig__rad { flex: 0 0 18px; width: 18px; height: 18px; border-radius: 50%; border: 2px solid #c2ccd8; position: relative; }
.dx-trig.is-sel .dx-trig__rad { border-color: var(--accent); }
.dx-trig.is-sel .dx-trig__rad::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--accent); }
.dx-trig__l { font-size: 0.9rem; font-weight: 600; color: var(--ink); }
.dx-trig.is-any .dx-trig__l { font-style: italic; color: var(--ink-soft); font-weight: 500; }

.dx-opt { display: flex; flex-wrap: wrap; gap: 0.4rem 0.7rem; align-items: center; padding: 0.6rem 0.75rem; border: 1.5px solid var(--border); border-radius: var(--radius); margin-bottom: 0.5rem; cursor: pointer; transition: border-color 0.12s ease, background 0.12s ease; }
.dx-opt:hover { border-color: #c9d3df; }
.dx-opt.is-on { border-color: var(--accent); background: var(--accent-soft); }
.dx-opt__box { flex: 0 0 20px; width: 20px; height: 20px; border-radius: 5px; border: 2px solid #c2ccd8; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 0.72rem; }
.dx-opt.is-on .dx-opt__box { background: var(--accent); border-color: var(--accent); }
.dx-opt__ic { flex: 0 0 22px; width: 22px; height: 22px; color: var(--accent); }
.dx-opt__ic svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; display: block; }
.dx-opt__l { flex: 0 0 auto; max-width: 100%; font-size: 0.9rem; font-weight: 600; color: var(--ink); }
.dx-opt__s { display: block; font-weight: 400; color: var(--ink-soft); font-size: 0.78rem; margin-top: 1px; }
.dx-opt__extra { margin-left: auto; display: flex; align-items: center; flex-shrink: 0; gap: 0.35rem; }
.dx-dot { width: 18px; height: 18px; border-radius: 50%; border: 0; box-shadow: 0 0 0 1px #cbd5e1; cursor: pointer; padding: 0; }
.dx-dot--red { background: #e5484d; } .dx-dot--amber { background: #f5a623; } .dx-dot--green { background: #2fa968; } .dx-dot--blue { background: #4a90d9; }
.dx-dot.is-sel { box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--ink); }
.dx-dot:disabled { opacity: 0.3; cursor: default; box-shadow: 0 0 0 1px #cbd5e1; }
.dx-pill { border: 1px solid var(--border); background: var(--surface); border-radius: 999px; padding: 0.15rem 0.55rem; font-size: 0.72rem; cursor: pointer; color: var(--ink-soft); font-family: var(--font-mono); }
.dx-pill.is-sel { background: var(--accent); border-color: var(--accent); color: #fff; }
.dx-pill:disabled { opacity: 0.4; cursor: default; }

.dx-scenario__sum { margin-top: var(--sp-5); background: #eaf7ef; border: 1px solid #b7e4c7; border-radius: var(--radius); padding: 0.9rem 1.3rem; font-size: 0.95rem; color: #1a2230; text-align: center; line-height: 1.55; }
.dx-scenario__sum b { color: #14181f; }
.dx-scenario__note { margin-top: var(--sp-5); display: flex; gap: 1rem; align-items: flex-start; background: var(--bg-subtle); border: 1px solid var(--border); border-radius: var(--radius); padding: var(--sp-5); }
.dx-scenario__note-ic { flex: 0 0 44px; width: 44px; height: 44px; border-radius: 10px; background: var(--accent-soft); display: flex; align-items: center; justify-content: center; color: var(--accent); }
.dx-scenario__note-ic svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.dx-scenario__note b { font-size: 1rem; color: var(--ink); }
.dx-scenario__note p { margin: 0.4rem 0 0; font-size: 0.9rem; color: var(--ink-soft); line-height: 1.6; }
@media (max-width: 760px) { .dx-scenario__note { flex-direction: column; gap: 0.6rem; } }

/* ==================================================================
   SHOPIFY BUY / CART  (design-system port of the .sc-* components)
   custom.css is not loaded on DS pages, so the product grid, product
   modal, cart drawer and FAB are re-skinned here with DS tokens.
   ================================================================== */

/* Product grid cards (rendered by shopify-cart.js in DS mode) */
.sc-product-card { padding: 0; overflow: hidden; display: flex; flex-direction: column; height: 100%; }
.sc-product-img { width: 100%; display: block; aspect-ratio: 1 / 1; object-fit: contain; background: #fff; padding: var(--sp-4); }
.sc-product-title { padding: 0 var(--sp-5); margin: var(--sp-3) 0 var(--sp-2); font-size: var(--fs-h4); }
.sc-product-price { padding: 0 var(--sp-5); margin-bottom: var(--sp-4); }
.sc-product-amount { font-family: var(--font-head); font-weight: 800; font-size: 1.4rem; color: var(--ink); }
.sc-product-compare { text-decoration: line-through; color: var(--ink-faint); font-weight: 600; margin-right: 0.4rem; }
.sc-product-card .sc-see-details { margin-top: auto; border-radius: 0; }
.sc-loading { text-align: center; padding: 40px 0; font-size: 1.1em; color: var(--ink-soft); }

/* Reset stray margins on buttons inside the custom overlays */
.sc-modal button, .sc-cart-drawer button { margin: 0; }

/* Product modal */
.sc-modal-overlay { position: fixed; inset: 0; background: rgba(15,23,41,0.6); z-index: 10000; display: flex; align-items: center; justify-content: center; overflow-y: auto; padding: 20px; }
.sc-modal { background: var(--surface); max-width: 960px; width: 100%; display: flex; position: relative; border-radius: var(--radius-sm); max-height: 90vh; overflow: hidden; }
.sc-modal-images { flex: 1 1 50%; position: relative; min-width: 0; display: flex; flex-direction: column; align-items: center; padding: 20px; overflow-y: auto; max-height: 90vh; }
.sc-modal-main-img { width: 100%; max-height: 400px; object-fit: contain; display: block; }
.sc-img-arrow { position: absolute; top: 50%; transform: translateY(-80%); font-size: 3em; background: none; border: none; color: var(--ink-faint); cursor: pointer; padding: 0 8px; z-index: 2; line-height: 1; }
.sc-img-arrow:hover { color: var(--ink); }
.sc-img-prev { left: 0; }
.sc-img-next { right: 0; }
.sc-thumb-row { display: flex; gap: 8px; margin-top: 12px; justify-content: center; flex-wrap: wrap; }
.sc-thumb { width: 60px; height: 60px; object-fit: cover; border: 2px solid transparent; cursor: pointer; border-radius: var(--radius-sm); }
.sc-thumb-active { border-color: var(--accent); }
.sc-modal-details { flex: 1 1 50%; padding: 24px 28px 28px; overflow-y: auto; max-height: 90vh; }
.sc-modal-title { font-size: 1.6em; font-weight: 700; margin-top: 0; margin-bottom: 0.4em; padding-right: 40px; line-height: 1.3; }
.sc-modal-close { position: absolute; top: 0; right: 0; padding: 12px 16px; font-size: 1.4em; line-height: 1; background: none; border: none; color: var(--ink-soft); cursor: pointer; z-index: 20; }
.sc-modal-close:hover { color: var(--ink); }
.sc-modal-pricing { margin-bottom: 1em; }
.sc-modal-price { font-size: 1.5em; font-weight: 700; color: var(--ink); }
.sc-modal-compare { font-size: 1.25em; text-decoration: line-through; color: var(--ink-faint); margin-right: 0.5em; }
.sc-modal-actions { display: flex; gap: 10px; align-items: stretch; margin-bottom: 1.5em; }
input.sc-qty { width: 60px; flex: 0 0 60px; text-align: center; font-size: 1em; padding: 0 8px; height: 46px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); box-sizing: border-box; }
.sc-add-to-cart { background: var(--accent); color: var(--accent-ink); border: none; padding: 0 28px; height: 46px; font-size: 1em; cursor: pointer; border-radius: var(--radius-sm); font-weight: 600; white-space: nowrap; display: flex; align-items: center; }
.sc-add-to-cart:hover { background: var(--accent-hover); }
.sc-modal-description { font-size: 0.95em; line-height: 1.6; color: var(--ink-soft); }
.sc-modal-description :is(h3, h4) { margin-top: 14px; margin-bottom: 3px; font-size: 1.05em; font-weight: 700; color: var(--ink); }
.sc-modal-description ul { padding-left: 20px; margin-top: 2px; margin-bottom: 8px; }

/* Spinner */
.sc-spinner { display: inline-block; width: 16px; height: 16px; border: 2px solid rgba(255,255,255,0.4); border-top-color: #fff; border-radius: 50%; animation: sc-spin 0.7s linear infinite; vertical-align: middle; }
.sc-spinner-sm { width: 11px; height: 11px; border-color: rgba(0,0,0,0.15); border-top-color: var(--ink-soft); }
.sc-btn-loading { opacity: 0.8; cursor: not-allowed; }
@keyframes sc-spin { to { transform: rotate(360deg); } }

/* Cart drawer */
.sc-cart-backdrop { position: fixed; inset: 0; background: rgba(15,23,41,0.4); z-index: 10002; opacity: 0; transition: opacity 0.3s; }
.sc-cart-backdrop-visible { opacity: 1; }
.sc-cart-drawer { position: fixed; top: 0; right: -380px; width: 380px; height: 100%; background: var(--surface); z-index: 10003; display: flex; flex-direction: column; box-shadow: -2px 0 8px rgba(0,0,0,0.15); transition: right 0.3s ease; }
.sc-cart-open { right: 0; }
.sc-cart-header { display: flex; justify-content: space-between; align-items: center; padding: 15px 20px; border-bottom: 1px solid var(--border); }
.sc-cart-title { font-size: 1.5em; font-weight: 700; }
.sc-cart-close { font-size: 1.8em; background: none; border: none; cursor: pointer; line-height: 1; color: var(--ink); }
.sc-cart-items { flex: 1; overflow-y: auto; padding: 15px 20px; }
.sc-cart-empty { text-align: center; color: var(--ink-soft); padding: 30px 0; }
.sc-cart-item { display: flex; align-items: flex-start; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--border); }
.sc-cart-item-img { width: 80px; height: 80px; object-fit: cover; border-radius: var(--radius-sm); flex-shrink: 0; }
.sc-cart-item-info { flex: 1; min-width: 0; }
.sc-cart-item-title { font-weight: 600; font-size: 0.9em; margin-bottom: 6px; }
.sc-cart-item-qty { display: flex; align-items: center; gap: 8px; }
.sc-qty-btn { width: 28px; height: 28px; border: 1px solid var(--border-strong); background: var(--surface); cursor: pointer; font-size: 1em; line-height: 1; border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center; }
.sc-qty-btn:hover { background: var(--bg-subtle); }
.sc-qty-val { min-width: 20px; text-align: center; font-size: 0.95em; }
.sc-cart-item-right { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex-shrink: 0; }
.sc-cart-item-price { font-weight: 600; font-size: 0.95em; white-space: nowrap; }
.sc-cart-item-remove { background: none; border: none; color: var(--ink-faint); cursor: pointer; font-size: 1.2em; line-height: 1; padding: 2px 4px; }
.sc-cart-item-remove:hover { color: var(--accent); }
.sc-cart-footer { border-top: 1px solid var(--border); padding: 15px 20px; }
.sc-cart-note { margin-bottom: 0.8em; }
.sc-cart-note-toggle { display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; background: none; border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 8px 12px; font-size: 0.9em; color: var(--ink-soft); cursor: pointer; }
.sc-cart-note-toggle:hover { background: var(--bg-subtle); }
.sc-note-arrow { font-size: 0.8em; }
.sc-cart-note-input { width: 100%; min-height: 60px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: 8px; font-size: 0.9em; resize: vertical; margin-top: 0.5em; box-sizing: border-box; }
.sc-cart-subtotal { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.3em; }
.sc-cart-subtotal-label { font-size: 1.25em; font-weight: 600; }
.sc-cart-subtotal-amount { font-size: 1.25em; font-weight: 700; }
.sc-cart-notice { font-size: 1em; color: var(--ink-soft); margin-bottom: 1em; }
.sc-cart-checkout { display: block; width: 100%; padding: 12px; background: var(--accent); color: var(--accent-ink); border: none; font-size: 1.25em; font-weight: 700; text-transform: uppercase; cursor: pointer; border-radius: var(--radius-sm); letter-spacing: 0.5px; }
.sc-cart-checkout:hover { background: var(--accent-hover); }

/* Cart FAB */
.sc-cart-fab { position: fixed; bottom: 24px; right: 24px; width: 56px; height: 56px; background: var(--band-bg, #0f1729); color: #fff; border: none; border-radius: 50%; cursor: pointer; display: none; align-items: center; justify-content: center; box-shadow: 0 4px 14px rgba(0,0,0,0.3); z-index: 9999; transition: background 0.2s; }
.sc-cart-fab:hover { background: #000; }
.sc-cart-fab-badge { position: absolute; top: -4px; right: -4px; background: var(--accent); color: var(--accent-ink); font-size: 11px; font-weight: 700; width: 20px; height: 20px; border-radius: 50%; display: flex; align-items: center; justify-content: center; line-height: 1; }

/* Responsive: modal & cart */
@media (max-width: 768px) {
	.sc-modal-overlay { padding: 0; align-items: flex-start; overflow-y: auto; }
	.sc-modal { flex-direction: column; width: 100%; max-width: 100%; min-height: 100vh; max-height: none; height: auto; border-radius: 0; overflow: visible; }
	.sc-modal-images { flex: none; width: 100%; max-height: none; overflow: visible; padding: 40px 16px 8px; }
	.sc-modal-details { flex: none; min-height: 0; width: 100%; max-height: none; overflow: visible; padding: 12px 16px 48px; }
	.sc-modal-title { font-size: 1.3em; padding-right: 44px; }
	.sc-modal-close { position: fixed; top: 8px; right: 8px; width: 36px; height: 36px; padding: 0; display: flex; align-items: center; justify-content: center; background: rgba(255,255,255,0.92); border-radius: 50%; box-shadow: 0 1px 5px rgba(0,0,0,0.2); font-size: 1.3em; z-index: 10010; }
	.sc-modal-pricing { margin-bottom: 0.7em; }
	.sc-modal-price { font-size: 1.3em; }
	.sc-modal-compare { font-size: 1.1em; }
	.sc-modal-actions { margin-bottom: 1em; }
	.sc-cart-drawer { width: 100%; right: -100%; }
	.sc-cart-open { right: 0; }
	.sc-cart-fab { bottom: 16px; right: 16px; }
}

/* =====================================================================
   10. Reusable landing-page patterns folded from the Medical
   Call-Button page. Design-system components (.dx-logowall,
   .dx-cfg-*, .dx-faq-cta), token-based, additive. (The page's hero +
   device-cluster CSS stays inline on the page: it is page-specific.)
   ===================================================================== */

/* --- 10a. Customer logo marquee (multi-specialty proof strip) ------- */
.dx-proof-stat { color:var(--accent); font-weight:800; }
.dx-logowall__tile {
	position:relative; display:flex; flex-direction:column; align-items:center; gap:var(--sp-2);
	margin:0; padding:var(--sp-4) var(--sp-3) var(--sp-3);
	background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-sm);
	transition:border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}
.dx-logowall__tile:hover { border-color:var(--border-strong); box-shadow:var(--shadow-sm); transform:translateY(-2px); }
.dx-logowall__img { height:52px; width:100%; display:flex; align-items:center; justify-content:center; }
.dx-logowall__img img { max-height:52px; max-width:100%; width:auto; object-fit:contain; }
.dx-logowall__name {
	font-size:.76rem; line-height:1.2; font-weight:600; color:var(--ink-soft);
	text-align:center; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
/* margin-top:auto pins the tag to the bottom of the tile; tiles in a row stretch
 * to equal height, so every tag lands on the same baseline regardless of whether
 * the name above it is 1 or 2 lines. */
.dx-logowall__chip { margin-top:auto; font-size:.62rem; font-weight:700; letter-spacing:.03em; text-transform:uppercase; padding:2px 8px; border-radius:999px; white-space:nowrap; }
.dx-logowall { display:flex; flex-direction:column; gap:var(--sp-3); padding:var(--sp-2) 0; overflow-x:clip; overflow-y:visible; -webkit-mask-image:linear-gradient(90deg,transparent,#000 5%,#000 95%,transparent); mask-image:linear-gradient(90deg,transparent,#000 5%,#000 95%,transparent); }
.dx-logowall__row { display:flex; gap:var(--sp-3); width:max-content; animation:dxLogowallScroll linear infinite; }
.dx-logowall__row:hover { animation-play-state:paused; }
/* Duration scales with row length: the loop is one row-width of travel, so a
 * fixed duration makes a long row race past. Pages with many logos set
 * --dx-lw-dur to hold the speed at roughly 20px/s. */
.dx-logowall__row--1 { animation-duration:var(--dx-lw-dur,60s); }
.dx-logowall__row--2 { animation-duration:calc(var(--dx-lw-dur,60s) * 1.25); animation-direction:reverse; }
.dx-logowall__row--3 { animation-duration:calc(var(--dx-lw-dur,60s) * 1.13); }
.dx-logowall__row .dx-logowall__tile { width:150px; flex:none; }
/* Reduced motion: a wall that scrolls by itself is exactly what the preference asks us
 * not to do, and CSS is the only lever because the movement is a keyframe animation.
 * Stopping it alone would strand every logo past the right edge inside overflow-x:clip,
 * so hand the scrolling to the reader instead. Same strip, same order, now driven by a
 * swipe or a scrollbar rather than a clock. The edge fade goes with it: it existed to
 * sell the motion, and it would otherwise hide the ends of a strip nobody is moving. */
@media (prefers-reduced-motion: reduce) {
	.dx-logowall { -webkit-mask-image:none; mask-image:none; overflow-x:auto; }
	.dx-logowall__row { animation:none; }
}
@keyframes dxLogowallScroll { from { transform:translateX(0); } to { transform:translateX(-50%); } }
/* Static variant, for a curated set of 4-8 logos. A scrolling row needs
   enough tiles that the loop never shows the same logo twice on screen;
   below that it reads as a glitch, so the small sets sit still and centred
   in the same tile instead.
   Set --dx-lw-cols to the number of tiles you want per row; the wall caps its
   own width to that many so eight logos break 4 + 4 instead of 6 + 2. */
.dx-logowall--static {
	flex-direction:row; flex-wrap:wrap; justify-content:center; gap:var(--sp-4);
	overflow:visible; -webkit-mask-image:none; mask-image:none;
	max-width:calc(var(--dx-lw-cols, 6) * 172px + (var(--dx-lw-cols, 6) - 1) * var(--sp-4));
	margin-left:auto; margin-right:auto;
}
.dx-logowall--static .dx-logowall__tile { width:172px; flex:none; }
@media (max-width:600px){ .dx-logowall--static { gap:var(--sp-3); max-width:none; } .dx-logowall--static .dx-logowall__tile { width:138px; } }
@media (max-width:600px){
	.dx-logowall__row .dx-logowall__tile { width:128px; }
	.dx-logowall__img, .dx-logowall__img img { height:44px; max-height:44px; }
}
@media (prefers-reduced-motion:reduce){
	.dx-logowall__row { animation:none; }
	.dx-logowall { overflow-x:auto; }
}

/* --- 10b. Build-your-system configurator (instant-quote replacement)  */
/* Fixed aside: a checkout panel has one comfortable size. A fractional ratio
 * renders it differently on every page whose list column differs, which is how
 * the flat and area configurators drifted apart visibly. */
.dx-cfg-grid { display:grid; grid-template-columns:minmax(0,1fr) 420px; gap:var(--sp-6); align-items:start; }
@media (max-width:900px){ .dx-cfg-grid { grid-template-columns:1fr; } .dx-cfg-grid > *, .dx-cfg-row > div, .dx-cfg-base > div { min-width:0; } }
/* align-items:start collapses the aside column to the panel's own height, which
 * leaves position:sticky below with zero travel. Stretch just that column. */
.dx-cfg-grid > *:last-child { align-self:stretch; }
.dx-cfg-base { display:flex; align-items:center; gap:var(--sp-4); background:var(--bg-subtle); border:1px solid var(--border); border-radius:var(--radius); padding:var(--sp-5); margin-bottom:var(--sp-5); }
.dx-cfg-base__img { width:64px; height:64px; object-fit:contain; flex:none; }
.dx-cfg-base :is(h3, h4) { margin:0 0 var(--sp-2); font-size:var(--fs-body); }
.dx-cfg-base p { margin:0; color:var(--ink-soft); font-size:var(--fs-small); }
.dx-cfg-base .dx-cfg-inc { display:inline-block; background:var(--accent); color:#fff; font-family:var(--font-mono); font-size:11px; letter-spacing:.06em; text-transform:uppercase; padding:3px 10px; border-radius:999px; margin-bottom:var(--sp-2); }
.dx-cfg-row { display:flex; align-items:center; gap:var(--sp-4); padding:var(--sp-4) 0; border-bottom:1px solid var(--border); }
.dx-cfg-row:last-child { border-bottom:0; }
.dx-cfg-thumb { width:56px; height:56px; object-fit:contain; flex:none; }
.dx-cfg-row__info { flex:1; }
.dx-cfg-row__info :is(h3, h4) { margin:0; font-size:var(--fs-body); }
.dx-cfg-row__info .dx-cfg-sub { color:var(--ink-soft); font-size:var(--fs-small); }
.dx-cfg-row__info .dx-cfg-help { color:var(--ink-faint); font-size:var(--fs-small); margin-top:2px; }
.dx-cfg-row__price { color:var(--ink-soft); font-size:var(--fs-small); white-space:nowrap; }
.dx-cfg-step { display:inline-flex; align-items:center; border:1px solid var(--border); border-radius:999px; overflow:hidden; }
.dx-cfg-step button { width:38px; height:38px; border:0; background:var(--surface); font-size:1.3rem; line-height:1; cursor:pointer; color:var(--ink); }
.dx-cfg-step button:hover { background:var(--bg-subtle); }
.dx-cfg-step input { width:46px; height:38px; border:0; border-left:1px solid var(--border); border-right:1px solid var(--border); text-align:center; font-size:1rem; font-family:var(--font-head); font-weight:700; }
@media (max-width:560px){ .dx-cfg-row { flex-wrap:wrap; row-gap:var(--sp-3); } .dx-cfg-row__info { flex:1 1 150px; } .dx-cfg-step { margin-left:auto; } }
/* No max-height: capping it to the viewport puts a scrollbar inside the panel on
 * any short window, which is worse than letting the panel run past the fold. */
.dx-cfg-sum { position:sticky; top:var(--sp-5); background:var(--surface); border:1px solid var(--border); border-radius:var(--radius); padding:var(--sp-6); box-shadow:0 12px 34px rgba(15,27,45,.10); }
/* Single column: the panel is simply the last block on the page, so there is
 * nothing for it to stick to. */
@media (max-width:900px){ .dx-cfg-sum { position:static; } }
.dx-cfg-sum h3 { margin:0 0 var(--sp-4); font-size:var(--fs-h4); }
.dx-cfg-line { display:flex; justify-content:space-between; gap:var(--sp-3); font-size:var(--fs-small); padding:5px 0; color:var(--ink); }
.dx-cfg-line span:last-child { white-space:nowrap; }
/* Product name first, count as metadata: keeps the names in a flush-left column
 * you can scan, matches the rows on the left and the Shopify cart we hand off to. */
.dx-cfg-line__q { color:var(--ink-faint); }
.dx-cfg-line > span:last-child { font-variant-numeric:tabular-nums; }
.dx-cfg-line--auto { color:var(--ink-faint); font-style:italic; }
.dx-cfg-line--muted span { color:var(--ink-faint); }
.dx-cfg-empty { color:var(--ink-faint); font-size:var(--fs-small); }
.dx-cfg-hr { border:0; border-top:1px solid var(--border); margin:var(--sp-3) 0; }
.dx-cfg-sub-row { display:flex; justify-content:space-between; font-size:var(--fs-small); color:var(--ink-soft); }
.dx-cfg-promo { display:flex; justify-content:space-between; font-size:var(--fs-small); color:#1a7f37; font-weight:600; }
.dx-cfg-total { display:flex; justify-content:space-between; align-items:baseline; margin-top:var(--sp-3); }
.dx-cfg-total .dx-cfg-total__amt { font-family:var(--font-head); font-weight:800; font-size:2rem; line-height:1; }
/* The note qualifies the number above it (one idea, so it can be quiet); the
 * guarantees that reverse risk sit in .dx-cfg-trust under the buttons instead. */
.dx-cfg-note { color:var(--ink-faint); font-size:var(--fs-small); margin:var(--sp-2) 0 var(--sp-5); }
.dx-cfg-cta { display:flex; flex-direction:column; gap:var(--sp-3); }
.dx-cfg-checkout.is-off { opacity:.5; pointer-events:none; }
.dx-cfg-trust { display:flex; align-items:center; justify-content:center; gap:var(--sp-2); margin:var(--sp-3) 0 0; font-size:var(--fs-small); color:var(--ink-soft); }
.dx-cfg-trust svg { width:15px; height:15px; flex:none; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; color:var(--ink-faint); }
.dx-cfg-ready { border:1px solid var(--border); border-radius:var(--radius); background:var(--bg-subtle); padding:var(--sp-4); margin:0 0 var(--sp-5); }
/* line-height is pinned to the body value this label had as an h5, which sits
   outside the base h1-h4 rule. */
.dx-cfg-ready :is(h4, h5) { margin:0 0 var(--sp-3); font-size:11px; line-height:1.65; text-transform:uppercase; letter-spacing:.06em; color:var(--ink-soft); font-family:var(--font-mono); }
/* Tracks the REQUIRED checks only, so advisory lines never make a complete
 * system look incomplete. */
.dx-cfg-bar { height:6px; border-radius:4px; background:var(--border); overflow:hidden; margin:0 0 var(--sp-3); }
.dx-cfg-bar > span { display:block; height:100%; width:0; background:#1a9d5a; transition:width .3s; }
.dx-cfg-chk { display:flex; align-items:flex-start; gap:var(--sp-2); font-size:var(--fs-small); padding:3px 0; color:var(--ink); }
.dx-cfg-dot { width:18px; height:18px; border-radius:50%; flex:none; display:grid; place-items:center; font-size:11px; color:#fff; margin-top:1px; }
.dx-cfg-dot.ok { background:#1a9d5a; }
.dx-cfg-dot.inc { background:#1a9d5a; }
.dx-cfg-dot.no { background:var(--border); color:var(--ink-faint); }
.dx-cfg-dot.info { background:#2f6fb0; font-family:var(--font-head); }
.dx-cfg-dot.warn { background:#c9860a; }
.dx-cfg-chk--tip span:last-child { color:var(--ink-soft); }
.dx-cfg-expert { color:var(--ink-soft); font-size:var(--fs-small); }
.dx-cfg-expert a { color:var(--accent); font-weight:600; }
.dx-cfg-helpfoot { display:flex; gap:.7rem; align-items:flex-start; margin-top:var(--sp-4); padding-top:var(--sp-4); border-top:1px solid var(--border); }
.dx-cfg-helpfoot__ic { flex:none; width:34px; height:34px; border-radius:9px; background:var(--accent-soft); color:var(--accent); display:grid; place-items:center; }
.dx-cfg-helpfoot__ic svg { width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.dx-cfg-helpfoot strong { display:block; font-size:var(--fs-small); }
.dx-cfg-helpfoot__t { display:block; color:var(--ink-soft); font-size:var(--fs-small); margin:1px 0 3px; }
.dx-cfg-helpfoot a { color:var(--accent); font-weight:600; font-size:var(--fs-small); }
.dx-cfg-email__note { font-size:var(--fs-small); margin:var(--sp-2) 0 0; min-height:1.1em; text-align:center; }
.dx-cfg-email__note.err { color:#b42318; }
.dx-cfg-email__note.ok { color:#1a7f37; }

/* --- 10c. FAQ + Talk-to-an-expert shared band spacing --------------- */
/* FAQ + Talk-to-an-expert share one tinted band: drop the doubled section
   padding between them so the CTA reads as part of the FAQ. */
.dx-faq-cta > section:first-of-type { padding-bottom: var(--sp-7); }
.dx-faq-cta > section:last-of-type { padding-top: 0; }
@media (max-width:600px){ .dx-faq-cta > section:first-of-type { padding-bottom: var(--sp-6); } }

/* --- 10d. Build-by-area configurator: the step accordion only ------- */
/* The area variant (nurse call) differs from the flat one on the LEFT only:
   a step accordion whose rows can repeat the same SKU per area. Its "Your
   system" panel is the shared .dx-cfg-* panel above. Lives here rather than
   inside includes/components/configurator-area.php so the next page that
   reuses the component cannot fork the styling again. */
.dx-ac-steps { min-width:0; }
.dx-ac-step { border:1px solid var(--border); border-radius:var(--radius); margin-bottom:var(--sp-4); overflow:hidden; background:var(--surface); }
.dx-ac-step__hd { padding:var(--sp-4) var(--sp-5); font-weight:800; display:flex; justify-content:space-between; align-items:center; gap:var(--sp-3); background:var(--bg-subtle); border-bottom:1px solid var(--border); }
.dx-ac-step__n { display:flex; align-items:center; gap:var(--sp-3); }
.dx-ac-step__num { width:26px; height:26px; border-radius:50%; background:var(--ink); color:#fff; display:grid; place-items:center; font-size:0.82rem; flex:none; }
.dx-ac-step__sum { font-weight:600; color:var(--ink-faint); font-size:var(--fs-small); white-space:nowrap; flex:none; }
.dx-ac-step__body { padding:var(--sp-4) var(--sp-5); }
.dx-ac-hint { color:var(--ink-soft); font-size:var(--fs-small); margin:0 0 var(--sp-4); }
.dx-ac-row { display:flex; align-items:center; gap:var(--sp-4); padding:var(--sp-3) 0; border-bottom:1px solid var(--border); }
.dx-ac-row:last-child { border-bottom:0; }
.dx-ac-thumb { width:58px; height:58px; object-fit:contain; background:var(--bg-subtle); border:1px solid var(--border); border-radius:10px; flex:none; }
.dx-ac-row__info { flex:1; min-width:0; }
.dx-ac-row__info :is(h3, h4) { margin:0; font-size:var(--fs-body); }
.dx-ac-badge { display:inline-block; background:rgba(47,109,246,.1); color:var(--accent); border:1px solid rgba(47,109,246,.25); border-radius:6px; font-size:0.6rem; padding:1px 6px; font-weight:800; vertical-align:middle; letter-spacing:.03em; }
.dx-ac-sub { color:var(--ink-faint); font-size:0.78rem; margin-top:2px; }
.dx-ac-row__price { font-weight:700; font-size:0.9rem; white-space:nowrap; }
.dx-ac-step2 { display:flex; align-items:center; flex:none; }
.dx-ac-step2 button { width:32px; height:34px; border:1px solid var(--border); background:var(--surface); font-size:1.1rem; line-height:1; cursor:pointer; border-radius:8px; color:var(--ink-soft); }
.dx-ac-step2 button:hover { border-color:var(--accent); color:var(--accent); }
.dx-ac-step2 input { width:50px; height:34px; text-align:center; border:1px solid var(--border); border-radius:8px; margin:0 6px; font-size:0.95rem; -moz-appearance:textfield; }
.dx-ac-step2 input::-webkit-outer-spin-button, .dx-ac-step2 input::-webkit-inner-spin-button { -webkit-appearance:none; margin:0; }
/* Same wrap as .dx-cfg-row @560 — without it, price+qty crush the sub-copy on phone.
   flex-start keeps the price on the product-name line (not vertically centered on the sub). */
@media (max-width:560px){ .dx-ac-row { flex-wrap:wrap; align-items:flex-start; row-gap:var(--sp-3); } .dx-ac-row__info { flex:1 1 150px; } .dx-ac-step2 { margin-left:auto; } }

/* --- 10e. Quote-led pricing: one anchor price, no cart -------------- */
/* For considered-purchase pages (Andon, integration platform) that must set
   a budget expectation without a configurator: a .ds-price--featured card
   with one "from" number and what it includes, beside the drivers that move
   that number and an ROI note. Put both inside a .ds-grid--2. */
.ds-price > .ds-badge { align-self: flex-start; }
.ds-price > .ds-badge + .ds-price__amount { margin-top: var(--sp-4); }
/* Sub-label reads as its own line under the number, not as inline text
   inheriting the amount's display line-height. */
.ds-price__amount small { display: block; margin-top: var(--sp-2); line-height: 1.45; }
/* .ds-btn is nowrap, which on a phone makes a long CTA label set the card's
   min-content width and push the page into horizontal scroll. A full-width
   button inside the card can wrap instead. */
.ds-price .ds-btn--block { white-space: normal; }
.dx-price-note { font-size: var(--fs-small); color: var(--ink-faint); text-align: center; margin: var(--sp-3) 0 0; }
.dx-price-drivers { list-style: none; margin: var(--sp-4) 0 0; padding: 0; }
.dx-price-drivers li { position: relative; padding: 7px 0 7px 24px; color: var(--ink-soft); }
.dx-price-drivers li::before { content: ""; position: absolute; left: 0; top: 15px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
.dx-price-drivers li strong { color: var(--ink); font-weight: 600; }
.dx-price-roi { background: var(--accent-soft); border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent); border-radius: var(--radius-lg); padding: var(--sp-5) var(--sp-6); margin-top: var(--sp-6); }
.dx-price-roi p { margin: 0; color: var(--ink-soft); }
.dx-price-roi strong { color: var(--accent); }

/* --- 10g. Pinned narration bar ------------------------------------- */
/* The shell only. Everything inside sits in a shadow root, styled by rules
   the embed ships alongside the bar, so the pinned copy cannot drift from
   the original it stands in for. Driven by initNarrPin() in site-ds.js.
   pointer-events:none because it is a readout, not a control -- whatever
   it passes over stays clickable through it. */
.dx-narr-pin { position: fixed; z-index: 60; display: none; pointer-events: none; }
.dx-narr-pin.is-on { display: block; }
@media print { .dx-narr-pin { display: none !important; } }
