
.wf-design-mode .accordion_content_wrap {
	display: block;
}

:root {
  /* Single source of truth: the sticky TOC parks at this distance below
     the viewport top, and TOC-linked headings get the same scroll-margin
     so they align with the TOC's top edge when navigated to. */
  --cp-toc-scroll-offset: calc(var(--nav--height-total, 0rem) + 3rem);
}

/* TOC tint card (Item 3).
 *
 * The TOC reads as a subtle brand-tinted card rather than bare text with a
 * left line:
 *   - background: --color-primary-light (the ready-made 10% brand tint =
 *     hexToRgba(primary, 0.1), derived per-company in content-page-style.ts).
 *     A tint, NOT a saturated solid — so body text stays dark and there is
 *     no contrast gamble (no need for --color-text-on-primary).
 *   - border-radius + padding make it read as a card. The optional brand
 *     left-accent border is retained for continuity with the title colour.
 *   - body text stays --color-text-light / --color-text (dark on tint).
 *
 * Symmetric padding (unlike the old left-only padding) is now safe: the
 * card background bounds the box, so the left accent border no longer needs
 * to "end exactly at the last link's baseline" — the card edge does that.
 * The title sits inside the padded card; the scroll wrapper handles its own
 * overflow. Container-width on mobile is supplied by the Item 1 fix (the
 * aside column's u-container), so the card aligns to the content gutter and
 * is NOT full-bleed (D7). */
.cp-toc {
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--color-text-light);
  background: var(--color-primary-light);
  border-radius: 0.5rem;
  border-left: 0.1875rem solid var(--color-primary);
  padding: 1rem 1.25rem;
}

/* Scrollable wrapper around the list ONLY — the title sits outside this
   so its glyph ascender is never clipped by the overflow box.
   Height budget = small viewport height minus EVERYTHING stacked above and
   below the list inside the sticky card:
     --cp-toc-scroll-offset  column top-park (nav 4rem + 3rem)
     1rem                    .cp-toc card padding-top
     4rem                    fixed toggle-header height
     0.5rem                  .accordion_content_padding padding-top
     1rem                    .cp-toc card padding-bottom
     1rem                    breathing room
   = offset + 7.5rem. svh (not vh) so mobile landscape / dynamic browser
   chrome can't let the card overhang the visible viewport. */
.cp-toc_scroll {
  max-height: calc(100svh - var(--cp-toc-scroll-offset, 7rem) - 7.5rem);
  overflow-y: auto;
}

/* TOC visible title. Lumos's u-text-style-h4 supplies size/weight/family,
   u-margin-bottom-4 supplies the bottom gap to the list — we only paint
   the text in brand primary (matching the cp-toc left border) and zero
   the top margin so the title sits flush against the cp-toc top edge. */
.cp-toc_title {
  color: var(--color-primary);
  margin-top: 0;
}

/* TOC-targeted heading scroll alignment.
 *
 * When a TOC link is clicked, the browser scrolls the linked heading to
 * the viewport top. Without scroll-margin-top, the heading would slide
 * UNDER the sticky nav + TOC top edge. We set the same offset the sticky
 * TOC parks at, so the heading aligns exactly with the TOC's top edge.
 *
 * Scoped to [id] only — matches headings the TOC has injected ids onto
 * (or author-provided ids). Other headings (no id, not navigable) are
 * untouched. :where() contributes 0 specificity so this rule is trivially
 * overridable. */
:where(h2, h3, h4)[id] {
  scroll-margin-top: var(--cp-toc-scroll-offset, 7rem);
}

