/* ==========================================================================
   cms-blocks.css — generic CMS marketing blocks + CMS page chrome
   (hero-band, card-grid, stats-strip, steps, statement-banner, badge-row,
   product-grid, collection-grid, rich text, page fallbacks).

   Rendered by lib/components/cms/cms_content_blocks.dart and lib/pages/
   cms_page.dart. Shared by CMS pages, the homepage and PDPs.

   Theme-agnostic: everything reads design tokens; an area shell (e.g. the
   dark Noedra area, Stage 2) only redefines the tokens. Sub-brand accents
   are `[data-suite]` scoped so a card can carry its own accent inside a
   page with another one.

   House rules (scripts/ui-audit/lint-css.mjs): no px except hairlines, no raw
   vw (use var(--vwx)), rem everywhere.
   ========================================================================== */

/* ---- accent tokens ------------------------------------------------------ */
:root {
  --cms-accent: var(--se-brand-purple);
  --cms-accent-soft: rgba(100, 30, 140, 0.1);
  --cms-accent-ink: var(--color-white);
  /* Sub-brand palette (Noedra suites) — the one place these hex values live. */
  --suite-core: #8b6ef6;
  --suite-core-soft: rgba(139, 110, 246, 0.16);
  --suite-node: #f7c948;
  --suite-node-2: #3adf8c;
  --suite-node-soft: rgba(247, 201, 72, 0.14);
  --suite-flow: #3bb4f2;
  --suite-flow-2: #5ce5e8;
  --suite-flow-soft: rgba(59, 180, 242, 0.14);
  --suite-shield: #a06cf5;
  --suite-shield-2: #c89bff;
  --suite-shield-soft: rgba(160, 108, 245, 0.16);
  --suite-atlas: #35c46a;
  --suite-atlas-2: #7fe0a8;
  --suite-atlas-soft: rgba(53, 196, 106, 0.14);
  /* surfaces used by the blocks (light shop defaults) */
  --cms-surface: var(--color-white);
  --cms-surface-alt: var(--color-gray-50);
  --cms-surface-raised: var(--color-white);
  --cms-line: var(--color-gray-200);
  --cms-text: var(--color-gray-900);
  --cms-text-2: var(--color-gray-600);
  --cms-text-3: var(--color-gray-500);
}
[data-suite="core"] {
  --cms-accent: var(--suite-core);
  --cms-accent-soft: var(--suite-core-soft);
  --cms-accent-ink: #0f0925;
}
[data-suite="node"] {
  --cms-accent: var(--suite-node);
  --cms-accent-soft: var(--suite-node-soft);
  --cms-accent-ink: #141103;
}
[data-suite="flow"] {
  --cms-accent: var(--suite-flow);
  --cms-accent-soft: var(--suite-flow-soft);
  --cms-accent-ink: #03131c;
}
[data-suite="shield"] {
  --cms-accent: var(--suite-shield);
  --cms-accent-soft: var(--suite-shield-soft);
  --cms-accent-ink: #12081f;
}
[data-suite="atlas"] {
  --cms-accent: var(--suite-atlas);
  --cms-accent-soft: var(--suite-atlas-soft);
  --cms-accent-ink: #04140a;
}

/* ---- page + section chrome --------------------------------------------- */
/* Marketing pages read a step larger than the transactional shop. The global
   root knob (main.css "the only scale knob") is tuned for dense commerce UI —
   15.04px at desktop, ~6% under browser default, deliberately density-first —
   which is tight for long-form landing copy where `sm` (13.2px) carries most of
   the reading. These are TOKEN overrides, not a font-size on the wrapper: every
   size is rem, so a wrapper font-size would resolve against the root and change
   nothing. Spacing tokens are left alone, so the density stays put and only the
   type grows. Scoped to .cms-page, so PDPs and the rest of the shop keep the
   tuned scale. */
.cms-page {
  --font-size-xs: 0.8rem;
  --font-size-sm: 0.95rem;
  --font-size-base: 1.05rem;
  --font-size-lg: 1.18rem;
  --font-size-xl: 1.31rem;
  --cms-label-size: 0.75rem;
  background: var(--cms-surface);
  color: var(--cms-text);
}
.cms-page > .cms-block {
  padding: clamp(2rem, calc(4 * var(--vwx)), 4rem) 0;
}
/* Blocks that follow another block drop their top padding so two transparent
   sections do not stack two gaps. A BANDED block is different — its background
   is visible, so losing the top padding pins the copy to the top edge of the
   band while the bottom keeps its full inset. Exclude them from the reset.
   (Specificity matters here: the `+` selector carries three classes and beats
   the single-class banner rule below, so ordering alone would not fix it.) */
.cms-page
  > .cms-block
  + .cms-block:not(.cms-block--cta-banner):not(.cms-statement--band):not(.cms-card-rail) {
  padding-top: 0;
}
.cms-page > .cms-block--text-section,
.cms-page > .cms-block--image-text,
.cms-page > .cms-block--cta-banner {
  padding: clamp(2rem, calc(4 * var(--vwx)), 4rem) 0;
}
/* The full-bleed band that lived here moved to .cms-card-rail (owner decision
   2026-09-07) — see "Full-bleed band" in the card-rail section below. The CTA
   banner now stops at the 120rem body cap like every other block. It stays
   excluded from the padding-top reset above: it is still a BANDED block (it
   paints a background), it is just no longer pulled to the viewport edges. */
.cms-page > .cms-block--text-section .container,
.cms-page > .cms-block--image-text .container,
.cms-page > .cms-block--cta-banner .container {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--spacing-6);
  display: block;
}
/* CTA band breathing room — the heading sat flush against the band's top
   edge on the campaign landing (stakeholder review 2026-08-28). */
.cms-page > .cms-block--cta-banner {
  padding: clamp(3rem, calc(5 * var(--vwx)), 5rem) 0;
}
.cms-page > .cms-block--cta-banner .cms-block-heading {
  margin: 0 0 var(--spacing-3);
}
.cms-page > .cms-block--cta-banner .cms-block-body {
  max-width: 46rem;
}
:is(.cms-page, .product-content-blocks) .cms-block-heading {
  font-size: clamp(1.5rem, calc(2.6 * var(--vwx)), 2.25rem);
  line-height: 1.2;
  color: var(--cms-text);
}
:is(.cms-page, .product-content-blocks)
  .cms-block--cta-banner
  .cms-block-heading {
  color: var(--color-white);
}
:is(.cms-page, .product-content-blocks) .cms-block--cta-banner .cms-block-body {
  color: rgba(255, 255, 255, 0.8);
}
:is(.cms-page, .product-content-blocks) .cms-block-body {
  font-size: var(--font-size-base);
  line-height: 1.6;
  color: var(--cms-text-2);
}

/* ---- PDP host (`.product-content-blocks`, product_page.dart) -------------
   The PDP lays its enrichment out as a 2-column card grid and turns EVERY
   descendant `.container` into a grid (main.css). The page/marketing blocks
   are full-width bands with their own inner `.container`, so inside the PDP
   they span the row and their container is a plain box; the homepage's
   statement-size text-section is scaled down (see the :is() rules above). */
.product-content-blocks > .container > .cms-block {
  grid-column: 1 / -1;
  padding: clamp(2rem, calc(6 * var(--vwx)), 4rem) 0
    clamp(1rem, calc(2 * var(--vwx)), 2rem);
}
.product-content-blocks > .container > .cms-block + .cms-block {
  padding-top: 0;
}
/* On a PDP the sub-brand header is a masthead under the product's own title,
   not a landing-page display line: the 6.25rem homepage scale plus the band's
   4rem top padding read as an empty panel (DIAG TRF, demo review 2026-09-15). */
.product-content-blocks > .container > .cms-sub-brand-header {
  padding: var(--se-spacing-8, 2rem) 0 0;
}
.product-content-blocks .cms-sub-brand-heading {
  font-size: clamp(1.75rem, calc(3.2 * var(--vwx)), 2.75rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
}
.product-content-blocks .cms-sub-brand-tagline {
  font-size: var(--se-font-size-text-large, 1rem);
  line-height: 1.5;
}
/* The grid gap already separates the masthead from the section under it; a
   gallery's own 4rem band padding on top of that left a hole (DIAG TRF L1). */
.product-content-blocks
  > .container
  > .cms-sub-brand-header
  + .content-block.cms-image-gallery {
  padding-top: 0;
}
.product-content-blocks .cms-block .container {
  display: flex;
  padding: 0;
  flex-direction: column;
  gap: 0.5rem;
}
.product-content-blocks .cms-block--text-section {
  background: transparent;
}
.product-content-blocks .cms-block--text-section.cms-align-left .container,
.product-content-blocks .cms-block--text-section.cms-align-right .container {
  display: block;
}
.product-content-blocks > .container > .content-block.cms-configurator-summary,
.product-content-blocks > .container > .content-block.ncfg,
/* ---- image-gallery ------------------------------------------------------ */
/* Full-bleed: break out of .container so the strip can touch the edges */
.product-content-blocks > .container > .content-block.cms-image-gallery {
  grid-column: 1 / -1;
}

.cms-image-gallery {
  background: var(--cms-surface-alt, #f9f9f9);
  padding: clamp(2rem, calc(4 * var(--vwx)), 4rem) 0;
}

/* Header row: title left, arrows right — 24px side padding matches container */
.cms-gallery-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 clamp(1rem, calc(1.5 * var(--vwx)), 1.5rem) 0 0;
  margin-bottom: 1.25rem;
  min-height: 2rem;
}

.cms-gallery-title {
  font-size: 1rem;
  font-weight: 600;
  color: var(--cms-text, #3d3d3d);
  margin: 0;
}

.cms-gallery-arrows {
  display: flex;
  gap: 0.5rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
}

/* Arrows visible only when strip overflows */
.cms-image-gallery.has-overflow .cms-gallery-arrows {
  opacity: 1;
  pointer-events: auto;
}

.cms-gallery-arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border: none;
  background: none;
  cursor: pointer;
  padding: 0;
}

.cms-gallery-arrow svg {
  width: 1.5rem;
  height: 1.5rem;
}

.cms-gallery-arrow:disabled {
  opacity: 0.25;
  cursor: default;
}

/* Viewport: clips the strip and positions the fade overlays */
.cms-gallery-viewport {
  position: relative;
  overflow: hidden;
}

/* Scrollable strip */
.cms-gallery-strip {
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.cms-gallery-strip::-webkit-scrollbar {
  display: none;
}

/* Edge fades — positioned over the strip */
.cms-gallery-fade {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 10rem;
  pointer-events: none;
  transition: opacity 0.2s;
}

.cms-gallery-fade--right {
  right: 0;
  background: linear-gradient(
    to left,
    var(--cms-surface-alt, #f9f9f9),
    transparent
  );
  opacity: 1;
}

.cms-gallery-fade--left {
  left: 0;
  background: linear-gradient(
    to right,
    var(--cms-surface-alt, #f9f9f9),
    transparent
  );
  opacity: 0;
}

/* JS toggles these when strip is at the edges */
.cms-image-gallery.at-start .cms-gallery-fade--left {
  opacity: 0;
}
.cms-image-gallery.at-end .cms-gallery-fade--right {
  opacity: 0;
}

/* Individual card */
.cms-gallery-card {
  display: flex;
  max-width: 11.125rem; /* 178px */
  flex-direction: column;
  border: 1px solid transparent;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  padding: 1rem;
  margin: 0;
  cursor: default;
  transition:
    background 0.15s,
    box-shadow 0.15s;
}

.cms-gallery-card:hover {
  background: #fff;
  border-radius: 1.5rem;
  border-color: #e3e3e3;
}

.cms-gallery-card-img {
  overflow: hidden;
  flex-shrink: 0;
  aspect-ratio: 1 / 1;
  width: 7.5rem;
}

.cms-gallery-card-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-top-right-radius: 1rem;
  border-top-left-radius: 1rem;
}

.cms-gallery-card-label {
  font-size: 0.875rem;
  font-weight: 700;
  line-height: 1.375rem;
  color: var(--cms-text, #3d3d3d);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* One image: a figure with its caption, not a thumbnail in a scroll strip. */
.product-content-blocks > .container > .content-block.cms-image-gallery--single {
  padding: 0;
}
.cms-image-gallery--single .cms-gallery-fade {
  display: none;
}
.cms-image-gallery--single .cms-gallery-card,
.cms-image-gallery--single .cms-gallery-card:hover {
  max-width: 26rem;
  padding: 0;
  align-items: flex-start;
  gap: var(--spacing-2, 0.5rem);
  background: transparent;
  border-color: transparent;
}
.cms-image-gallery--single .cms-gallery-card-img {
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: 0.75rem;
  background: #fff;
}
.cms-image-gallery--single .cms-gallery-card-img img {
  object-fit: contain;
  border-radius: 0;
}
.cms-image-gallery--single .cms-gallery-card-label {
  font-weight: 400;
  text-align: left;
  white-space: normal;
  color: var(--cms-text-2, #3d3d3d);
}

/* ---- sub-brand-header --------------------------------------------------- */
.cms-sub-brand-header {
  padding-top: clamp(2.5rem, calc(4 * var(--vwx)), 4rem);
  padding-bottom: clamp(1.5rem, calc(2.5 * var(--vwx)), 2rem);
}

.cms-sub-brand-header .container {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2, 0.5rem);
}

/* Display heading: inherits inline bold/italic/underline from Lexical */
.cms-sub-brand-heading {
  font-size: clamp(3rem, calc(8 * var(--vwx)), 6.25rem);
  /* line-height: clamp(2.5rem, calc(5 * var(--vwx)), 4.875rem); */
  line-height: 1;
  letter-spacing: -2px;
  color: var(--cms-text, #3d3d3d);
}

/* Strip paragraph wrapper that Lexical emits around inline content */
.cms-sub-brand-heading p,
.cms-sub-brand-tagline p {
  margin: 0;
}

/* Tagline: H2-scale, normal weight */
.cms-sub-brand-tagline {
  font-size: clamp(1rem, calc(1.6 * var(--vwx)), 1.375rem);
  line-height: 1.625;
  font-weight: 400;
  color: var(--cms-text-2, #3d3d3d);
}

.cms-section-head {
  max-width: 46rem;
  margin-bottom: var(--spacing-6);
}
.cms-eyebrow {
  margin: 0 0 var(--spacing-2);
  font-size: var(--font-size-xs);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cms-accent);
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
}
.cms-eyebrow::before {
  content: "";
  width: 1.5rem;
  height: 2px;
  background: var(--cms-accent);
  border-radius: var(--radius-full);
  flex: none;
}
.cms-section-heading {
  margin: 0 0 var(--spacing-3);
  font-size: clamp(1.5rem, calc(2.6 * var(--vwx)), 2.1rem);
  line-height: 1.15;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--cms-text);
}
.cms-section-lead {
  margin: 0;
  font-size: var(--font-size-lg);
  line-height: 1.55;
  color: var(--cms-text-2);
}
.cms-footnote {
  margin: var(--spacing-3) 0 0;
  font-size: var(--font-size-sm);
  color: var(--cms-text-3);
}
.cms-empty {
  color: var(--cms-text-3);
  font-size: var(--font-size-sm);
}

/* ---- hero band ---------------------------------------------------------- */
.cms-hero-band {
  position: relative;
}
.cms-hero-band--background {
  background-size: cover;
  background-position: center;
  color: var(--color-white);
}
.cms-hero-band--background::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(0, 0, 0, 0.62), rgba(0, 0, 0, 0.18));
}
.cms-hero-band--background .cms-hero-band-inner {
  position: relative;
}
.cms-hero-band--background .cms-hero-band-heading,
.cms-hero-band--background .cms-hero-band-lead,
.cms-hero-band--background .cms-hero-band-sub {
  color: var(--color-white);
}
.cms-hero-band-inner {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  gap: clamp(1.5rem, calc(4 * var(--vwx)), 4rem);
  align-items: center;
}
.cms-hero-band--plain .cms-hero-band-inner,
.cms-hero-band--background .cms-hero-band-inner {
  grid-template-columns: minmax(0, 1fr);
}
.cms-hero-band-heading {
  margin: 0 0 var(--spacing-3);
  font-size: clamp(1.9rem, calc(4.2 * var(--vwx)), 3.25rem);
  line-height: 1.08;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--cms-text);
}
.cms-hero-band-sub {
  margin: 0 0 var(--spacing-3);
  font-size: var(--font-size-xl);
  font-style: italic;
  color: var(--cms-accent);
}
/* On the scene hero (the area landing) the subheading is the positioning
   statement, not a pull-quote — it reads as a lede, not a caption. The italic
   accent treatment above stays for the suite pages, where the subheading IS a
   quoted line ("Listening to the grid's heartbeat"). */
.cms-hero-band--scene .cms-hero-band-sub {
  font-style: normal;
  color: var(--cms-text-2);
  line-height: 1.45;
  max-width: 34rem;
}
.cms-hero-band-lead {
  margin: 0 0 var(--spacing-5);
  font-size: var(--font-size-lg);
  line-height: 1.6;
  color: var(--cms-text-2);
  max-width: 40rem;
}
.cms-hero-band-note {
  margin: var(--spacing-3) 0 0;
  font-size: var(--font-size-sm);
  color: var(--cms-text-3);
}
.cms-hero-band-media img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  object-fit: cover;
  aspect-ratio: 4 / 3;
}
.cms-hero-band-scene:not(:empty) {
  min-height: 12rem;
}
.cms-hero-band--scene .cms-hero-band-inner {
  grid-template-columns: minmax(0, 1fr);
}

/* ---- chips / ctas / badges --------------------------------------------- */
.cms-chip-row,
.cms-cta-row,
.cms-badge-list,
.cms-filter-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-2);
}
.cms-cta-row {
  gap: var(--spacing-3);
  margin-top: var(--spacing-2);
}
.cms-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-1);
  padding: 0.3rem 0.7rem;
  font-size: var(--font-size-xs);
  font-weight: 600;
  line-height: 1.2;
  border-radius: var(--radius-full);
  border: 1px solid var(--cms-line);
  background: var(--cms-surface-alt);
  color: var(--cms-text-2);
  text-decoration: none;
}
a.cms-chip:hover {
  border-color: var(--cms-accent);
  color: var(--cms-text);
}
.cms-chip--suite {
  border-color: var(--cms-accent);
  color: var(--cms-text);
  background: var(--cms-accent-soft);
}
.cms-chip--live {
  background: rgba(53, 196, 106, 0.16);
  border-color: rgba(53, 196, 106, 0.6);
  color: var(--cms-text);
}
.cms-chip--phase2 {
  opacity: 0.85;
}
.cms-badge {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 0.35rem 0.75rem;
  font-size: var(--font-size-xs);
  font-weight: 600;
  border-radius: var(--radius-md);
  border: 1px solid var(--cms-line);
  background: var(--cms-surface-raised);
  color: var(--cms-text);
  cursor: help;
}
.cms-badge-tip {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 0.5rem);
  transform: translateX(-50%);
  min-width: 12rem;
  max-width: 18rem;
  padding: var(--spacing-2) var(--spacing-3);
  font-size: var(--font-size-xs);
  font-weight: 400;
  line-height: 1.4;
  color: var(--color-white);
  background: var(--color-gray-900);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
  z-index: 5;
}
.cms-badge:hover .cms-badge-tip,
.cms-badge:focus-visible .cms-badge-tip {
  opacity: 1;
}
.cms-badge-row-heading {
  margin: 0 0 var(--spacing-3);
  font-size: var(--font-size-sm);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cms-text-3);
}

