/* ============================================================================
 * canonical-1.0.0.css — DERIVED. Do not hand-edit.
 *
 * Generated by:  python db/tools/extract_reference_css.py
 * Source:        db/content_reference/96.json (the approved Azure landing page,
 *                content_type=competitive_comparison, status=draft) — the
 *                13,050-byte <style> block extracted from body_markdown.
 * Re-derive and diff:  python db/tools/extract_reference_css.py --check
 *
 * WHAT WAS CHANGED, AND WHY
 * -------------------------
 * 1. BODY FONT CORRECTED (D2, and this is the one intended visual difference).
 *    The approved page sets `body { font-family: 'Space Grotesk' }`. CLAUDE.md's
 *    brand guide assigns Space Grotesk to HEADLINES and Plus Jakarta Sans to
 *    BODY COPY. Body copy is now 'Plus Jakarta Sans'; h1/h2/h3 keep
 *    'Space Grotesk'. Every block of body text will therefore differ from
 *    the approved page. That is expected, documented, and must not be read as
 *    drift.
 * 2. FONT IMPORT WIDENED. The approved page imports Space Grotesk only, so
 *    Plus Jakarta Sans was never actually loaded anywhere. The @import now
 *    requests both families.
 * 3. SCOPED TO #sds-doc. Every selector is prefixed, `body` becomes
 *    `#sds-doc`, and the `*` reset is scoped rather than global. Unprefixed
 *    selectors are limited to `:root`, `@import` and the theme-escape block
 *    below; `canonical.lock.json` records the allowlist.
 * 4. TARGET-OWNED CHROME DELETED. Rules for nav / header / footer are removed —
 *    WordPress owns page chrome and `verify_render` rejects those tags in post
 *    content. (The Azure source carries none; the Fivetran page carries 14.)
 * 5. BRAND HEX FOLDED BACK INTO var(). #5227D2 / #E1F3FF / #000826 appear only
 *    in `:root`. Non-brand greys and #fff are left as literals, and one purple
 *    written as `rgba(82,39,210,.4)` is left alone — an alpha value cannot be a
 *    plain var() reference.
 * 6. FULL-BLEED UNIFIED. One `.sdsdoc-bleed` mechanism is appended, replacing the
 *    `width:100vw; left:50%; margin-left:-50vw` pattern the old publish path
 *    injected (in which `right:50%` did nothing, and which included the
 *    scrollbar in 100vw).
 *
 * WHAT WAS NOT CHANGED, AND WHEN IT WILL BE
 * -----------------------------------------
 * The 52 legacy class names are retained verbatim. Renaming them to the
 * registry's `sds-*` emitted classes lands with the renderer (plan Phase 2),
 * because a stylesheet full of class names nothing emits is untested prose.
 * Until then the class vocabulary here is asserted against `legacy_map.py`.
 *
 * NOTES ON THE SOURCE, recorded because the plan states otherwise
 * --------------------------------------------------------------
 * - The source CSS uses `!important` exactly twice, both on Gravity Forms
 *   overrides. Plan §3.3 says "essentially every declaration"; that describes
 *   the old publish-time transform's output, not the stored stylesheet.
 * - The source CSS contains no `@media` block at all — the approved page is not
 *   responsive. Nothing was removed here; it was never there.
 * - Neither `get-in-touch-section` nor `quote-section` appears in the source
 *   CSS, so both are dropped on the plan's authority rather than on observation.
 * ==========================================================================*/

@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&family=Space+Grotesk:wght@400;500;600;700&display=swap');

#sds-doc *,
#sds-doc *::before,
#sds-doc *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  --purple:    #5227D2;
  --sky:       #E1F3FF;
  --dark:      #000826;
  --gray-50:   #f9fafb;
  --gray-100:  #f3f4f6;
  --gray-200:  #e5e7eb;
  --gray-500:  #6b7280;
  --green:     #16a34a;
  --red:       #dc2626;
}

/* translated from `body`: **`font-size` and `line-height` are added, and they are the capture's own values by omission.** The capture states neither, because the capture *was* the page: leaving them unset meant the browser defaults, 16px and `normal`. Our bytes are injected into a page that has already set them — measured on symmetricds.org, the theme supplies `font-size: 20px` and `line-height: 36px`, and both inherit into every element that does not state its own. That is one omission producing loose spacing across the whole document, and it is the single largest visual difference from the approved page. Stating the defaults restores the context the capture assumed; it does not impose a new design. */
#sds-doc {
  font-family: 'Plus Jakarta Sans', Arial, sans-serif;
  color: var(--dark);
  background: #fff;
  font-size: 16px;
  line-height: normal;
  -webkit-font-smoothing: antialiased;
}

/* D2: headlines keep Space Grotesk; body copy above is Plus Jakarta Sans. */
#sds-doc h1,
#sds-doc h2,
#sds-doc h3 {
  font-family: 'Space Grotesk', Arial, sans-serif;
}

#sds-doc .sdsdoc-hero {
  padding: 96px 48px 80px;
  text-align: center;
  max-width: 900px;
  margin: 0 auto;
}

#sds-doc .sdsdoc-lockup {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 28px;
  margin-bottom: 32px;
  flex-wrap: wrap;
}

#sds-doc .sdsdoc-lockup__brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  font-size: .9rem;
  letter-spacing: -.01em;
}

#sds-doc .sdsdoc-lockup__brand[data-side="a"] .sdsdoc-lockup__name {
  color: var(--dark);
}

#sds-doc .sdsdoc-lockup__brand[data-side="b"] .sdsdoc-lockup__name {
  color: #555;
}

#sds-doc .sdsdoc-lockup__sep {
  font-size: .7rem;
  font-weight: 800;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #bbb;
  align-self: center;
}

#sds-doc .sdsdoc-lockup__brand img {
  height: 100px;
  width: 100px;
  object-fit: contain;
  display: block;
  border-radius: 10px;
}

#sds-doc .sdsdoc-hero h1 {
  font-size: clamp(2rem, 4vw, 2.8rem);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -.02em;
  color: var(--dark);
  margin-bottom: 24px;
}

#sds-doc .sdsdoc-hero .sdsdoc-prose[data-variant="lede"] {
  font-size: 1.15rem;
  color: var(--gray-500);
  line-height: 1.65;
  margin-bottom: 40px;
  font-weight: 400;
}

#sds-doc .sdsdoc-hero .sdsdoc-actions {
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
}