/* Override Lumos's hardcoded sticky-column top offset.
 *
 * Why this override exists:
 *   Lumos emits a literal "top: calc(12rem * var(--_responsive---large)
 *   + 0rem * var(--_responsive---medium))" on .u-layout-column-N for sticky-right
 *   and sticky-left variants (webflow-shared-raw.css :2671 / :2667).
 *   The 12rem is a literal, not derived from --nav--height-total or any
 *   other Lumos variable — Webflow / Lumos picked it as a generic "safe
 *   distance below the nav" that happens to ignore:
 *     - the actual --nav--height (4rem default)
 *     - the announcement banner height (2.4rem when visible)
 *     - --nav--spacing-outer-vertical (= --site--margin)
 *
 * What this override does:
 *   Replaces the 12rem with a banner-aware offset built from the actual
 *   Lumos --nav--height-total variable, exposed via --cp-toc-scroll-offset
 *   so this file's max-height calc, this top: override, and the heading
 *   scroll-margin-top all agree by construction.
 *
 * Scope:
 *   :has(.cp-toc) restricts the override to columns that contain our TOC
 *   nav specifically — NOT every .cp-aside. Other aside types (e.g. the
 *   solutions/product-card aside .cp-aside.cp-solutions-aside) live in
 *   non-sticky layout variants whose columns default to position: relative.
 *   On a relative element, top: offsets the box from its natural position
 *   rather than no-op'ing — applying the override there pushes the entire
 *   column ~7rem down and creates a visible gap above the aside content.
 *   Scoping by .cp-toc avoids that side effect; only the TOC's own column
 *   (which IS sticky via the sticky-right / sticky-left variants) receives
 *   the offset. We use the descendant form because the aside is wrapped in
 *   a u-content-wrapper > u-display-contents shell and is therefore a
 *   grandchild of the column.
 *
 * Specificity:
 *   Ours:   .u-layout-column-1:has(.cp-toc)           = (0, 2, 0)
 *   Lumos:  .u-layout-column-1:where(.w-variant-GUID) = (0, 1, 0)
 *           (:where() contributes 0 to specificity by spec)
 *   So ours wins cleanly. A future Lumos export that drops the :where()
 *   wrapper would raise Lumos to (0, 2, 0) tie — worth re-checking on
 *   framework updates.
 *
 * Browser support:
 *   :has() is Baseline 2023 (all evergreen browsers Dec 2023+). Already
 *   a hard dependency because Lumos itself uses :has(> .u-section-spacer)
 *   elsewhere — we're not raising the floor.
 *
 * Desktop only (>= 50em):
 *   Below this breakpoint Lumos collapses the layout to stacked and
 *   swaps the column from position: sticky to position: relative via
 *   --relative-medium. On a relative element, top: shifts the box
 *   visually WITHOUT changing flow — so the TOC paints ~8rem lower than
 *   its layout slot, the article column starts at the slot's natural
 *   bottom (overlapping the visible TOC's last items), and the mobile
 *   spacer sits at the natural bottom too (so it's also overlapped).
 *   Symptoms: TOC last items disappear under the article H2, no visible
 *   gap between TOC and article, oversized gap above the TOC. The fix
 *   is simply to gate the override at the same breakpoint Lumos uses to
 *   make the column sticky in the first place. */
@container (width >= 50em) {
  .u-layout-column-1:has(.cp-toc),
  .u-layout-column-2:has(.cp-toc) {
    top: var(--cp-toc-scroll-offset, 7rem);
  }
}

/* Allow glyph bleed in the article column when paired with our aside.
 *
 * Lumos sets overflow: clip on .u-layout-column-1 in our aside layout
 * variants (sticky-right column-1 explicitly at webflow-shared-raw.css
 * :2572-2575, columns---align-top column-1 from the CDN-hosted Lumos
 * stylesheet). overflow: clip clips glyph bleed past the line-box edge
 * — the dot on lowercase 'i', the top of 'f', the descender of 'g/y/p'
 * — which makes the first/last lines of the article column look subtly
 * truncated.
 *
 * Why overflow-clip-margin (not overflow: visible):
 *   The clip is presumably defending against runaway descendant overflow
 *   (transforms, long words, sticky child boxes). We don't know exactly
 *   what — Lumos's CDN CSS is opaque — so removing the clip entirely
 *   would re-expose whichever case it was guarding. overflow-clip-margin
 *   keeps the clip but expands the painted region by a fixed amount past
 *   the padding-box, sized to the typical glyph ascender/descender
 *   (~0.4em of the body line-height) — enough for font metrics to render
 *   in full, not enough to leak a stuck child halfway into the next
 *   column.
 *
 * Scope:
 *   :has(.cp-aside) on the layout wrapper matches both TOC and
 *   solutions/product-card aside layouts (same selector as the mobile
 *   aspect-ratio rule below). Direct-child combinators target only the
 *   outer layout's column-1 — nested .u-layout-column-1 inside the
 *   article body keeps Lumos's default clip extent.
 *
 * Specificity:
 *   Ours:  .u-layout-wrapper:has(.cp-aside) > .u-layout > .u-layout-column-1 = (0, 4, 0)
 *   Lumos: .u-layout-column-1:where(.w-variant-GUID)                          = (0, 1, 0)
 *   Comfortably ours.
 *
 * Browser support:
 *   overflow-clip-margin is Baseline 2024 (Chrome 90+, Firefox 102+,
 *   Safari 16+). On older engines the property is ignored and the clip
 *   reverts to its default 0px extent — text bleed is clipped again, no
 *   visual regression beyond the prior state. */
.u-layout-wrapper:has(.cp-aside) > .u-layout > .u-layout-column-1 {
  overflow-clip-margin: 0.5em;
}