/* ---- grids & cards ------------------------------------------------------ */
/* Responsive without width media queries (house rule): the column count is
   a MINIMUM card width, so grids wrap naturally on narrow viewports. */
.cms-grid,
.cms-product-grid {
  --cms-card-min: 15rem;
  display: grid;
  gap: var(--spacing-4);
  grid-template-columns: repeat(
    auto-fill,
    minmax(min(100%, var(--cms-card-min)), 1fr)
  );
}
.cms-cols-2 .cms-grid,
.cms-cols-2.cms-product-grid {
  --cms-card-min: 20rem;
}
.cms-cols-3 .cms-grid,
.cms-cols-3.cms-product-grid {
  --cms-card-min: 15rem;
}
/* cols-4: auto-FIT so a four-card strip (e.g. the suites row) stretches to
   the full container width instead of leaving empty auto-fill tracks. */
.cms-cols-4 .cms-grid,
.cms-cols-4.cms-product-grid {
  --cms-card-min: 12rem;
  grid-template-columns: repeat(
    auto-fit,
    minmax(min(100%, var(--cms-card-min)), 1fr)
  );
}
.cms-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--spacing-3);
  padding: var(--spacing-5);
  background: var(--cms-surface-raised);
  border: 1px solid var(--cms-line);
  border-radius: var(--radius-card);
  color: inherit;
  text-decoration: none;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}
.cms-tile--link:hover {
  border-color: var(--cms-accent);
  box-shadow: var(--shadow-card);
  text-decoration: none;
}
.cms-tile--tile {
  padding: var(--spacing-4);
}
.cms-tile--feature {
  padding: 0;
  border: 0;
  background: transparent;
}
.cms-tile-media img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border-radius: var(--radius-md);
}
.cms-tile-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  font-size: var(--font-size-lg);
  font-weight: 700;
  border-radius: var(--radius-md);
  border: 2px solid var(--cms-accent);
  color: var(--cms-accent);
  background: var(--cms-accent-soft);
}
.cms-tile-body {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-1);
}
.cms-tile-badge {
  align-self: flex-start;
  font-size: var(--cms-label-size, 0.65rem);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cms-text-3);
  border: 1px solid var(--cms-line);
  border-radius: var(--radius-sm);
  padding: 0.1rem 0.4rem;
}
.cms-tile-title {
  margin: 0;
  font-size: var(--font-size-lg);
  line-height: 1.25;
  font-weight: 700;
  color: var(--cms-text);
}
.cms-tile-subtitle {
  margin: 0;
  font-size: var(--font-size-sm);
  font-style: italic;
  color: var(--cms-accent);
}
/* Tile style (suites strip): the badge is the suite's DOMAIN — the thing a
   reader scans the four tiles for — so it carries real weight here rather
   than the hairline-chrome treatment badges get elsewhere. Subtitle is the
   quoted tagline. (No count line: it was noise beside four countable cards.) */
.cms-tile--tile .cms-tile-badge {
  border: 0;
  padding: 0;
  border-radius: 0;
  color: var(--cms-accent);
  font-size: 0.9rem;
  letter-spacing: 0.08em;
}
.cms-tile--tile .cms-tile-subtitle {
  color: var(--cms-text-2);
}
/* A card-style tile lays its body out against its OWN width, not the
   viewport's — a container query, because the same card is ~334px in a
   four-up grid and full width when it is the only one in its grid. Wide, the
   copy moves beside the heading instead of running as one very long measure. */
.cms-card-grid--card .cms-tile {
  container-type: inline-size;
}
@container (min-width: 45rem) {
  /* Scoped to the card-style tile that declares the container above. An
     unscoped `.cms-tile-body` would also match inside any OTHER
     `container-type: inline-size` ancestor — there are eight in these
     stylesheets (cart.css, line_item.css, main.css, overview_header.css) — and
     silently pick up the two-column body at ≥45rem. */
  .cms-card-grid--card .cms-tile-body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
    gap: var(--spacing-2) var(--spacing-6);
    align-items: start;
  }
  .cms-card-grid--card .cms-tile-body > .cms-tile-badge,
  .cms-card-grid--card .cms-tile-body > .cms-tile-title,
  .cms-card-grid--card .cms-tile-body > .cms-tile-subtitle {
    grid-column: 1;
  }
  /* The badge sizes to its text: `align-self: flex-start` above is a flex
     property and does nothing once the body becomes a grid, so it stretched
     the full column. */
  .cms-card-grid--card .cms-tile-body > .cms-tile-badge {
    justify-self: start;
  }
  .cms-card-grid--card .cms-tile-body > .cms-tile-desc {
    grid-column: 2;
    grid-row: 1 / span 3;
  }
}
.cms-tile-desc {
  margin: 0;
  font-size: var(--font-size-sm);
  line-height: 1.55;
  color: var(--cms-text-2);
}
/* Card bullets: the authored list form. These used to arrive as one `·`-joined
   paragraph, which read as a run-on sentence at card width. */
.cms-tile-bullets {
  margin: 0;
  padding-left: 1.1rem;
  font-size: var(--font-size-sm);
  line-height: 1.5;
  color: var(--cms-text-2);
}
.cms-tile-bullets li + li {
  margin-top: 0.25rem;
}
.cms-tile--tile .cms-tile-desc {
  font-size: var(--font-size-xs);
  color: var(--cms-text-3);
}

/* ---- card-grid: theme --------------------------------------------------- */
/* Both themes paint a ground — the light references are a grey field, not the
   page white. Only tokens are redefined; every rule below reads them, so no
   component needs a per-theme variant of its own. */
.cms-card-grid.cms-theme-light {
  background: var(--cms-surface-alt);
  color: var(--cms-text);
}
.cms-card-grid.cms-theme-dark {
  --cms-surface: #1c1c1c;
  --cms-surface-alt: #232323;
  --cms-surface-raised: #262626;
  --cms-line: rgba(255, 255, 255, 0.12);
  --cms-text: #ffffff;
  --cms-text-2: rgba(255, 255, 255, 0.72);
  --cms-text-3: rgba(255, 255, 255, 0.5);
  background: var(--cms-surface);
  color: var(--cms-text);
}

/* ---- card-grid: `card` style (stacked rows, copy in a left column) ------
   Section copy sits beside the items rather than above them, and each item
   lays its image next to the text, alternating sides. Flex (not grid) so the
   1:2 ratio holds when wide and the columns stack when narrow — no width
   media queries (house rule). */
.cms-block.cms-card-grid--card > .container {
  display: flex;
  /* Explicit: the PDP host sets `flex-direction: column` on every
     `.cms-block .container` at equal specificity, so omitting this collapses
     the two columns into a stack on product pages only. */
  flex-direction: row;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: clamp(1.5rem, calc(3 * var(--vwx)), 3.5rem);
}
.cms-card-grid--card > .container > .cms-section-head {
  flex: 1 1 16rem;
  max-width: none;
  margin-bottom: 0;
}
.cms-card-grid--card > .container > .cms-grid {
  flex: 2 1 26rem;
  display: flex;
  flex-direction: column;
  gap: clamp(1.25rem, calc(2.5 * var(--vwx)), 2.25rem);
}

/* Section copy reads as display text here, not as an eyebrow: the "Title"
   line is the bold half and "Subtitle" the light half of one statement. */
.cms-card-grid--card .cms-eyebrow {
  display: block;
  margin: 0;
  font-size: clamp(1.25rem, calc(2.2 * var(--vwx)), 1.75rem);
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--cms-text);
}
.cms-card-grid--card .cms-eyebrow::before {
  display: none;
}
.cms-card-grid--card .cms-section-heading {
  margin: 0;
  font-size: clamp(1.25rem, calc(2.2 * var(--vwx)), 1.75rem);
  line-height: 1.2;
  font-weight: 400;
  color: var(--cms-text-3);
}
.cms-card-grid--card .cms-section-lead {
  margin: var(--spacing-3) 0 0;
  font-size: var(--font-size-base);
}

/* Rows: image beside text, sides alternating. */
.cms-card-grid--card .cms-tile {
  flex-direction: row;
  align-items: flex-start;
  gap: clamp(0.75rem, calc(1.5 * var(--vwx)), 1.25rem);
  padding: 0;
  border: 0;
  background: transparent;
  border-radius: 0;
}
.cms-card-grid--card .cms-tile:nth-child(even) {
  flex-direction: row-reverse;
}
.cms-card-grid--card .cms-tile-media {
  flex: 0 0 var(--cms-cardgrid-media, 7.5rem);
}
.cms-card-grid--card .cms-tile-media img {
  aspect-ratio: auto;
  border-radius: 0;
}
.cms-card-grid--card .cms-tile-body {
  flex: 1 1 auto;
  gap: var(--spacing-2);
}
.cms-card-grid--card .cms-tile-title {
  font-size: var(--font-size-sm);
  line-height: 1.4;
}
.cms-card-grid--card .cms-tile-desc {
  font-size: var(--font-size-sm);
  line-height: 1.55;
}
/* MVP: badge / icon / accent are authorable but unstyled by this look. */
.cms-card-grid--card .cms-tile-badge,
.cms-card-grid--card .cms-tile-icon {
  display: none;
}

