/* Shell: the Migration Tool's sidebar (.imt-top, .imt-nav), its docs menu (.imt-docs-nav) and docs card
   (.imt-docs-main), copied rule for rule with the ds prefix; the mega-menu panel takes the current docs site's
   tinted tiles. Tokens come from tokens.css. */
:root {
  --ds-tree-w: calc(212px + (var(--ds-text) - 14px) * 12);
  --ds-topbar-h: 56px;
}
body { --ds-side-w: 200px; }
body.is-collapsed { --ds-side-w: 64px; }

/* Sidebar (.imt-top) */
.ds-rail { position: fixed; top: 0; bottom: 0; left: 0; z-index: 50; display: flex; flex-direction: column; gap: 18px; width: var(--ds-side-w); padding: 20px 14px 14px; background: var(--ds-surface-sidebar); border-right: 1px solid var(--ds-border-divider); }
.ds-side-head { display: flex; align-items: center; height: 48px; flex: none; }
.ds-brand { display: flex; align-items: center; height: 48px; padding: 0 6px; color: var(--ds-text-primary); text-decoration: none; border-radius: var(--ds-r-input); }
.ds-brand-full svg { display: block; height: 46px; width: auto; }
.ds-brand-markbox { display: none; width: 11.2px; height: 27.2px; overflow: hidden; }
.ds-brand-mark { display: block; flex: none; width: 27.2px; height: 27.2px; max-width: none; margin-left: -6.12px; }
.ds-rail-items, .ds-rail-foot { display: flex; flex-direction: column; gap: 2px; }
.ds-rail-items { flex: 1; min-height: 0; overflow-y: auto; scrollbar-width: thin; }
.ds-rail-foot { flex: none; padding-top: 6px; }
.ds-rail-rule { width: 100%; margin: 4px 0 6px; border: 0; border-top: 1px solid var(--ds-border-divider); }
.ds-rail-item { position: relative; display: flex; align-items: center; gap: 10px; flex: none; height: 40px; padding: 0 12px; border: 0; border-radius: var(--ds-r-button); background: none; color: var(--ds-text-secondary); font: 500 14px var(--ds-font); text-decoration: none; white-space: nowrap; cursor: pointer; text-align: left; }
.ds-rail-foot .ds-rail-item { height: 36px; font-size: 13px; color: var(--ds-text-tertiary); }
.ds-rail-item svg { display: block; flex: none; width: 20px; height: 20px; }
.ds-rail-item:hover, .ds-rail-item[aria-expanded="true"] { background: var(--ds-surface-base); color: var(--ds-text-primary); }
.ds-rail-item.is-active { background: var(--ds-brand-subtle); color: var(--ds-brand-fg); font-weight: 600; }
.ds-side-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.ds-rail-toggle { display: flex; align-items: center; gap: 10px; height: 36px; padding: 0 12px; border: 0; border-radius: var(--ds-r-button); background: none; color: var(--ds-text-tertiary); font: 500 13px var(--ds-font); cursor: pointer; white-space: nowrap; }
.ds-rail-toggle:hover { background: var(--ds-surface-base); color: var(--ds-text-primary); }
.ds-rail-toggle svg { flex: none; width: 18px; height: 18px; }
.ds-rail-toggle .ds-rail-out, body.is-collapsed .ds-rail-toggle .ds-rail-in { display: none; }
body.is-collapsed .ds-rail-toggle .ds-rail-out { display: inline; }
/* The 64px rail (.imt-shell.is-collapsed) */
body.is-collapsed .ds-rail { align-items: center; padding: 18px 0 14px; }
body.is-collapsed :is(.ds-brand-full, .ds-side-label, .ds-toggle-label) { display: none; }
body.is-collapsed .ds-brand-markbox { display: block; }
body.is-collapsed .ds-side-head, body.is-collapsed .ds-brand { height: auto; }
body.is-collapsed .ds-brand { padding: 2px; }
body.is-collapsed :is(.ds-rail-items, .ds-rail-foot) { align-items: center; }
body.is-collapsed :is(.ds-rail-item, .ds-rail-toggle) { justify-content: center; width: 44px; height: 44px; padding: 0; }
/* An item's name beside it in the rail, on pointing and on keyboard focus (.imt-rail-tip). */
.ds-rail-item::after, .ds-rail-toggle::after { content: attr(aria-label); position: fixed; left: 72px; display: none; padding: 5px 10px; border-radius: var(--ds-r-input); background: var(--ds-text-primary); color: var(--ds-surface-raised); font: 500 13px/1.3 var(--ds-font); white-space: nowrap; pointer-events: none; box-shadow: 0 4px 14px rgba(20, 28, 50, 0.18); z-index: 70; }
body.is-collapsed :is(.ds-rail-item, .ds-rail-toggle):is(:hover, :focus-visible)::after { display: block; }
body.ds-flyout-open .ds-rail-item::after { display: none !important; }

/* Ask Insites AI: the IIA AI module's pill. A brand-to-violet gradient, a lighter sparkle badge, a soft glow. */
/* Ask pill: the IIA AI module launcher's motion (module-v6-ai ai.css): drifting gradient, breathing orb, lift on hover. */
.ds-ask-pill { position: relative; display: flex; align-items: center; gap: 10px; width: 100%; height: 42px; margin: 0 0 10px; padding: 0 14px 0 5px; border: 0; border-radius: 999px; background: var(--ds-ai-gradient); background-size: 220% 220%; color: var(--ds-on-brand); font: 600 14px var(--ds-display); white-space: nowrap; cursor: pointer; overflow: visible; box-shadow: 0 6px 18px rgba(42, 120, 214, 0.35), inset 0 0 0 1px rgba(255, 255, 255, 0.18); animation: ds-ai-drift 7s ease-in-out infinite; transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.25s ease; }
.ds-ask-pill:is(:hover, :focus-visible) { transform: translateY(-2px) scale(1.02); box-shadow: 0 12px 28px rgba(124, 92, 255, 0.4), inset 0 0 0 1px rgba(255, 255, 255, 0.3); animation-duration: 2.5s; }
.ds-ask-pill:active { transform: translateY(0) scale(0.98); }
.ds-ask-pill .ds-ask-spark { animation: ds-ai-breathe 2.8s ease-in-out infinite; }
.ds-ask-pill:hover .ds-ask-spark { animation-duration: 1.2s; }
.ds-ask-spark svg { transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1); }
.ds-ask-pill:hover .ds-ask-spark svg { transform: rotate(72deg) scale(1.15); }
@keyframes ds-ai-drift { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }
@keyframes ds-ai-breathe { 0%, 100% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.35); } 50% { box-shadow: 0 0 0 7px rgba(255, 255, 255, 0); } }
body.is-collapsed .ds-ask-pill { width: 40px; padding: 0 3px; justify-content: center; }
.ds-ask-pill::after { content: attr(aria-label); position: fixed; left: 72px; display: none; padding: 5px 10px; border-radius: var(--ds-r-input); background: var(--ds-text-primary); color: var(--ds-surface-raised); font: 500 13px/1.3 var(--ds-font); white-space: nowrap; pointer-events: none; z-index: 70; }
body.is-collapsed .ds-ask-pill:is(:hover, :focus-visible)::after { display: block; }
.ds-ask-spark { display: grid; place-items: center; flex: none; width: 32px; height: 32px; border-radius: 50%; background: rgba(255, 255, 255, 0.2); }
body.is-collapsed .ds-ask-pill { width: 40px; padding: 0 3px; justify-content: center; }
body.is-collapsed .ds-ask-pill:is(:hover, :focus-visible)::after { display: block; }
.ds-drawer-more, .ds-tree-menu-only { display: none; }
.ds-step-tile { background: var(--ds-brand-subtle); color: var(--ds-brand-fg); font: 600 13px var(--ds-display); }

/* Mega-menu panel: the current docs site's tiles */
.ds-flyout { position: fixed; z-index: 45; top: 0; bottom: 0; left: var(--ds-side-w); width: min(860px, calc(100vw - var(--ds-side-w))); overflow-y: auto; background: var(--ds-surface-raised); border-right: 1px solid var(--ds-border-subtle); box-shadow: 16px 0 40px rgba(20, 28, 50, 0.16); visibility: hidden; opacity: 0; transform: translateX(-16px); transition: transform 180ms var(--ds-ease), opacity 180ms var(--ds-ease), visibility 0s linear 180ms; }
.ds-flyout.is-open { visibility: visible; opacity: 1; transform: none; transition: transform var(--ds-dur-base) var(--ds-ease), opacity var(--ds-dur-base) var(--ds-ease); }
.ds-flyout-panel { display: none; min-height: 100%; }
.ds-flyout-panel.is-on { display: grid; grid-template-columns: 300px minmax(0, 1fr); }
.ds-flyout-panel.is-on:not(:has(.ds-flyout-main)) { grid-template-columns: 300px; }
.ds-flyout-feature, .ds-flyout-main { padding: 28px 16px 24px; }
.ds-flyout-feature { border-right: 1px solid var(--ds-border-subtle); background: light-dark(#fafbfd, #1e1e1e); }
.ds-flyout-feature h2, .ds-flyout-main h2 { margin: 0 0 12px; font: 600 19px/1.3 var(--ds-display); color: var(--ds-text-primary); }
.ds-flyout-feature > p { margin: 0 0 16px; padding: 0 8px; color: var(--ds-text-secondary); font-size: 15px; line-height: 1.45; }
/* one shared header row: every h2 in a panel has the same box and the same rule under it */
.ds-flyout-feature h2, .ds-flyout-main h2 { min-height: 25px; padding-bottom: 20px; margin: 0 0 20px; border-bottom: 1px solid var(--ds-border-divider); }
.ds-flyout-feature ul, .ds-flyout-main ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }
.ds-flyout-main { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); align-content: start; gap: 8px 16px; }
.ds-flyout-main section { display: flex; flex-direction: column; }
.ds-flyout-main section > ul { flex: 1; align-content: start; }
.ds-flyout-main .ds-flyout-all { margin: 12px 0 0 8px; }
.ds-flyout-feature ul { padding: 0 8px; gap: 14px; }
.ds-flyout-link { display: grid; grid-template-columns: 32px minmax(0, 1fr); gap: 16px; padding: 8px; border-radius: var(--ds-r-button); color: var(--ds-text-primary); text-decoration: none; }
.ds-flyout-link:hover { background: var(--ds-surface-base); }
.ds-flyout-feature .ds-flyout-link:hover { background: var(--ds-surface-raised); }
/* Menu tiles: option 7 of pages/menu-icon-styles.html, chosen by Shane on 31 October 2026: the current site's
   coloured icons (or ones drawn in their style) on a neutral grey tile. */
.ds-mtile { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 8px; background: var(--ds-surface-deep); color: var(--ds-text-secondary); }
.ds-mtile svg { width: 20px; height: 20px; }
.ds-mtile.is-module svg { width: 32px; height: 32px; }
.ds-mtile.is-line { background: none; color: var(--ds-brand-fg); }   /* option 1: everything that is not an IIA module */
.ds-flyout-link:hover .ds-mtile.is-line, a.ds-chapter-card:hover .ds-mtile.is-line { background: none; color: var(--ds-brand-fg); }   /* option 7: IIA modules only; the rest are option 2 until chosen */
.ds-step-tile { font: 600 13px var(--ds-display); }
.ds-flyout-link b { display: block; font: 600 15px/1.35 var(--ds-display); color: var(--ds-text-primary); }
.ds-flyout-link div span { display: block; margin-top: 2px; color: var(--ds-text-secondary); font-size: 13px; line-height: 1.45; }
/* Round 9 (DS-27 budget): a menu row's title and line sit directly in the link, with no wrapper div. The icon or art
   spans both rows; the text takes the last column whether or not the row has an icon. */