/* Mobile spacer between stacked TOC and main content.
 *
 * On desktop, sticky-column wrapping puts the aside next to the main
 * column — no gap is needed. On mobile (container < 50em) the columns
 * stack with the aside above the main column (Lumos applies order: -1)
 * and the visual lacks any breathing room because the first section's
 * top spacer was lifted up to the outer wrapper for column alignment.
 *
 * The wrapper emits a mirrored copy of the lifted top spacer wrapped in
 * .cp-aside-mobile-spacer, hidden on desktop and revealed at the same
 * breakpoint Lumos uses to flip the layout. The spacer's data-wf--spacer
 * --variant attribute drives its height — same Lumos variant as the
 * first section's original top spacer, so the gap matches the section
 * spacing exactly. */
.cp-aside-mobile-spacer {
  display: none;
}

/* Drop the list's max-height + internal scroll when the TOC is NOT a sticky
   sidebar (stacked layout) — otherwise the stacked TOC gets a capped
   scrollable box above the article (a double-scroll trap).

   Why @media, NOT @container here: this rule is scoped to '.cp-toc_scroll',
   which lives DEEP inside column-2's own '.u-container'
   (.u-layout-column-2 > .u-container > .u-content-wrapper > ... > .cp-toc_scroll).
   An @container query resolves against the NEAREST container ancestor — that
   inner '.u-container' is sidebar-width (~19em), so @container (width < 50em)
   is permanently true on desktop and would kill the scroll cap entirely (the
   list never scrolls, just overflows the viewport). The column-level rules
   below (mobile spacer, aspect-ratio) sit ABOVE that inner container so THEIR
   nearest container is the page-width outer '.u-container' and they flip
   correctly — those stay @container. The cap toggle must key off the
   viewport instead, so it uses @media. The crossover is ~the layout
   stack point (off only by the page side-margins, which is immaterial: both
   sides of the breakpoint behave correctly, only the exact px differs). */
@media (width < 50em) {
  .cp-toc_scroll {
    max-height: none;
    overflow-y: visible;
  }
}

/* Mobile: when the Lumos layout collapses to stacked (container < 50em,
   matching lumos.css :339 which also flips column order via order: -1),
   the aside stops being a sticky sidebar and starts being a block above
   the main content. Lumos switches the column to position: relative via
   its --relative-medium var, so the sticky override above no longer
   applies. Reveals the cp-aside-mobile-spacer wrapper so the mirrored top
   spacer renders, providing the gap between stacked TOC and main column. */
@container (width < 50em) {
  .cp-aside-mobile-spacer {
    display: block;
  }
  /* Drop the column's 16/9 aspect-ratio when stacked. Lumos's
     .u-layout-column-{1,2} has aspect-ratio: 16/9 (webflow-shared-raw.css
     :2577 base + variant overrides at :2656 / :2667). On desktop the
     column is wide and the aside fits inside the 16/9 box; on mobile the
     column narrows to ~viewport width and the box becomes ~width × 9/16
     tall — only ~2 TOC links high. With overflow: visible the TOC
     content renders past the box, but the next column starts at
     column.box.bottom and paints over the overflow, so the TOC LOOKS
     cut off and there's no gap to the main content. Setting
     aspect-ratio: auto lets the column grow to its content; main content
     then starts below the full TOC + cp-aside-mobile-spacer. Scoped to
     :has(.cp-aside) so non-aside columns keep Lumos's 16/9 behaviour. */
  .u-layout-column-1:has(.cp-aside),
  .u-layout-column-2:has(.cp-aside) {
    aspect-ratio: auto;
  }
}
.cp-toc_list {
  list-style: none;
  padding-left: 0;
  margin: 0;
}
.cp-toc_list--nested {
  padding-left: 1rem;
  margin-top: 0.25rem;
}
.cp-toc_item {
  margin: 0.375rem 0;
}
/* Zero the trailing margin so the cp-toc left border ends exactly at the
   last link's baseline, not 0.375rem past it. Applies recursively (last
   item of nested lists too) so the bottom of any TOC shape is flush. */
.cp-toc_item:last-child {
  margin-bottom: 0;
}
/* Match: the last cp-toc_link in the box loses its bottom padding so the
   border-left ends precisely at the text baseline. */
.cp-toc_item:last-child > .cp-toc_link:last-child {
  padding-bottom: 0;
}
.cp-toc_link {
  display: block;
  text-decoration: none;
  color: inherit;
  padding: 0.125rem 0;
  transition: color 0.15s ease;
}
.cp-toc_link:hover {
  color: var(--color-text);
}
.cp-toc_link.is-active {
  color: var(--color-primary);
  font-weight: 600;
}