#sds-doc .sdsdoc-actions__btn[data-variant="primary"] {
  background: var(--purple);
  color: #fff;
  padding: 14px 32px;
  border-radius: 10px;
  font-weight: 600;
  font-size: 1rem;
  text-decoration: none;
  display: inline-block;
  transition: opacity .15s;
}

#sds-doc .sdsdoc-actions__btn[data-variant="primary"]:hover {
  opacity: .88;
}

#sds-doc .sdsdoc-actions__btn[data-variant="secondary"],
#sds-doc .sdsdoc-actions__btn[data-variant="ghost"] {
  background: transparent;
  color: var(--dark);
  border: 1.5px solid var(--gray-200);
  padding: 13px 30px;
  border-radius: 10px;
  font-weight: 600;
  font-size: 1rem;
  text-decoration: none;
  display: inline-block;
  transition: border-color .15s;
}

#sds-doc .sdsdoc-actions__btn[data-variant="secondary"]:hover {
  border-color: var(--dark);
}

/* translated from `.bidirectional-callout`: The bleeding dark panel: background, colour and padding only. The flex row and the 900px measure belong to `.inner` and are translated there. */
#sds-doc .sdsdoc-callout[data-variant="knockout"] {
  background: var(--dark);
  color: #fff;
  padding: 56px 48px;
  max-width: none;
}

/* translated from `.bidirectional-callout .inner`: **`callout` now emits this wrapper** (`sdsdoc-callout__inner`), for the same reason `section` and `hero` each emit one: the root carries `.sdsdoc-bleed`, and one element cannot be both a full-bleed background and a 900px centred box. It previously had no target, and its `max-width: 900px; margin: 0 auto` was dropped on the grounds that the width could be left to the bleed mechanism — which is what put the icon and copy against the viewport edges instead of centred on the panel. Every declaration here is the capture's. */
#sds-doc .sdsdoc-callout__inner {
  max-width: 900px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 48px;
}

#sds-doc .sdsdoc-callout__icon {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: rgba(82,39,210,.4);
  border: 2px solid var(--purple);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

#sds-doc .sdsdoc-callout[data-variant="knockout"] h2,
#sds-doc .sdsdoc-callout[data-variant="knockout"] h3 {
  font-size: clamp(1.4rem, 2.5vw, 2rem);
  font-weight: 700;
  margin-bottom: 12px;
  color: #fff;
  letter-spacing: -.01em;
}

#sds-doc .sdsdoc-callout[data-variant="knockout"] p {
  font-size: .95rem;
  color: rgba(255,255,255,.75);
  line-height: 1.7;
  margin-bottom: 0;
}

#sds-doc .sdsdoc-callout__eyebrow {
  display: inline-block;
  background: var(--purple);
  color: #fff;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: 4px;
  margin-bottom: 12px;
}

/* translated from `.compare-section .section-header`: There is no section-header wrapper: `section` emits eyebrow, heading and lede as flat siblings, so the wrapper's centring and its 48px offset move onto the three children themselves. `grid-column: 1 / -1` is what the wrapper did structurally — it sat above `.compare-body` and spanned the full measure — and it is needed here because those three children are now items of the rail grid rather than content of a block above it. `margin-inline: auto` is the second consequence of the same flattening, and the one that was visible: the capture's `.section-header p` had no max-width, and the lede that replaces it inherits `max-width: 720px` from `.ai-analysis .analysis-intro`. A 720px box with no auto margins hugs the left of the span, so the subtitle read as left-aligned under a centred heading. Centring the box is what the wrapper did for free. */
#sds-doc .sdsdoc-section[data-layout="rail"] .sdsdoc-section__eyebrow,
#sds-doc .sdsdoc-section[data-layout="rail"] .sdsdoc-section__inner > h2,
#sds-doc .sdsdoc-section[data-layout="rail"] > .sdsdoc-section__inner > .sdsdoc-prose {
  text-align: center;
  margin-bottom: 48px;
  grid-column: 1 / -1;
  margin-inline: auto;
}

#sds-doc .sdsdoc-section[data-layout="rail"] .sdsdoc-section__inner > h2 {
  font-size: clamp(1.8rem, 3vw, 2.6rem);
  font-weight: 700;
  color: var(--purple);
  letter-spacing: -.025em;
  margin-bottom: 10px;
}

/* translated from `.compare-body`: The 520px + 1fr radar/table pairing had a wrapper div; `section` emits its children as flat siblings, so the section's own `.sdsdoc-section__inner` is the grid and `layout=rail` is what turns it on. `max-width: none` is one addition: the capture's compare body sat inside `.compare-section`, which sets padding and no max-width at all, exactly as `layout=split` needs `max-width: none` for the same reason. **The second track is `minmax(0, 900px)` rather than the capture's `1fr`, with `justify-content: center` — and that is a DELIBERATE DIVERGENCE from the reference, the only one in this table.** `1fr` grows without bound, but the compare table inside it inherits the derived 900px measure, so past about 1500px of viewport the track kept growing while its content did not: the table sat hard against the left of a track with hundreds of pixels of dead space to its right, and the whole radar/table pair drifted left of the centred heading above it. Measured on the live Quest page at a 1728px viewport: track two was 1064px around a 900px table, and at Josh's ~2560px it was near 1900px. Naming the real width the content uses and centring the track set puts the pair's centre on the heading's centre exactly (857px and 857px in that measurement) and holds at any width, because centring tracks does not depend on the container's size. The reference page has the same flaw; it was authored at a narrower viewport and never reproduced at this one, so faithfulness here would mean copying a bug. */
#sds-doc .sdsdoc-section[data-layout="rail"] .sdsdoc-section__inner {
  display: grid;
  grid-template-columns: 520px minmax(0, 900px);
  gap: 48px;
  align-items: start;
  max-width: none;
  justify-content: center;
}

/* translated from `.radar-col`: `position: sticky; top: 24px` only means something inside the two-column grid, which is now `layout=rail` rather than a wrapper div every chart sits in. So the sticky half moves to a derived rule scoped to that layout and this rule keeps the flow-block default, which is what a chart in a stacked section needs. */
#sds-doc .sdsdoc-chart {
  display: block;
  margin: 0 auto 24px;
}

#sds-doc .sdsdoc-chart__legend {
  display: flex;
  gap: 20px;
  justify-content: center;
  align-items: center;
  margin-bottom: 10px;
  flex-wrap: wrap;
}