.ds-flyout-link:has(> b) { row-gap: 0; align-content: start; }
.ds-flyout-link > b, .ds-flyout-link > b + span { grid-column: -2; min-width: 0; }
.ds-flyout-link:has(> b) > :first-child:not(b) { grid-row: span 2; }
.ds-flyout-link > b + span { display: block; margin-top: 2px; color: var(--ds-text-secondary); font-size: 13px; line-height: 1.45; }
.ds-flyout-link:has(> b):has(.ds-menu-art) { align-content: center; align-items: start; }
.ds-flyout-all { display: inline-flex; align-items: center; gap: 6px; margin: 20px 0 0 16px; color: var(--ds-text-primary); font: 600 13px var(--ds-display); text-decoration: none; }
.ds-flyout-all::after { content: ""; width: 5px; height: 5px; border: solid currentColor; border-width: 1.5px 1.5px 0 0; transform: rotate(45deg); }
.ds-flyout-all:hover { color: var(--ds-brand-fg); }
.ds-flyout-tile { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 8px; background: var(--ds-brand-subtle); color: var(--ds-brand-fg); }
.ds-flyout-tile svg { width: 20px; height: 20px; }

/* Frame and top bar: the breadcrumb on the left, three links on the right, on the page surface */
.ds-frame { margin-left: var(--ds-side-w); min-height: 100vh; }
.ds-topbar { position: sticky; top: 0; z-index: 30; display: flex; align-items: center; justify-content: space-between; gap: 16px; height: var(--ds-topbar-h); padding: 0 20px; background: var(--ds-surface-raised); border-bottom: 1px solid var(--ds-border-divider); }
.ds-crumbs-wrap { min-width: 0; }
.ds-crumbs { display: flex; gap: 6px; margin: 0; padding: 0; list-style: none; font-size: 13px; color: var(--ds-text-tertiary); overflow: hidden; white-space: nowrap; }
.ds-crumbs li { display: flex; gap: 6px; min-width: 0; overflow: hidden; }
.ds-crumbs li::before { flex: none; }
.ds-crumbs a, .ds-crumbs li:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.ds-crumbs li + li::before { content: "/"; color: var(--ds-text-subtle); }
.ds-crumbs li:last-child { color: var(--ds-text-primary); font-weight: 500; overflow: hidden; text-overflow: ellipsis; }
.ds-crumbs a { color: inherit; text-decoration: none; }
.ds-crumbs a:hover { color: var(--ds-brand-fg); }
.ds-search-wrap { display: flex; flex: 1; justify-content: center; min-width: 0; margin: 0; }
.ds-search-wrap .ds-search { width: min(420px, 100%); }
.ds-toplinks { display: flex; justify-content: flex-end; gap: 20px; font-size: 13px; white-space: nowrap; }
.ds-toplinks a { color: var(--ds-text-secondary); text-decoration: none; }
.ds-toplinks a:hover { color: var(--ds-brand-fg); }
/* Search at the top of the section menu (.imt-docs-search) */
.ds-search { position: relative; display: block; margin: 0; }
.ds-search input { width: 100%; height: 36px; padding: 6px 30px 6px 10px; border: 1px solid var(--ds-border-divider); border-radius: var(--ds-r-input); font: 14px var(--ds-font); color: var(--ds-text-primary); background: var(--ds-surface-raised); -webkit-appearance: none; appearance: none; }
.ds-search input::placeholder { color: var(--ds-text-subtle); }
.ds-search input:focus { border-color: var(--ds-brand); }
.ds-search kbd { position: absolute; top: 9px; right: 9px; min-width: 18px; padding: 0 5px; border: 1px solid var(--ds-border-subtle); border-radius: 4px; font: 12px/18px var(--ds-font); color: var(--ds-text-tertiary); text-align: center; pointer-events: none; }
.ds-search input:focus ~ kbd, .ds-search input:not(:placeholder-shown) ~ kbd { display: none; }
.ds-tree-search { position: sticky; top: -2px; z-index: 1; margin: 0 0 18px; padding: 2px 0 6px; background: var(--ds-surface-base); }

/* Body: the section menu (.imt-docs-nav), then the content */
.ds-body { display: grid; grid-template-columns: var(--ds-tree-w) minmax(0, 1fr); gap: 20px; align-items: start; padding: 8px 20px 64px; }
.ds-tree { position: sticky; top: calc(var(--ds-topbar-h) + 8px); align-self: start; max-height: calc(100vh - var(--ds-topbar-h) - 24px); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; margin-left: -10px; padding: 2px 6px 24px 10px; font-size: var(--ds-text); }
.ds-tree-title { margin: 0 0 6px; font-size: 13px; font-weight: 600; color: var(--ds-text-primary); }
.ds-tree ul { margin: 0; padding: 0; list-style: none; }
.ds-tree ul ul { margin-left: 10px; padding-left: 8px; border-left: 1px solid var(--ds-border-subtle); }
.ds-tree ul[hidden] { display: none; }
.ds-tree-row { position: relative; display: flex; align-items: center; }
.ds-tree :is(li, .ds-tree-row) > a { flex: 1; min-width: 0; display: block; padding: 5px 10px; margin-left: -10px; border-radius: var(--ds-r-input); color: var(--ds-text-secondary); text-decoration: none; overflow-wrap: break-word; hyphens: manual; }
.ds-tree ul ul :is(li, .ds-tree-row) > a { margin-left: 0; }
.ds-tree :is(li, .ds-tree-row) > a:hover { color: var(--ds-text-primary); background: var(--ds-surface-raised); }
.ds-tree :is(li, .ds-tree-row) > a[aria-current="page"] { background: var(--ds-brand-subtle); color: var(--ds-brand-fg); font-weight: 600; }
.ds-tree-row button { position: absolute; right: 2px; top: 50%; display: grid; place-items: center; width: 24px; height: 24px; margin-top: -12px; border: 0; border-radius: var(--ds-r-input); background: none; color: var(--ds-text-subtle); opacity: 0.7; cursor: pointer; }
.ds-tree-row button:hover { opacity: 1; color: var(--ds-text-primary); }
.ds-tree-row button::before { content: ""; width: 5px; height: 5px; border: solid currentColor; border-width: 0 1.5px 1.5px 0; transform: rotate(-45deg); transition: transform 150ms var(--ds-ease); }
.ds-tree-row button[aria-expanded="true"]::before { transform: rotate(45deg); }
.ds-tree-row:has(button) > a { padding-right: 28px; }
/* Round 4 menu rule: an accordion parent is a button, never a link. It spans the row, reads like a link, and carries the
   chevron at its right edge (row-reverse puts the ::before chevron last). */
.ds-tree-row button:only-child { position: static; flex: 1; min-width: 0; width: auto; height: auto; margin: 0 0 0 -10px; padding: 5px 10px; display: flex; flex-direction: row-reverse; justify-content: space-between; align-items: center; gap: 8px; text-align: left; font: inherit; color: var(--ds-text-secondary); opacity: 1; cursor: pointer; overflow-wrap: break-word; }
.ds-tree ul ul .ds-tree-row button:only-child { margin-left: 0; }
/* Round 5 (DS-44): one thin rule between the Developers build topics and how-you-work groups; never a heading. */
.ds-tree-divider { height: 0; margin: 8px 10px 8px 0; border-top: 1px solid var(--ds-border-subtle); list-style: none; }
.ds-tree-row button:only-child:hover { color: var(--ds-text-primary); background: var(--ds-surface-raised); }
.ds-tree-row button:only-child::before { flex: none; color: var(--ds-text-subtle); }
.ds-tree-row button:only-child:focus-visible { outline: 2px solid var(--ds-focus, var(--ds-brand)); outline-offset: -2px; }

/* Content card (.imt-docs-main) */
.ds-main { display: grid; grid-template-columns: minmax(0, 1fr); gap: 32px; align-items: start; min-width: 0; }
.ds-card { min-width: 0; width: 100%; padding: 40px 48px; background: var(--ds-surface-raised); border: 1px solid var(--ds-border-subtle); border-radius: var(--ds-r-card); box-shadow: var(--ds-elevation-sm); overflow-x: clip; --ds-measure: 44rem; }
.ds-eyebrow { color: var(--ds-brand-fg); font-weight: 600; font-size: 12px; letter-spacing: 0.04em; margin: 0 0 8px; }
.ds-card h1 { margin-bottom: 12px; }
.ds-lead, .ds-lead p { max-width: var(--ds-measure); margin: 0 0 20px; font-size: calc(var(--ds-text) * 16 / 14); line-height: 1.75; color: var(--ds-text-secondary); }
.ds-lead p { margin: 0; }
.ds-prose { font-size: var(--ds-text); }
.ds-prose :is(p, ul, ol, dl, blockquote) { max-width: var(--ds-measure); }
.ds-prose :is(p, li) { line-height: 1.7; }
.ds-prose h2 { margin: 36px 0 10px; }
.ds-prose h3 { margin: 24px 0 8px; }
.ds-prose h2, .ds-prose h3 { scroll-margin-top: calc(var(--ds-topbar-h) + 16px); }
.ds-prose img, .ds-prose svg { max-width: 100%; height: auto; }
.ds-prose pre { background: var(--ds-surface-subtle); border: 1px solid var(--ds-border-subtle); border-radius: var(--ds-r-input); padding: 10px 12px; }
.ds-prose blockquote, .ds-callout { display: block; width: 100%; margin: 16px 0; padding: 12px 16px; border: 1px solid var(--ds-brand-border); border-radius: var(--ds-r-button); background: var(--ds-brand-subtle); color: var(--ds-text-primary); }
.ds-prose blockquote > :first-child { margin-top: 0; }
.ds-prose blockquote > :last-child { margin-bottom: 0; }
.ds-prose table { display: table; max-width: 100%; margin: 12px 0 20px; border-collapse: collapse; font-size: 13px; color: var(--ds-text-secondary); }
.ds-prose :is(th, td) { text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--ds-border-subtle); vertical-align: top; }
.ds-prose th { background: var(--ds-surface-subtle); font-size: 12px; font-weight: 600; color: var(--ds-text-secondary); }
.ds-prose tr:last-child td { border-bottom: 0; }
.ds-main.has-toc { grid-template-columns: minmax(0, 1fr) 184px; gap: 20px; }
.ds-main.has-toc:not(:has(.ds-toc)) { grid-template-columns: minmax(0, 1fr); }   /* DS-47: no h2, no contents column */
.ds-body-wide { grid-template-columns: minmax(0, 1fr); }
.ds-toc { position: sticky; top: calc(var(--ds-topbar-h) + 8px); max-height: calc(100vh - var(--ds-topbar-h) - 48px); overflow-y: auto; overscroll-behavior: contain; min-height: 1px; font-size: calc(var(--ds-text) * 13 / 14); }
.ds-toc-title { display: block; margin: 0 0 8px; padding: 0; border: 0; background: none; text-align: left; cursor: default; font: 600 13px var(--ds-font); color: var(--ds-text-primary); }
.ds-toc ol { margin: 0; padding: 0; list-style: none; border-left: 1px solid var(--ds-border-divider); }
.ds-toc li.is-sub a { padding-left: 24px; }
.ds-toc a { display: block; margin-left: -1px; padding: 4px 12px; border-left: 2px solid transparent; color: var(--ds-text-secondary); text-decoration: none; overflow-wrap: anywhere; }
.ds-toc a:hover { color: var(--ds-text-primary); }
.ds-toc a[aria-current] { border-left-color: var(--ds-brand); color: var(--ds-brand-fg); font-weight: 600; }