/* ── Collapsible accordion (Item 2) ──────────────────────────────────────
 *
 * The TOC list is wrapped in the global FAQ GSAP accordion structure
 * (.accordion_wrap > .accordion_list > .accordion_item > .accordion_component,
 * with an .accordion_toggle_button header and a collapsible
 * .accordion_content_wrap). The global .accordion_* CSS + GSAP are already
 * loaded on every published page, so the collapse animation needs no CSS
 * here — and crucially, we DON'T override the toggle button's layout either.
 *
 * The TOC is a faithful clone of the FAQ toggle: same markup (incl. the
 * .accordion_toggle_icon chevron — see toc.ts), so Lumos's native
 * .accordion_toggle_button styling renders it correctly. A previous version
 * stripped that native styling with a bespoke .cp-toc .accordion_toggle_button
 * reset AND dropped the chevron; together they collapsed the toggle row and
 * let leading-trim pull the title out the top of the header. Both deviations
 * are now removed — "copy the FAQ" means letting Lumos's button rules apply.
 *
 * The one rule we KEEP below is the :focus-visible indicator. */

/* CRITICAL focus indicator (WCAG 2.4.7). Kept as a GUARANTEED indicator: the
   Lumos global `button:focus-visible` rule also applies to this button, but we
   ship our own brand-primary ring so the TOC toggle has a clear, on-brand
   focus state regardless of what the CDN-hosted Lumos CSS does or stops doing.
   :focus-visible only — keyboard users get a clear ring; mouse clicks don't
   paint one. 2px brand-primary outline with an offset so it reads against the
   tint card background. */
.cp-toc .accordion_toggle_button:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: 0.25rem;
}

/* Content-panel spacing. Two things to get right, both via the INNER
   `.accordion_content_padding` rather than the `.accordion_content_wrap`:

   1. Open-state bottom: the global `.accordion_content_padding` ships
      `padding-bottom: var(--_spacing---space--5)` (FAQ-sized), which leaves the
      list far heavier at the bottom than the top. Zero it — the `.cp-toc`
      card's own 1rem bottom padding frames the list.
   2. Header→list gap: we want a small gap between the toggle and the list when
      OPEN, but it must NOT show when closed. Putting it as `margin-top` on
      `.accordion_content_wrap` fails: GSAP closes the panel to
      `display:block; height:0`, and a top margin still renders at height 0 —
      so the gap leaks into the closed card as extra space below the header.
      `.accordion_content_padding` lives INSIDE the wrap, so its padding is
      clipped to nothing when the wrap collapses to height 0, and only appears
      when the panel is open. */
.cp-toc .accordion_content_padding {
  padding-top: 0.5rem;
  padding-bottom: 0;
}

/* Drop the global per-card divider. The global accordion paints
   `.accordion_component { border-bottom: ... }` — a divider meant to separate
   stacked FAQ items. A single-item TOC has nothing to separate, so the rule
   just leaves a stray line under the whole card; remove it. TOC-scoped, so the
   FAQ keeps its dividers. */
.cp-toc .accordion_component {
  border-bottom: 0;
}

/* Neutralise the FAQ first-item pull-up. The global accordion gives
   `.accordion_list { margin-top: calc(var(--_spacing---space--4) * -1) }` to
   cancel the first toggle's top padding so item #1 sits flush in a bare FAQ
   column. Inside our padded `.cp-toc` tint card that negative margin instead
   drags the content box up above `.accordion_wrap`'s top edge (the title pokes
   out the top of the card). We keep the `.accordion_list` element (the shared
   global init dereferences it — removing it breaks the toggle JS) and just zero
   its margin here. TOC-scoped; the FAQ keeps its pull-up. */
.cp-toc .accordion_list {
  margin-top: 0;
}

/* Fixed toggle-header height. The header is pinned to a deterministic 4rem so
   the `.cp-toc_scroll` max-height calc can subtract a known value rather than a
   font-metric-dependent line-height (the global `.accordion_toggle_button` uses
   `padding-block: var(--_spacing---space--4)` + the h4 line box, which is not a
   stable number to budget against). The native button is `display:flex;
   align-items:center`, so the title + chevron stay vertically centred within the
   4rem; box-sizing is border-box (Webflow global), so the native padding-block
   is absorbed into the 4rem rather than added on top. TOC-scoped. */
.cp-toc .accordion_toggle_button {
  height: 4rem;
}
.cp-solutions-aside .card_primary_visual { flex-shrink: 0; align-self: flex-start; }