/* ---- card-grid: `feature` style (grid, image above text) ----------------
   The grid arrangement is inherited (.cms-grid + .cms-tile's column flex);
   only the vocabulary changes here. Everything is theme-INDEPENDENT — the
   light and dark references are the same layout on different tokens — so
   these rules are unscoped and the 21 pre-existing feature blocks adopt the
   new look by design.

   Three card shapes fall out of the item data alone, no extra field:
     no image                  → text-only card (the left column)
     image + description       → normal card
     image, but no description → overlay card (text over the image)
   The last two are selected with :has(), so authoring stays declarative. */

/* Section head: Title and Subtitle are ONE display statement flowing inline,
   not an eyebrow stacked above a heading. */
.cms-card-grid--feature .cms-section-head {
  max-width: none;
}
.cms-card-grid--feature .cms-eyebrow,
.cms-card-grid--feature .cms-section-heading {
  display: inline;
  margin: 0;
  font-size: clamp(2rem, calc(5 * var(--vwx)), 4rem);
  line-height: 1.1;
  letter-spacing: -0.01em;
  text-transform: none;
}
.cms-card-grid--feature .cms-eyebrow {
  /* Explicit space: Jaspr emits no whitespace between sibling elements. */
  margin-right: 0.25em;
  font-weight: 400;
  color: var(--cms-text-3);
}
.cms-card-grid--feature .cms-eyebrow::before {
  display: none;
}
.cms-card-grid--feature .cms-section-heading {
  font-weight: 700;
  color: var(--cms-text);
}
.cms-card-grid--feature .cms-section-lead {
  display: block;
  max-width: 46rem;
  margin-top: var(--spacing-4);
  font-size: clamp(1rem, calc(1.6 * var(--vwx)), 1.375rem);
  color: var(--cms-text);
}

/* Badge is the per-card eyebrow here ("PRODUCT CLASS"), not a pill. */
.cms-card-grid--feature .cms-tile-badge {
  border: 0;
  padding: 0;
  border-radius: 0;
  font-size: 0.65rem;
  letter-spacing: 0.12em;
  color: var(--cms-text-3);
}

/* Subtitle is the second half of the headline in both new looks — NOT the
   accented italic aside, which `tile` still wants (its "quoted tagline"). */
:is(.cms-card-grid--card, .cms-card-grid--feature) .cms-tile-subtitle {
  font-weight: 400;
  font-style: normal;
  color: var(--cms-text-2);
}
.cms-card-grid--feature .cms-tile-subtitle {
  font-size: var(--font-size-lg);
  line-height: 1.25;
}
.cms-card-grid--card .cms-tile-subtitle {
  font-size: var(--font-size-sm);
  line-height: 1.4;
}

/* Every reference card truncates rather than running long. */
.cms-card-grid--feature .cms-tile-desc {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: var(--cms-feature-clamp, 5);
  overflow: hidden;
}

/* Link affordance. Authorable per card later; fixed copy for now. */
.cms-card-grid--feature .cms-tile--link::after {
  content: "More →";
  margin-top: auto;
  padding-top: var(--spacing-3);
  font-size: var(--font-size-sm);
  font-weight: 700;
  color: var(--cms-text);
}

/* Row divider. Grid rows stretch to equal height, so the borders line up
   across a row; the column gap interrupts the line. */
.cms-card-grid--feature .cms-tile {
  padding-bottom: clamp(1rem, calc(2 * var(--vwx)), 1.75rem);
  border-bottom: 1px solid var(--cms-line);
}

/* -- overlay card: image present, description absent -- */
.cms-card-grid--feature .cms-tile:has(.cms-tile-media):not(:has(.cms-tile-desc)) {
  position: relative;
  min-height: 13rem;
  justify-content: flex-end;
  padding: var(--spacing-4);
  border-bottom: 0;
  overflow: hidden;
  isolation: isolate;
}
.cms-card-grid--feature
  .cms-tile:has(.cms-tile-media):not(:has(.cms-tile-desc))
  .cms-tile-media {
  position: absolute;
  inset: 0;
  z-index: -1;
}
.cms-card-grid--feature
  .cms-tile:has(.cms-tile-media):not(:has(.cms-tile-desc))
  .cms-tile-media img {
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  object-fit: cover;
  border-radius: 0;
}
/* Scrim so the copy holds contrast over any photo, in either theme. */
.cms-card-grid--feature
  .cms-tile:has(.cms-tile-media):not(:has(.cms-tile-desc))
  .cms-tile-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0.15));
}
/* Overlay copy is always light — it sits on a photo, not on the theme ground. */
.cms-card-grid--feature
  .cms-tile:has(.cms-tile-media):not(:has(.cms-tile-desc))
  :is(.cms-tile-badge, .cms-tile-title, .cms-tile-subtitle) {
  color: #ffffff;
}
.cms-card-grid--feature
  .cms-tile:has(.cms-tile-media):not(:has(.cms-tile-desc))
  .cms-tile-title {
  font-size: clamp(1.25rem, calc(2.2 * var(--vwx)), 1.75rem);
}
.cms-card-grid--feature
  .cms-tile:has(.cms-tile-media):not(:has(.cms-tile-desc))
  .cms-tile-subtitle {
  font-size: clamp(1.25rem, calc(2.2 * var(--vwx)), 1.75rem);
}

/* ---- stats strip -------------------------------------------------------- */
.cms-stats-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: var(--spacing-4);
}
/* Plain bordered tile, centered, accent-coloured value — no accent side bar
   (prototype .stat). */
.cms-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--spacing-1);
  padding: var(--spacing-4) var(--spacing-5);
  border: 1px solid var(--cms-line);
  background: var(--cms-surface-alt);
  border-radius: var(--radius-md);
}
.cms-stat-value {
  font-size: clamp(1.6rem, calc(2.6 * var(--vwx)), 2.4rem);
  font-weight: 700;
  line-height: 1;
  color: var(--cms-accent);
  letter-spacing: -0.02em;
}
.cms-stat-label {
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--cms-text-2);
}
.cms-stat-note {
  font-size: var(--font-size-xs);
  color: var(--cms-text-3);
}
.cms-stats-cta {
  margin: var(--spacing-5) 0 0;
}

/* ---- steps -------------------------------------------------------------- */
.cms-steps-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--spacing-4);
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  counter-reset: cms-step;
}
.cms-steps--list .cms-steps-list {
  grid-template-columns: minmax(0, 1fr);
}
.cms-step {
  display: flex;
  gap: var(--spacing-4);
  padding: var(--spacing-5);
  background: var(--cms-surface-raised);
  border: 1px solid var(--cms-line);
  border-radius: var(--radius-card);
}
.cms-steps--timeline .cms-step {
  border: 0;
  background: transparent;
  padding: 0 0 0 0;
  position: relative;
}
.cms-steps--timeline .cms-steps-list {
  position: relative;
}
.cms-steps--timeline .cms-steps-list::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 1.05rem;
  height: 2px;
  background: var(--cms-line);
}
.cms-step-marker {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  border-radius: var(--radius-full);
  background: var(--cms-accent);
  color: var(--cms-accent-ink);
  font-weight: 700;
  font-size: var(--font-size-sm);
  position: relative;
  z-index: 1;
}
.cms-step-body {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-1);
}
.cms-step-title {
  margin: 0;
  font-size: var(--font-size-base);
  font-weight: 700;
  color: var(--cms-text);
}
.cms-step-text {
  margin: 0;
  font-size: var(--font-size-sm);
  line-height: 1.55;
  color: var(--cms-text-2);
}
.cms-step-link {
  font-size: var(--font-size-sm);
  font-weight: 600;
  color: var(--cms-accent);
  text-decoration: none;
}
.cms-step-link:hover {
  text-decoration: underline;
}
/* Sub-brand contribution dots (value arc): each dot resolves --cms-accent
   through its own [data-suite] scope. */
.cms-step-dots {
  display: inline-flex;
  gap: 0.4rem;
  margin-top: var(--spacing-2);
}
.cms-step-dot {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: var(--radius-full);
  background: var(--cms-accent);
  box-shadow: 0 0 0 3px var(--cms-accent-soft);
}

/* ---- statement banner --------------------------------------------------- */
.cms-statement--panel .cms-statement-inner {
  padding: clamp(1.5rem, calc(3 * var(--vwx)), 3rem);
  border: 1px solid var(--cms-accent);
  border-radius: var(--radius-card);
  background: var(--cms-accent-soft);
  text-align: center;
}
.cms-statement--band {
  background: var(--cms-accent-soft);
}
.cms-statement--band .cms-statement-inner {
  padding: clamp(1.5rem, calc(3 * var(--vwx)), 3rem) var(--spacing-6);
  text-align: center;
}
.cms-statement--quiet .cms-statement-inner {
  border-left: 3px solid var(--cms-accent);
  padding-left: var(--spacing-5);
}
.cms-statement-inner .cms-eyebrow {
  justify-content: center;
}
.cms-statement--quiet .cms-statement-inner .cms-eyebrow {
  justify-content: flex-start;
}
.cms-statement-text {
  margin: 0 auto var(--spacing-3);
  max-width: 42rem;
  font-size: clamp(1.25rem, calc(2.2 * var(--vwx)), 1.75rem);
  line-height: 1.3;
  font-weight: 700;
  color: var(--cms-text);
}
.cms-statement--quiet .cms-statement-text {
  margin-left: 0;
}
.cms-statement-sub {
  margin: 0 auto var(--spacing-4);
  max-width: 42rem;
  color: var(--cms-text-2);
}

/* ---- product grid ------------------------------------------------------- */
.cms-product-grid--rows {
  --cms-card-min: 20rem;
}
/* Grouped product grid: one row per group — the group label in a narrow left
   gutter, its cards beside it. A full-width label row was the alternative, but
   it forces a break, so a group of one offering ended up either stretched
   across the page (a 1380px box around 270px of copy) or alone in one track of
   several. The gutter keeps the label without costing a row. */
.cms-product-grid--grouped {
  display: block;
}
.cms-product-group {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--spacing-2);
}
.cms-product-group + .cms-product-group {
  margin-top: var(--spacing-5);
}
.cms-product-group-label {
  margin: 0;
  font-size: var(--font-size-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--cms-text-3);
}
/* `auto-fit` (not auto-fill) so empty tracks COLLAPSE: a group of one offering
   fills the whole card area rather than leaving a half row of background, and a
   pair splits it evenly. That only works because the card is a banner row —
   media left, copy centre, type right — so a full-width card is used, not an
   empty box with 270px of copy in the corner. */
.cms-product-group-cards {
  display: grid;
  gap: var(--spacing-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 30rem), 1fr));
}
/* Banner row inside a grouped grid: bigger media and the copy laid out across
   the width, with the type label pushed to the trailing edge. */
.cms-product-grid--grouped .cms-product-card--rows {
  gap: var(--spacing-5);
  padding: var(--spacing-4) var(--spacing-5);
}
.cms-product-grid--grouped .cms-product-card--rows .cms-product-card-media {
  width: 8rem;
}
.cms-product-grid--grouped .cms-product-card--rows .cms-product-card-body {
  flex: 1 1 auto;
  flex-direction: row;
  align-items: center;
  gap: var(--spacing-4);
  flex-wrap: wrap;
}
.cms-product-grid--grouped .cms-product-card--rows .cms-product-card-type {
  margin-left: auto;
}
@media (min-width: 60rem) {
  .cms-product-group {
    grid-template-columns: 9rem minmax(0, 1fr);
    gap: var(--spacing-5);
    align-items: start;
  }
  .cms-product-group-label {
    padding-top: var(--spacing-2);
  }
}
.cms-product-card {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-3);
  padding: var(--spacing-4);
  background: var(--cms-surface-raised);
  border: 1px solid var(--cms-line);
  border-radius: var(--radius-card);
  color: inherit;
  text-decoration: none;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}
.cms-product-card:hover {
  border-color: var(--cms-accent);
  box-shadow: var(--shadow-card);
  text-decoration: none;
}
.cms-product-card--rows {
  flex-direction: row;
  align-items: center;
}
.cms-product-card--rows .cms-product-card-media {
  flex: none;
  width: 4.5rem;
}
.cms-product-card--tiles {
  padding: var(--spacing-3);
}
.cms-product-card-media {
  background: var(--cms-surface-alt);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.cms-product-card-media img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: contain;
}
.cms-product-card--rows .cms-product-card-media img {
  aspect-ratio: 1 / 1;
}
.cms-product-card-media--empty {
  aspect-ratio: 4 / 3;
}
.cms-product-card--rows .cms-product-card-media--empty {
  aspect-ratio: 1 / 1;
}
.cms-product-card-body {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}
.cms-product-card-title {
  margin: 0;
  font-size: var(--font-size-base);
  font-weight: 700;
  line-height: 1.3;
  color: var(--cms-text);
}
.cms-product-card-tagline {
  margin: 0;
  font-size: var(--font-size-sm);
  font-style: italic;
  color: var(--cms-accent);
}
.cms-product-card-type {
  font-size: var(--cms-label-size, 0.65rem);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cms-text-3);
}
.cms-product-card-caption {
  margin: 0;
  font-size: var(--font-size-xs);
  color: var(--cms-text-2);
}
.cms-product-card-price {
  margin-top: auto;
  font-size: var(--font-size-sm);
  font-weight: 700;
  color: var(--cms-text);
}
.cms-product-card--skeleton,
.cms-ref-card--skeleton,
.cms-page-skeleton {
  min-height: 9rem;
  border-radius: var(--radius-card);
  background: linear-gradient(
    90deg,
    var(--cms-surface-alt) 25%,
    var(--cms-line) 50%,
    var(--cms-surface-alt) 75%
  );
  background-size: 200% 100%;
  animation: cms-shimmer 1.4s ease-in-out infinite;
}
.cms-page-skeleton {
  min-height: 24rem;
  margin: var(--spacing-8) 0;
}
@keyframes cms-shimmer {
  from {
    background-position: 200% 0;
  }
  to {
    background-position: -200% 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .cms-product-card--skeleton,
  .cms-ref-card--skeleton,
  .cms-page-skeleton {
    animation: none;
  }
}

/* ---- collection grid: references / demos / solutions / glossary --------- */
.cms-filter-bar {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2);
  margin-bottom: var(--spacing-5);
}
.cms-filter-pill {
  padding: 0.35rem 0.85rem;
  font: inherit;
  font-size: var(--font-size-xs);
  font-weight: 600;
  border-radius: var(--radius-full);
  border: 1px solid var(--cms-line);
  background: var(--cms-surface-raised);
  color: var(--cms-text-2);
  cursor: pointer;
}
.cms-filter-pill.is-active {
  border-color: var(--cms-accent);
  background: var(--cms-accent-soft);
  color: var(--cms-text);
}
.cms-group + .cms-group {
  margin-top: var(--spacing-8);
}
/* Solutions: journeys are few per group (1–2), so auto-FIT — the tracks
   collapse to the cards present and each card grows into a real column
   (capped) instead of one 15rem sliver per row. */