/* Pager, landing, home */
.ds-pager { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 16px; margin-top: 40px; padding-top: 24px; border-top: 1px solid var(--ds-border-divider); }
.ds-pager-link { display: grid; gap: 2px; width: fit-content; min-width: min(160px, calc(50% - 8px)); max-width: calc(50% - 8px); box-sizing: border-box; padding: 12px 16px; border: 1px solid var(--ds-border-subtle); border-radius: var(--ds-r-card); color: var(--ds-text-primary); text-decoration: none; }
.ds-pager-link span { font-size: 12px; color: var(--ds-text-tertiary); }
.ds-pager-link.is-next { margin-left: auto; text-align: right; }
.ds-pager-link:hover { border-color: var(--ds-brand-border); }
.ds-hero { display: grid; place-items: center; max-width: 1200px; height: 160px; max-height: 160px; margin: 16px 0 24px; background: var(--ds-brand-subtle); border-radius: var(--ds-r-card); color: var(--ds-brand-fg); }
.ds-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; margin: 0; padding: 0; list-style: none; }
.ds-chapter-card, .ds-door, .ds-ai-callout { display: grid; grid-template-columns: 32px minmax(0, 1fr); gap: 12px; padding: 16px; border: 1px solid var(--ds-border-subtle); border-radius: var(--ds-r-card); background: var(--ds-surface-raised); color: var(--ds-text-primary); text-decoration: none; }
.ds-chapter-card span:not(.ds-flyout-tile), .ds-door > span:last-child, .ds-ai-callout div span { display: block; font-size: 13px; color: var(--ds-text-tertiary); }
.ds-chapter-card.is-planned { opacity: 0.6; }
a.ds-chapter-card:hover, .ds-door:hover, .ds-ai-callout:hover { border-color: var(--ds-brand-border); }
.ds-home { justify-self: center; width: 100%; max-width: 1080px; padding: 24px 0; }
.ds-lede { color: var(--ds-text-secondary); font-size: 17px; }
.ds-home-search label { display: flex; align-items: center; gap: 10px; max-width: none; padding: 12px 16px; border: 1px solid var(--ds-border-default); border-radius: var(--ds-r-button); background: var(--ds-surface-raised); color: var(--ds-text-tertiary); }
.ds-home-search input { flex: 1; min-width: 0; border: 0; background: none; color: var(--ds-text-primary); font: 16px var(--ds-font); outline: none; }
.ds-doors { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; margin: 32px 0 16px; }
.ds-door { grid-template-columns: minmax(0, 1fr); padding: 24px; }
.ds-door b { font-size: 18px; }
.ds-ai-callout { margin-bottom: 32px; background: var(--ds-brand-subtle); border-color: var(--ds-brand-border); }
.ds-home-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 32px; }
.ds-home-cols ul, .ds-whatsnew .ds-home-recent { margin: 0; padding: 0; list-style: none; }
.ds-home-cols li, .ds-whatsnew .ds-home-recent li { display: flex; justify-content: space-between; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--ds-border-divider); }
.ds-list-link { color: var(--ds-text-primary); text-decoration: none; }
a.ds-list-link:hover { color: var(--ds-brand-fg); }
.ds-list-link.is-planned { color: var(--ds-text-tertiary); }
.ds-date { flex: none; font-size: 13px; color: var(--ds-text-tertiary); }

@media (max-width: 1279px) and (min-width: 860px) { .ds-main, .ds-main.has-toc { grid-template-columns: minmax(0, 1fr); } .ds-toc { display: none; } .ds-toplinks a:not(:last-child) { display: none; } }