#sds-doc .sdsdoc-chart__legend li {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: .78rem;
  font-weight: 600;
  color: #374151;
}

/* translated from `.legend-dot`: **The capture hides `.legend-dot`.** Every `.legend-item` carries `<div class="legend-dot" style="display:none;…">` as an `onerror` fallback, and the swatch a reader actually sees is the `<span>` beside it drawn in that series' own stroke — `width:22px;height:3px;background:…;border-radius:2px` for the solid series and `width:22px;height:0;border-top:3px dashed …` for the dashed one. We emit one swatch rather than a hidden div plus a visible span, so this rule takes the *visible* one's shared declarations and the per-series rules in DERIVED_RULES carry the height and the stroke. The legacy `10px` circle is dropped because it identifies neither line on the plot; `flex-shrink: 0` is the legacy rule's. */
#sds-doc .sdsdoc-chart__dot {
  display: inline-block;
  width: 22px;
  border-radius: 2px;
  flex-shrink: 0;
}

/* translated from `.compare-header .col-label`: The legacy header cell was a flex column inside a CSS grid; it is now a `<th>`. `display: flex` on a table cell removes it from the table layout, so the flex trio is replaced by `vertical-align` and the grid's `gap: 6px` by bottom padding. Every other value is the legacy rule's. */
#sds-doc .sdsdoc-compare__head .sdsdoc-compare__cell {
  font-size: .8rem;
  font-weight: 700;
  color: var(--gray-500);
  text-transform: uppercase;
  letter-spacing: .06em;
  text-align: center;
  padding: 0 24px 6px;
  vertical-align: bottom;
}

/* translated from `.compare-header .col-label:first-child`: `align-items: flex-start` was the flex spelling of the same intent. */
#sds-doc .sdsdoc-compare__head .sdsdoc-compare__cell:first-child {
  text-align: left;
}

#sds-doc .sdsdoc-compare__head .sdsdoc-compare__cell[data-col="a"] {
  color: var(--purple);
}

/* translated from `.compare-header .col-label img`: The mark above each product column. `height: 24px; object-fit: contain; display: block` are the legacy rule's, verbatim. Two additions, both forced by the header cell becoming a `<th>`: the flex column's `align-items: center` becomes `margin-inline: auto`, because `text-align: center` does not centre a `display: block` image, and its `gap: 6px` becomes the bottom margin. `width: auto` restores what the derived `.sdsdoc-compare__cell img` rule — written for the 18px verdict sprites — would otherwise fix at 18px for every image in the table. */
#sds-doc .sdsdoc-compare__head .sdsdoc-compare__cell img {
  height: 24px;
  width: auto;
  object-fit: contain;
  display: block;
  margin: 0 auto 6px;
}

/* translated from `.compare-row`: `display: grid; grid-template-columns: 1fr 1fr 1fr` on what is now a `<tr>`: a real table computes its own columns. The border and 12px radius move to the cells, because a `<tr>` cannot reliably carry either, and `margin-bottom: 10px` becomes the table's `border-spacing`. */
#sds-doc .sdsdoc-compare__row {
  background: #fff;
  transition: box-shadow .15s;
}

#sds-doc .sdsdoc-compare__row:hover {
  box-shadow: 0 2px 12px rgba(0,0,0,.06);
}

/* translated from `.compare-row .feature-name`: Same shape change: `display: flex; align-items: flex-start; gap: 10px` on a `<th>` would take it out of the table layout. `text-align: left` restores what a `<th>`'s default centring would otherwise change. */
#sds-doc .sdsdoc-compare__row > th.sdsdoc-compare__cell {
  padding: 22px 24px;
  font-weight: 600;
  font-size: .95rem;
  color: var(--dark);
  border-right: 1px solid var(--gray-200);
  text-align: left;
}

/* translated from `.compare-row .feature-sym`: The flex trio is dropped for the same reason; the icon/text gap it provided is reproduced by the derived `.sdsdoc-compare__cell img` margin. */
#sds-doc .sdsdoc-compare__cell[data-col="a"] {
  padding: 22px 24px;
  font-size: .9rem;
  color: #374151;
  line-height: 1.55;
  border-right: 1px solid var(--gray-200);
  background: #fafbff;
}

/* translated from `.compare-row .feature-comp`: As `.compare-row .feature-sym`: the flex trio cannot survive on a `<td>`, and this cell has no right-hand border because it is the last column. */
#sds-doc .sdsdoc-compare__cell[data-col="b"] {
  padding: 22px 24px;
  font-size: .9rem;
  color: #374151;
  line-height: 1.55;
}

/* translated from `.icon-check`: `color: var(--green)` styled an inline `<svg>` that inherited `currentColor`; the verdict sprite is an `<img>` and carries its own colour. `flex-shrink: 0` has no flex parent left. The 18px box and the 10px gap are the capture's own values, from the `<svg width="18">` and the parent cell's `gap: 10px`. */
#sds-doc .sdsdoc-compare__cell[data-verdict="yes"] img {
  vertical-align: top;
  margin: 2px 10px 0 0;
  width: 18px;
  height: 18px;
}

/* translated from `.icon-cross`: As `.icon-check`: `color: var(--red)` styled an inline `<svg>`, and the verdict sprite is an `<img>` carrying its own colour. */
#sds-doc .sdsdoc-compare__cell[data-verdict="no"] img {
  vertical-align: top;
  margin: 2px 10px 0 0;
  width: 18px;
  height: 18px;
}

/* translated from `.icon-warn`: As `.icon-check`: `color: #d97706` styled an inline `<svg>`, and the verdict sprite is an `<img>` carrying its own colour. */
#sds-doc .sdsdoc-compare__cell[data-verdict="partial"] img {
  vertical-align: top;
  margin: 2px 10px 0 0;
  width: 18px;
  height: 18px;
}

#sds-doc .sdsdoc-section__inner {
  max-width: 900px;
  margin: 0 auto;
}

#sds-doc .sdsdoc-section__eyebrow,
#sds-doc .sdsdoc-hero__eyebrow {
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--purple);
  margin-bottom: 16px;
}

#sds-doc .sdsdoc-section__inner > h2 {
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  font-weight: 700;
  color: var(--dark);
  margin-bottom: 12px;
  letter-spacing: -.01em;
}

#sds-doc .sdsdoc-section .sdsdoc-prose[data-variant="lede"] {
  font-size: 1rem;
  color: #374151;
  line-height: 1.7;
  max-width: 720px;
  margin-bottom: 40px;
}