.cms-collection-grid--solutions .cms-grid {
  --cms-card-min: 20rem;
  grid-template-columns: repeat(
    auto-fit,
    minmax(min(100%, var(--cms-card-min)), 1fr)
  );
}
.cms-solution-card {
  max-width: 38rem;
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2);
}
/* theme panels: outcome themes as a grid of panels, journeys stacked inside.
   The ladder stops at THREE across because there are six outcome themes — three
   fills two whole rows and leaves no empty track, which is the arrangement the
   prototype's Solutions menu used. Left on the auto-fill/auto-fit track above,
   six panels resolved to four columns and row two stood half empty.
   The selector must carry the parent: `.cms-collection-grid--solutions .cms-grid`
   (above) also matches this element and out-specifies a bare `.cms-theme-grid`,
   so a single-class rule here is dead. Panels stretch to the tallest in their
   row (grid default) — the themes hold 1–3 journeys each and a ragged row of
   bottoms reads as breakage, not as rhythm. */
.cms-collection-grid--solutions .cms-theme-grid {
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 40rem) {
  .cms-collection-grid--solutions .cms-theme-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 64rem) {
  .cms-collection-grid--solutions .cms-theme-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
.cms-theme-grid .cms-group {
  margin: 0;
  padding: var(--spacing-4);
  border: 1px solid var(--cms-line);
  border-radius: var(--radius-card);
  background: var(--cms-surface-alt);
  display: flex;
  flex-direction: column;
  gap: var(--spacing-3);
}
.cms-theme-grid .cms-group + .cms-group {
  margin-top: 0;
}
.cms-theme-grid .cms-group-heading {
  margin: 0;
}
.cms-theme-grid .cms-grid {
  grid-template-columns: minmax(0, 1fr);
  flex: 1;
  align-content: start;
}
.cms-theme-grid .cms-solution-card {
  max-width: none;
  background: var(--cms-surface);
}
.cms-solution-card .cms-ref-title {
  font-size: var(--font-size-xl);
}
.cms-solution-card .cms-card-description {
  font-size: var(--font-size-base);
  color: var(--cms-text);
}
/* Suite chips sit at the BOTTOM of a solution card (prototype home cards):
   name and problem lead, the composition meta closes the card. */
.cms-solution-card .cms-ref-meta {
  order: 1;
  margin-top: auto;
  padding-top: var(--spacing-2);
}
.cms-solution-card .cms-footnote {
  order: 2;
  margin-top: 0;
}
.cms-group-heading {
  margin: 0 0 var(--spacing-3);
  font-size: var(--font-size-sm);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cms-text-3);
}
.cms-ref-card {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2);
  padding: var(--spacing-5);
  border-radius: var(--radius-card);
  border: 1px solid var(--cms-line);
  background: var(--cms-surface-raised);
  color: inherit;
  text-decoration: none;
}
.cms-ref-card.cms-card--link:hover {
  box-shadow: var(--shadow-card);
  text-decoration: none;
}
/* A case study alone in its grid: span the row and put Challenge / Scope /
   Outcomes side by side. Stacked in a single track those three lists make the
   card several times taller than it is wide, with the rest of the row empty. */
.cms-ref-card--wide {
  grid-column: 1 / -1;
}
@media (min-width: 60rem) {
  .cms-ref-card--wide {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--spacing-2) var(--spacing-6);
    align-items: start;
  }
  .cms-ref-card--wide > .cms-ref-media,
  .cms-ref-card--wide > .cms-ref-meta,
  .cms-ref-card--wide > .cms-ref-title,
  .cms-ref-card--wide > .cms-ref-customer,
  .cms-ref-card--wide > .cms-step-link {
    grid-column: 1 / -1;
  }
  .cms-ref-card--wide > .cms-ref-media {
    max-width: 22rem;
  }
}
/* Reference cards carry media + meta + title + customer + three bullet lists,
   so they are inherently tall. Left on the shared 15rem auto-fill track they
   resolved to FIVE ~264px columns at desktop and each card came out 597px
   high — a row of narrow towers. An explicit ladder caps them at four across
   however wide the viewport gets, so the cards stay wide enough for their
   copy to breathe. A lone reference still spans the row (--wide, above). */
.cms-collection-grid--references .cms-grid {
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 40rem) {
  .cms-collection-grid--references .cms-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 64rem) {
  .cms-collection-grid--references .cms-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
@media (min-width: 80rem) {
  .cms-collection-grid--references .cms-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
.cms-ref-media img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius-md);
}
.cms-ref-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-2);
  align-items: center;
  font-size: var(--font-size-xs);
  color: var(--cms-text-3);
}
.cms-ref-title {
  margin: 0;
  font-size: var(--font-size-lg);
  line-height: 1.25;
  font-weight: 700;
  color: var(--cms-text);
}
.cms-ref-customer {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--cms-text-2);
}
.cms-ref-short {
  margin: 0;
  font-size: var(--font-size-sm);
  line-height: 1.5;
  color: var(--cms-text-2);
}
.cms-ref-section {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.cms-ref-section-label {
  font-size: var(--cms-label-size, 0.65rem);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cms-text-3);
}
.cms-ref-section ul {
  margin: 0;
  padding-left: 1.1rem;
  font-size: var(--font-size-sm);
  line-height: 1.5;
  color: var(--cms-text-2);
}
.cms-ref-section--strong ul {
  color: var(--cms-text);
  font-weight: 600;
}
.cms-demo-card.is-phase2 {
  opacity: 0.85;
  border-style: dashed;
}
.cms-demo-launch {
  align-self: flex-start;
  margin-top: auto;
}
.cms-glossary-list {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--spacing-2);
}
.cms-glossary-term {
  font-weight: 700;
  color: var(--cms-text);
}
.cms-glossary-full {
  font-weight: 400;
  color: var(--cms-text-3);
}
.cms-glossary-def {
  margin: 0 0 var(--spacing-3);
  font-size: var(--font-size-sm);
  line-height: 1.5;
  color: var(--cms-text-2);
}

/* ---- rich text (shared Lexical renderer output) -------------------------- */
.cms-rich-text {
  color: var(--cms-text-2);
  line-height: 1.6;
}
.cms-rich-text h2,
.cms-rich-text h3,
.cms-rich-text h4 {
  color: var(--cms-text);
  margin: var(--spacing-5) 0 var(--spacing-2);
  line-height: 1.25;
}
.cms-rich-text p {
  margin: 0 0 var(--spacing-3);
}
.cms-rich-text a {
  color: var(--cms-accent);
}
.cms-rich-text ul,
.cms-rich-text ol {
  margin: 0 0 var(--spacing-3);
  padding-left: 1.4rem;
}
.cms-rich-text blockquote {
  margin: var(--spacing-4) 0;
  padding-left: var(--spacing-4);
  border-left: 3px solid var(--cms-accent);
  color: var(--cms-text);
}
.cms-rich-text code {
  font-size: 0.9em;
  padding: 0.1rem 0.3rem;
  background: var(--cms-surface-alt);
  border-radius: var(--radius-sm);
}
/* A rich-text body that carries a table is data, not prose — release the
   68ch measure the centered text-section applies to copy. */
.cms-block--text-section .cms-block-body:has(.cms-table) {
  max-width: none;
  width: 100%;
}
.cms-table-scroll {
  overflow-x: auto;
  margin: var(--spacing-3) 0;
}
.cms-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-sm);
}
.cms-table th,
.cms-table td {
  text-align: left;
  padding: var(--spacing-2) var(--spacing-3);
  border-bottom: 1px solid var(--cms-line);
  vertical-align: top;
}
.cms-table th {
  color: var(--cms-text);
  font-weight: 700;
  background: var(--cms-surface-alt);
}
.cms-inline-upload img {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius-md);
}
.cms-checklist {
  list-style: none;
  padding-left: 0;
}
.cms-checklist li::before {
  content: "☐ ";
}
.cms-checklist li.checked::before {
  content: "☑ ";
}

/* ---- page fallbacks ----------------------------------------------------- */
.cms-missing {
  text-align: center;
  padding: var(--spacing-16) 0;
}
.cms-missing h1 {
  margin: 0 0 var(--spacing-3);
  font-size: var(--font-size-2xl);
}
.cms-missing .cms-block-body {
  margin: 0 auto var(--spacing-5);
  max-width: 32rem;
}

/* ---- Noedra configurator v2 (components/noedra/noedra_configurator.dart) --
   Theme-agnostic: surfaces/text/accents come from --cms-* and [data-suite],
   so the same engine renders on the light shop and inside the dark area. */
.ncfg {
  padding: var(--spacing-6);
  container-type: inline-size;
}
.ncfg-title {
  margin: 0 0 var(--spacing-2);
  font-size: var(--font-size-xl);
  color: var(--cms-text);
}
.ncfg-intro {
  margin: 0 0 var(--spacing-5);
  color: var(--cms-text-2);
  max-width: 70ch;
}
.ncfg-shell {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(16rem, 22rem);
  gap: var(--spacing-6);
  align-items: start;
}
@container (max-width: 52rem) {
  .ncfg-shell {
    grid-template-columns: minmax(0, 1fr);
  }
}
.ncfg-groups {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-5);
  min-width: 0;
}
.ncfg-group {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-3);
}
.ncfg-glabel {
  font-weight: 700;
  color: var(--cms-text);
  display: flex;
  align-items: baseline;
  gap: var(--spacing-2);
}
.ncfg-req {
  font-size: var(--font-size-xs);
  font-weight: 600;
  color: var(--cms-text-3);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.ncfg-gnote {
  font-size: var(--font-size-sm);
  color: var(--cms-text-3);
}
.ncfg-group--gated .ncfg-glabel {
  color: var(--cms-text-3);
}
.ncfg-gated-note {
  display: flex;
  gap: var(--spacing-2);
  align-items: flex-start;
  font-size: var(--font-size-sm);
  color: var(--cms-text-2);
  padding: var(--spacing-3);
  border: 1px dashed var(--cms-line);
  border-radius: var(--radius-card);
}
.ncfg-opts {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2);
}
.ncfg-tiles,
.ncfg-plans {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr));
  gap: var(--spacing-3);
}
.ncfg-plans.ncfg-cols-2 {
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr));
}
.ncfg-opt {
  display: flex;
  gap: var(--spacing-3);
  align-items: flex-start;
  padding: var(--spacing-3) var(--spacing-4);
  border: 1px solid var(--cms-line);
  border-radius: var(--radius-card);
  background: var(--cms-surface-alt);
  color: var(--cms-text);
  cursor: pointer;
  transition:
    border-color 0.15s ease,
    background 0.15s ease,
    box-shadow 0.15s ease;
}
.ncfg-opt:hover {
  border-color: var(--cms-accent);
}
.ncfg-opt:focus-visible {
  outline: 2px solid var(--cms-accent);
  outline-offset: 2px;
}
.ncfg-opt.is-selected {
  border-color: var(--cms-accent);
  background: var(--cms-accent-soft);
  box-shadow: inset 0 0 0 1px var(--cms-accent);
}
.ncfg-opt.is-included {
  cursor: default;
  opacity: 0.92;
}
.ncfg-opt--plan,
.ncfg-opt--tile {
  flex-direction: column;
  position: relative;
  padding-right: var(--spacing-8);
}
.ncfg-ctrl {
  flex: none;
  width: 1.1rem;
  height: 1.1rem;
  margin-top: 0.15rem;
  border-radius: var(--radius-sm);
  border: 2px solid var(--cms-text-3);
  position: relative;
}
.ncfg-opt--radio .ncfg-ctrl {
  border-radius: var(--radius-full);
}
.ncfg-opt.is-selected .ncfg-ctrl {
  border-color: var(--cms-accent);
  background: var(--cms-accent);
}
.ncfg-opt.is-selected .ncfg-ctrl::after {
  content: "";
  position: absolute;
  inset: 0.2rem;
  border-radius: inherit;
  background: var(--cms-accent-ink, #fff);
}
.ncfg-opt--plan .ncfg-ctrl,
.ncfg-opt--tile .ncfg-ctrl {
  position: absolute;
  top: var(--spacing-3);
  right: var(--spacing-3);
  margin: 0;
}
.ncfg-oicon {
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-sm);
  background: var(--cms-surface-raised);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.ncfg-oicon img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.ncfg-oicon--empty {
  background: transparent;
}
.ncfg-obody {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
  flex: 1;
}
.ncfg-olabel {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--spacing-2);
}
.ncfg-oname {
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
}
.ncfg-otag {
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 0.1rem 0.45rem;
  border-radius: var(--radius-full);
  background: var(--cms-accent-soft);
  color: var(--cms-text);
}
.ncfg-ometa {
  font-size: var(--font-size-sm);
  color: var(--cms-text-3);
}
.ncfg-odesc {
  font-size: var(--font-size-sm);
  color: var(--cms-text-2);
}
.ncfg-odemo,
.ncfg-odevice {
  font-size: var(--font-size-sm);
  color: var(--cms-accent);
  text-decoration: none;
}
.ncfg-odemo:hover,
.ncfg-odevice:hover {
  text-decoration: underline;
}
.ncfg-oinfo {
  appearance: none;
  border: 1px solid var(--cms-line);
  background: transparent;
  color: var(--cms-text-2);
  width: 1.25rem;
  height: 1.25rem;
  border-radius: var(--radius-full);
  font: inherit;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}