/* Settings popover, rail labels (shown on mobile only), Menu button (mobile only) */
.ds-rail-label, .ds-menu-btn, .ds-flyout-close { display: none; }
/* DS-86 Settings panel as cards (372px, 18px padding, 8px gaps); selected card: brand ring and tick */
.ds-settings { position: fixed; z-index: 80; left: calc(var(--ds-side-w) + 8px); bottom: 12px; width: 372px; max-height: calc(100vh - 24px); overflow-y: auto; box-sizing: border-box; padding: 18px; display: grid; gap: 16px; background: var(--ds-surface-raised); color: var(--ds-text-secondary); border: 1px solid var(--ds-border-subtle); border-radius: var(--ds-r-card); box-shadow: var(--ds-elevation-sm), 0 12px 32px rgba(20, 28, 50, 0.18); }
.ds-settings section { margin: 0; }
.ds-settings h3, .ds-settings .ds-set-h { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; font: 600 12px var(--ds-font); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ds-text-tertiary); }
.ds-settings h3 svg, .ds-settings .ds-set-h svg { width: 18px; height: 18px; color: var(--ds-text-secondary); }
.ds-set-cards { display: grid; gap: 8px; grid-template-columns: repeat(4, minmax(0, 1fr)); }   /* minmax(0): a track never grows past its share of the 334px content box */
.ds-set-cards--theme { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ds-set-cards--voice { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ds-set-card { position: relative; display: grid; gap: 6px; justify-items: center; padding: 10px 8px 9px; border: 1px solid var(--ds-border-divider); border-radius: 10px; background: var(--ds-surface-subtle); color: var(--ds-text-primary); font: 500 12.5px var(--ds-font); cursor: pointer; user-select: none; transition: border-color 160ms cubic-bezier(.16,1,.3,1), transform 160ms cubic-bezier(.16,1,.3,1); }
.ds-set-card:hover { border-color: var(--ds-brand); transform: translateY(-1px); }
.ds-set-card:focus-visible { outline: 2px solid var(--ds-brand-fg); outline-offset: 2px; }
.ds-set-card[aria-checked="true"] { border-color: var(--ds-brand); box-shadow: 0 0 0 2px rgba(48, 68, 255, 0.22); }
.ds-set-card[aria-checked="true"]::after { content: ""; position: absolute; top: 6px; right: 6px; width: 16px; height: 16px; border-radius: 50%; background: var(--ds-brand) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12l5 5L20 7'/%3E%3C/svg%3E") center / 10px no-repeat; }
.ds-sw { position: relative; width: 100%; aspect-ratio: 16 / 10; border-radius: 6px; border: 1px solid var(--ds-border-divider); overflow: hidden; background: #f5f7fb; }
.ds-sw::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 30%; background: #fff; border-right: 1px solid #e7ebf2; }
.ds-sw::after { content: ""; position: absolute; left: 38%; right: 12%; top: 28%; height: 8px; border-radius: 4px; background: #3044ff; box-shadow: 0 16px 0 -2px #dfe4ee, 0 30px 0 -2px #dfe4ee; }
.ds-sw--dark { background: #1f1f1f; } .ds-sw--dark::before { background: #181818; border-color: #2b2b2b; } .ds-sw--dark::after { box-shadow: 0 16px 0 -2px #313131, 0 30px 0 -2px #313131; }
.ds-sw--system { background: linear-gradient(100deg, #f5f7fb 50%, #1f1f1f 50%); } .ds-sw--system::before { background: linear-gradient(100deg, #fff 50%, #181818 50%); border-color: transparent; } .ds-sw--system::after { box-shadow: 0 16px 0 -2px #cfd6e4, 0 30px 0 -2px #cfd6e4; }
.ds-aa { height: 40px; display: grid; place-items: center; font-family: var(--ds-font-display, "Poppins", var(--ds-font)); font-weight: 600; color: var(--ds-text-primary); line-height: 1; }
.ds-set-cards--voice .ds-set-card { display: flex; align-items: center; gap: 8px; padding: 10px 8px; min-width: 0; justify-items: start; text-align: left; }
.ds-set-cards--voice .ds-set-card[aria-checked="true"]::after { display: none; }
.ds-av { flex: none; display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%; color: #fff; font: 600 11px var(--ds-font); }
.ds-av--au { background: linear-gradient(135deg, #19b3a6, #3044ff); } .ds-av--us { background: linear-gradient(135deg, #7c5cff, #3044ff); }
.ds-set-card[aria-checked="true"] .ds-av { box-shadow: 0 0 0 2px var(--ds-surface-raised), 0 0 0 4px var(--ds-brand); }
.ds-vn { flex: 1; min-width: 0; } .ds-vn b { display: block; font-weight: 500; font-size: 13px; color: var(--ds-text-primary); } .ds-vn span { display: block; font-size: 11px; color: var(--ds-text-tertiary); }
.ds-voice-sample { flex: none; display: grid; place-items: center; width: 30px; height: 30px; padding: 0; border: 1px solid var(--ds-border-divider); border-radius: 50%; background: var(--ds-surface-raised); color: var(--ds-text-secondary); cursor: pointer; }
.ds-voice-sample:hover { border-color: var(--ds-brand); color: var(--ds-brand-fg); } .ds-voice-sample svg { width: 12px; height: 12px; }
.ds-settings .ds-keys-link { padding-top: 12px; }

/* G1 art (Task 7c): inline SVG rendered at build time; the viewBox is the drawing size, CSS sets the box. */
.ds-art { display: block; width: 100%; height: 100%; }
.ds-hero:has(.ds-art) { display: block; height: 220px; max-height: none; padding: 0; overflow: hidden; background: none; border: 1px solid var(--ds-border-subtle); }
@media (max-width: 700px) { .ds-hero:has(.ds-art) { height: 160px; } }
.ds-door { overflow: hidden; }
.ds-door-art { margin: -24px -24px 4px; }
/* Card art bands (doors, What's New, Getting Started): an integer-height box whose own border-bottom is the divider,
   so the art always meets it and adjacent bands end on the same pixel (Shane, 31 October 2026). */
.ds-door-art, .ds-card-art { display: block; box-sizing: content-box; height: 150px; overflow: hidden; border: 0; border-bottom: 1px solid var(--ds-border-subtle); border-radius: calc(var(--ds-r-card) - 1px) calc(var(--ds-r-card) - 1px) 0 0; }
.ds-door-art > svg, .ds-card-art > svg, .ds-door-art .ds-art, .ds-card-art .ds-art { display: block; width: 100%; height: 150px; }
.ds-ai-callout:has(.ds-callout-art) { grid-template-columns: 200px minmax(0, 1fr); align-items: center; padding: 0 16px 0 0; overflow: hidden; }
.ds-callout-art { display: block; width: 200px; height: 88px; }
@media (max-width: 520px) { .ds-ai-callout:has(.ds-callout-art) { grid-template-columns: 120px minmax(0, 1fr); } .ds-callout-art { width: 120px; } }
/* Art motion: seeded per-fragment entrances (G1.MOVES), once, inside 1000ms, never under reduced motion. */
/* art-motion:start (generated by G1.css, scripts/art_g1.py sync_css) */
.g1-frag{transform-box:fill-box;transform-origin:center}[data-move="unfold"]{transform-origin:center top}[data-move="fill"]{transform-origin:left center}[data-move="sweep"]{transform-origin:left top}@media (prefers-reduced-motion:no-preference){.ds-art-anim .g1-frag{animation:g1m-fade var(--t,420ms) cubic-bezier(.2,.7,.3,1) var(--d,0ms) both}.ds-art-anim [data-move="slide-left"]{animation-name:g1m-slide-left}.ds-art-anim [data-move="slide-right"]{animation-name:g1m-slide-right}.ds-art-anim [data-move="slide-top"]{animation-name:g1m-slide-top}.ds-art-anim [data-move="slide-bottom"]{animation-name:g1m-slide-bottom}.ds-art-anim [data-move="fade"]{animation-name:g1m-fade}.ds-art-anim [data-move="pop"]{animation-name:g1m-pop}.ds-art-anim [data-move="drop"]{animation-name:g1m-drop}.ds-art-anim [data-move="rise"]{animation-name:g1m-rise}.ds-art-anim [data-move="rotate"]{animation-name:g1m-rotate}.ds-art-anim [data-move="draw"]{animation-name:g1m-draw}.ds-art-anim [data-move="fill"]{animation-name:g1m-fill}.ds-art-anim [data-move="sweep"]{animation-name:g1m-sweep}.ds-art-anim [data-move="unfold"]{animation-name:g1m-unfold}.ds-art-anim [data-move="step"]{animation-name:g1m-step}.ds-art-anim [data-move="pop"],.ds-art-anim [data-move="drop"]{animation-timing-function:cubic-bezier(.3,.7,.4,1)}.ds-art-anim [data-move="step"]{animation-timing-function:steps(1,end)}.ds-art-anim [data-move="draw"]>:first-child{stroke-dasharray:1;animation:g1m-dash var(--t,420ms) ease-out var(--d,0ms) both}.ds-art-anim .g1-fade,.ds-art-anim .ds-art-fade{animation:g1m-fade 420ms cubic-bezier(.2,.7,.3,1) var(--d,0ms) both}.ds-art-anim .g1-dot{animation:g1m-fade 300ms ease-out var(--d,0ms) both}.ds-art-anim .g1-part{animation:g1m-rise 300ms cubic-bezier(.2,.7,.3,1) var(--d,0ms) both;transform-box:fill-box;transform-origin:center}.ds-art-anim[data-entrance="fill"] .g1-fill{animation:g1s-fill 450ms 350ms cubic-bezier(.2,.7,.3,1) both;transform-box:fill-box;transform-origin:left center}.ds-art-anim[data-entrance="fill"] .g1-grow{animation:g1s-grow 450ms 300ms cubic-bezier(.2,.7,.3,1) both;transform-box:fill-box;transform-origin:center bottom}.ds-art-anim[data-entrance="tick"] .g1-tick{stroke-dasharray:1;animation:g1s-tick 380ms 420ms ease-out both}.ds-art-anim[data-entrance="sweep"] .g1-sweep{animation:g1s-sweep 600ms 250ms cubic-bezier(.2,.7,.3,1) both}.ds-art-anim[data-entrance="travel"] .g1-travel{animation:g1s-travel 520ms 320ms cubic-bezier(.2,.7,.3,1) both}.ds-art-anim[data-entrance="blink"] .g1-cursor{animation:g1s-blink 840ms steps(1,end) both}.ds-art-anim[data-entrance="twinkle"] .g1-star{animation:g1s-twinkle 560ms 300ms ease-out both;transform-box:fill-box;transform-origin:center}}@keyframes g1m-slide-left{from{opacity:0;transform:translateX(-16px)}}@keyframes g1m-slide-right{from{opacity:0;transform:translateX(16px)}}@keyframes g1m-slide-top{from{opacity:0;transform:translateY(-14px)}}@keyframes g1m-slide-bottom{from{opacity:0;transform:translateY(14px)}}@keyframes g1m-fade{from{opacity:0}}@keyframes g1m-pop{0%{opacity:0;transform:scale(.85)}65%{opacity:1;transform:scale(1.03)}100%{transform:scale(1)}}@keyframes g1m-drop{0%{opacity:0;transform:translateY(-18px)}60%{opacity:1;transform:translateY(3px)}80%{transform:translateY(-1px)}100%{transform:none}}@keyframes g1m-rise{from{opacity:0;transform:translateY(10px) scale(.98)}}@keyframes g1m-rotate{from{opacity:0;transform:rotate(-6deg) scale(.97)}}@keyframes g1m-draw{0%{opacity:.25}100%{opacity:1}}@keyframes g1m-dash{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}@keyframes g1m-fill{from{opacity:.2;transform:scaleX(0)}}@keyframes g1m-sweep{from{opacity:0;transform:rotate(-8deg) scale(.6)}}@keyframes g1m-unfold{from{opacity:0;transform:scaleY(0)}}@keyframes g1m-step{0%{opacity:0}100%{opacity:1}}@keyframes g1s-fill{from{transform:scaleX(0)}}@keyframes g1s-grow{from{transform:scaleY(0)}}@keyframes g1s-tick{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}@keyframes g1s-sweep{from{stroke-dashoffset:var(--len)}to{stroke-dashoffset:0}}@keyframes g1s-travel{from{transform:translate(var(--tx),var(--ty));opacity:0}20%{opacity:1}}@keyframes g1s-blink{0%,50%{opacity:0}25%,75%,100%{opacity:1}}@keyframes g1s-twinkle{0%{opacity:0;transform:scale(.3)}60%{opacity:1;transform:scale(1.25)}100%{transform:scale(1)}}
/* art-motion:end */

/* Motion system (Task 7c): the Migration Tool easing and three durations. One reduced-motion rule turns it all off. */
:root { --ds-dur-fast: 120ms; --ds-dur-base: 200ms; --ds-dur-slow: 320ms; interpolate-size: allow-keywords; }
@view-transition { navigation: auto; }
.ds-main > .ds-card, .ds-main > .ds-home { view-transition-name: ds-card; }
.ds-toc { view-transition-name: ds-toc; }
/* Navigation: an opacity-only cross-fade of the card and the contents, 160ms; nothing else takes part (Shane). */
::view-transition-group(ds-card), ::view-transition-group(ds-toc) { animation-duration: 160ms; animation-timing-function: var(--ds-ease); }
::view-transition-old(ds-card), ::view-transition-old(ds-toc) { animation: ds-vt-out 160ms var(--ds-ease) both; }
::view-transition-new(ds-card), ::view-transition-new(ds-toc) { animation: ds-vt-in 160ms var(--ds-ease) both; }
/* The sidebar, docs menu and top bar have their own stable names, so a navigation keeps them exactly where they are. */
.ds-rail { view-transition-name: ds-rail; }
.ds-tree { view-transition-name: ds-tree; }
.ds-topbar { view-transition-name: ds-top; }
::view-transition-group(ds-rail), ::view-transition-group(ds-tree), ::view-transition-group(ds-top),
::view-transition-old(ds-rail), ::view-transition-old(ds-tree), ::view-transition-old(ds-top),
::view-transition-new(ds-rail), ::view-transition-new(ds-tree), ::view-transition-new(ds-top) { animation: none; }
::view-transition-old(ds-rail), ::view-transition-old(ds-top) { display: none; }
/* The docs menu keeps its old snapshot under the new one until the new one paints, so nothing flashes; both have the same shape, because the new page's state is settled before its first paint. */
::view-transition-old(root), ::view-transition-new(root) { animation: none; }
::view-transition-group(root) { animation: none; }
@keyframes ds-vt-out { to { opacity: 0; } }
@keyframes ds-vt-in { from { opacity: 0; } }
.ds-rail-item, .ds-tree :is(li, .ds-tree-row) > a, .ds-flyout-link, .ds-toc a { transition: background-color var(--ds-dur-base) var(--ds-ease), color var(--ds-dur-base) var(--ds-ease), transform var(--ds-dur-fast) var(--ds-ease), border-color var(--ds-dur-base) var(--ds-ease); }
.ds-tree ul ul.is-opening { overflow: hidden; animation: ds-branch var(--ds-dur-slow) var(--ds-ease); }
@keyframes ds-branch { from { height: 0; opacity: 0; } to { height: auto; opacity: 1; } }
.ds-flyout.is-open .ds-flyout-panel.is-on li { animation: ds-rise var(--ds-dur-base) var(--ds-ease) both; }
.ds-flyout.is-open li:nth-child(2) { animation-delay: 20ms; }
.ds-flyout.is-open li:nth-child(3) { animation-delay: 40ms; }
.ds-flyout.is-open li:nth-child(4) { animation-delay: 60ms; }
.ds-flyout.is-open li:nth-child(5) { animation-delay: 80ms; }
.ds-flyout.is-open li:nth-child(6) { animation-delay: 100ms; }
.ds-flyout.is-open li:nth-child(7) { animation-delay: 120ms; }
.ds-flyout.is-open li:nth-child(8) { animation-delay: 140ms; }
.ds-flyout.is-open li:nth-child(9) { animation-delay: 160ms; }
.ds-flyout.is-open li:nth-child(10) { animation-delay: 180ms; }
@keyframes ds-rise { from { opacity: 0; transform: translateY(6px); } }
.ds-flyout-link .ds-mtile { transition: transform var(--ds-dur-fast) var(--ds-ease), box-shadow var(--ds-dur-fast) var(--ds-ease); }
.ds-flyout-link:hover .ds-mtile { transform: translateY(-1px); box-shadow: 0 4px 10px -6px rgba(20, 28, 50, 0.35); color: var(--ds-text-primary); }
.ds-toc a:hover { transform: translateX(2px); }
.ds-btn, .ds-drawer-more :is(a, button) { transition: transform var(--ds-dur-fast) var(--ds-ease), background-color var(--ds-dur-base) var(--ds-ease); }
.ds-btn:hover, .ds-drawer-more :is(a, button):hover { transform: scale(1.02); }
.ds-chapter-card, .ds-door, .ds-ai-callout { transition: transform var(--ds-dur-base) var(--ds-ease), box-shadow var(--ds-dur-base) var(--ds-ease), border-color var(--ds-dur-base) var(--ds-ease); }

.ds-prose a:not([class]) { text-decoration: none; background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat; transition: background-size var(--ds-dur-base) var(--ds-ease); box-shadow: inset 0 -1px color-mix(in srgb, currentColor 35%, transparent); }
.ds-prose a:not([class]):hover { background-size: 100% 1px; }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after, ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation-duration: 0s !important; animation-iteration-count: 1 !important; animation-delay: 0s !important; transition-duration: 0s !important; transition-delay: 0s !important; } }

/* Focus (Shane, 1 November 2026): no browser outline and no big ring on anything. Keyboard focus only
   (:focus-visible, never :focus) shows a quiet 1px brand edge and a 2px brand-subtle halo; a mouse click shows
   nothing beyond the hover state. Text fields take the edge as their border, so their halo is the whole 2px. */
:focus, :focus-visible { outline: none !important; }
:focus:not(:focus-visible) { box-shadow: none; }
:focus-visible { box-shadow: 0 0 0 1px var(--ds-brand), 0 0 0 3px var(--ds-brand-subtle); }
:is(.ds-input, .ds-select, .ds-search input, textarea, input[type=text], input[type=search], input[type=email]):focus-visible { border-color: var(--ds-brand); box-shadow: 0 0 0 2px var(--ds-brand-subtle); }
:is(.ds-input, .ds-select, textarea, input):focus:not(:focus-visible) { box-shadow: none; }
input[type=radio]:focus-visible, input[type=checkbox]:focus-visible { box-shadow: 0 0 0 1px var(--ds-brand), 0 0 0 3px var(--ds-brand-subtle); }

/* Previous and next: a 16px chevron that moves 2px in its direction on hover. */
.ds-chev { display: inline-block; width: 16px; height: 16px; vertical-align: -3px; transition: transform var(--ds-dur-fast) var(--ds-ease); }
.ds-pager-link span, [data-step-prev], [data-step-next] { display: inline-flex; align-items: center; gap: 4px; }
.ds-pager-link.is-next span { justify-content: flex-end; }
:is(.ds-pager-link.is-prev, [data-step-prev]):hover:not(:disabled) .ds-chev { transform: translateX(-2px); }
:is(.ds-pager-link.is-next, [data-step-next]):hover:not(:disabled) .ds-chev { transform: translateX(2px); }

/* Row hover, ported from the IIA admin rail (a.iia-rail-item__link): text and icon brighten together, the
   background fades in, 150ms on cubic-bezier(0, 0, .2, 1). Light: text-secondary to text-primary over brand-subtle. */
:root { --ds-ease-row: cubic-bezier(0, 0, 0.2, 1); }
.ds-rail-item, .ds-tree :is(li, .ds-tree-row) > a, .ds-flyout-link, .mi-panel li { transition: color 0.15s var(--ds-ease-row), background-color 0.15s var(--ds-ease-row), padding 0.2s var(--ds-ease-row); }
.ds-rail-item:not(.is-active):hover, .ds-tree :is(li, .ds-tree-row) > a:not([aria-current]):hover, .ds-flyout-link:hover, .mi-panel li:hover { background: var(--ds-brand-subtle); color: var(--ds-text-primary); }
.ds-rail-item:hover svg, .ds-flyout-link:hover b { color: inherit; }
.ds-flyout-link .ds-mtile, .ds-chapter-card .ds-mtile, .mi-ic { transition: transform 0.15s var(--ds-ease-row), color 0.15s var(--ds-ease-row), background-color 0.15s var(--ds-ease-row), box-shadow 0.15s var(--ds-ease-row); }
.ds-flyout-link:hover .ds-mtile, a.ds-chapter-card:hover .ds-mtile, .mi-panel li:hover .mi-ic { transform: translateY(-1px); color: var(--ds-text-primary); }
.ds-flyout-link:hover .ds-mtile, a.ds-chapter-card:hover .ds-mtile { background: var(--ds-brand-subtle); }
.ds-tree-row button::before { transition: transform 0.15s var(--ds-ease-row), translate 0.15s var(--ds-ease-row); }
.ds-tree-row:hover button::before { translate: 2px 0; }
.mi-ic svg { transition: fill 0.15s var(--ds-ease-row), stroke 0.15s var(--ds-ease-row); }

/* Developers panel: three list columns; every column's intro sits under the shared header row. */
.ds-flyout:has(.ds-flyout-panel.is-on[data-flyout=developers]), .ds-flyout:has(.ds-flyout-panel.is-on[data-flyout=changelog]) { width: min(1180px, calc(100vw - var(--ds-side-w))); }   /* What's New the same size as Developers (round 4) */
.ds-flyout-panel[data-flyout=developers] .ds-flyout-main { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ds-flyout-intro { margin: -8px 0 16px; padding: 0 8px; color: var(--ds-text-secondary); font-size: 14px; line-height: 1.45; }
/* What's New */
.ds-releases { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; margin: 0 0 32px; padding: 0; list-style: none; }
.ds-release { display: flex; flex-direction: column; height: 100%; padding: 24px; overflow: hidden; border: 1px solid var(--ds-border-subtle); border-radius: var(--ds-r-card); background: var(--ds-surface-raised); color: var(--ds-text-primary); text-decoration: none; transition: transform var(--ds-dur-base) var(--ds-ease), border-color var(--ds-dur-base) var(--ds-ease); }
.ds-release:hover { transform: translateY(-2px); border-color: var(--ds-brand-border); }
.ds-release .ds-stamp { margin: 0 0 6px; }
.ds-release b { font: 600 18px/1.3 var(--ds-display); }
.ds-release-sum { margin-top: 2px; }

/* One header block per flyout column: heading row, then a two-line intro of fixed height, so every column's first link
   starts on the same line (Shane, 31 October 2026). */
.ds-flyout-feature > p, .ds-flyout-intro { display: block; overflow: visible; height: calc(2 * 1.45 * 14px);   /* no clamp: copy is written to fit (first panel one line, list panel two) */ margin: 0 0 16px !important; padding: 0 8px !important; border: 0 !important; font-size: 14px !important; line-height: 1.45 !important; color: var(--ds-text-secondary); }
.ds-flyout-feature ul, .ds-flyout-main ul { gap: 8px; padding: 0; }
.ds-card-art { margin: -24px -24px 12px; }
.ds-card-art:empty { display: none; }   /* filled by the imagery branch */
.ds-release { gap: 4px; }
.ds-release .ds-flyout-all { margin: 10px 0 0; }
.ds-home .ds-lede { line-height: 28px; }   /* integer, so the door bands below land on whole pixels */
.ds-theme-card { grid-template-columns: minmax(0, 1fr); overflow: hidden; }
.ds-theme-card .ds-card-art { box-sizing: border-box; height: 96px; margin: -16px -16px 4px; }   /* 95px of art plus the 1px divider */
.ds-theme-card .ds-card-art .ds-art { height: 95px; }

/* Flyout art (Getting Started themes, What's New): small G1 bands from the shared sprite assets/menu-art.svg. */
.ds-flyout-link:has(.ds-menu-art) { grid-template-columns: 120px minmax(0, 1fr); align-items: center; }
.ds-menu-art { display: block; width: 120px; height: 56px; overflow: hidden; border: 1px solid var(--ds-border-subtle); border-radius: var(--ds-r-button); }
.ds-menu-art svg, .ds-menu-hero svg, .ds-menu-art use, .ds-menu-hero use { display: block; width: 100%; height: 100%; }
.ds-menu-hero { display: block; height: 117px; margin: -28px -16px 20px; overflow: hidden; border-bottom: 1px solid var(--ds-border-subtle); }
.ds-wn-latest { margin: 0 0 8px; padding: 0 8px; font: 600 12px var(--ds-font); letter-spacing: 0.04em; text-transform: uppercase; color: var(--ds-text-tertiary); }
.ds-flyout-link:not(:has(.ds-menu-art, .ds-mtile)) { grid-template-columns: minmax(0, 1fr); }
/* Chapter cards: one height per row, title at most two lines, the count pinned to the bottom (Shane). */
.ds-cards { grid-auto-rows: auto; }   /* each row as tall as its tallest card; cards stretch within the row */
.ds-cards > li { display: flex; min-width: 0; }
.ds-cards > li > .ds-chapter-card { flex: 1; min-width: 0; }
.ds-chapter-card > div { display: flex; flex-direction: column; min-width: 0; }
.ds-chapter-card > div > b { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.ds-chapter-card > div > span { margin-top: auto; padding-top: 2px; }

/* Form controls, defined once and used everywhere (feedback, wizard, settings, search, the style reference). */
.ds-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 36px; padding: 0 16px; border: 1px solid var(--ds-border-divider); border-radius: var(--ds-r-button); background: var(--ds-surface-raised); color: var(--ds-text-primary); font: 600 14px/1 var(--ds-font); white-space: nowrap; cursor: pointer; transition: background-color 0.15s cubic-bezier(0, 0, 0.2, 1), border-color 0.15s cubic-bezier(0, 0, 0.2, 1), color 0.15s cubic-bezier(0, 0, 0.2, 1); }
.ds-btn:hover:not(:disabled) { border-color: var(--ds-border-default); }
.ds-btn--primary, .ds-btn.is-primary { border-color: var(--ds-brand); background: var(--ds-brand); color: #fff; }
.ds-btn--primary:hover:not(:disabled), .ds-btn.is-primary:hover:not(:disabled) { border-color: var(--ds-brand-emphasis); background: var(--ds-brand-emphasis); }
.ds-btn--ghost { border-radius: 999px; background: none; color: var(--ds-text-secondary); }
.ds-btn--ghost:hover:not(:disabled) { background: var(--ds-brand-subtle); color: var(--ds-text-primary); }
.ds-btn--ghost[aria-pressed="true"] { border-color: var(--ds-brand-border); background: var(--ds-brand-subtle); color: var(--ds-brand-fg); }
.ds-btn:disabled { opacity: 0.45; cursor: default; }
.ds-input, .ds-select { height: 36px; padding: 0 10px; border: 1px solid var(--ds-border-divider); border-radius: var(--ds-r-input); background: var(--ds-surface-raised); color: var(--ds-text-primary); font: 14px var(--ds-font); transition: border-color 0.15s cubic-bezier(0, 0, 0.2, 1); }
.ds-input::placeholder { color: var(--ds-text-subtle); }
.ds-input:hover, .ds-select:hover { border-color: var(--ds-border-default); }
/* Select: ours when closed (same height and border as an input, the sprite chevron); the open list stays native. */
.ds-select-wrap { position: relative; display: inline-flex; align-items: center; }
.ds-select { appearance: none; -webkit-appearance: none; padding-right: 32px; background: var(--ds-surface-raised); color-scheme: inherit; cursor: pointer; }
.ds-select-wrap .ds-select { width: 100%; }
.ds-select-wrap > svg { position: absolute; right: 10px; width: 16px; height: 16px; color: var(--ds-text-tertiary); pointer-events: none; }
.ds-select-wrap:hover > svg { color: var(--ds-text-primary); }
.ds-field { display: grid; gap: 6px; font-size: 14px; color: var(--ds-text-secondary); }

/* What's New flyout: one calm 560px panel, the same family as the others but lighter. */
.ds-flyout-panel.ds-wn.is-on { display: block; }
.ds-wn-thumb svg, .ds-wn-thumb use { display: block; width: 100%; height: 100%; }
.ds-wn-body { padding: 20px 16px 24px; }
.ds-wn-body h2 { margin: 0 8px 4px; font: 600 19px/1.3 var(--ds-display); color: var(--ds-text-primary); }
.ds-wn-intro { margin: 0 8px 20px; color: var(--ds-text-secondary); font-size: 14px; }
.ds-wn-latest { margin: 0 8px 6px; font: 600 12px var(--ds-font); letter-spacing: 0.04em; text-transform: uppercase; color: var(--ds-text-tertiary); }
.ds-wn ul { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }
.ds-flyout-link.ds-wn-row { grid-template-columns: 96px minmax(0, 1fr) 16px; align-items: start; gap: 16px; padding: 12px 8px; }
.ds-wn-row .ds-chev { align-self: center; }
.ds-wn-thumb { display: block; width: 96px; height: 64px; overflow: hidden; border: 1px solid var(--ds-border-subtle); border-radius: 6px; }
.ds-wn-row b { display: inline; font: 600 14px var(--ds-display); }
.ds-wn-row .ds-wn-meta { display: inline; margin: 0 0 0 6px; font-size: 12px; color: var(--ds-text-tertiary); }
.ds-wn-row .ds-wn-sum { display: block; margin-top: 4px; font-size: 13px; line-height: 1.5; color: var(--ds-text-secondary); }
.ds-wn .ds-chev { color: var(--ds-text-tertiary); transition: transform 0.15s cubic-bezier(0, 0, 0.2, 1); }
.ds-wn .ds-flyout-link:hover .ds-chev { transform: translateX(2px); color: var(--ds-text-primary); }
.ds-flyout-link.ds-wn-all { grid-template-columns: minmax(0, 1fr) 16px; align-items: center; margin-top: 12px; padding-top: 14px; border-top: 1px solid var(--ds-border-subtle); border-radius: 0 0 var(--ds-r-button) var(--ds-r-button); }
.ds-wn-all b { font: 600 14px var(--ds-display); }

/* Flyout alignment (Shane): a badge sits inline after its title; Getting Started's two panels are equal and wide enough. */
.ds-flyout-link b .ds-badge { display: inline-block; margin-top: 0; }
.ds-flyout:has(.ds-flyout-panel.is-on[data-flyout=getting-started]) { width: min(1000px, calc(100vw - var(--ds-side-w))); }
.ds-flyout-panel[data-flyout=getting-started].is-on { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
/* DS-46 (Shane, 2 November 2026): Resources is the Getting Started layout in ONE column: art beside a title and a line. */
.ds-flyout:has(.ds-flyout-panel.is-on[data-flyout=resources]) { width: min(500px, calc(100vw - var(--ds-side-w))); }
.ds-flyout-panel[data-flyout=resources].is-on { grid-template-columns: minmax(0, 1fr); }

/* Search: pinned to the centre of the top bar, the same x on every page; the breadcrumb gives way, never the search. */
.ds-topbar { position: sticky; }
.ds-topbar .ds-search-wrap { position: absolute; top: 10px; left: 50%; width: 420px; max-width: calc(100% - 40px); transform: translateX(-50%); }
.ds-topbar .ds-search-wrap .ds-search { width: 100%; }
.ds-crumbs-wrap { max-width: calc(50% - 230px); overflow: hidden; }
.ds-crumbs-wrap ol { flex-wrap: nowrap; }
.ds-crumbs-wrap li { white-space: nowrap; }
.ds-crumbs-wrap li:last-child { overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 859.98px) { .ds-topbar .ds-search-wrap { position: static; width: auto; transform: none; } .ds-crumbs-wrap { max-width: none; } }

/* Getting Started theme cards: title top-aligned under the fixed art band, description straight after it. */
.ds-theme-card { align-content: start; }
.ds-theme-card > div > span { margin-top: 2px; }
.ds-theme-card > div > b { -webkit-line-clamp: unset; display: block; }
/* A long list under one heading: Instance modules as a two-column grid. */
.ds-flyout-panel[data-flyout=instance] .ds-flyout-main { grid-template-columns: minmax(0, 1fr); }
.ds-flyout-panel[data-flyout=instance] .ds-flyout-main section > ul { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 16px; }
/* What's New flyout: the six latest releases as cards in two rows of three; no banner above (Shane, 1 November 2026). */
.ds-wn ul.ds-wn-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px 16px; }
.ds-flyout-link.ds-wn-card { display: flex; flex-direction: column; gap: 8px; height: 100%; padding: 8px; }
.ds-wn-card .ds-wn-thumb { width: 100%; height: 140px; }
.ds-wn-card .ds-wn-meta { margin: 0; }
.ds-wn-card .ds-wn-sum { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; margin-top: 2px; }

/* What's New page: the flyout's layout at page size (Shane, 1 November 2026). */
.ds-whatsnew h1 { margin-bottom: 6px; }
.ds-wn-lede { margin: 0 0 28px; color: var(--ds-text-secondary); }
.ds-whatsnew .ds-wn-latest { margin: 0 0 12px; padding: 0; }
.ds-whatsnew .ds-releases { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; margin: 0 0 24px; }
.ds-whatsnew .ds-release { padding: 0; border: 0; background: none; border-radius: 0; gap: 2px; }
.ds-whatsnew .ds-release:hover { transform: none; }
.ds-whatsnew .ds-release .ds-card-art { margin: 0 0 12px; height: 140px; border: 1px solid var(--ds-border-subtle); border-radius: 8px; }
.ds-whatsnew .ds-release .ds-card-art .ds-art { height: 140px; }
.ds-whatsnew .ds-release .ds-card-art:empty { display: block; }   /* hold the 140px while the art is drawn, so the cards never shift (CLS 0) */
.ds-whatsnew .ds-release b { font: 600 17px/1.3 var(--ds-display); }
.ds-whatsnew .ds-release .ds-stamp { margin: 0; }
.ds-whatsnew .ds-release-sum { margin: 4px 0 0; font-size: 14px; line-height: 1.5; color: var(--ds-text-secondary); display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 8; overflow: hidden; }   /* DS-52: whole sentences up to 320 characters, full width; clamped only if they truly overflow */
.ds-wn-allrel { border-top: 1px solid var(--ds-border-subtle); }
.ds-wn-allrel summary { display: flex; align-items: center; justify-content: space-between; padding: 16px 0; cursor: pointer; list-style: none; }
.ds-wn-allrel summary::-webkit-details-marker { display: none; }
.ds-wn-allrel summary b { font: 600 16px var(--ds-display); }
.ds-wn-allrel summary .ds-chev { color: var(--ds-text-tertiary); transition: transform var(--ds-dur-base) var(--ds-ease); }
.ds-wn-allrel[open] summary .ds-chev { transform: rotate(90deg); }
@media (max-width: 900px) { .ds-whatsnew .ds-releases { grid-template-columns: minmax(0, 1fr); } }

/* Card rows (Shane, 1 November 2026): one rule for the home doors, chapter cards, Getting Started cards and
   What's New cards. A soft 1px border, no shadow at rest; on hover a 1px lift and a very soft shadow only. */
:is(.ds-chapter-card, .ds-door, .ds-ai-callout, .ds-whatsnew .ds-release) { border: 1px solid var(--ds-border-subtle); background: var(--ds-surface-raised); box-shadow: none; transition: transform var(--ds-dur-base) var(--ds-ease), box-shadow var(--ds-dur-base) var(--ds-ease); }
:is(a.ds-chapter-card, .ds-door, .ds-ai-callout, .ds-whatsnew .ds-release):hover { transform: translateY(-1px); border-color: var(--ds-border-subtle); box-shadow: 0 4px 12px -6px rgba(20, 28, 50, 0.14); }
.ds-whatsnew .ds-release { overflow: hidden; border-radius: var(--ds-r-card); padding: 0 16px 16px; }
.ds-whatsnew .ds-release .ds-card-art { margin: 0 -16px 12px; border: 0; border-bottom: 1px solid var(--ds-border-subtle); border-radius: 0; }
.ds-card-before { box-shadow: 0 10px 24px -12px rgba(20, 28, 50, 0.28), inset 0 -3px 0 var(--ds-border-default) !important; border-color: var(--ds-border-default) !important; }

/* Skip link: the first focusable element, shown only on focus. */
.ds-skip { position: fixed; z-index: 200; left: 12px; top: 8px; padding: 8px 14px; border-radius: var(--ds-r-button); background: var(--ds-brand); color: #fff; font: 600 14px var(--ds-font); text-decoration: none; transform: translateY(-160%); }
.ds-skip:focus-visible { transform: none; }
.ds-main:focus { outline: none; box-shadow: none; }

/* Empty and error states: quiet text, never an empty box. */
.ds-empty-state, .ds-asof { color: var(--ds-text-secondary); font-size: 14px; }
.ds-empty-state { padding: 16px; border: 1px dashed var(--ds-border-default); border-radius: var(--ds-r-card); }
.ds-asof { margin: -20px 0 24px; font-size: 13px; }
.ds-notfound .ds-doors { margin-top: 24px; }

/* Loading: a shimmer under every art slot until its drawing paints over it; skeletons only while a link navigates
   (body.is-navigating, set by shell.js on a click), never on a full load. Reduced motion: static grey. */
:is(.ds-hero, .ds-door-art, .ds-card-art, .ds-step-art, .ds-callout-art, .ds-menu-art, .ds-wn-thumb) { background: var(--ds-surface-subtle) linear-gradient(100deg, transparent 30%, color-mix(in srgb, var(--ds-surface-raised) 70%, transparent) 50%, transparent 70%) 0 0 / 200% 100%; }
@media (prefers-reduced-motion: no-preference) {
  :is(.ds-hero, .ds-door-art, .ds-card-art, .ds-step-art, .ds-callout-art, .ds-menu-art, .ds-wn-thumb):not(:has(svg)) { animation: ds-shimmer 1.2s linear infinite; }
  body.is-navigating .ds-skel { animation: ds-shimmer 1.2s linear infinite; }
}
@keyframes ds-shimmer { to { background-position: -200% 0; } }
.ds-skel { display: none; }
body.is-navigating .ds-skel { display: block; position: absolute; inset: 0; z-index: 5; padding: 40px 48px; background: var(--ds-surface-raised); border-radius: inherit; }
body.is-navigating .ds-skel i { display: block; height: 14px; margin: 0 0 14px; border-radius: 7px; background: var(--ds-surface-subtle) linear-gradient(100deg, transparent 30%, color-mix(in srgb, var(--ds-surface-raised) 70%, transparent) 50%, transparent 70%) 0 0 / 200% 100%; }
body.is-navigating .ds-skel i:first-child { width: 40%; height: 28px; margin-bottom: 24px; }
/* The tree skeleton is a ghost of the tree it covers: the same grey-blue surface, and one white bar where each visible
   menu item sits (shell.js measures them at click time), so the swap to the next page's tree barely moves. */
body.is-navigating .ds-tree .ds-skel { padding: 0; background: var(--ds-surface-base); }
body.is-navigating .ds-tree .ds-skel i { position: absolute; margin: 0; height: 14px; border-radius: 7px; background: var(--ds-surface-raised); animation: none; }
body.is-navigating .ds-tree .ds-skel i:first-child { height: 16px; }
body.is-navigating :is(.ds-main > .ds-card, .ds-main > .ds-home, .ds-tree) { position: relative; }
.ds-state-demo { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 16px; align-items: start; }
.ds-state-demo .ds-state-art { margin: 0; height: 96px; border: 1px solid var(--ds-border-subtle); border-radius: 8px; }
.ds-skel.ds-skel-demo { display: block; position: static; padding: 0; }
.ds-skel-demo i { display: block; height: 14px; margin: 0 0 12px; border-radius: 7px; background: var(--ds-surface-subtle); }
.ds-skel-demo i:first-child { width: 40%; height: 24px; }
.ds-asof.ds-asof-demo { margin: 0 0 12px; }
@media (max-width: 520px) { .ds-state-demo { grid-template-columns: minmax(0, 1fr); } }

/* What's New, round 5 (Shane, 1 November 2026): six cards, the promo banner, the product filter, the release page and
   the entrance gate. The gate holds the card and art entrances until a second after the page has fully loaded
   (WN_GATE in render.py and ds/whatsnew_cards); without JS or under reduced motion there is no gate at all. */
.ds-release-link { display: block; height: 100%; color: inherit; text-decoration: none; border-radius: var(--ds-r-card); }
.ds-release-link:hover .ds-release { transform: translateY(-2px); border-color: var(--ds-brand-border); }
.ds-releases { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 1100px) { .ds-releases { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .ds-releases { grid-template-columns: minmax(0, 1fr); } }
@media (prefers-reduced-motion: no-preference) {
  .ds-wn-wait .ds-release { opacity: 0; }
  .ds-wn-wait .g1-art *, .ds-wn-wait .ds-art * { animation-play-state: paused !important; }
  .ds-wn-go .ds-release { animation: ds-rise var(--ds-dur-slow) var(--ds-ease) both; }
  .ds-wn-go li:nth-child(2) > a > .ds-release { animation-delay: 60ms; }
  .ds-wn-go li:nth-child(3) > a > .ds-release { animation-delay: 120ms; }
  .ds-wn-go li:nth-child(4) > a > .ds-release { animation-delay: 180ms; }
  .ds-wn-go li:nth-child(5) > a > .ds-release { animation-delay: 240ms; }
  .ds-wn-go li:nth-child(6) > a > .ds-release { animation-delay: 300ms; }
}
/* The promo banner is the page header of What's New (Shane, 1 November 2026). Text top left, art top right, the
   feature items in one row across the bottom. Its motion is a recorded exception to DS-14 and DS-17
   (docs/DESIGN-EXCLUSIONS.yml): a staggered rise of the text and items on load, then a soft highlight that moves from
   item to item. Only opacity and transform animate, so nothing reflows (CLS 0), and the highlight is a layer behind
   the text, so no words move while someone reads them. Reduced motion: no animation, the final state shows. */
/* Promotional banner (PB-01..PB-10; Variant B, chosen by Shane 1 November 2026): the page header of /change-log, flush
   to the top of the card and its full width, and the top of the What's New mega-menu panel. Near-black promo surface
   with a blue glow and a perspective grid floor; the stage is tilted into the floor and drifts slowly. The text never
   moves; the stage presents one feature at a time (6s each, 30s for five), cross-fading in step with the highlighted
   item, and each scene's parts enter one after another (PB-09). Scenes: prototype/scripts/promo_scenes.py. */
.ds-promo { --ds-promo-step: 6s; --n: 5; --ds-promo-cycle: calc(var(--n) * var(--ds-promo-step)); position: relative; isolation: isolate; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); grid-template-areas: "text art" "feats feats"; align-items: center; margin: -40px -48px 32px; overflow: hidden; border-bottom: 1px solid var(--ds-surface-promo-edge); border-radius: calc(var(--ds-r-card) - 1px) calc(var(--ds-r-card) - 1px) 0 0; background: radial-gradient(60% 80% at 74% 42%, rgba(48, 68, 255, 0.38), rgba(124, 92, 255, 0.12) 45%, transparent 72%), var(--ds-surface-promo); color: var(--ds-on-promo); }
.ds-promo--6 { --n: 6; }
.ds-promo { contain: layout paint; }   /* already overflow: hidden, so paint containment changes nothing visible; it keeps the loop's repaints inside the banner */
.ds-promo-floor { position: absolute; z-index: -1; right: -20%; bottom: -6%; width: 90%; height: 150%; background-image: linear-gradient(rgba(147, 180, 255, 0.16) 1px, transparent 1px), linear-gradient(90deg, rgba(147, 180, 255, 0.16) 1px, transparent 1px); background-size: 32px 32px; transform: perspective(420px) rotateX(66deg); transform-origin: 50% 100%; -webkit-mask-image: linear-gradient(to top, #000 10%, transparent 70%); mask-image: linear-gradient(to top, #000 10%, transparent 70%); pointer-events: none; }
.ds-promo-text { grid-area: text; position: relative; z-index: 1; padding: 36px 0 18px 48px; }
.ds-promo-eyebrow { display: inline-block; margin: 0 0 10px; padding: 2px 10px; border-radius: 999px; background: var(--ds-ai-gradient); color: #fff; font: 600 11px/18px var(--ds-font); letter-spacing: 0.04em; text-transform: uppercase; }
.ds-promo h2 { margin: 0 0 8px; border: 0; padding: 0; color: var(--ds-on-promo-strong); font: 600 calc(var(--ds-text) * 28 / 14)/1.2 var(--ds-display); }
.ds-promo-body { margin: 0 0 20px; max-width: 46ch; color: var(--ds-on-promo-muted); }
.ds-promo .ds-promo-cta { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; }
.ds-promo :is(.ds-promo-cta, .ds-promo-feat):focus-visible { outline: 2px solid var(--ds-on-promo-focus); outline-offset: 2px; }
.ds-promo-art { grid-area: art; align-self: stretch; position: relative; margin: 0; min-height: 270px; perspective: 1000px; }
.ds-promo-rig { position: absolute; inset: 12px 32px 8px 8px; transform-style: preserve-3d; transform: rotateY(-16deg) rotateX(8deg); will-change: transform; }
.ds-promo-scene { position: absolute; inset: 0; opacity: 0; }
.ds-promo-scene:first-child { opacity: 1; }
.ds-promo-ill { display: block; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(-14px 22px 18px rgba(0, 0, 0, 0.6)); }
.ds-promo-cap { display: none; color: var(--ds-on-promo-strong); font: 600 12px/18px var(--ds-font); text-align: center; }
.ds-promo-feats { grid-area: feats; position: relative; z-index: 1; display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin: 0; padding: 6px 48px 28px; list-style: none; }
.ds-promo-feats li { margin: 0; padding: 0; }
.ds-promo-badges { display: block; margin-top: 6px; font-style: normal; font-size: 0.86em; color: var(--ds-on-promo); opacity: 0.85; }   /* round 9 G */
.ds-promo-badges .ds-badge { display: inline-block; margin-left: 4px; font-size: 11px; line-height: 16px; }
.ds-promo-feat { position: relative; display: block; height: 100%; padding: 12px 14px; border: 1px solid rgba(255, 255, 255, 0.12); border-radius: 10px; background: rgba(255, 255, 255, 0.04); color: var(--ds-on-promo); text-decoration: none; transition: border-color var(--ds-dur-base) var(--ds-ease), background-color var(--ds-dur-base) var(--ds-ease); }
.ds-promo-feat::before { content: ""; position: absolute; inset: -1px; border: 1px solid #93b4ff; border-radius: inherit; box-shadow: 0 0 0 3px rgba(124, 92, 255, 0.18), inset 0 0 24px rgba(124, 92, 255, 0.18); opacity: 0; pointer-events: none; }
.ds-promo-feat > * { position: relative; z-index: 1; }
.ds-promo-feat b { display: block; margin: 0 0 2px; color: var(--ds-on-promo-strong); font: 600 14px/20px var(--ds-font); }
.ds-promo-feat span { display: block; color: var(--ds-on-promo-muted); font-size: 13px; line-height: 18px; }
.ds-promo-feat:hover { border-color: rgba(255, 255, 255, 0.32); background: rgba(255, 255, 255, 0.08); }
.ds-promo-feat:hover b { text-decoration: underline; text-underline-offset: 3px; }
.ds-promo :is(.sc-pop, .sc-fill) { transform-box: fill-box; }
.ds-promo .sc-pop { transform-origin: 50% 50%; }
.ds-promo .sc-fill { transform-origin: 0 50%; }
@media (prefers-reduced-motion: no-preference) {
  .ds-promo-text > *, .ds-promo-feats li { animation: ds-promo-rise var(--ds-dur-slow) var(--ds-ease) both; }
  .ds-promo-text > :nth-child(2) { animation-delay: 80ms; }
  .ds-promo-text > :nth-child(3) { animation-delay: 160ms; }
  .ds-promo-text > :nth-child(4) { animation-delay: 240ms; }
  .ds-promo-feats li { animation-delay: calc(320ms + var(--i, 0) * 70ms); }
  .ds-promo-rig { animation: ds-promo-drift 14s ease-in-out infinite alternate; }
  .ds-promo-scene .sc-flow { animation: ds-sc-flow 0.8s linear infinite; }
  .ds-promo-scene .sc-blink { animation: ds-sc-blink 1s steps(1) infinite; }
  .ds-promo.is-paused :is(.ds-promo-rig, .ds-promo-scene, .ds-promo-scene *) { animation-play-state: paused; }   /* off screen (shell.js also stops the scheduler) */
}
@keyframes ds-promo-rise { from { opacity: 0; transform: translateY(8px); } }
@keyframes ds-promo-drift { from { transform: rotateY(-19deg) rotateX(9deg) translateY(4px); } to { transform: rotateY(-11deg) rotateX(6deg) translateY(-6px); } }
@keyframes ds-sc-flow { to { stroke-dashoffset: -24; } }
@keyframes ds-sc-blink { 50% { opacity: 0; } }
/* PB-04: no motion, the final state: all five scenes side by side, flat, with their names. */
@media (prefers-reduced-motion: reduce) {
  .ds-promo-art { min-height: 0; perspective: none; }
  .ds-promo-rig { position: static; display: grid; grid-template-columns: repeat(var(--n), minmax(0, 1fr)); gap: 10px; padding: 24px 32px 8px 0; transform: none; }
  .ds-promo-scene, .ds-promo-scene:first-child { position: relative; inset: auto; opacity: 1; }
  .ds-promo-ill { height: auto; filter: none; }
  .ds-promo-cap { display: block; margin-top: 4px; }
  .ds-promo-scene .sc-go { display: none; }
}
@media (max-width: 860px) { .ds-promo { grid-template-columns: minmax(0, 1fr); grid-template-areas: "text" "art" "feats"; } .ds-promo-text { padding: 28px 24px 8px; } .ds-promo-feats { padding: 0 24px 24px; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); } .ds-promo-art { min-height: 230px; height: 230px; } .ds-promo-rig { inset: 4px 16px; } }
@media (max-width: 860px) and (prefers-reduced-motion: reduce) { .ds-promo-art { height: auto; } .ds-promo-rig { grid-template-columns: repeat(3, minmax(0, 1fr)); padding: 12px 24px; } }
@media (max-width: 700px) { .ds-promo { margin: -20px -16px 24px; } .ds-promo-text { padding: 24px 16px 8px; } .ds-promo-feats { padding: 0 16px 20px; } .ds-promo-art { height: 210px; min-height: 210px; } }
/* In the What's New mega-menu panel: full width of the panel, above everything, rounded; shorter, and no feature row, on small screens. */
.ds-wn-promo { margin: 0 0 20px; }
.ds-wn-promo:empty { display: none; }
.ds-promo--flyout { margin: 0; border: 0; border-radius: var(--ds-r-card); }
.ds-promo--flyout .ds-promo-text { padding: 28px 0 14px 32px; }
.ds-promo--flyout .ds-promo-feats { gap: 8px; padding: 2px 32px 18px; }
.ds-promo--flyout .ds-promo-feat { display: flex; flex-direction: column; gap: 2px; padding: 9px 12px; }
.ds-promo--flyout .ds-promo-feat b { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-size: 13px; line-height: 18px; }
.ds-promo--flyout .ds-promo-feat span { overflow: hidden; font-size: 12px; line-height: 16px; text-overflow: ellipsis; white-space: nowrap; }
.ds-promo--flyout .ds-promo-art { min-height: 230px; }
@media (max-width: 860px) { .ds-promo--flyout .ds-promo-feats { display: none; } .ds-promo--flyout .ds-promo-text { padding: 20px 16px 4px; } .ds-promo--flyout .ds-promo-body { display: none; } .ds-promo--flyout .ds-promo-art { height: 150px; min-height: 150px; } .ds-promo--flyout .ds-promo-cta { margin-bottom: 4px; } }
@media (max-width: 860px) and (prefers-reduced-motion: reduce) { .ds-promo--flyout .ds-promo-art { height: auto; min-height: 0; } }
@media (max-width: 420px) { .ds-promo h2 { font-size: calc(var(--ds-text) * 22 / 14); } .ds-promo-feats { grid-template-columns: minmax(0, 1fr); } }
.ds-wn-filter { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 4px; }
.ds-wn-filter .ds-pill { height: 30px; padding: 0 12px; font-size: 13px; }
.ds-wn-allrel .ds-list-link { color: var(--ds-text-primary); text-decoration: none; }
.ds-wn-allrel .ds-list-link:hover { color: var(--ds-brand-fg); }
.ds-wn-none { margin: 16px 0 0; color: var(--ds-text-tertiary); }
.ds-release-meta { display: flex; flex-wrap: wrap; gap: 12px; }
.ds-release-cat { color: var(--ds-text-tertiary); }
.ds-release-tags { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 20px; }
.ds-tag { background: var(--ds-brand-subtle); color: var(--ds-brand-fg); }
.ds-tag.is-breaking { background: var(--ds-danger-subtle); color: var(--ds-danger-fg); }
/* DS-51 (Shane, round 5c item 13): the five release category pills, each a tint with AA text in both themes. Only the
   categories a release carries are shown (the tags come from the release data). */
:root {
  --ds-pill-feature-bg: light-dark(#e6edfe, #1c2a55); --ds-pill-feature-fg: light-dark(#1f3fae, #b9caff);
  --ds-pill-improvement-bg: light-dark(#dcf5ee, #0f3a32); --ds-pill-improvement-fg: light-dark(#0b6b55, #9fe6d2);
  --ds-pill-fix-bg: light-dark(#fdf0d5, #3d2e0a); --ds-pill-fix-fg: light-dark(#8a5a00, #f7d27a);
  --ds-pill-security-bg: light-dark(#efe6fd, #2f1d55); --ds-pill-security-fg: light-dark(#5b2bb5, #d4bfff);
  --ds-pill-breaking-bg: light-dark(#fde4e4, #4a1717); --ds-pill-breaking-fg: light-dark(#a3191b, #ffb9b9);
}
.ds-tag.ds-pill-new-feature, .ds-tag.ds-pill-new-features { background: var(--ds-pill-feature-bg); color: var(--ds-pill-feature-fg); }
.ds-tag.ds-pill-improvement, .ds-tag.ds-pill-improvements { background: var(--ds-pill-improvement-bg); color: var(--ds-pill-improvement-fg); }
.ds-tag.ds-pill-bug-fix, .ds-tag.ds-pill-bug-fixes { background: var(--ds-pill-fix-bg); color: var(--ds-pill-fix-fg); }
.ds-tag.ds-pill-security { background: var(--ds-pill-security-bg); color: var(--ds-pill-security-fg); }
.ds-tag.ds-pill-breaking-change, .ds-tag.ds-pill-breaking-changes { background: var(--ds-pill-breaking-bg); color: var(--ds-pill-breaking-fg); }
.ds-release-hero { height: 200px; margin: 0 0 24px; overflow: hidden; border: 1px solid var(--ds-border-subtle); border-radius: var(--ds-r-card); }
.ds-release-hero .ds-art, .ds-release-hero img { display: block; width: 100%; height: 200px; object-fit: cover; }
/* Guide callouts (Shane, 1 November 2026): under the link columns of Console, Instance, Insites AI and Designers, a rule
   and three how-to guides, each G1 art plus a title and one line. shell.js fills the strip on first open and adds
   is-filled; only then does it get its rule and height, and a failed fetch removes it, so nothing blank is ever shown.
   Pinned to the bottom of the panel (Shane, 1 November 2026: "I like it pinned to the bottom"). */
.ds-flyout-panel.is-on:has(.ds-flyout-guides.is-filled) { height: 100%; grid-template-rows: minmax(auto, 1fr) minmax(0, auto); }   /* DS-50: columns stretch to meet the strip */
.ds-flyout-panel:has(.ds-flyout-guides.is-filled) :is(.ds-flyout-feature, .ds-flyout-main) { padding-bottom: 4px; }
/* Guide strip (DS-45, round 5, Shane 1 November 2026): three stacked cards at equal widths. The drawn art is exactly as
   wide as its card (the card's padding aside), at the art's own 2:1 shape, and the title and one line of text sit under
   it. The strip is as tall as its cards, so it has no empty band, and it stays pinned to the bottom: the panel spaces
   its two rows apart rather than stretching either. Only when the links leave too little room (a short window) does
   the art give up height, never width, so the flyout keeps its outer size and never scrolls inside (DS-23, DS-42).
   Every box in a card has min-width 0, so a long line ellipses instead of widening its card into the next one. */
.ds-flyout-guides { grid-column: 1 / -1; box-sizing: border-box; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.ds-flyout-guides.is-filled { padding: 12px 16px 16px; border-top: 1px solid var(--ds-border-divider); background: var(--ds-surface-raised); }
.ds-flyout-guides ul { flex: 0 1 auto; min-height: 0; display: flex; gap: 16px; margin: 0; padding: 0; list-style: none; }
.ds-flyout-guides li { flex: 1 1 0; display: flex; min-width: 0; min-height: 0; }
.ds-flyout-link.ds-guide-card { flex: 1; display: flex; flex-direction: column; align-items: stretch; gap: 8px; padding: 8px; min-width: 0; min-height: 0; }
.ds-guide-thumb { display: block; box-sizing: border-box; flex: 0 1 auto; width: 100%; aspect-ratio: 2 / 1; min-height: 0; overflow: hidden; border: 1px solid var(--ds-border-subtle); border-radius: var(--ds-r-button); }
.ds-guide-thumb svg, .ds-guide-thumb use { display: block; width: 100%; height: 100%; }
.ds-guide-card > div { flex: none; min-width: 0; }
.ds-guide-card b { display: block; font-size: 14px; }
.ds-guide-card div span { display: block; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* DS-57 search facets and DS-58 command palette (round 7). */
.ds-search-facets { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; padding: 0 16px 8px; }
.ds-search-facets button { height: 26px; padding: 0 10px; border: 1px solid var(--ds-border-subtle); border-radius: 999px; background: none; color: var(--ds-text-secondary); font: 500 12px var(--ds-font); cursor: pointer; }
.ds-search-facets button[aria-pressed="true"] { border-color: var(--ds-brand-border); background: var(--ds-brand-subtle); color: var(--ds-brand-fg); }
.ds-search-ver { display: inline-flex; gap: 6px; align-items: center; margin-left: auto; font: 500 12px var(--ds-font); color: var(--ds-text-tertiary); }
.ds-search-ver select { height: 26px; border: 1px solid var(--ds-border-subtle); border-radius: 6px; background: var(--ds-surface-raised); color: var(--ds-text-primary); font: 12px var(--ds-font); }
.ds-search-action { display: block; width: 100%; padding: 8px 12px; border: 0; border-radius: var(--ds-r-input); background: none; color: var(--ds-text-primary); font: 500 14px var(--ds-font); text-align: left; cursor: pointer; }
.ds-search-action[aria-selected="true"], .ds-search-action:hover { background: var(--ds-brand-subtle); color: var(--ds-brand-fg); }
/* DS-63 search modal motion: scales in from 0.98, results stagger, all inside the house durations. */
@media (prefers-reduced-motion: no-preference) {
  #ds-search[open] { animation: ds-search-in var(--ds-dur-base) var(--ds-ease) both; }
  @keyframes ds-search-in { from { opacity: 0; transform: scale(0.98); } }
  #ds-search-results.is-in [role=option] { animation: ds-rise var(--ds-dur-base) var(--ds-ease) both; }
  #ds-search-results.is-in [role=option]:nth-of-type(2) { animation-delay: 20ms; }
  #ds-search-results.is-in [role=option]:nth-of-type(3) { animation-delay: 40ms; }
  #ds-search-results.is-in [role=option]:nth-of-type(4) { animation-delay: 60ms; }
  #ds-search-results.is-in [role=option]:nth-of-type(n+5) { animation-delay: 80ms; }
}

/* DS-62 contents marker: one bar that glides between headings; the per-link border stays as the no-motion fallback. */
.ds-toc ol { position: relative; }
.ds-toc-marker { position: absolute; left: -1px; top: 0; width: 2px; background: var(--ds-brand); border-radius: 1px; pointer-events: none; }
.ds-toc:has(.ds-toc-marker) a[aria-current] { border-left-color: transparent; }
@media (prefers-reduced-motion: no-preference) { .ds-toc-marker { transition: transform var(--ds-dur-base) var(--ds-ease), height var(--ds-dur-base) var(--ds-ease); } }
/* DS-64 card hover art shift: G1 fragments move 2 to 3px in parallax on hover and come back on leave. */
@media (prefers-reduced-motion: no-preference) and (hover: hover) {
  :is(.ds-chapter-card, .ds-release-link, .ds-guide-card, .ds-flyout-link) .g1-frag { transition: translate var(--ds-dur-base) var(--ds-ease); }
  :is(.ds-chapter-card, .ds-release-link, .ds-guide-card, .ds-flyout-link):hover .g1-frag:nth-of-type(odd) { translate: 2px -2px; }
  :is(.ds-chapter-card, .ds-release-link, .ds-guide-card, .ds-flyout-link):hover .g1-frag:nth-of-type(even) { translate: -3px 1px; }
}
/* DS-66 flyout stagger: shell.js numbers every row of the open panel in reading order, so rows enter 20ms apart on
   every flyout, columns included, and the guide cards come last. */
/* DS-68 theme switch: a 200ms cross-fade of the page on toggle (the house base duration). */
@media (prefers-reduced-motion: no-preference) { html.ds-theme-fading body { animation: ds-theme-fade var(--ds-dur-base) var(--ds-ease); } @keyframes ds-theme-fade { from { opacity: .55; } } }
/* DS-70 rail collapse: labels fade out before the width animates, so text never squashes. */
@media (prefers-reduced-motion: no-preference) {
  .ds-rail :is(.ds-brand-full, .ds-side-label, .ds-toggle-label) { transition: opacity var(--ds-dur-fast) var(--ds-ease); }
  .ds-rail-collapsing :is(.ds-brand-full, .ds-side-label, .ds-toggle-label) { opacity: 0; }
}

/* Progressive promo scenes (Shane, 2 November 2026). shell.js marks one .ds-promo-scene .is-live at a time, every 6s
   (--ds-promo-step, the same on the page and in the flyout), and the matching .ds-promo-feat .is-live. Inside the live
   scene the prompt types over 900ms (sc-type, sc-caret), then each animated part (sc-pop, sc-on, sc-fill, sc-go, numbered
   --j in DOM order by promo_scenes.py) enters 170ms after the one before, each over 380ms. A scene leaves with a 300ms
   fade and the next starts clean, so the first paint shows an empty scene, not the end state. It never pauses on hover or
   focus; it stops only when the banner is off screen (.is-paused). Reduced motion: no entrance, the static scenes stay. */
.ds-promo { --pn-lead: 900ms; --pn-gap: 170ms; --pn-rise: 380ms; }
.ds-promo-feat.is-live::before { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .ds-promo.is-run .ds-promo-scene { opacity: 0; transition: opacity 300ms ease; }
  .ds-promo.is-run .ds-promo-scene.is-live { opacity: 1; transition: none; }
  .ds-promo.is-run .ds-promo-scene.is-live.is-out { opacity: 0; transition: opacity 300ms ease; }
  .ds-promo.is-run .ds-promo-scene :is(.sc-pop, .sc-on, .sc-go, .sc-type, .sc-caret, .sc-fill) { opacity: 0; }
  .ds-promo.is-run .ds-promo-scene.is-live :is(.sc-pop, .sc-on) { opacity: 1; animation: ds-pn-pop var(--pn-rise) var(--ds-ease) both; animation-delay: calc(var(--pn-lead) + var(--j, 0) * var(--pn-gap)); }
  .ds-promo.is-run .ds-promo-scene.is-live .sc-type { opacity: 1; animation: ds-pn-type var(--pn-lead) steps(32, end) both; }
  .ds-promo.is-run .ds-promo-scene.is-live .sc-caret { opacity: 1; animation: ds-pn-caret var(--pn-lead) steps(32, end) both; }
  .ds-promo.is-run .ds-promo-scene.is-live .sc-fill { opacity: 1; animation: ds-pn-fill 600ms ease-out both; animation-delay: calc(var(--pn-lead) + var(--j, 0) * var(--pn-gap)); }
  .ds-promo.is-run .ds-promo-scene.is-live .sc-go { animation: ds-pn-go 1400ms cubic-bezier(0.45, 0, 0.2, 1) both; animation-delay: calc(var(--pn-lead) + var(--j, 0) * var(--pn-gap)); }
  .ds-promo-feat::before { transition: opacity 300ms; }
}
/* Hidden from the first paint, before shell.js has started the scheduler, so the page never flashes a finished scene. */
@media (prefers-reduced-motion: no-preference) and (scripting: enabled) {
  .ds-promo .ds-promo-scene :is(.sc-pop, .sc-on, .sc-go, .sc-type, .sc-caret, .sc-fill) { opacity: 0; }
}
@keyframes ds-pn-pop { from { opacity: 0; transform: translateY(10px) scale(0.94); } to { opacity: 1; transform: none; } }
@keyframes ds-pn-type { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes ds-pn-caret { from { transform: translateX(-214px); } to { transform: none; } }
@keyframes ds-pn-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes ds-pn-go { 0% { opacity: 0; transform: none; } 15% { opacity: 1; } 85% { opacity: 1; transform: translate(var(--dx, 0), var(--dy, 0)); } 100% { opacity: 0; transform: translate(var(--dx, 0), var(--dy, 0)); } }
.ds-voice { display: flex; align-items: center; gap: 6px; }
.ds-voice-sample { margin-left: auto; height: 24px; padding: 0 8px; border: 1px solid var(--ds-border-divider); border-radius: 999px; background: none; color: var(--ds-text-secondary); font: 600 11px var(--ds-font); cursor: pointer; }

/* DS-85 menu scrim: while a mega-menu flyout is open, the content to its right darkens (45% light, 60% dark).
   Under the flyout (45), over the content and the left tree; never over the rail (it starts at --ds-side-w);
   pointer events pass through, so click-outside and hover-away still close the flyout. Desktop only: mobile.css
   removes it where the flyout is full width. */
body.ds-flyout-open::after { content: ""; position: fixed; z-index: 44; top: 0; bottom: 0; left: var(--ds-side-w); right: 0; background: light-dark(rgba(12, 15, 22, .45), rgba(0, 0, 0, .60)); pointer-events: none; animation: ds-scrim-in 220ms var(--ds-ease) both; }
@keyframes ds-scrim-in { from { opacity: 0; } to { opacity: 1; } }

/* WC-THUMB: component library cards on /web-components carry their thumbnail (400 x 240, 5:3) above the title. */
.ds-wc-cards { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; }
.ds-wc-cards li { list-style: none; margin: 0; }
.ds-chapter-card.ds-wc-card { display: flex; flex-direction: column; gap: 10px; padding: 10px 10px 14px; align-items: stretch; }
.ds-wc-thumb { display: block; aspect-ratio: 5 / 3; border-radius: 10px; overflow: hidden; background: #F5F4F5; border: 1px solid light-dark(rgba(0, 0, 0, .08), rgba(255, 255, 255, .08)); }
.ds-wc-thumb img { display: block; width: 100%; height: auto; }
.ds-wc-card > div { padding: 0 4px; }
.ds-wc-card b { display: block; font-size: 15px; }
.ds-wc-card code { font-size: 12px; }
:root[data-theme="dark"] .ds-wc-thumb { opacity: .92; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .ds-wc-thumb { opacity: .92; } }