/* translated from `.insight-grid`: `grid-template-columns: repeat(3, 1fr)` is hardcoded to three. `grid` carries `columns` as a field, so the column count moves to the derived per-`data-columns` rules and only the gap is inherited. */
#sds-doc .sdsdoc-grid {
  display: grid;
  gap: 16px;
}

#sds-doc .sdsdoc-grid[data-columns="3"] > .sdsdoc-card:last-child:not(:nth-child(3n)) {
  grid-column: 1 / -1;
  max-width: calc((100% - 16px) * 2 / 3 + 8px);
  margin: 0 auto;
}

#sds-doc .sdsdoc-card[data-variant="bordered"] {
  background: #fff;
  border-radius: 12px;
  padding: 24px 24px 28px;
  border: 1px solid var(--gray-200);
}

#sds-doc .sdsdoc-card[data-variant="bordered"] h3 {
  font-size: 1rem;
  font-weight: 700;
  color: var(--dark);
  margin-bottom: 8px;
}

#sds-doc .sdsdoc-card[data-variant="bordered"] p {
  font-size: .875rem;
  color: var(--gray-500);
  line-height: 1.65;
  margin: 0;
}

#sds-doc .sdsdoc-section[data-layout="split"] .sdsdoc-section__inner > h2 {
  font-size: clamp(1.8rem, 3vw, 2.6rem);
  font-weight: 700;
  color: var(--dark);
  margin-bottom: 20px;
  line-height: 1.2;
  letter-spacing: -.02em;
}

#sds-doc .sdsdoc-section[data-layout="split"] > .sdsdoc-section__inner > .sdsdoc-prose {
  font-size: 1rem;
  color: #374151;
  line-height: 1.7;
  max-width: 360px;
}

/* translated from `.usecase-right`: The dark panel was a flex column; it is now the `grid` component, whose `display: grid` the derived rules set. The flex trio goes; every colour, padding and gap value is the legacy rule's. */
#sds-doc .sdsdoc-section[data-layout="split"] .sdsdoc-grid {
  background: var(--dark);
  padding: 56px 48px;
  gap: 16px;
  position: relative;
  overflow: hidden;
}

#sds-doc .sdsdoc-section[data-layout="split"] .sdsdoc-grid::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(135deg, transparent 40%, rgba(255,255,255,.04) 40%, rgba(255,255,255,.04) 41%, transparent 41%),
    linear-gradient(135deg, transparent 55%, rgba(255,255,255,.03) 55%, rgba(255,255,255,.03) 56%, transparent 56%),
    linear-gradient(135deg, transparent 70%, rgba(255,255,255,.02) 70%, rgba(255,255,255,.02) 71%, transparent 71%);
}

#sds-doc .sdsdoc-section[data-layout="split"] .sdsdoc-card {
  background: rgba(82,39,210,.55);
  border-radius: 16px;
  padding: 28px 28px 32px;
  position: relative;
  z-index: 1;
  border: 1px solid rgba(255,255,255,.08);
}

#sds-doc .sdsdoc-card__icon {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  background: var(--sky);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 16px;
}

#sds-doc .sdsdoc-section[data-layout="split"] .sdsdoc-card h3 {
  font-size: 1.1rem;
  font-weight: 700;
  color: #fff;
  margin-bottom: 10px;
}

#sds-doc .sdsdoc-section[data-layout="split"] .sdsdoc-card p {
  font-size: .9rem;
  color: rgba(255,255,255,.75);
  line-height: 1.65;
  margin: 0;
}

#sds-doc .sdsdoc-steps__item {
  display: flex;
  gap: 24px;
  margin-bottom: 28px;
  align-items: flex-start;
}

#sds-doc .sdsdoc-steps__num {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--sky);
  color: var(--purple);
  font-weight: 700;
  font-size: .95rem;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

#sds-doc .sdsdoc-steps__body {
  font-size: .95rem;
  color: #374151;
  line-height: 1.7;
  padding-top: 6px;
}

#sds-doc .sdsdoc-steps__label strong {
  color: var(--dark);
  display: block;
  margin-bottom: 4px;
  font-size: 1rem;
}

#sds-doc .sdsdoc-steps__closing {
  font-size: .9rem;
  color: var(--gray-500);
  font-style: italic;
  margin-top: 24px;
}

/* translated from `.cta-section`: `background: var(--gray-50)` does not travel with the rest: a section's background derives from `data-tone`, never from its layout, or every centred section on every page would be grey. The colour is not lost — it is where it belongs, as the `muted` tone in DERIVED_RULES, and this rule is where that tone's value comes from. **The contradiction this used to record is settled:** `legacy_map`, the `cta` preset and `template.py` all called this section `tone=dark`, while both approved pages render it on `--gray-50` (`legacy_fivetran_reference.css` line for line the same) with `.cta-section h2 { color: var(--dark) }`. The captured CSS is the specification, so the declaration was wrong and both now say `tone=muted`. */
#sds-doc .sdsdoc-section[data-layout="center"] {
  padding: 96px 48px;
  text-align: center;
}

#sds-doc .sdsdoc-section[data-layout="center"] .sdsdoc-section__inner > h2 {
  font-size: clamp(1.8rem, 4vw, 2.6rem);
  font-weight: 700;
  color: var(--dark);
  margin-bottom: 16px;
  letter-spacing: -.02em;
}

#sds-doc .sdsdoc-section[data-layout="center"] .sdsdoc-prose {
  font-size: 1.05rem;
  color: var(--gray-500);
  margin-bottom: 36px;
  max-width: 540px;
  margin-left: auto;
  margin-right: auto;
  line-height: 1.65;
}

/* translated from `.make-the-move-section .inner`: The 640px centred wrapper is now the `embed` element itself rather than a wrapper around heading, lede and shortcode. So the heading and lede sit outside it and take the section's width — the narrower measure applies to the form alone. */
#sds-doc .sdsdoc-embed {
  display: block;
  max-width: 640px;
  margin: 0 auto;
  text-align: center;
}

#sds-doc .sdsdoc-embed .gform_wrapper {
  background: transparent !important;
  box-shadow: none !important;
}

#sds-doc .sdsdoc-embed .gform_title {
  display: none !important;
}

#sds-doc .sdsdoc-embed .gfield_label {
  font-size: .85rem;
  font-weight: 600;
  color: var(--dark);
  margin-bottom: 6px;
  display: block;
  text-align: left;
}