.ncfg-oinfo:hover,
.ncfg-oinfo[aria-expanded="true"] {
  border-color: var(--cms-accent);
  color: var(--cms-accent);
}
.ncfg-oinfo-panel {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin-top: var(--spacing-2);
  padding: var(--spacing-3);
  border-radius: var(--radius-sm);
  background: var(--cms-surface-raised);
  font-size: var(--font-size-sm);
  color: var(--cms-text-2);
}
.ncfg-oi-src {
  color: var(--cms-text-3);
  font-size: var(--font-size-xs);
}
.ncfg-gap {
  font-size: var(--font-size-xs);
  color: var(--cms-text-3);
  font-style: italic;
}
.ncfg-onist {
  flex: none;
  align-self: flex-start;
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 0.15rem 0.5rem;
  border-radius: var(--radius-full);
  border: 1px solid var(--cms-line);
  color: var(--cms-text-2);
}
.ncfg-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-2);
}
.ncfg-chip {
  appearance: none;
  cursor: pointer;
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: 600;
}
.ncfg-chip.is-active {
  border-color: var(--cms-accent);
  background: var(--cms-accent-soft);
  color: var(--cms-text);
}
.ncfg-counter {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2);
}
.ncfg-count-btn {
  appearance: none;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-full);
  border: 1px solid var(--cms-line);
  background: var(--cms-surface-alt);
  color: var(--cms-text);
  font: inherit;
  font-size: var(--font-size-lg);
  line-height: 1;
  cursor: pointer;
}
.ncfg-count-btn:hover {
  border-color: var(--cms-accent);
}
.ncfg-count-input {
  width: 4.5rem;
  text-align: center;
  font: inherit;
  color: var(--cms-text);
  background: var(--cms-surface-alt);
  border: 1px solid var(--cms-line);
  border-radius: var(--radius-sm);
  padding: 0.35rem;
}
.ncfg-unit {
  color: var(--cms-text-2);
  font-size: var(--font-size-sm);
}
/* summary aside */
.ncfg-summary {
  position: sticky;
  top: calc(var(--header-height, 4rem) + 4rem);
  padding: var(--spacing-5);
  border-radius: var(--radius-card);
  border: 1px solid var(--cms-line);
  background: var(--cms-surface-alt);
  display: flex;
  flex-direction: column;
  gap: var(--spacing-3);
}
.ncfg-summary-title {
  margin: 0;
  font-size: var(--font-size-lg);
  color: var(--cms-text);
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
}
.ncfg-pill {
  display: inline-block;
  min-width: 1.5rem;
  padding: 0 0.4rem;
  border-radius: var(--radius-full);
  background: var(--cms-accent);
  color: var(--cms-accent-ink, #fff);
  font-size: var(--font-size-xs);
  text-align: center;
  line-height: 1.5rem;
}
.ncfg-sel-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-size: var(--font-size-sm);
  color: var(--cms-text-2);
}
.ncfg-sel-list b {
  color: var(--cms-text);
  font-weight: 600;
}
.ncfg-inc-pill {
  margin-left: 0.4rem;
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 0.05rem 0.4rem;
  border-radius: var(--radius-full);
  background: var(--cms-accent-soft);
  color: var(--cms-text);
}
.ncfg-kit-line {
  padding-left: var(--spacing-3);
  color: var(--cms-text-3);
}
.ncfg-note {
  margin: 0;
  font-size: var(--font-size-xs);
  color: var(--cms-text-3);
}
.ncfg-next {
  color: var(--cms-text-2);
}
.ncfg-cta {
  width: 100%;
  justify-content: center;
}
.ncfg-done {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--cms-text-2);
}
.ncfg-done a {
  color: var(--cms-accent);
}
.ncfg-error {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-error, #d33);
}
/* coverage meter */
.ncfg-coverage {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.ncfg-cov-row {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 0.25rem;
}
.ncfg-cov-cell {
  text-align: center;
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.35rem 0.2rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--cms-line);
  color: var(--cms-text-3);
}
.ncfg-cov-cell.is-on {
  border-color: var(--cms-accent);
  background: var(--cms-accent-soft);
  color: var(--cms-text);
}
.ncfg-cov-label {
  font-size: var(--font-size-xs);
  color: var(--cms-text-3);
}
/* pricing */
.ncfg-price-block {
  border-top: 1px solid var(--cms-line);
  padding-top: var(--spacing-3);
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: var(--font-size-sm);
}
.ncfg-pb-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: var(--cms-text-3);
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.ncfg-acct-chip {
  font-size: 0.6rem;
  padding: 0.1rem 0.45rem;
  border-radius: var(--radius-full);
  border: 1px solid var(--cms-line);
  text-transform: none;
  letter-spacing: 0;
}
.ncfg-price-line {
  display: flex;
  justify-content: space-between;
  gap: var(--spacing-3);
  color: var(--cms-text-2);
}
.ncfg-price-line b {
  color: var(--cms-text);
  white-space: nowrap;
}
.ncfg-price-total {
  border-top: 1px dashed var(--cms-line);
  padding-top: 0.3rem;
  color: var(--cms-text);
}
.ncfg-pb-foot {
  font-size: var(--font-size-xs);
  color: var(--cms-text-3);
}
.ncfg-price-lock {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2);
  padding: var(--spacing-3);
  border-radius: var(--radius-sm);
  border: 1px dashed var(--cms-line);
  font-size: var(--font-size-sm);
  color: var(--cms-text-2);
}
.ncfg-signin {
  align-self: flex-start;
}

/* ==========================================================================
   card-rail  (layout=rail | layout=stack)
   Rendered by lib/components/cms/card_rail_gallery.dart +
   lib/components/cms/cms_content_blocks.dart (_railCard).

   Theme works identically to cms-card-grid: only tokens are redefined on the
   theme modifier; every child rule reads the tokens, so no component needs a
   per-theme variant of its own. Light/dark text colours come from --cms-text,
   --cms-text-2, --cms-text-3; surfaces from --cms-surface / --cms-surface-raised.
   ========================================================================== */

/* ---- theme tokens --------------------------------------------------------
   Both themes are pure token resets — every rule below reads the tokens, so
   nothing needs a per-theme variant of its own.

   The two palettes are NOT symmetric, and that is the design, not a slip:
   dark collapses the section heading and the card's muted text onto one grey
   (#cfcfcf), while light splits them (#3d3d3d vs #737373). So --cms-text-2 is
   "muted but prominent" (section heading) and --cms-text-3 is "tertiary"
   (eyebrow, subtitle, description); dark sets both to the same value.

   Figma: rail 19819:290680 / 20523:143462, stack 20548:151410 / 20523:143438. */
.cms-card-rail.cms-theme-light {
  --cms-surface: #f2f2f2; /* surface/canvas */
  --cms-surface-raised: #ffffff;
  --cms-line: #e3e3e3; /* border/hairline */
  --cms-text: #3d3d3d; /* --semantic-color-text-secondary */
  --cms-text-2: #3d3d3d;
  --cms-text-3: #737373; /* --semantic-color-text-tertiary */
  /* Card description is #cfcfcf in dark (owner, 2026-09-07). Light keeps the
     tertiary grey: #cfcfcf on the #f2f2f2 ground is ~1.1:1 and unreadable. */
  --cms-rail-desc: #737373;
  --cms-rail-dot: #737373;
  --cms-rail-dot-ring: #e3e3e3;
  background: var(--cms-surface);
  color: var(--cms-text);
}
/* Dark runs all-white text by owner decision (2026-09-07), not the #cfcfcf
   --semantic-color-text-tertiary-inverse the Figma dark frames use. Light keeps
   its two-grey split. */
.cms-card-rail.cms-theme-dark {
  --cms-surface: #141414; /* elevation-surface-default-inverse */
  --cms-surface-raised: #1c1c1c;
  --cms-line: rgba(255, 255, 255, 0.12);
  --cms-text: #ffffff; /* --semantic-color-text-on-color */
  --cms-text-2: #ffffff;
  --cms-text-3: #ffffff;
  --cms-rail-desc: #cfcfcf;
  --cms-rail-dot: #cfcfcf;
  --cms-rail-dot-ring: rgba(255, 255, 255, 0.7);
  background: var(--cms-surface);
  color: var(--cms-text);
}

/* ---- local scale tokens --------------------------------------------------
   The section head uses display sizes the global --font-size-* scale doesn't
   reach (it tops out at 3rem). Both clamps hit the Figma value exactly at the
   1232px container width and shrink from there; --vwx (not raw vw) so the
   zoom-compensation in main.css applies. */
.cms-card-rail {
  --rail-display: clamp(2.5rem, calc(8.1 * var(--vwx)), 6.25rem); /* 100px */
  --rail-d1: clamp(1.5rem, calc(3.25 * var(--vwx)), 2.5rem); /*  40px */
  --rail-h1: clamp(1.125rem, calc(1.95 * var(--vwx)), 1.5rem); /*  24px */
  /* Head/card link arrow, applied as a mask (see .cms-rail-link::after). The
     source fill is white but masking ignores colour, so it inherits the text. */
  --cms-rail-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='24' viewBox='0 0 32 24' fill='none'%3E%3Cpath d='M19.4714 23.5573L17.2755 21.2979L25.2323 13.3411H0V10.2161H25.2323L17.2755 2.25938L19.4714 0L31.25 11.7786L19.4714 23.5573Z' fill='%23fff'/%3E%3C/svg%3E");
}

/* ---- section wrapper ----------------------------------------------------- */
.cms-block.cms-card-rail {
  --cms-rail-pad-block: clamp(2.5rem, calc(6.5 * var(--vwx)), 5rem); /* 80px */
  padding-block: var(--cms-rail-pad-block);
}
/* Banded block: both themes paint a background, so the band has to reach the
   edge of the CMS surface it sits on — otherwise the parent's grey (or the
   page white) shows beside it and the band reads as a broken edge.

   It closes the WRAPPER PADDING only, not the 120rem body cap. The page and the
   enrichment surface are themselves capped, so a viewport-wide band would
   overhang them; matching their extent is what makes it read as one surface.

   The gutter is a variable defaulting to 0 because this block renders under
   three different wrappers: `.cms-page` (cms_page.dart) has no horizontal
   padding, while `.cms-blocks` (home_page.dart via CmsBlockRenderer) and
   `.product-content-blocks > .container` (product_page.dart) both pad by the
   same clamp — mirrored below, so the two stay in step if that token moves.

   align-self is load-bearing for the `.cms-blocks` path: that wrapper is a flex
   column with `align-items: flex-start`, which makes children shrink-to-fit —
   negative margins alone would not widen a fit-content box. */
.cms-block.cms-card-rail {
  align-self: stretch;
  /* Pull out over the wrapper's padding, then put the same amount back as our
     own padding: the BACKGROUND gains the gutter, the CONTENT does not move.
     Without the second half the copy slides outward by the gutter and the
     block loses the inset the wrapper was giving it. */
  margin-inline: calc(-1 * var(--cms-rail-gutter, 0px));
  padding-inline: var(--cms-rail-gutter, 0px);
}
/* The gutter mirrors each wrapper's own `padding: 0 clamp(...)` (main.css).

   padding-inline is repeated here, not just on the base rule above, purely to
   win specificity: the PDP sets `.product-content-blocks > .container >
   .cms-block { padding: <block> 0 }` (0,3,0) which zeroes the base rule's
   inline padding, and noedra.css re-states it at (0,4,0) — and noedra.css is
   linked AFTER this file (main.server.dart), so matching its specificity is not
   enough. Hence the third selector at (0,5,0). Measured on the real PDP: the
   band bled correctly but content inset was L 0.0 / R 0.0 without this. */
.cms-blocks > .cms-block.cms-card-rail,
.product-content-blocks > .container > .cms-block.cms-card-rail,
.area-noedra .product-content-blocks > .container > .cms-block.cms-card-rail {
  --cms-rail-gutter: clamp(1rem, calc(2.6 * var(--vwx)), 2.5rem);
  padding-inline: var(--cms-rail-gutter);
  /* padding-block is restated for the same reason. The PDP has its own copy of
     the "block after a block" reset — `.product-content-blocks > .container >
     .cms-block + .cms-block { padding-top: 0 }` — which does NOT carry the
     banded-block exclusion the .cms-page one does, so two card-rails in a row
     rendered with padding-top 0 and the copy pinned to the band's top edge
     (measured on the real PDP: instances 1-3 all 0px, and the first was an
     asymmetric 57/26 rather than the design's 80/80). */
  padding-block: var(--cms-rail-pad-block);
}
.cms-block.cms-card-rail > .container {
  display: flex;
  flex-direction: column;
  gap: 0;
}
/* 88px as padding on the HEAD, not as a gap on the container: a column gap only
   opens space below the head, whereas the design (Figma SectionHeader carries
   `py-88`) wants it above and below. Putting it on the head does both AND still
   separates the head from the track — a container `padding-block` with `gap: 0`
   gave the right outer spacing but left the cards 12px under "More".

   Rail only: stack's container is a ROW, where this was never the head/track
   separator, and stack has its own tighter 40px band padding. */
.cms-card-rail--rail .cms-rail-head {
  padding-block: clamp(2.5rem, calc(7.1 * var(--vwx)), 5.5rem); /* 88px */
}

/* ---- section head -------------------------------------------------------- */
.cms-rail-head {
  display: flex;
  flex-direction: column;
 no   min-width: 0;
}
/* Display 1 pair. The rich-text bold half differs by WEIGHT only — Figma sets
   one colour on the whole wrapping line, so no colour override here. */
.cms-rail-title {
  font-size: var(--rail-display);
  line-height: 1;
  font-weight: 400;
  letter-spacing: -0.02em; /* -2px @ 100px */
  color: var(--cms-text-2);
}
.cms-rail-title strong,
.cms-rail-title b {
  font-weight: 700;
}
.cms-rail-subtitle {
  font-size: var(--rail-display);
  line-height: 1;
  font-weight: 400;
  letter-spacing: -0.02em;
  color: var(--cms-text-2);
}
.cms-rail-lead {
  font-size: var(--rail-d1);
  line-height: 1.25; /* 50/40 */
  font-weight: 400;
  letter-spacing: -0.0025em;
  color: var(--cms-text);
}
/* Weight/tracking/colour follow .cms-rail-subtitle; the size does not — the
   link stays at 1.5rem in both layouts rather than scaling to the display head. */