#sds-doc .sdsdoc-embed .ginput_container input,
#sds-doc .sdsdoc-embed .ginput_container textarea,
#sds-doc .sdsdoc-embed .ginput_container select {
  width: 100%;
  padding: 11px 16px;
  border-radius: 50px;
  border: 1.5px solid rgba(0,8,38,.15);
  font-size: .9rem;
  font-family: inherit;
  color: var(--dark);
  background: rgba(255,255,255,.8);
  transition: border-color .15s, background .15s;
}

#sds-doc .sdsdoc-embed .ginput_container input:focus,
#sds-doc .sdsdoc-embed .ginput_container textarea:focus,
#sds-doc .sdsdoc-embed .ginput_container select:focus {
  outline: none;
  border-color: var(--purple);
  background: #fff;
}

#sds-doc .sdsdoc-embed .ginput_container textarea {
  border-radius: 16px;
  min-height: 100px;
  resize: vertical;
}

#sds-doc .sdsdoc-embed .gform_button,
#sds-doc .sdsdoc-embed input[type="submit"] {
  background: var(--purple);
  color: #fff;
  padding: 13px 32px;
  border-radius: 50px;
  border: none;
  font-weight: 600;
  font-size: .95rem;
  font-family: inherit;
  cursor: pointer;
  transition: opacity .15s;
  width: 100%;
  margin-top: 8px;
}

#sds-doc .sdsdoc-embed .gform_button:hover,
#sds-doc .sdsdoc-embed input[type="submit"]:hover {
  opacity: .88;
}

/* ══ Derived rules: components the capture never rendered, plus the values
 *    that had to move because the DOM shape changed. Each carries the capture
 *    rule it came from, or says plainly that there was none. ═════════════ */

/* From `.ai-analysis`. The capture's five section paddings (72px 64px 0, 72px 48px, 0 48px, 96px 48px, 96px 48px) collapse to one; see COLLAPSED_RULES for each value lost. */
#sds-doc .sdsdoc-section {
  padding: 72px 48px;
}

/* 900px is the capture's dominant content width: `.hero`, `.ai-analysis .inner`, `.migration-section` and `.table-col` all use it. */
#sds-doc .sdsdoc-section__inner {
  max-width: 900px;
  margin: 0 auto;
}

/* From `.hero`, whose max-width and centring now belong to the inner element so that a bleeding hero can still centre its content. */
#sds-doc .sdsdoc-hero__inner {
  max-width: 900px;
  margin: 0 auto;
}

/* From `body`. CLAUDE.md: white background takes Purple or Dark Blue text. */
#sds-doc .sdsdoc-section[data-tone="light"],
#sds-doc .sdsdoc-hero[data-tone="light"],
#sds-doc .sdsdoc-callout[data-tone="light"] {
  background: #fff;
  color: var(--dark);
}

/* From `.cta-section`, whose `background: var(--gray-50)` is the capture's fourth surface, and from `.cta-section h2`'s `color: var(--dark)` — the closing CTA is the one place either approved page uses it, and both use it the same way. CLAUDE.md: an off-white background takes Purple or Dark Blue text, so the same rule as `light`. */
#sds-doc .sdsdoc-section[data-tone="muted"],
#sds-doc .sdsdoc-hero[data-tone="muted"],
#sds-doc .sdsdoc-callout[data-tone="muted"] {
  background: var(--gray-50);
  color: var(--dark);
}

/* From `.ai-analysis`, `.make-the-move-section` and `.usecase-left`. CLAUDE.md: Sky Blue background takes Purple or Dark Blue text. */
#sds-doc .sdsdoc-section[data-tone="sky"],
#sds-doc .sdsdoc-hero[data-tone="sky"],
#sds-doc .sdsdoc-callout[data-tone="sky"] {
  background: var(--sky);
  color: var(--dark);
}

/* From `.bidirectional-callout` and `.usecase-right`. CLAUDE.md: Dark Blue background takes White or Sky Blue text. */
#sds-doc .sdsdoc-section[data-tone="dark"],
#sds-doc .sdsdoc-hero[data-tone="dark"] {
  background: var(--dark);
  color: #fff;
}

/* From `.bidirectional-callout h2` and `.usecase-card h3`, which agree: a heading on a dark panel is white in both approved pages. */
#sds-doc .sdsdoc-section[data-tone="dark"] h2,
#sds-doc .sdsdoc-section[data-tone="dark"] h3,
#sds-doc .sdsdoc-hero[data-tone="dark"] h1 {
  color: #fff;
}

/* From `.bidirectional-callout p` and `.usecase-card p` — the same value in both. */
#sds-doc .sdsdoc-section[data-tone="dark"] p,
#sds-doc .sdsdoc-section[data-tone="dark"] li {
  color: rgba(255,255,255,.75);
}

/* From `.step-num`, restated so the numeral survives the dark tone's `color: #fff`. */
#sds-doc .sdsdoc-section[data-tone="dark"] .sdsdoc-steps__num {
  background: var(--sky);
  color: var(--purple);
}

/* From `.insight-grid`'s `repeat(3, 1fr)`, generalised over the `columns` field's four permitted values. */
#sds-doc .sdsdoc-grid[data-columns="2"] {
  grid-template-columns: repeat(2, 1fr);
}

/* `.insight-grid` verbatim; three is the capture's own value, used by both the insights grid and the use-case column. */
#sds-doc .sdsdoc-grid[data-columns="3"] {
  grid-template-columns: repeat(3, 1fr);
}

/* As `data-columns="2"`: `.insight-grid`'s pattern over the `columns` field's four permitted values. Nothing ships that uses four yet. */
#sds-doc .sdsdoc-grid[data-columns="4"] {
  grid-template-columns: repeat(4, 1fr);
}

/* D16's dense connector grid. Nothing ships that reaches it (D20); the tighter gap is the only invented value in this table and it is one declaration. */
#sds-doc .sdsdoc-grid[data-columns="6"] {
  grid-template-columns: repeat(6, 1fr);
  gap: 12px;
}

/* From `.insight-card`, minus its background and border, which belong to the `bordered` variant. */
#sds-doc .sdsdoc-card {
  border-radius: 12px;
  padding: 24px 24px 28px;
}

/* From `.insight-card h3`, minus the colour: a card heading's colour comes from the tone of the section it sits in, so that a card on a dark panel is white without a second rule saying so. */
#sds-doc .sdsdoc-card h3 {
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.3;
  margin-bottom: 8px;
}

/* From `.insight-card p`, minus the colour, which tone supplies for the same reason the heading's does. */
#sds-doc .sdsdoc-card p {
  font-size: .875rem;
  line-height: 1.65;
  margin: 0;
}

/* The shadow is `.compare-row:hover`'s, which is the only shadow either approved page defines — so an elevated card is a hovered compare row's elevation, not a new value. */
#sds-doc .sdsdoc-card[data-variant="elevated"] {
  background: #fff;
  box-shadow: 0 2px 12px rgba(0,0,0,.06);
}

/* D16's compact connector cell: logo, name and badges with no body copy. Nothing ships that reaches it (D20), and there was never a legacy rule. */
#sds-doc .sdsdoc-card[data-variant="compact"] {
  padding: 12px;
  text-align: center;
}

/* Clips the sprite to the 10px radius `.usecase-card-icon` sets on the box rather than on the image — which mattered less when the icon was an inline `<svg>` with no box of its own. */
#sds-doc .sdsdoc-card__icon {
  overflow: hidden;
}

/* The capture's card icons are `<svg width="20" height="20">` sized by their own attributes; ours are `<img>` referencing the same shapes, so the size has to be stated here. */
#sds-doc .sdsdoc-card__icon img {
  width: 20px;
  height: 20px;
  display: block;
}

/* From `.bidirectional-callout .callout-tag`, which is the capture's only pill, recoloured onto `--gray-100` because a chip sits on a card rather than on a dark panel. */
#sds-doc .sdsdoc-card__chip {
  display: inline-block;
  background: var(--gray-100);
  color: var(--dark);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: 4px;
  margin-right: 6px;
}

/* From `.ai-analysis .analysis-intro`, minus the colour and max-width. */
#sds-doc .sdsdoc-prose {
  font-size: 1rem;
  line-height: 1.7;
}

/* The capture has no multi-paragraph prose block anywhere, so there is nothing to inherit; `.insight-grid`'s 16px gap is reused as the vertical rhythm rather than a new number being chosen. */
#sds-doc .sdsdoc-prose p + p,
#sds-doc .sdsdoc-prose ul {
  margin-top: 16px;
}

/* **No legacy counterpart**: neither approved page renders a list, and the scoped `*` reset zeroes the browser's default indent. */
#sds-doc .sdsdoc-prose ul {
  padding-left: 20px;
}

/* From `.insight-card p`, which is the capture's smallest body size and the closest thing it has to a caption treatment. */
#sds-doc .sdsdoc-prose[data-variant="caption"] {
  font-size: .875rem;
  color: var(--gray-500);
}

/* **No legacy counterpart**: `quote-section` was generated and then stripped at publish, so it is absent from both captured stylesheets. Sizes are `.cta-section p`'s; the rule is `quote`'s alone (D11). */
#sds-doc .sdsdoc-quote {
  border-left: 3px solid var(--purple);
  padding: 8px 0 8px 24px;
  font-size: 1.05rem;
  line-height: 1.65;
}

/* **No legacy counterpart** — `quote-section` never reached either stored stylesheet. Sizes from `.ai-analysis .section-tag`. */
#sds-doc .sdsdoc-quote__attribution {
  font-size: .85rem;
  font-weight: 600;
  color: var(--gray-500);
  margin-top: 12px;
}

/* **No legacy counterpart**: neither approved page carries a code sample. Border, radius and greys are `.insight-card`'s. */
#sds-doc .sdsdoc-code {
  background: var(--gray-50);
  border: 1px solid var(--gray-200);
  border-radius: 12px;
  padding: 20px 24px;
  overflow-x: auto;
  font-size: .85rem;
  line-height: 1.6;
}

/* **No legacy counterpart**: the plain data table is a blog and overview component, and neither approved page is one. Size from `.compare-row`. */
#sds-doc .sdsdoc-table {
  width: 100%;
  border-collapse: collapse;
  font-size: .9rem;
}

/* Padding and rule colour from `.compare-row .feature-name`, halved: a plain data row is denser than a comparison row carrying a verdict and a sentence. */
#sds-doc .sdsdoc-table th,
#sds-doc .sdsdoc-table td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--gray-200);
  text-align: left;
}

/* **No legacy counterpart**: the capture's images are logos and icons, never a figure, so the vertical rhythm is `.migration-timing`'s doubled. */
#sds-doc .sdsdoc-media {
  margin: 24px 0;
}

/* Radius from `.ll-brand img`, the capture's only image radius. The rest is what any responsive figure needs and the capture never had one. */
#sds-doc .sdsdoc-media img {
  max-width: 100%;
  height: auto;
  display: block;
  border-radius: 10px;
}

/* Sizes from `.insight-card p`, the capture's smallest body text. **No legacy counterpart** otherwise: nothing on the approved page has a caption. */
#sds-doc .sdsdoc-media__caption {
  font-size: .85rem;
  color: var(--gray-500);
  margin-top: 8px;
}

/* **No legacy counterpart** and deliberately almost empty: a `custom` block carries its own scoped CSS through the bridge (§2.6 rule 3). */
#sds-doc .sdsdoc-custom {
  margin: 24px 0;
}

/* **No legacy counterpart — the approved page carries no internal-link block at all (§7.5, the orphan finding).** Width and padding follow the section rhythm so the block reads as part of the page. */
#sds-doc .sdsdoc-links {
  max-width: 900px;
  margin: 0 auto;
  padding: 40px 48px;
}

/* D21. A sibling block that resolved to nothing still emits its container, so that `verify_render`'s component count stays a real assertion and `refresh_siblings` has a region to confine its diff to. It must occupy no space. */
#sds-doc .sdsdoc-links:empty {
  display: none;
  padding: 0;
}

/* Sizes from `.usecase-card h3`, the capture's largest sub-heading; the colour is left to tone. */
#sds-doc .sdsdoc-links h2 {
  font-size: 1.1rem;
  font-weight: 700;
  margin-bottom: 12px;
}

/* The wrapping flex row from `.radar-legend`, which is the capture's only horizontal list of labelled items. */
#sds-doc .sdsdoc-links ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 12px 24px;
}

/* Purple link treatment from `.compare-header .col-label.sym`; sizes from `.compare-row .feature-comp`. */
#sds-doc .sdsdoc-links__item a {
  color: var(--purple);
  font-size: .9rem;
  font-weight: 600;
  text-decoration: none;
}