.cms-rail-link {
  display: inline-flex;
  align-items: center;
  /* em, not rem, so the arrow's offset tracks the type instead of a fixed gap. */
  gap: 0.25em;
  font-size: 1.5rem;
  line-height: 1.25;
  font-weight: 400;
  letter-spacing: -0.02em;
  color: var(--cms-text-2);
  text-decoration: none;
}
/* The arrow is a MASK, not a background image: the source SVG is a white fill,
   and masking paints it with currentColor instead, so one asset serves both
   themes (and the white-on-photo overlay) without a second copy. Sized in `em`
   so it tracks whatever font-size the link resolves to; 1em x 0.75em keeps the
   asset's own 32:24 aspect exactly. */
.cms-rail-link::after {
  content: '';
  flex: none;
  width: 1em;
  height: 0.75em;
  background-color: currentColor;
  -webkit-mask: var(--cms-rail-arrow) no-repeat center / contain;
  mask: var(--cms-rail-arrow) no-repeat center / contain;
}

/* ---- card track ----------------------------------------------------------
   rail: 3-up wrapping grid — 24px between columns, 64px between rows.

   The light-theme Figma frame (20523:143462) also draws a continuous #e3e3e3
   hairline between card rows; dark does not. Deliberately NOT implemented
   (owner, 2026-09-07): a continuous rule cannot cross a wrapping flex track —
   per-card borders break at every column gap, and there is no selector for
   "cards below the first row" — so it would need per-row wrapper elements,
   which this block's single-DOM-across-variants contract rules out. */
/* Grid, not wrapping flex. Two requirements pull against each other: every card
   the SAME size, and the row fully used. Flex can only satisfy the second — a
   trailing card grows to fill and ends up three times its neighbours (which is
   exactly what a 4th card did). Grid columns are equal by construction, and
   `auto-fit` collapses the tracks no card occupies, so N cards that fit on one
   line divide that line between them: 4 cards → 4 equal columns, full width.

   The floor is what decides how many fit — 16rem lets 4 (often 5) share a
   desktop track. Past that the extras wrap to a second line and keep their
   column width, so the last line can end short. That is the deliberate trade:
   equal cards win over a flush right edge. */
.cms-card-rail--rail .cms-rail-track {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 4rem 1.5rem; /* --semantic-spacing-140 / -90 */
}
/* No flex sizing on the card any more — the grid track above owns the width,
   which is what keeps every card identical. min-width: 0 (base rule) still
   applies so long words cannot push a column wider than its share. */

/* ---- individual card ----------------------------------------------------- */
.cms-rail-card {
  display: flex;
  flex-direction: column;
  gap: 0.75rem; /* --semantic-spacing-60 */
  min-width: 0;
}

/* ---- card media (.cms-rail-media) --------------------------------------- */
.cms-rail-media {
  position: relative;
  width: 100%;
}
.cms-rail-media--none {
  display: none;
}
.cms-rail-media-frame {
  position: relative;
  width: 100%;
  /* 394.67 card width : 150 image height at the 1232px container */
  aspect-ratio: 2.63;
  overflow: hidden;
  border-radius: 2px; /* --semantic-radius-xs */
  background: var(--cms-surface-raised);
}
.cms-rail-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.2s ease;
  pointer-events: none;
}
.cms-rail-img.is-active {
  opacity: 1;
}

/* ---- carousel dot indicator --------------------------------------------- */
.cms-rail-dots {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 4px; /* --semantic-spacing-30 */
}
/* Inactive is an OUTLINE, not a faint fill — measured off the Figma dots in
   both themes (dark ring peaks ~#b8b8b8 over #141414, light ring #e3e3e3 over
   #f2f2f2, both with the ground showing through the middle). Active is a solid
   fill. Own tokens rather than --cms-text-3/--cms-line: for media=top the dots
   sit on the section background, and the dark theme's text token is pure white
   while the design's dot fill is #cfcfcf. The 1px ring is a hairline, which the
   house rule allows. */
.cms-rail-dot {
  width: 0.75rem;
  height: 0.75rem;
  border-radius: 50%;
  padding: 0;
  cursor: pointer;
  background: transparent;
  border: 1px solid var(--cms-rail-dot-ring);
  transition: background 0.15s ease, border-color 0.15s ease;
}
.cms-rail-dot.is-active {
  background: var(--cms-rail-dot);
  border-color: var(--cms-rail-dot);
}

/* ---- card body ----------------------------------------------------------- */
.cms-rail-body {
  display: flex;
  flex-direction: column;
  gap: 0;
  flex: 1;
  min-width: 0;
}
.cms-rail-eyebrow {
  display: block;
  font-size: var(--font-size-sm); /* 14/22 Bold */
  line-height: 1.57;
  font-weight: 700;
  color: var(--cms-text-3);
}
.cms-rail-card-title {
  margin: 0;
  font-size: var(--rail-h1); /* 24/30 Bold */
  line-height: 1.25;
  font-weight: 700;
  color: var(--cms-text);
}
.cms-rail-card-subtitle {
  margin: 0;
  font-size: var(--rail-h1); /* 24/30 Regular */
  line-height: 1.25;
  font-weight: 400;
  color: var(--cms-text-3);
}
.cms-rail-card-desc {
  margin: 0.375rem 0 0;
  font-size: var(--font-size-base); /* 16/24 */
  line-height: 1.5;
  color: var(--cms-rail-desc);
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 6;
  -webkit-box-orient: vertical;
}
.cms-rail-card-link {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem; /* --semantic-spacing-30 */
  margin-top: auto;
  padding-top: 0.75rem;
  font-size: var(--font-size-base);
  line-height: 1.5;
  font-weight: 700;
  color: var(--cms-text);
  text-decoration: none;
}
.cms-rail-card-link::after {
  content: '→';
}

/* ---- rail + media=top: dots sit in the body's eyebrow row ----------------
   The gallery owns the dots (they're inside .cms-rail-media), but the design
   puts them right-aligned on the eyebrow line, below the image. Rather than
   move them in Dart — the block deliberately keeps one DOM across every
   variant — collapse .cms-rail-media so the frame and the dots become grid
   items of the card, then place the dots in the body's cell. */
.cms-card-rail--rail.cms-card-rail--media-top .cms-rail-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto 1fr;
}
.cms-card-rail--rail.cms-card-rail--media-top .cms-rail-media:not(.cms-rail-media--none) {
  display: contents;
}
.cms-card-rail--rail.cms-card-rail--media-top .cms-rail-media-frame {
  grid-area: 1 / 1;
}
.cms-card-rail--rail.cms-card-rail--media-top .cms-rail-body {
  grid-area: 2 / 1;
}
/* Text-only card: no image row, so the body takes the whole card. */
.cms-card-rail--rail.cms-card-rail--media-top .cms-rail-card:has(.cms-rail-media--none) {
  grid-template-rows: 1fr;
}
.cms-card-rail--rail.cms-card-rail--media-top .cms-rail-card:has(.cms-rail-media--none) .cms-rail-body {
  grid-area: 1 / 1;
}
/* Per-variant description length. In Figma all media=top cards in a row are the
   same height (413px), so a card that spends its top 150px on an image has room
   for fewer lines than a text-only one in the same row — 5 vs 8, measured off
   nodes 20523:113958 and 20523:114009. The overlay variant clamps to 2 further
   down. Same DOM, same height, different budget. */
.cms-card-rail--rail.cms-card-rail--media-top .cms-rail-card-desc {
  -webkit-line-clamp: 5;
}
.cms-card-rail--rail.cms-card-rail--media-top
  .cms-rail-card:has(.cms-rail-media--none)
  .cms-rail-card-desc {
  -webkit-line-clamp: 8;
}
.cms-card-rail--rail.cms-card-rail--media-top .cms-rail-dots {
  grid-area: 2 / 1;
  /* The body occupies this same cell and comes later in the DOM, so it painted
     over the dots and swallowed every click — elementFromPoint on a dot
     returned .cms-rail-card-title. Grid items honour z-index while static. */
  z-index: 1;
  position: static;
  flex-direction: row;
  align-items: center;
  justify-self: end;
  align-self: start;
  height: 1.375rem; /* eyebrow line box, so the dots centre on it */
}
/* Reserve the 44px indicator strip + 20px gap so the eyebrow never runs under it. */
.cms-card-rail--rail.cms-card-rail--media-top .cms-rail-eyebrow {
  padding-right: 4rem;
}

/* ---- media=overlay variant: text + gradient over the image --------------- */
.cms-card-rail--media-overlay .cms-rail-card {
  display: grid;
  grid-template-areas: 'stack';
  aspect-ratio: 394 / 251;
  border-radius: 2px;
  overflow: hidden;
  gap: 0;
}
.cms-card-rail--media-overlay .cms-rail-media {
  grid-area: stack;
}
.cms-card-rail--media-overlay .cms-rail-media-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  border-radius: 0;
}
.cms-card-rail--media-overlay .cms-rail-body {
  grid-area: stack;
  z-index: 1;
  justify-content: flex-end;
  gap: 0.75rem;
  /* pt 16 / pr 20 / pb 24 / pl 16; the extra right inset clears the dots. */
  padding: 1rem 3.5rem 1.5rem 1rem;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.4) 0%, rgba(0, 0, 0, 0.1) 100%);
  /* Always white-on-image regardless of section theme */
  --cms-text: #ffffff;
  --cms-text-2: #ffffff;
  --cms-text-3: #ffffff;
  /* Over the photo the description is white in BOTH themes — without this it
     would inherit the light theme's #737373 and disappear into the image. */
  --cms-rail-desc: #ffffff;
  color: var(--cms-text);
}
.cms-card-rail--media-overlay .cms-rail-eyebrow {
  font-size: var(--font-size-base); /* 16/24 Bold */
  line-height: 1.5;
}
.cms-card-rail--media-overlay .cms-rail-card-title {
  font-size: var(--rail-d1);
  line-height: 1.25;
  letter-spacing: -0.0025em;
}
.cms-card-rail--media-overlay .cms-rail-card-subtitle {
  font-size: var(--rail-d1);
  line-height: 1.25;
  letter-spacing: -0.0025em;
}
.cms-card-rail--media-overlay .cms-rail-card-desc {
  font-weight: 700;
  -webkit-line-clamp: 2;
}
.cms-card-rail--media-overlay .cms-rail-card-link {
  margin-top: 0;
  padding-top: 0;
}
.cms-card-rail--media-overlay .cms-rail-dots {
  z-index: 2;
  top: auto;
  bottom: 1.5rem;
  right: 1.25rem;
}
/* Back over the photo, so white in both themes — same ring/fill treatment. */
.cms-card-rail--media-overlay .cms-rail-dots {
  --cms-rail-dot: #ffffff;
  --cms-rail-dot-ring: rgba(255, 255, 255, 0.7);
}

/* ---- stack layout --------------------------------------------------------
   Two columns: a 320px head beside a flex-1 track of full-width rows whose
   thumbnail alternates side. Figma node 20548-151410.

   min-width: 0 on the track is load-bearing — without it the flex item
   refuses to shrink below its content and the right column overflows the
   container. (Figma's own export carries `min-w-px` for the same reason.) */
/* Stack sits tighter than rail: 40px of band padding, not 80. Set on the
   variable so both the base rule and the specificity-bumped PDP/noedra rule
   pick it up without restating the value. */
.cms-block.cms-card-rail--stack {
  --cms-rail-pad-block: clamp(1.25rem, calc(3.25 * var(--vwx)), 2.5rem); /* 40px */
}
.cms-block.cms-card-rail--stack > .container {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: clamp(2rem, calc(6.5 * var(--vwx)), 5rem); /* 80px */
}
/* Head column: caps at 30rem, then tapers with the viewport down to an 18rem
   floor, below which the container wraps it above the track.

   The basis is a clamped PERCENTAGE, not a rem step. flex-shrink can't do this
   job here: with flex-wrap on, a line breaks when the items' bases overflow —
   shrinking only ever applies after the break — so a fixed `flex: 0 1 30rem`
   would hold 30rem exactly and then snap to wrapped, never tapering. At 36% the
   head gives up 0.36px per px the container loses against the track's 0.64px,
   which is the "shrinks, but slower than the right side" the design wants —
   it starts narrower, so it should concede less. */
.cms-card-rail--stack .cms-rail-head {
  flex: 0 1 clamp(18rem, 36%, 30rem);
  min-width: 0;
  /* Indent tapering 2.5rem → 0, reaching 0 exactly as the column wraps (~580px)
     so the head never sits inset once it is stacked above the track. The ramp
     is viewport-linear — value(580px) = 0, value(1280px) = 40px — which is why
     the offset is px: rem is itself fluid here (main.css scales the root), and
     a rem offset would bend the line. */
  padding-left: clamp(0rem, calc(5.71 * var(--vwx) - 33.1px), 2.5rem);
}
/* The stack head is a Display 1 pair, both white — not the 100px rail heading. */
.cms-card-rail--stack .cms-rail-title {
  font-size: var(--rail-d1);
  line-height: 1.25;
  font-weight: 700;
  letter-spacing: -0.0025em;
  color: var(--cms-text);
}
.cms-card-rail--stack .cms-rail-subtitle {
  font-size: var(--rail-d1);
  line-height: 1.25;
  letter-spacing: -0.0025em;
  color: var(--cms-text);
}
.cms-card-rail--stack .cms-rail-lead {
  font-size: var(--font-size-base);
  line-height: 1.5;
  color: var(--cms-text-2);
}
/* Size is inherited from the base rule (1.5rem) — only the stack's colour and
   tracking differ, matching its own subtitle. */
.cms-card-rail--stack .cms-rail-link {
  line-height: 1.25;
  font-weight: 400;
  letter-spacing: -0.0025em;
  color: var(--cms-text);
}
.cms-card-rail--stack .cms-rail-track {
  flex: 1 1 26rem;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2.5rem; /* --semantic-spacing-110 */
}
.cms-card-rail--stack .cms-rail-card {
  flex-direction: row;
  align-items: flex-start;
  gap: 1rem; /* --semantic-spacing-70 */
}
.cms-card-rail--stack .cms-rail-card:nth-child(even) {
  flex-direction: row-reverse;
}
.cms-card-rail--stack .cms-rail-media {
  flex: 0 0 7.5rem;
  width: 7.5rem;
}
.cms-card-rail--stack .cms-rail-media-frame {
  width: 7.5rem; /* 120 */
  height: 10rem; /* 160 */
  aspect-ratio: auto;
  background: #ffffff;
}
.cms-card-rail--stack .cms-rail-body {
  flex: 1 1 0;
  min-width: 0;
  justify-content: center;
  gap: 0;
}
.cms-card-rail--stack .cms-rail-card-link {
  margin-top: 0;
}
.cms-card-rail--stack .cms-rail-dots {
  display: none;
}