/* **No legacy counterpart**: the capture's only links are buttons, which change opacity rather than gaining an underline. */
#sds-doc .sdsdoc-links__item a:hover {
  text-decoration: underline;
}

/* The capture has no steps wrapper — `.step` divs sat directly in the section — so the offset is taken from `.migration-timing`'s `margin-top`, the only vertical value in that section's own rules. */
#sds-doc .sdsdoc-steps {
  margin-top: 24px;
}

/* The capture numbered steps with hand-written `.step-num` divs, so there is no `<ol>` to inherit from; numbering is renderer-owned now. */
#sds-doc .sdsdoc-steps__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* The capture's `<strong>` sat inside `.step-body`; ours is its own paragraph, so it needs its margin zeroed. `.step-body strong` supplies the typography. */
#sds-doc .sdsdoc-steps__label {
  margin: 0;
}

/* `.step` is a flex row and `.step-body` is the child that must grow. The legacy `.step-body` rule supplies the typography and says nothing about the flex behaviour, which the grid it sat in provided implicitly. */
#sds-doc .sdsdoc-steps__body {
  flex: 1;
}

/* From `.usecase-section`. `max-width: none` because the split spans the bleed; `align-items: center` is `.usecase-left`'s `justify-content: center` in grid spelling. */
#sds-doc .sdsdoc-section[data-layout="split"] .sdsdoc-section__inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  min-height: 520px;
  max-width: none;
  align-items: center;
}

/* The one placement decision the flat child list forces. The `grid` is pinned to column two spanning every row, and CSS grid auto-placement then flows the heading and the lede down column one — which is what the capture's `.usecase-left` / `.usecase-right` wrappers did structurally. */
#sds-doc .sdsdoc-section[data-layout="split"] .sdsdoc-grid {
  grid-column: 2;
  grid-row: 1 / span 20;
}

/* `.usecase-left`'s `padding: 80px 56px`, inline half only: the vertical padding belongs to the section. */
#sds-doc .sdsdoc-section[data-layout="split"] .sdsdoc-section__inner > h2,
#sds-doc .sdsdoc-section[data-layout="split"] > .sdsdoc-section__inner > .sdsdoc-prose {
  grid-column: 1;
  padding-inline: 56px;
}

/* From `.cta-section`, moved onto the inner so the centring does not also centre a bleeding background. */
#sds-doc .sdsdoc-section[data-layout="center"] .sdsdoc-section__inner {
  text-align: center;
}

/* `.radar-col` verbatim, scoped to the layout that gives it a taller sibling column to stick against. The `margin: 0` cancels the flow-block centring the translated `.sdsdoc-chart` rule applies for every other layout, because here the grid track is the width. */
#sds-doc .sdsdoc-section[data-layout="rail"] .sdsdoc-chart {
  position: sticky;
  top: 24px;
  margin: 0;
}

/* `.table-col` was the second grid track and `.compare-body` centred nothing inside it; the derived `.sdsdoc-compare` rule's `margin: 0 auto` is for a table that owns the full measure, and in a 1fr track it would leave the column's own gutter doubled. The `max-width: 900px` is left alone. */
#sds-doc .sdsdoc-section[data-layout="rail"] .sdsdoc-compare {
  margin: 0;
}

/* `max-width` from `.table-col`; `border-spacing` from `.compare-row`'s `margin-bottom: 10px`, which is how row gaps are spelt on a table. */
#sds-doc .sdsdoc-compare {
  display: table;
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  border-collapse: separate;
  border-spacing: 0 10px;
}

/* `.compare-row`'s white row background, hoisted to the row group so that a `<tbody>` is not the one element in the table with no rule at all. */
#sds-doc .sdsdoc-compare__body {
  background: #fff;
}

/* `.compare-row`'s 1px border, moved to the cells because a `<tr>` cannot carry one. `vertical-align: top` replaces `align-items: flex-start`. */
#sds-doc .sdsdoc-compare__cell {
  vertical-align: top;
  border-top: 1px solid var(--gray-200);
  border-bottom: 1px solid var(--gray-200);
}

/* `.compare-row`'s `border` and `border-radius: 12px`, applied to the row's end cells — the only way a separated-border table can show a rounded row. */
#sds-doc .sdsdoc-compare__row > :first-child {
  border-left: 1px solid var(--gray-200);
  border-top-left-radius: 12px;
  border-bottom-left-radius: 12px;
}

/* As `:first-child`: `.compare-row`'s border and 12px radius, on the other end cell of the row. */
#sds-doc .sdsdoc-compare__row > :last-child {
  border-right: 1px solid var(--gray-200);
  border-top-right-radius: 12px;
  border-bottom-right-radius: 12px;
}

/* The `gap: 10px` the legacy flex cells used, plus the capture's own `<svg width="18">` box. */
#sds-doc .sdsdoc-compare__cell img {
  vertical-align: top;
  margin: 2px 10px 0 0;
  width: 18px;
  height: 18px;
}

/* The product-facts accuracy line. Italic small print from `.migration-timing`; nothing shipped renders it (D20). */
#sds-doc .sdsdoc-compare__note,
#sds-doc .sdsdoc-grid__note {
  font-size: .8rem;
  color: var(--gray-500);
  font-style: italic;
  margin-top: 12px;
  text-align: left;
  caption-side: bottom;
}

/* The radar was a `<canvas responsive: true>`; it is now an `<img>` referencing a content-addressed SVG (D13). */
#sds-doc .sdsdoc-chart img {
  width: 100%;
  height: auto;
  display: block;
}

/* The same, for the `static_html` adapter, which does not strip inline SVG and so styles the `<svg>` root directly rather than an `<img>` around it. */
#sds-doc .sdsdoc-chart__plot {
  width: 100%;
  height: auto;
  display: block;
}

/* The `<g>` wrapping the rings and spokes. There is nothing to inherit — Chart.js drew its grid onto the canvas rather than as elements — and nothing to style beyond keeping the group inert to the cursor. */
#sds-doc .sdsdoc-chart__grid {
  pointer-events: none;
}

/* Chart.js `scales.r.grid.color: "rgba(0,0,0,.08)"`, from the script block committed in `legacy_azure_reference.html`. */
#sds-doc .sdsdoc-chart__ring {
  fill: none;
  stroke: rgba(0,0,0,.08);
  stroke-width: 1;
}

/* Chart.js `scales.r.angleLines.color: "rgba(0,0,0,.1)"`, from the same script block. */
#sds-doc .sdsdoc-chart__spoke {
  stroke: rgba(0,0,0,.1);
  stroke-width: 1;
}