/* ---- lcoe-calculator ------------------------------------------------------
   Live LCoE estimate (components/cms/lcoe/lcoe_calculator.dart). Neutral
   palette matched to the PDP buy box (.purchase-bar) and the account
   grouping tabs — no brand colour. */
.lcoe-calc {
  --lcoe-ink: #262626;
  --lcoe-ink-soft: #737373;
  --lcoe-line: #e3e3e3;
  --lcoe-line-soft: #ebebeb;
  --lcoe-control-line: #d4d4d4;
  --lcoe-fill: #fafafa;
  --lcoe-capex: #5fa8ff;
  --lcoe-opex: #4cc29b;
  --lcoe-fuel: #ffb648;
  --lcoe-financing: #f0776f;
  color: var(--lcoe-ink);
  padding-block: 2rem;
}
/* Outranks `.product-content-blocks .cms-block .container` (flex column). */
.cms-block.lcoe-calc .lcoe-calc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  gap: 1.5rem;
  align-items: stretch;
}
.lcoe-panel {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  min-width: 0;
  padding: 1.5rem;
  border: 1px solid var(--lcoe-line);
  border-radius: 1.5rem;
  background: #fff;
}
.lcoe-head { display: flex; align-items: center; gap: 0.6rem; }
.lcoe-head h3 { margin: 0; color: var(--lcoe-ink); font-size: 1.125rem; font-weight: 600; }
.lcoe-head-icon {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 2.125rem;
  height: 2.125rem;
  border: 1px solid var(--lcoe-line-soft);
  border-radius: 0.625rem;
  background: var(--lcoe-fill);
  color: var(--lcoe-ink-soft);
}
.lcoe-copy { margin: 0 0 0.5rem; color: var(--lcoe-ink-soft); font-size: 0.875rem; line-height: 1.45; }
.lcoe-fields {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
}
/* Last row (steam / series) absorbs leftover height so both cards end level. */
.lcoe-panel--inputs .lcoe-fields { flex: 1; grid-template-rows: auto auto 1fr; }
.lcoe-field { position: relative; display: flex; flex-direction: column; gap: 0.4rem; min-width: 0; color: var(--lcoe-ink-soft); font-size: 0.875rem; }
.lcoe-field.is-open { z-index: 30; }
.lcoe-dropdown-scrim { position: fixed; inset: 0; z-index: 25; }
.lcoe-field-label { color: var(--lcoe-ink); font-weight: 600; }
/* plpSortDropdown (plp_toolbar.dart), sized to the field instead of the PLP toolbar. */
.lcoe-field .sort-dropdown {
  width: 100%;
  min-height: 2.5rem;
  box-sizing: border-box;
  padding: 0.5rem 0.75rem;
  border-color: var(--lcoe-control-line);
}
.lcoe-field .sort-dropdown-label:empty,
.lcoe-field .view-toggle__divider { display: none; }
.lcoe-field .sort-dropdown-value { font-size: 0.875rem; color: var(--lcoe-ink); }
.lcoe-field .sort-dropdown-chevron { margin-left: auto; }
/* Single-select: no radio glyphs; the chosen option reads bold instead. */
.lcoe-field .sort-option-radio { display: none; }
.lcoe-field .sort-option {
  padding: 0.5rem 0.625rem;
  border-radius: 0.5rem;
  transition: background-color 0.15s;
}
.lcoe-field .sort-option:hover { background: #f2f2f2; color: var(--lcoe-ink); }
.lcoe-field .sort-option:active { background: #ebebeb; }
.lcoe-field .sort-option:focus-visible { outline: 2px solid #737373; outline-offset: -2px; }
.lcoe-field .sort-option.selected { background: #f5f5f5; font-weight: 600; color: var(--lcoe-ink); }
.lcoe-field .sort-option.selected:hover { background: #ebebeb; }
.lcoe-field .sort-dropdown.open .sort-dropdown-panel { gap: 0.125rem; }
.lcoe-field .sort-dropdown-panel {
  top: calc(100% + 0.25rem);
  width: 100%;
  box-sizing: border-box;
  max-height: 18rem;
  overflow-y: auto;
  z-index: 20;
  padding: 0.375rem;
}
.lcoe-card {
  min-width: 0;
  padding: 0.75rem;
  border: 1px solid var(--lcoe-line-soft);
  border-radius: 1rem;
  background: var(--lcoe-fill);
}
.lcoe-range-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  color: var(--lcoe-ink);
  font-size: 0.875rem;
  font-weight: 600;
}
.lcoe-range-value { display: inline-flex; align-items: center; gap: 0.4rem; flex-shrink: 0; color: var(--lcoe-ink); font-weight: 400; }
.lcoe-range-value input {
  width: 4.75rem;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--lcoe-control-line);
  border-radius: 0.625rem;
  background: #fff;
  color: var(--lcoe-ink);
  font: inherit;
}
.lcoe-unit { font-size: 0.8125rem; color: var(--lcoe-ink-soft); }
.lcoe-range-scale {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  margin-top: 0.25rem;
  color: var(--lcoe-ink-soft);
  font-size: 0.75rem;
}
.lcoe-series-eyebrow { margin: 0 0 0.4rem; color: var(--lcoe-ink); font-size: 0.875rem; font-weight: 600; }
.lcoe-series-body { display: flex; align-items: center; gap: 1rem; }
.lcoe-series-meta { display: flex; flex: 0 0 auto; flex-direction: column; gap: 0.25rem; }
.lcoe-series-name { margin: 0; color: var(--lcoe-ink); font-size: 1.125rem; font-weight: 700; }
.lcoe-series-range { margin: 0; color: var(--lcoe-ink-soft); font-size: 0.8125rem; }
.lcoe-series-note {
  margin: 0.5rem 0 0;
  padding: 0.75rem;
  border: 1px dashed var(--lcoe-control-line);
  border-radius: 0.625rem;
  color: var(--lcoe-ink-soft);
  font-size: 0.8125rem;
}
/* Takes every pixel the text column leaves, so there is no trailing gap. */
.lcoe-series-image { display: block; flex: 1 1 0; min-width: 0; width: 100%; height: auto; max-height: 10rem; object-fit: contain; mix-blend-mode: multiply; }
.lcoe-cta {
  flex-shrink: 0;
  min-height: 2.5rem;
  padding: 0.5rem 1rem;
  border: 1px solid var(--lcoe-ink);
  border-radius: 0.75rem;
  background: var(--lcoe-ink);
  color: #fff;
  font: inherit;
  font-size: 0.875rem;
  cursor: pointer;
  transition: background-color 0.15s, border-color 0.15s;
}
.lcoe-cta:hover { border-color: #3d3d3d; background: #3d3d3d; }
.lcoe-cta:active { background: #1a1a1a; }
.lcoe-cta:disabled, .lcoe-cta.is-loading { opacity: 0.6; cursor: progress; }

.lcoe-head-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}
.lcoe-head-row .lcoe-unit-toggle { margin-bottom: 0; }
.lcoe-kpi { display: flex; flex-direction: column; align-items: flex-start; gap: 0.25rem; }
.lcoe-unit-toggle {
  display: inline-flex;
  margin-bottom: 0.5rem;
  padding: 0.1875rem;
  border: 1px solid var(--lcoe-line-soft);
  border-radius: 0.625rem;
  background: var(--lcoe-fill);
}
.lcoe-unit-btn {
  padding: 0.3rem 0.75rem;
  border: none;
  border-radius: 0.4375rem;
  background: transparent;
  color: #525252;
  font: inherit;
  font-size: 0.8125rem;
  cursor: pointer;
  transition: background-color 160ms ease-out, color 160ms ease-out;
}
.lcoe-unit-btn:hover:not(.is-active) { background: #f2f2f2; color: var(--lcoe-ink); }
.lcoe-unit-btn.is-active { background: var(--lcoe-ink); color: #fff; }
.lcoe-kpi-label { color: var(--lcoe-ink-soft); font-size: 0.8125rem; }
.lcoe-kpi-value { color: var(--lcoe-ink); font-size: 1.5rem; font-weight: 600; }
.lcoe-donut {
  display: grid;
  place-items: center;
  align-self: center;
  width: min(12.5rem, 100%);
  aspect-ratio: 1;
  margin-block: 0.25rem;
  border-radius: 50%;
}
.lcoe-donut-core {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 62%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: #fff;
  text-align: center;
}
.lcoe-donut-core span, .lcoe-donut-core small { color: var(--lcoe-ink-soft); font-size: 0.7rem; }
.lcoe-donut-core strong { color: var(--lcoe-ink); font-size: 1.75rem; }
.lcoe-legend {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem;
  margin-top: auto;
}
.lcoe-legend-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-width: 0;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--lcoe-line-soft);
  border-radius: 0.75rem;
  background: var(--lcoe-fill);
}
.lcoe-legend-item p { margin: 0; color: var(--lcoe-ink-soft); font-size: 0.75rem; }
.lcoe-legend-item strong { color: var(--lcoe-ink); font-size: 0.9375rem; font-weight: 600; }
.lcoe-swatch { flex-shrink: 0; width: 0.75rem; height: 0.75rem; border-radius: 50%; }
.lcoe-swatch--capex { background: var(--lcoe-capex); }
.lcoe-swatch--opex { background: var(--lcoe-opex); }
.lcoe-swatch--fuel { background: var(--lcoe-fuel); }
.lcoe-swatch--financing { background: var(--lcoe-financing); }

/* Form modal. */
.lcoe-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: grid;
  place-items: center;
  padding: 1rem;
}
.lcoe-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(38, 38, 38, 0.45);
  animation: lcoe-overlay-enter 160ms ease-out;
}
.lcoe-modal-card {
  animation: lcoe-dialog-enter 200ms cubic-bezier(0.16, 1, 0.3, 1);
  position: relative;
  width: min(47.5rem, 100%);
  max-height: calc(100dvh - 2rem);
  overflow-y: auto;
  padding: 2rem;
  border: 1px solid var(--lcoe-line);
  border-radius: 1.5rem;
  background: #fff;
  color: var(--lcoe-ink);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.18);
}
.lcoe-modal-card h2 { margin: 0 4rem 0.5rem 0; color: var(--lcoe-ink); font-size: 1.375rem; font-weight: 600; }
.lcoe-modal-intro, .lcoe-modal-ref { max-width: 60ch; margin: 0 0 1.25rem; color: var(--lcoe-ink-soft); font-size: 0.875rem; }
.lcoe-modal-close {
  position: absolute;
  top: 1.25rem;
  right: 1.25rem;
  padding: 0.35rem 0.85rem;
  border: 1px solid var(--lcoe-control-line);
  border-radius: 0.625rem;
  background: #fff;
  color: var(--lcoe-ink);
  font: inherit;
  font-size: 0.8125rem;
  cursor: pointer;
}
.lcoe-modal-close:hover { background: #f2f2f2; }
.lcoe-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 9rem), 1fr));
  gap: 0.6rem;
  margin-bottom: 1.25rem;
}
.lcoe-summary-item {
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--lcoe-line-soft);
  border-radius: 0.75rem;
  background: var(--lcoe-fill);
}
.lcoe-summary-item p { margin: 0 0 0.2rem; color: var(--lcoe-ink-soft); font-size: 0.75rem; }
.lcoe-summary-item strong { font-size: 0.875rem; }
.lcoe-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
  gap: 0.75rem;
  margin-bottom: 1rem;
}
.lcoe-form-field { display: flex; flex-direction: column; gap: 0.35rem; color: var(--lcoe-ink-soft); font-size: 0.8125rem; }
.lcoe-form-field--wide { grid-column: 1 / -1; }
.lcoe-form-field input, .lcoe-form-field textarea {
  width: 100%;
  box-sizing: border-box;
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--lcoe-control-line);
  border-radius: 0.75rem;
  background: #fff;
  color: var(--lcoe-ink);
  font: inherit;
}
.lcoe-form-error { margin: 0 0 1rem; color: #b42318; font-size: 0.8125rem; }
.lcoe-cta--submit { width: auto; margin-top: 0; }

@keyframes lcoe-overlay-enter {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes lcoe-dialog-enter {
  from { opacity: 0; transform: translateY(0.5rem); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .lcoe-unit-btn, .lcoe-cta { transition: none; }
  .lcoe-modal-backdrop, .lcoe-modal-card { animation: none; }
}

/* All PDP enrichment sections share a grey ground and consistent outer rhythm.
   Direct-child selectors keep nested calculator/gallery layouts independent. */
.product-content-blocks--details {
  --pdp-section-gap: clamp(2rem, calc(4 * var(--vwx)), 4rem);
  --cms-text: var(--se-text-default, #1a1a1a);
  --cms-text-2: var(--se-text-secondary, #666666);
  --cms-text-3: var(--se-text-secondary, #666666);
  --cms-accent: var(--se-text-default, #1a1a1a);
  --cms-accent-ink: var(--se-text-inverted, #ffffff);
  --cms-surface: var(--se-layer-02, #ffffff);
  --cms-surface-alt: var(--se-layer-01, #f2f2f2);
  --cms-line: var(--se-layer-02-stroke, #ebebeb);
  background: var(--cms-surface-alt);
  border-top: 1px solid var(--cms-line);
  padding-block: clamp(2rem, calc(4 * var(--vwx)), 4rem);
}
.product-content-blocks--details > .container {
  max-width: var(--container-max, 82.5rem);
  /* Keep the empty second column beside a standalone spec table. */
  grid-template-columns: repeat(auto-fill, minmax(min(100%, max(25rem, calc((100% - var(--pdp-section-gap)) / 2))), 1fr));
  gap: var(--pdp-section-gap);
  align-items: start;
}
.product-content-blocks--details > .container > .content-block.feature-highlight,
.product-content-blocks--details > .container > .content-block.spec-table-block {
  grid-column: auto;
  width: auto;
  max-width: none;
  border: 0;
  padding: 0;
}
.product-content-blocks--details > .container > .content-block.feature-highlight h3::before {
  display: none;
}
.product-content-blocks--details > .container > .cms-block.lcoe-calc {
  grid-column: 1 / -1;
}
.product-content-blocks--details .cms-block.lcoe-calc > .lcoe-calc-grid {
  max-width: none;
  width: 100%;
  box-sizing: border-box;
}
.product-content-blocks--details > .container > :is(.feature-highlight, .spec-table-block, .callout, .cms-external-reference, .cms-configurator-summary) {
  min-width: 0;
  color: var(--cms-text);
  font-family: var(--se-font-family, var(--font-family));
  overflow-wrap: anywhere;
  box-shadow: none;
}
.product-content-blocks.product-content-blocks--details > .container > :is(.feature-highlight, .spec-table-block, .callout, .cms-configurator-summary) > :is(h3, h4) {
  margin: 0 0 var(--spacing-4);
  font-size: var(--se-font-size-h4, 1.375rem);
  line-height: var(--se-line-height-h4, 1.625rem);
  font-weight: 700;
  color: var(--cms-text);
  letter-spacing: 0;
}
.product-content-blocks--details > .container > .content-block.feature-highlight > h3 {
  font-size: var(--se-font-size-h2, 1.75rem);
  line-height: var(--se-line-height-h2, 2.125rem);
  max-width: 24ch;
  padding: 0;
}
.product-content-blocks--details :is(.feature-description, .callout-content, .cms-configurator-summary .cms-block-body) {
  max-width: 70ch;
  font-size: var(--se-font-size-text-large, 1rem);
  line-height: var(--se-line-height-text-large, 1.5rem);
  color: var(--cms-text-2);
}
.product-content-blocks--details :is(.feature-description, .callout-content) :is(p, ul, ol) {
  font-size: inherit;
  line-height: inherit;
  color: inherit;
}
.product-content-blocks--details .feature-highlight > img {
  display: block;
  width: 100%;
  height: auto;
  margin-top: var(--spacing-5);
  object-fit: contain;
}
.product-content-blocks--details .content-block.spec-table-block .spec-table {
  width: 100%;
  max-width: none;
  table-layout: fixed;
  border-collapse: collapse;
}
.product-content-blocks--details .content-block.spec-table-block .spec-table :is(th, td) {
  padding: var(--spacing-4) 0;
  border-bottom: 1px solid var(--cms-line);
  color: var(--cms-text);
  font-size: var(--se-font-size-text-default, 0.875rem);
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.product-content-blocks--details .content-block.spec-table-block .spec-table th {
  width: 55%;
  text-align: left;
  font-weight: 400;
  color: var(--cms-text-2);
}
.product-content-blocks--details .content-block.spec-table-block .spec-table td {
  padding-left: var(--spacing-5);
  font-variant-numeric: tabular-nums;
  font-weight: 400;
}
.product-content-blocks--details > .container > .content-block.callout:not(:has(h4[data-pillar])) {
  grid-column: auto;
  align-self: stretch;
  padding: clamp(1.25rem, calc(3 * var(--vwx)), 2rem);
  border: 1px solid var(--se-layer-03-stroke, #c9c9c9);
  border-radius: var(--se-radius-card, 0.75rem);
  width: 100%;
  max-width: none;
  box-sizing: border-box;
  background: var(--cms-surface);
}
.product-content-blocks--details > .container > .content-block.callout:not(:has(h4[data-pillar])) h4 {
  color: var(--cms-text);
}
.product-content-blocks--details > .container > .content-block.callout:not(:has(h4[data-pillar])) .callout-content,
.product-content-blocks--details > .container > .content-block.callout:not(:has(h4[data-pillar])) .callout-content :is(p, li, strong, a) {
  color: var(--cms-text-2);
}
.product-content-blocks--details .cms-external-reference-card {
  flex-wrap: wrap;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  padding: clamp(1.25rem, calc(3 * var(--vwx)), 2rem);
  border: 1px solid var(--se-layer-03-stroke, #c9c9c9);
  border-radius: var(--se-radius-card, 0.75rem);
  background: var(--cms-surface);
  color: var(--cms-text);
}
.product-content-blocks--details .cms-external-reference-main {
  flex: 0 1 auto;
  gap: var(--spacing-2);
}
.product-content-blocks--details .cms-external-reference-title {
  font-size: var(--se-font-size-text-large, 1rem);
  color: var(--cms-accent);
  text-underline-offset: 0.2em;
}
.product-content-blocks--details .cms-external-reference-card:hover .cms-external-reference-title,
.product-content-blocks--details .cms-external-reference-card:focus-visible .cms-external-reference-title {
  text-decoration: none;
}
.product-content-blocks--details .cms-external-reference-desc {
  max-width: 70ch;
  font-size: var(--se-font-size-text-default, 0.875rem);
  line-height: 1.5;
  color: var(--cms-text-2);
}
.product-content-blocks--details .cms-external-reference-kind {
  padding: 0;
  border: 0;
  border-radius: 0;
  color: var(--cms-accent);
  font-size: var(--se-font-size-text-default, 0.875rem);
}
.product-content-blocks--details .cms-external-reference-card:focus-visible {
  outline: 2px solid var(--cms-accent);
  outline-offset: var(--spacing-1);
}
.product-content-blocks--details > .container > .content-block.cms-external-reference,
.product-content-blocks--details > .container > .content-block.cms-configurator-summary {
  grid-column: 1 / -1;
  padding: 0;
  border-radius: 0;
  background: transparent;
}
.product-content-blocks--details > .container > .content-block.cms-external-reference {
  grid-column: auto;
  display: flex;
  align-items: stretch;
  align-self: stretch;
}
.product-content-blocks--details > .container > .content-block.cms-external-reference > .cms-external-reference-card {
  width: 100%;
  box-sizing: border-box;
}
.product-content-blocks--details .cms-cfg-groups {
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  margin-top: var(--spacing-5);
}
.product-content-blocks--details .cms-cfg-groups .cms-step {
  padding: var(--spacing-5) 0;
  border: 0;
  border-top: 1px solid var(--cms-line);
  border-radius: 0;
  background: transparent;
}
.product-content-blocks--details .cms-cfg-groups .cms-step-body {
  min-width: 0;
  gap: var(--spacing-3);
}
.product-content-blocks--details .cms-cfg-groups .cms-chip {
  border-radius: var(--spacing-1);
  font-size: var(--se-font-size-text-default, 0.875rem);
  font-weight: 400;
  line-height: 1.5;
  white-space: normal;
}
.product-content-blocks--details .cms-configurator-summary .cms-footnote {
  margin: var(--spacing-4) 0 0;
  color: var(--cms-text-2);
  font-size: var(--se-font-size-text-default, 0.875rem);
  line-height: 1.5;
}

/* The interactive Payload configurator shares a class with the standalone
   configurator hero. Keep that hero's flush padding out of the PDP form. */
.product-content-blocks--details .content-block.configurator-form {
  --pdp-form-inset: clamp(1.25rem, calc(3 * var(--vwx)), 2rem);
  min-width: 0;
  font-family: var(--se-font-family, var(--font-family));
  color: var(--cms-text);
  box-shadow: none;
  border: 0;
  border-radius: 0;
  border-top: 1px solid var(--cms-line);
  overflow: visible;
}
.product-content-blocks--details .configurator-form .configurator-header {
  padding: var(--pdp-form-inset) var(--pdp-form-inset) var(--spacing-6);
  text-align: left;
}
.product-content-blocks--details .configurator-form .configurator-header h3 {
  font-family: inherit;
  font-size: var(--se-font-size-h2, 1.75rem);
  line-height: var(--se-line-height-h2, 2.125rem);
  color: var(--cms-text);
}
.product-content-blocks--details .configurator-form .configurator-intro {
  max-width: 70ch;
  margin: var(--spacing-3) 0 0;
  color: var(--cms-text-2);
  font-size: var(--se-font-size-text-large, 1rem);
  line-height: 1.5;
}
.product-content-blocks--details .configurator-form .configurator-stepper {
  margin-top: 0;
  flex-wrap: wrap;
  max-width: 34rem;
  border: 0;
  background: transparent;
  margin-inline: var(--pdp-form-inset);
}
.product-content-blocks--details .configurator-form .configurator-step {
  white-space: normal;
  overflow-wrap: anywhere;
  border-right: 0;
  border-bottom: 1px solid var(--cms-line);
  padding: var(--spacing-4) var(--spacing-3);
  box-shadow: none;
}
.product-content-blocks--details .configurator-form .configurator-step--active {
  border-bottom: 2px solid var(--cms-accent);
  color: var(--cms-accent);
  box-shadow: none;
}
.product-content-blocks--details .configurator-form .configurator-phase-content {
  padding: var(--spacing-6) var(--pdp-form-inset);
}
.product-content-blocks--details .configurator-form .configurator-phase:not(.configurator-phase--submit) {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 23rem), 1fr));
  gap: var(--spacing-6);
}
.product-content-blocks--details .content-block.configurator-mirror.configurator-form .configurator-phase .configurator-question,
.product-content-blocks--details .content-block.configurator-mirror.configurator-form .configurator-phase .configurator-question:first-of-type {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--spacing-2);
  padding: 0;
  border: 0;
  min-width: 0;
}
.product-content-blocks--details .configurator-form .configurator-question:has(textarea) {
  grid-column: 1 / -1;
}
.product-content-blocks--details .configurator-form .configurator-question > * {
  grid-column: auto;
  grid-row: auto;
  width: auto;
  max-width: none;
}
.product-content-blocks--details .configurator-form :is(.configurator-input, .configurator-select, .configurator-textarea) {
  width: 100%;
  box-sizing: border-box;
  min-height: 3rem;
  border-radius: var(--spacing-1);
  font: inherit;
  background: var(--cms-surface);
  color: var(--cms-text);
}
.product-content-blocks--details .configurator-form .configurator-question:not(.has-error) :is(.configurator-input, .configurator-select, .configurator-textarea) {
  border-color: var(--se-layer-03-stroke, #c9c9c9);
}
.product-content-blocks--details .configurator-form .configurator-question .help-text {
  color: var(--cms-text-2);
  order: 1;
}
.product-content-blocks--details .configurator-form .configurator-footer {
  padding: var(--spacing-5) var(--pdp-form-inset) var(--pdp-form-inset);
  background: transparent;
  gap: var(--spacing-4);
  flex-wrap: wrap;
}

/* Match SEButton's primary/secondary treatments, including interaction states.
   These selectors also beat the legacy purple configurator rules in main.css. */
.product-content-blocks--details .content-block.configurator-form :is(.configurator-next-button, .configurator-submit-button, .configurator-back-button) {
  font-family: var(--se-font-family, var(--font-family));
  font-size: var(--se-font-size-text-large, 1rem);
  line-height: var(--se-line-height-text-large, 1.5rem);
  font-weight: 700;
  letter-spacing: 0;
  padding: 0.625rem 1.25rem 0.75rem;
  min-height: 3rem;
  border: 1px solid var(--cms-text);
  border-radius: var(--se-radius-button, 0.75rem);
  background: var(--cms-text);
  color: var(--cms-accent-ink);
}
.product-content-blocks--details .content-block.configurator-form :is(.configurator-next-button, .configurator-submit-button):hover:not(:disabled) {
  background: #333333;
  border-color: #333333;
}
.product-content-blocks--details .content-block.configurator-form .configurator-back-button {
  background: var(--cms-surface);
  color: var(--cms-text);
  border-color: var(--cms-line);
}
.product-content-blocks--details .content-block.configurator-form .configurator-back-button:hover {
  background: var(--cms-surface-alt);
  border-color: var(--se-layer-03-stroke, #c9c9c9);
}
.product-content-blocks--details .configurator-form :is(button, input, select, textarea):focus-visible {
  outline: 2px solid var(--color-focus-ring, #009999);
  outline-offset: var(--spacing-1);
}
.product-content-blocks--details .configurator-form :is(.configurator-input, .configurator-select, .configurator-textarea):focus {
  border-color: var(--cms-text);
  box-shadow: none;
}
.product-content-blocks--details .content-block.configurator-form :is(.configurator-next-button, .configurator-submit-button):disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.product-content-blocks--details .configurator-form .configurator-step,
.product-content-blocks--details .content-block.configurator-form .configurator-question-label {
  color: var(--cms-text);
  font-family: inherit;
}
.product-content-blocks--details .configurator-form .configurator-step {
  font-weight: 400;
}
.product-content-blocks--details .configurator-form .configurator-step--active,
.product-content-blocks--details .content-block.configurator-form .configurator-question-label {
  font-weight: 700;
}
.product-content-blocks--details .configurator-form .configurator-step-index {
  background: var(--cms-surface-alt);
  color: var(--cms-text-2);
}
.product-content-blocks--details .configurator-form :is(.configurator-step--active, .configurator-step--past) .configurator-step-index {
  background: var(--cms-text);
  color: var(--cms-accent-ink);
}
.product-content-blocks--details .content-block.configurator-form .required-marker {
  color: var(--cms-text);
}
.product-content-blocks--details .configurator-form .configurator-footer-actions {
  gap: var(--spacing-3);
}
.product-content-blocks--details .configurator-form .configurator-submit-meta {
  margin: var(--spacing-4, 1rem) 0 0;
  color: var(--cms-text-2);
  font-size: var(--se-font-size-text-small, 0.75rem);
  line-height: var(--se-line-height-text-small, 1.125rem);
}

/* Only the newly selected form step moves; its values remain in form state. */
.product-content-blocks--details .configurator-form .configurator-phase-content {
  animation: pdp-form-step-enter 180ms cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes pdp-form-step-enter {
  from { opacity: 0; transform: translateY(0.375rem); }
  to { opacity: 1; transform: translateY(0); }
}
.product-content-blocks--details .configurator-form .configurator-step {
  transition: background-color 150ms ease-out, color 150ms ease-out, border-color 150ms ease-out;
}
.product-content-blocks--details .cms-external-reference-card {
  transition: background-color 150ms ease-out, border-color 150ms ease-out;
}
.product-content-blocks--details .cms-external-reference-card:hover,
.product-content-blocks--details .cms-external-reference-card:focus-visible {
  background: var(--cms-surface);
  border-color: var(--cms-text);
}
@media (prefers-reduced-motion: reduce) {
  .product-content-blocks--details .configurator-form .configurator-phase-content {
    animation: none;
  }
  .product-content-blocks--details .configurator-form :is(button, input, select, textarea),
  .product-content-blocks--details .cms-external-reference-card {
    transition: none;
  }
}