/* Chart.js `scales.r.pointLabels: { font: { size: 14, weight: "600" }, color: "#000826" }` — the axis labels, at the capture's own size. */
#sds-doc .sdsdoc-chart__label {
  font-size: 14px;
  font-weight: 600;
  fill: var(--dark);
}

/* Chart.js dataset 1: `backgroundColor: "rgba(82,39,210,0.15)"`, `borderColor: "#5227D2"`, `borderWidth: 2` — transcribed from the script block committed in `legacy_azure_reference.html`. */
#sds-doc .sdsdoc-chart__area[data-series="a"] {
  fill: rgba(82,39,210,.15);
  stroke: var(--purple);
  stroke-width: 2;
}

/* Chart.js dataset 2, `borderDash: [5, 5]` included — the dashed competitor outline the approved page draws. */
#sds-doc .sdsdoc-chart__area[data-series="b"] {
  fill: rgba(156,163,175,.10);
  stroke: #9ca3af;
  stroke-width: 2;
  stroke-dasharray: 5 5;
}

/* Chart.js dataset 1 `pointBackgroundColor: "#5227D2"`, from the script block committed in `legacy_azure_reference.html`. */
#sds-doc .sdsdoc-chart__point[data-series="a"] {
  fill: var(--purple);
}

/* Chart.js dataset 2 `pointBackgroundColor: "#9ca3af"`, from the same script block. */
#sds-doc .sdsdoc-chart__point[data-series="b"] {
  fill: #9ca3af;
}

/* The capture compares two products, so series c–e have no counterpart. `chart.py` permits five; an unstyled series would render black. */
#sds-doc .sdsdoc-chart__area[data-series="c"],
#sds-doc .sdsdoc-chart__area[data-series="d"],
#sds-doc .sdsdoc-chart__area[data-series="e"] {
  fill: rgba(0,8,38,.06);
  stroke: var(--dark);
  stroke-width: 2;
}

/* As the c–e areas: the capture compares two products, so these have no counterpart and would otherwise render black. */
#sds-doc .sdsdoc-chart__point[data-series="c"],
#sds-doc .sdsdoc-chart__point[data-series="d"],
#sds-doc .sdsdoc-chart__point[data-series="e"] {
  fill: var(--dark);
}

/* The capture's solid legend swatch, `style="display:inline-block;width:22px;height:3px;background:#5227D2;border-radius:2px"` — one of the 14 inline styles this pipeline removes. Series `a` is drawn solid on the plot and the swatch says so. */
#sds-doc .sdsdoc-chart__dot[data-series="a"] {
  height: 3px;
  background: var(--purple);
}

/* The capture's second swatch, `style="display:inline-block;width:22px;height:0;border-top:3px dashed #94a3b8"`. A dashed rule rather than a filled bar, because series `b` is drawn dashed on the plot (`stroke-dasharray: 5 5`) and a legend that does not distinguish the two line styles identifies nothing. **One deliberate correction to the capture: `#94a3b8` becomes `#9ca3af`.** The capture drew this swatch a shade lighter than the line it stands for — the plot strokes `#9ca3af` (`SERIES_AREA_APPEARANCE['b']`) — so the legend and the plot disagreed about the competitor's colour. On a page whose whole claim is which line is whose, that is a defect rather than a style, and it surfaced only because `legend_swatch_style` derives the swatch from the plot's own table. Both carriers now read the same value from that table. */
#sds-doc .sdsdoc-chart__dot[data-series="b"] {
  height: 0;
  border-top: 3px dashed #9ca3af;
}

/* As the c–e areas: no counterpart in a two-product comparison. Solid, matching the c–e stroke, which carries no dash array. */
#sds-doc .sdsdoc-chart__dot[data-series="c"],
#sds-doc .sdsdoc-chart__dot[data-series="d"],
#sds-doc .sdsdoc-chart__dot[data-series="e"] {
  height: 3px;
  background: var(--dark);
}

/* `.radar-legend` was a div of divs; ours is a `<ul>`, so the marker has to go. Its flex layout is inherited from the legacy rule. */
#sds-doc .sdsdoc-chart__legend {
  list-style: none;
}

/* Each legend item opens with that brand's mark. The capture writes it inline — `style="height:40px;object-fit:contain;border-radius:5px;flex-shrink:0"` on `.legend-item img` — and these are those declarations, with `width: auto` stated because our `<img>` carries no width attribute. */
#sds-doc .sdsdoc-chart__legend img {
  height: 40px;
  width: auto;
  object-fit: contain;
  border-radius: 5px;
  flex-shrink: 0;
}

/* The shortcode line, sized from `.compare-row .feature-comp`. Every surface now emits the same `[gravityforms id="…"]` the capture does; on WordPress Gravity Forms replaces it with its own markup and this rule matches nothing, and on a preview it is the one line of visible text. */
#sds-doc .sdsdoc-embed p {
  font-size: .9rem;
  color: var(--gray-500);
}

/* The capture's callout is a two-child flex row — `.icon-ring` and one **unclassed** `<div>` holding the tag, the heading and the copy — so there is no legacy rule to inherit, only a legacy *element*. One declaration, and not a new value: it is the same job `.sdsdoc-steps__body` does as the growing child of the other translated flex row, spelt the same way. Everything visible inside the column is already styled by `.bidirectional-callout .callout-tag`, `h2` and `p`. */
#sds-doc .sdsdoc-callout__body {
  flex: 1;
}

/* Collapsed — see COLLAPSED_RULES in db/content/stylesheet.py for why each
 *   of these has no target: .ai-analysis, .compare-header, .compare-section, .compare-section .section-header p, .make-the-move-section, .make-the-move-section .sub, .make-the-move-section h2, .migration-section, .migration-section h2, .migration-sub, .table-col, .usecase-card-icon svg, .usecase-left, .usecase-section */

/* ── Full-bleed: ONE mechanism, geometry defined once (plan §3.3 rule 5) ──── */
#sds-doc .sdsdoc-bleed { margin-inline: calc(50% - 50vw); max-width: none; }

/* ── Theme escape: the only rules that reach outside the wrapper. A theme
 *    setting `overflow-x: hidden` on the post container clips full-bleed, so
 *    this is the documented exception in canonical.lock.json. ─────────────── */
.entry-content, .post-content, .site-content { overflow-x: visible; }
