/*fern-site-stylesheet*/:root {
  --header-height: 64px;
  --header-height-real: 64px;
  --mobile-header-height-real: 64px;
  --content-width: 640px;
  --sidebar-width: 288px;
  --page-width: 100vw;
  --logo-height: 28px;
  --font-body: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
  --font-heading: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
  --font-code: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
}

:root {
  --typography-body-font-family: var(--font-body);
  --typography-heading-font-family: var(--font-heading);
  --typography-code-font-family: var(--font-code);
}


.light, :root {
  --accent-1: #f9f4f7;
  --accent-2: #f4ebf0;
  --accent-3: #e8dde3;
  --accent-4: #ddccd6;
  --accent-5: #d1bcca;
  --accent-6: #c4b0bd;
  --accent-7: #a48b9c;
  --accent-8: #8f6d81;
  --accent-9: #6f0c4a;
  --accent-10: #85175e;
  --accent-11: #6f0c4a;
  --accent-12: #4d0834;

  --accent-a1: #e6d5ff20;
  --accent-a2: #b00dc10b;
  --accent-a3: #e308941c;
  --accent-a4: #d7027c2a;
  --accent-a5: #ce02743a;
  --accent-a6: #bf03674b;
  --accent-a7: #b6036261;
  --accent-a8: #b1025f7c;
  --accent-a9: #680142f3;
  --accent-a10: #700143da;
  --accent-a11: #80014ac2;
  --accent-a12: #670042fa;

  --accent-contrast: #fff;
  --accent-surface: #f1e7eccc;
  --accent-indicator: #6f0c4a;
  --accent-track: #6f0c4a;
}

@supports (color: color(display-p3 1 1 1)) {
  @media (color-gamut: p3) {
    .light, :root {
      --accent-1: oklch(97.2% 0.0066 340.4);
      --accent-2: oklch(94.9% 0.0117 342.6);
      --accent-3: oklch(90.8% 0.0144 343.2);
      --accent-4: oklch(86.2% 0.0231 341.4);
      --accent-5: oklch(81.7% 0.0303 338);
      --accent-6: oklch(77.8% 0.029 338.7);
      --accent-7: oklch(66.5% 0.0384 337.8);
      --accent-8: oklch(57.5% 0.0515 342.7);
      --accent-9: oklch(36.5% 0.142 348.9);
      --accent-10: oklch(42.1% 0.1588 346.9);
      --accent-11: oklch(36.5% 0.142 348.9);
      --accent-12: oklch(28.6% 0.1087 347.5);

      --accent-a1: color(display-p3 0.8667 0.8314 1 / 0.125);
      --accent-a2: color(display-p3 0.5804 0.0039 0.749 / 0.041);
      --accent-a3: color(display-p3 0.7333 0.0078 0.5216 / 0.103);
      --accent-a4: color(display-p3 0.6941 0.0039 0.451 / 0.16);
      --accent-a5: color(display-p3 0.6745 0.0039 0.4157 / 0.218);
      --accent-a6: color(display-p3 0.6157 0.0039 0.3725 / 0.283);
      --accent-a7: color(display-p3 0.5961 0.0039 0.349 / 0.365);
      --accent-a8: color(display-p3 0.5843 0.0039 0.3373 / 0.468);
      --accent-a9: color(display-p3 0.3373 0 0.2157 / 0.906);
      --accent-a10: color(display-p3 0.3725 0 0.2235 / 0.82);
      --accent-a11: color(display-p3 0.4275 0 0.251 / 0.734);
      --accent-a12: color(display-p3 0.3333 0 0.2157 / 0.927);

      --accent-contrast: #fff;
      --accent-surface: color(display-p3 0.9412 0.9059 0.9255 / 0.8);
      --accent-indicator: oklch(36.5% 0.142 348.9);
      --accent-track: oklch(36.5% 0.142 348.9);
    }
  }
}


.light, :root {
  --grayscale-1: #fdfdfc;
  --grayscale-2: #f9f9f8;
  --grayscale-3: #f1f0ef;
  --grayscale-4: #e9e8e6;
  --grayscale-5: #e2e1de;
  --grayscale-6: #dad9d6;
  --grayscale-7: #cfceca;
  --grayscale-8: #bcbbb5;
  --grayscale-9: #8d8d86;
  --grayscale-10: #82827c;
  --grayscale-11: #63635e;
  --grayscale-12: #21201c;

  --grayscale-a1: #55550003;
  --grayscale-a2: #25250007;
  --grayscale-a3: #20100010;
  --grayscale-a4: #1f150019;
  --grayscale-a5: #1f180021;
  --grayscale-a6: #19130029;
  --grayscale-a7: #19140035;
  --grayscale-a8: #1915014a;
  --grayscale-a9: #0f0f0079;
  --grayscale-a10: #0c0c0083;
  --grayscale-a11: #080800a1;
  --grayscale-a12: #060500e3;

  --grayscale-contrast: #000;
  --grayscale-surface: #ffffffcc;
  --grayscale-indicator: #8d8d86;
  --grayscale-track: #8d8d86;
}

@supports (color: color(display-p3 1 1 1)) {
  @media (color-gamut: p3) {
    .light, :root {
      --grayscale-1: color(display-p3 0.992 0.992 0.989);
      --grayscale-2: color(display-p3 0.977 0.977 0.973);
      --grayscale-3: color(display-p3 0.943 0.942 0.936);
      --grayscale-4: color(display-p3 0.913 0.912 0.903);
      --grayscale-5: color(display-p3 0.885 0.883 0.873);
      --grayscale-6: color(display-p3 0.854 0.852 0.839);
      --grayscale-7: color(display-p3 0.813 0.81 0.794);
      --grayscale-8: color(display-p3 0.738 0.734 0.713);
      --grayscale-9: color(display-p3 0.553 0.553 0.528);
      --grayscale-10: color(display-p3 0.511 0.511 0.488);
      --grayscale-11: color(display-p3 0.388 0.388 0.37);
      --grayscale-12: color(display-p3 0.129 0.126 0.111);

      --grayscale-a1: #55550003;
      --grayscale-a2: #25250007;
      --grayscale-a3: #20100010;
      --grayscale-a4: #1f150019;
      --grayscale-a5: #1f180021;
      --grayscale-a6: #19130029;
      --grayscale-a7: #19140035;
      --grayscale-a8: #1915014a;
      --grayscale-a9: #0f0f0079;
      --grayscale-a10: #0c0c0083;
      --grayscale-a11: #080800a1;
      --grayscale-a12: #060500e3;

      --grayscale-contrast: #000;
      --grayscale-surface: color(display-p3 1 1 1 / 80%);
      --grayscale-indicator: color(display-p3 0.553 0.553 0.528);
      --grayscale-track: color(display-p3 0.553 0.553 0.528);
    }
  }
}


.dark {
  --accent-1: #27071f;
  --accent-2: #301329;
  --accent-3: #3b1e3b;
  --accent-4: #452845;
  --accent-5: #4f314f;
  --accent-6: #5a3c5c;
  --accent-7: #694769;
  --accent-8: #704d75;
  --accent-9: #d2add2;
  --accent-10: #e0cae0;
  --accent-11: #d2add2;
  --accent-12: #f0e2f0;

  --accent-a1: #00fb000d;
  --accent-a2: #00f40113;
  --accent-a3: #5efc881b;
  --accent-a4: #aafece1f;
  --accent-a5: #c9fae526;
  --accent-a6: #e1fef82f;
  --accent-a7: #ebebfd41;
  --accent-a8: #f5ddfe61;
  --accent-a9: #fdd7feca;
  --accent-a10: #fcd5febd;
  --accent-a11: #fdd7fec3;
  --accent-a12: #fef2fff0;

  --accent-contrast: #2c1b2c;
  --accent-surface: #1f312480;
  --accent-indicator: #d2add2;
  --accent-track: #d2add2;
}

@supports (color: color(display-p3 1 1 1)) {
  @media (color-gamut: p3) {
    .dark {
      --accent-1: oklch(19.8% 0.0643 339);
      --accent-2: oklch(24% 0.0581 337.2);
      --accent-3: oklch(28.7% 0.0643 327.1);
      --accent-4: oklch(32.6% 0.063 326.9);
      --accent-5: oklch(36.1% 0.0637 326.8);
      --accent-6: oklch(40.3% 0.0647 324.6);
      --accent-7: oklch(44.8% 0.0688 326.6);
      --accent-8: oklch(47.4% 0.0758 322.3);
      --accent-9: oklch(79.2% 0.0657 326.2);
      --accent-10: oklch(86.4% 0.0383 325.9);
      --accent-11: oklch(79.2% 0.0657 326.2);
      --accent-12: oklch(92.8% 0.0239 325.8);

      --accent-a1: color(display-p3 0 0.9804 0 / 0.043);
      --accent-a2: color(display-p3 0 0.9882 0.0353 / 0.064);
      --accent-a3: color(display-p3 0.451 1 0.5647 / 0.097);
      --accent-a4: color(display-p3 0.698 1 0.8235 / 0.118);
      --accent-a5: color(display-p3 0.8235 1 0.9255 / 0.143);
      --accent-a6: color(display-p3 0.902 1 0.9804 / 0.181);
      --accent-a7: color(display-p3 0.9255 0.9412 1 / 0.247);
      --accent-a8: color(display-p3 0.9569 0.8745 1 / 0.373);
      --accent-a9: color(display-p3 0.9765 0.8549 1 / 0.782);
      --accent-a10: color(display-p3 0.9765 0.8471 1 / 0.731);
      --accent-a11: color(display-p3 0.9765 0.8588 1 / 0.754);
      --accent-a12: color(display-p3 0.9961 0.9569 1 / 0.935);

      --accent-contrast: #2c1b2c;
      --accent-surface: color(display-p3 0.1255 0.1804 0.1412 / 0.5);
      --accent-indicator: oklch(79.2% 0.0657 326.2);
      --accent-track: oklch(79.2% 0.0657 326.2);
    }
  }
}


.dark {
  --grayscale-1: #121113;
  --grayscale-2: #1a191b;
  --grayscale-3: #232225;
  --grayscale-4: #2b292d;
  --grayscale-5: #323035;
  --grayscale-6: #3c393f;
  --grayscale-7: #49474e;
  --grayscale-8: #625f69;
  --grayscale-9: #6f6d78;
  --grayscale-10: #7c7a85;
  --grayscale-11: #b5b2bc;
  --grayscale-12: #eeeef0;

  --grayscale-a1: #00000000;
  --grayscale-a2: #f5f4f609;
  --grayscale-a3: #ebeaf814;
  --grayscale-a4: #eee5f81d;
  --grayscale-a5: #efe6fe25;
  --grayscale-a6: #f1e6fd30;
  --grayscale-a7: #eee9ff40;
  --grayscale-a8: #eee7ff5d;
  --grayscale-a9: #eae6fd6e;
  --grayscale-a10: #ece9fd7c;
  --grayscale-a11: #f5f1ffb7;
  --grayscale-a12: #fdfdffef;

  --grayscale-contrast: #fff;
  --grayscale-surface: rgba(0, 0, 0, 0.05);
  --grayscale-indicator: #6f6d78;
  --grayscale-track: #6f6d78;
}

@supports (color: color(display-p3 1 1 1)) {
  @media (color-gamut: p3) {
    .dark {
      --grayscale-1: color(display-p3 0.07 0.067 0.074);
      --grayscale-2: color(display-p3 0.101 0.098 0.105);
      --grayscale-3: color(display-p3 0.138 0.134 0.144);
      --grayscale-4: color(display-p3 0.167 0.161 0.175);
      --grayscale-5: color(display-p3 0.196 0.189 0.206);
      --grayscale-6: color(display-p3 0.232 0.225 0.245);
      --grayscale-7: color(display-p3 0.286 0.277 0.302);
      --grayscale-8: color(display-p3 0.383 0.373 0.408);
      --grayscale-9: color(display-p3 0.434 0.428 0.467);
      --grayscale-10: color(display-p3 0.487 0.48 0.519);
      --grayscale-11: color(display-p3 0.707 0.7 0.735);
      --grayscale-12: color(display-p3 0.933 0.933 0.94);

      --grayscale-a1: #00000000;
      --grayscale-a2: #f5f4f609;
      --grayscale-a3: #ebeaf814;
      --grayscale-a4: #eee5f81d;
      --grayscale-a5: #efe6fe25;
      --grayscale-a6: #f1e6fd30;
      --grayscale-a7: #eee9ff40;
      --grayscale-a8: #eee7ff5d;
      --grayscale-a9: #eae6fd6e;
      --grayscale-a10: #ece9fd7c;
      --grayscale-a11: #f5f1ffb7;
      --grayscale-a12: #fdfdffef;

      --grayscale-contrast: #fff;
      --grayscale-surface: color(display-p3 0 0 0 / 5%);
      --grayscale-indicator: color(display-p3 0.434 0.428 0.467);
      --grayscale-track: color(display-p3 0.434 0.428 0.467);
    }
  }
}

.light, :root {
  color-scheme: light;
  --accent: rgba(111, 12, 74, 1);
  --background: rgba(245, 244, 239, 1);
  --border: rgba(228, 224, 219, 1);
  --sidebar-background: initial;
  --header-background: color-mix(in srgb, var(--background), transparent 30%);
  --card-background: rgba(251, 250, 246, 1);
  --theme-color: #f5f4ef;
}

.dark {
  color-scheme: dark;
  --accent: rgba(210, 173, 210, 1);
  --background: rgba(46, 15, 41, 1);
  --border: rgba(79, 49, 79, 1);
  --sidebar-background: initial;
  --header-background: color-mix(in srgb, var(--background), transparent 30%);
  --card-background: rgba(39, 7, 31, 1);
  --theme-color: #2e0f29;
}

/* Canvas Body Theme */
:root [data-body-theme="canvas"] .canvas-wrapper {
  display: flex;
  width: 100%;
  overflow: auto;
  height: 100%;
  border-radius: 16px 16px 16px 16px;
  justify-content: center;
  align-items: flex-start;
  margin-right: 12px;
  margin-bottom: 12px;
  height: calc(100vh - var(--header-height-real) - 12px);
  border: 1px solid var(--border);
  background-color: var(--card-background);
}

:root [data-body-theme="canvas"] body {
  overflow: hidden;
}


:root [data-body-theme="canvas"] #fern-toc {
  position: sticky;
  max-height: calc(100vh - var(--header-height-real) - 12px);
  overflow-y: auto;
  overflow-x: hidden;
  top: 0;
}

:root [data-body-theme="canvas"] #fern-toc:has(> *) {
  margin-right: 12px;
}

:root [data-body-theme="canvas"] .fern-layout-guide,
:root [data-body-theme="canvas"] .fern-layout-overview {
  width: 100%;
  border: none;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}

:root [data-body-theme="canvas"] .fern-layout-reference {
  width: 100%;
  border: none;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  position: relative;
}

/* The sticky changelog day label offsets its top by the header height by default
   (window scroll). On canvas the scroll container already starts below the fixed
   header, so zero the offset to keep the date from pinning too early. */
:root [data-body-theme="canvas"] {
  --fern-changelog-sticky-top: 0px;
}

/* Bubble Tabs Theme */
:root [data-tabs-theme="bubble"] #fern-header [data-radix-collection-item]::after {
  display: none;
}

:root [data-tabs-theme="bubble"] #fern-header [data-radix-collection-item] {
  position: relative;
  isolation: isolate;
  transition: color 0.15s ease-in-out;
}

:root [data-tabs-theme="bubble"] #fern-header [data-radix-collection-item]::before {
  content: "";
  position: absolute;
  inset: 6px 0;
  border-radius: 9999px;
  z-index: -1;
  transition: background-color 0.15s ease-in-out;
}

:root [data-tabs-theme="bubble"] #fern-header [data-radix-collection-item][data-state="active"] {
  color: var(--accent-a11);
}

:root [data-tabs-theme="bubble"] #fern-header [data-radix-collection-item][data-state="active"]::before {
  background-color: var(--accent-a3);
}

:root [data-tabs-theme="bubble"] #fern-header [data-radix-collection-item][data-state="active"] > span {
  -webkit-text-stroke: 0.5px currentcolor;
}

:root [data-tabs-theme="bubble"] #fern-header [data-radix-collection-item][data-state="inactive"]:hover::before {
  background-color: var(--grayscale-a3);
}
:root [data-tabs-theme="bubble"] #fern-header [data-radix-collection-item][data-state="inactive"]:focus-visible::before {
  background-color: var(--grayscale-a3);
}

.dark [data-tabs-theme="bubble"] #fern-header [data-radix-collection-item][data-state="active"] {
  color: var(--accent-a11);
}

.dark [data-tabs-theme="bubble"] #fern-header [data-radix-collection-item][data-state="active"]::before {
  background-color: var(--accent-a3);
}

.dark [data-tabs-theme="bubble"] #fern-header [data-radix-collection-item][data-state="inactive"]:hover::before {
  background-color: var(--grayscale-a3);
}
.dark [data-tabs-theme="bubble"] #fern-header [data-radix-collection-item][data-state="inactive"]:focus-visible::before {
  background-color: var(--grayscale-a3);
}

/* Bubble theme: reset parent bg on active+focus-visible to avoid stacked alpha with the ::before pill */
:root [data-tabs-theme="bubble"] #fern-header [data-radix-collection-item][data-state="active"]:focus-visible {
  background: transparent;
}

/* ==========================
   Brand Faces — Domaine Display, Söhne & Futura PT
   ==========================
   Standards CSS only (@font-face, element selectors, inherited text
   properties) — no renderer internals, so this file is stable across
   `fern-api` bumps. Renderer-internal selectors live in `styles.css`;
   the two files touch disjoint properties, so `css:` list order is
   immaterial. Faces load from the shared GCS bucket (woff2 is the only
   published format; CORS verified cross-origin from `legal.curate.wine`). */

@font-face {
  font-family: 'Domaine Display';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('https://static.curate.software/wine/brand/fonts/domaine-display--regular.woff2') format('woff2');
}

@font-face {
  font-family: 'Soehne';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('https://static.curate.software/wine/brand/fonts/soehne--buch.woff2') format('woff2');
}

@font-face {
  font-family: 'Soehne';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('https://static.curate.software/wine/brand/fonts/soehne--buch-kursiv.woff2') format('woff2');
}

@font-face {
  font-family: 'Soehne';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('https://static.curate.software/wine/brand/fonts/soehne--kraftig.woff2') format('woff2');
}

/* Halbfett (600) is the portal's heaviest Söhne: true-bold
   Dreiviertelfett reads heavy against one-weight Domaine and 500-cap
   Futura, and its only brand use is the web's stylized display
   headers. Any residual 700 request resolves to the real 600. */
@font-face {
  font-family: 'Soehne';
  font-style: normal;
  font-weight: 600 700;
  font-display: swap;
  src: url('https://static.curate.software/wine/brand/fonts/soehne--halbfett.woff2') format('woff2');
}

/* Futura PT — the app's working voice, carried here by the chrome only
   (sidebar, breadcrumb, page actions, tabs, buttons, badges, TOC):
   short strings, never continuous prose. Upright-only by policy: an
   italic in chrome is an antipattern, so the Book Oblique cut is
   deliberately not registered (with `font-synthesis: none`, a stray
   `em` in chrome renders upright rather than faux-oblique). */
@font-face {
  font-family: 'Futura-PT';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('https://static.curate.software/wine/brand/fonts/futura-pt--book.woff2') format('woff2');
}

@font-face {
  font-family: 'Futura-PT';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('https://static.curate.software/wine/brand/fonts/futura-pt--medium.woff2') format('woff2');
}

/* Metric-Matched Fallbacks
   ------------------------
   Synthetic local faces that impersonate each webfont's box: the swap
   flash keeps the brand face's advance widths and line boxes, so
   layout shift ≈ 0 and no heavy system cut (the 2026-08-09 system-
   Futura incident) ever flashes through. Values follow the
   `next/font` formulas — `size-adjust` = brand avg advance ÷ local
   avg advance; overrides = brand metric ÷ `size-adjust` — computed
   from rendered canvas metrics (2026-08-09). Recompute if a face or
   its local source changes; Windows locals share the macOS numbers
   as an approximation. */
@font-face {
  font-family: 'Soehne Fallback';
  src: local('Helvetica Neue'), local('Arial');
  size-adjust: 97.72%;
  ascent-override: 119.83%;
  descent-override: 43.29%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Futura-PT Fallback';
  font-weight: 400;
  src: local('Futura');
  size-adjust: 84.35%;
  ascent-override: 116.42%;
  descent-override: 35.57%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Futura-PT Fallback';
  font-weight: 500;
  src: local('Futura');
  size-adjust: 86.5%;
  ascent-override: 113.53%;
  descent-override: 34.68%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Domaine Display Fallback';
  src: local('Georgia');
  size-adjust: 100.5%;
  ascent-override: 102.49%;
  descent-override: 27.86%;
  line-gap-override: 0%;
}

/* Family Variables
   ----------------
   `typography` in `docs.yml` with `name:` but no `path` emits neither
   @font-face nor these variables (verified live at 5.90.1), so the
   stacks are set here. `:root:root` (specificity 0,2,0) outranks any
   single-`:root` declaration Fern generates, without `!important`.
   The metric-matched synthetic sits directly behind each brand face;
   the remaining chain is the last-resort tail. */
:root:root {
  --font-heading: 'Domaine Display', 'Domaine Display Fallback', 'Georgia Pro', Georgia, Baskerville, 'Times New Roman', serif;
  --font-body: 'Soehne', 'Soehne Fallback', -apple-system, 'Segoe UI Variable', 'Segoe UI', 'Noto Sans', 'Helvetica Neue', Ubuntu, Roboto, Cantarell, ui-sans-serif, system-ui, sans-serif;
  --font-chrome: 'Futura-PT', 'Futura-PT Fallback', 'Futura', 'Avenir Next', 'Century Gothic', system-ui, sans-serif;  /* app canonical fallback chain */
}

/* Text Rendering
   --------------
   `font-synthesis: none` is load-bearing: Domaine Display is licensed
   at 400 only, Söhne italic at 400 only, and Futura PT tops out at 500
   — never allow faux bold or faux oblique (a 600/700 request on a
   Futura element resolves to the real 500, and a 700 Söhne request to
   the real Halbfett). `ss02` selects Söhne's double-storey g — and,
   by happy coincidence of feature tags, Futura PT's single-storey g
   that echoes the brand mark. `zero` (the slashed zero) is deliberately
   absent from running text — legal's prose carries it, but readability
   wins here; step anchors re-enable it locally in `styles.css`. */
body {
  font-feature-settings: 'kern' 1, 'liga' 1, 'calt' 1, 'ss02' 1;
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Headings
   --------
   Hierarchy comes from size, colour, and space — never weight (Domaine
   ships one weight). Explicit 400 also keeps the Georgia/Times fallback
   from flashing bold while the webfont loads. `-webkit-font-smoothing:
   auto` (subpixel) is deliberate on the Domaine voice, matching the app
   standard: it renders the face ~100 heavier, wanted because Domaine
   runs light at small display sizes (borderline 24–26px, clearly
   below 20px). Elements restyled to Futura chrome (tabs, callout and
   prompt titles) re-assert `antialiased` in `styles.css`. Tracking
   tiers: -0.02em at display scale, -0.015em mid, -0.01em below 21px. */
h1,
h2,
h3,
h4,
h5,
h6,
.fern-page-heading {
  font-weight: 400;
  -webkit-font-smoothing: auto;
  -moz-osx-font-smoothing: auto;
}

h1 {
  letter-spacing: -0.02em;
}

h2 {
  letter-spacing: -0.015em;
}

h3,
h4,
h5,
h6 {
  letter-spacing: -0.01em;
}

/* Wrap orphan control (app typography-guide port): balance wrapping
   display heads; truncating titles (footer nav) are nowrap and inert. */
h1,
h2,
h3 {
  text-wrap: balance;
}

/* ==========================
   Renderer Internals — chrome & components
   ==========================
   Every selector here targets the closed renderer's unversioned DOM —
   re-verify visually after every `fern-api` bump. Colors live in
   `docs.yml`; this file carries the enumerated remainder the schema
   cannot express (edge-sheen alphas, the legal/app shadow stacks, the
   app component recipes below), itemized in PORTAL §7. App recipe
   sources: `app/dist/app.bundle.css` (`.c-btn`, `.c-tabs.nav-tabs`,
   `.tippy-popper`) — keep light mode numerically in lockstep when the app moves;
   Help's dark treatment is defined independently in Brand's color guidance. */

/* Shared surface roles also reach body-portaled menus, tooltips, and figures.
   Identity artwork and screenshot pixels keep their approved colors. */
:root {
  --c-sheet: #faf9f5;
  --c-surface-nested: #f0ede9;
  --c-foreground: #2d2926;
  --c-white: #ffffff;
  --c-white-rgb: 255 255 255;
  --c-tooltip-background: #1b1b1f;
  --c-tooltip-foreground: #dcdee6;
  /* The portal's one focus-ring color, consumed by every component sheet that
     draws a ring — as an `outline` on the figure triggers and the zoom close,
     and inside the `box-shadow` the form controls use. A light ground needs
     less alpha to carry a dark ink than a dark ground needs to carry a light
     one, which is why the two themes are not the same number. `<Compare>`
     deliberately opts out: its caret rings in `currentColor` so the ring
     matches the control it belongs to. */
  --c-focus-ring: rgb(111 12 74 / 0.55);
}

.dark {
  --c-sheet: var(--card-background);
  --c-surface-nested: var(--background);
  --c-surface-emphasis: #3b1e3b;
  --c-foreground: #fcf7fc;
  --c-white: var(--c-foreground);
  --c-white-rgb: 252 247 252;
  --c-tooltip-background: var(--accent);
  --c-tooltip-foreground: var(--c-sheet);
  --c-focus-ring: rgb(210 173 210 / 0.7);
  --color-white: var(--c-foreground);
  --color-body: var(--c-foreground);
}

/* Chrome
   ------ */

/* Remove sidebar and header border lines for the seamless recessed look */
#fern-sidebar {
  border-right-width: 0 !important;
}

#fern-header {
  border-color: transparent !important;
}

/* Type — the hybrid register (Söhne prose, Futura chrome)
   -------------------------------------------------------
   Prose reads in Söhne at 16px/1.6 — `strong` already resolves to
   the real Halbfett. Chrome — sidebar, breadcrumb, page actions,
   TOC, tabs, buttons, badges — takes Futura PT, the app's working
   voice: short strings only, never continuous prose. Tables stay
   Söhne throughout: a Futura `th` over Söhne `td` was tried and
   read as mismatch (ruled 2026-08-09, brand guide "boundary
   rulings"). Explicit 500s below pre-empt `font-synthesis: none`
   downgrading the renderer's 600/700 requests. */
/* Domaine needs more size than Söhne to establish the reading hierarchy:
   22px Step titles sit between 16px prose and the existing 25.5px h2. */
.fern-prose p,
.fern-prose li {
  font-size: 1rem;
  line-height: 1.6;
  text-wrap: pretty;
}

.fern-prose h2 {
  font-size: 1.59375rem;
  line-height: 1.25;
  /* The renderer's 1em bottom margin rode the size bump up to 25.5px;
     0.75em regroups the heading with its content (gap below stays
     well under the 2em section gap above). */
  margin-bottom: 0.75em;
}

.fern-prose .fern-step > h3 {
  font-size: 1.375rem;
  position: relative;
  top: -2px; /* Optical alignment with the fixed Step number block. */
}

/* Untitled steps start with 25.6px prose, rather than the 35.2px title.
   Center the 24px marker on that first line, not the full paragraph. */
.fern-prose .fern-step:has(> .fern-anchor + p) > .fern-anchor {
  margin-top: calc((1.6rem - 1.5rem) / 2);
}

/* App qualifier icons combine a base glyph with the native Light slash. */
.fern-prose .c-guide-icon-stack {
  display: inline-grid;
  width: 14px;
  height: 14px;
  vertical-align: middle;
}

.fern-prose .c-guide-icon-stack > .fern-mdx-icon {
  grid-area: 1 / 1;
  margin: 0;
}

.fern-prose .c-guide-icon-stack > .fern-mdx-icon:last-child {
  filter: drop-shadow(0 1px 0 var(--background)) drop-shadow(0 -1px 0 var(--background));
}

.fern-prose .fern-docs-badge .c-guide-icon-stack--badge > .fern-mdx-icon:last-child {
  width: 8px !important;
  height: 8px !important;
  align-self: end;
  justify-self: end;
  transform: translate(2px, 2px);
}

.fern-prose :where(p:has(+ ul)):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
  margin-bottom: 0.625em; /* Half the renderer's 1.25em paragraph margin. */
}

.fern-prose :where(p + ul):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
  margin-top: 0.625em;
}

.fern-prose :where(p + ul > li:first-child):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
  margin-top: 0;
}

/* Tables stay all-Söhne; Halbfett headers — true-bold 700 reads heavy
   beside one-weight Domaine and 500-cap Futura. */
.fern-prose th {
  font-weight: 600;
}

#fern-sidebar,
.fern-page-actions {
  font-family: var(--font-chrome);
}

#fern-sidebar .fern-sidebar-heading,
#fern-sidebar .fern-sidebar-heading-content {
  font-weight: 500;
}

/* App tab-rail parity (`.c-tabs__link`): label text and icons both
   exactly 16px — the proven balanced pairing. `width`/`height` pin
   the inline SVGs the renderer sizes via utility classes. */
.fern-sidebar-link {
  font-size: 1rem;
}

#fern-sidebar svg,
#fern-sidebar i {
  font-size: 1rem;
  width: 1rem;
  height: 1rem;
}

/* Futura's small x-height wants the half-step up from the row's 14px */
.fern-page-actions {
  font-size: 0.90625rem;
}

/* Breadcrumb as the app's eyebrow gesture (`.c-type-accent` register):
   uppercase tracked Futura over the Domaine title below it. */
/* The trailing negative margin swallows the phantom space tracking
   leaves after the last letter, restoring true optical edge alignment
   for every tracked-caps label below. */
.fern-breadcrumb,
.fern-breadcrumb .fern-breadcrumb-item {
  font-family: var(--font-chrome);
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-right: -0.08em;
}

/* Prompt titles use the `.c-type-accent` eyebrow register, below the
   minimum size for Domaine Display. Callout titles retain Fern's scale. */
.fern-prompt h5 {
  font-family: var(--font-chrome);
  font-size: 0.71875rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  margin-right: -0.12em;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Raw inline callout content inherits Fern's text-sm wrapper; MDX blocks
   also receive prose rules. Set both so intent and authored line breaks
   cannot change the body typography. Titles use the Söhne control register. */
.fern-callout {
  --c-callout-leading: 1.375rem; /* 22px: slightly tighter than 1.6 × 14.5px. */
  --c-callout-border: var(--grayscale-a6);
}

.fern-prose .fern-callout > div > div:last-child,
.fern-prose .fern-callout :is(p, li) {
  font-size: 0.90625rem;
  line-height: var(--c-callout-leading);
}

.fern-prose .fern-callout {
  padding: 0.625rem 0.8125rem;
  border-color: color-mix(in srgb, var(--c-callout-border) 75%, transparent);
}

/* A marker example inside a callout is a caption for the sentence beneath it,
   not a paragraph. Fern emits a callout body as bare inline content followed
   by real paragraphs, so an icon row gets no `p` of its own: it sits flush
   under the title and then takes the following paragraph's full margin
   beneath, which reads as a gap. The row carries the house `c-detail-levels`
   group so it can be addressed at all; make it a block and even both gaps. */
.fern-prose .fern-callout .c-detail-levels:not(p *) {
  display: block;
  margin: 0.5em 0 0;
}

.fern-prose .fern-callout .c-detail-levels:not(p *) + p {
  margin-top: 0.5em;
}

.fern-callout[data-intent='warning'] {
  --c-callout-border: var(--amber-a6);
}

.fern-callout:is([data-intent='success'], [data-intent='tip'], [data-intent='check']) {
  --c-callout-border: var(--green-a6);
}

.fern-callout[data-intent='error'] {
  --c-callout-border: var(--red-a6);
}

.fern-callout[data-intent='note'] {
  --c-callout-border: var(--blue-a6);
}

.fern-callout[data-intent='launch'] {
  --c-callout-border: var(--accent-a6);
}

/* The first body line and any nonempty title both use 22px leading. */
.fern-callout > div > div:first-child {
  display: flex;
  align-items: center;
  height: var(--c-callout-leading);
  margin-top: 0;
  margin-inline-end: 0.5rem;
}

.fern-callout > div > div:first-child svg {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
}

.fern-callout > div > div > .font-heading:empty + p {
  margin-top: 1rem; /* Cancel the content wrapper's -1rem top margin. */
}

.fern-prose .fern-callout > div > div > .font-heading:not(:empty) {
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 700;
  line-height: var(--c-callout-leading);
  margin-bottom: 0;
}

.fern-prose .fern-callout > div > div > .font-heading:not(:empty) + p {
  margin-top: 0.5rem;
}

/* Accordion titles stay Domaine, sized per the cap-harmonized scale
   above — at the heading rules' 16px they read perceptually smaller
   than the prose beside them. Tracking pinned to the sub-21px tier
   (a renderer utility otherwise leaves them at -0.02em). */
.fern-accordion-trigger-title {
  font-size: 1.1875rem;
  letter-spacing: -0.01em;
  line-height: 1.3;
}

/* Step anchors: 15px numerals aligned as a column. The feature string
   restates the body stack plus `zero` — slashed zeros stay wanted in
   technical anchors even though prose dropped them. */
.fern-anchor-icon {
  font-size: 0.9375rem;
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: 'kern' 1, 'liga' 1, 'calt' 1, 'ss02' 1, 'zero' 1;
}

/* Next/Previous footer nav titles are Domaine at the renderer's 16px —
   below the face's ~18px minimum; lift to the h6 tier. */
#fern-docs footer nav h4 {
  font-size: 1.1875rem;
  letter-spacing: -0.01em;
}

/* Table of contents — chrome describing the content: Futura, the
   sidebar's 16px, the breadcrumb's eyebrow on its label, and active
   emphasis capped at the real 500 (renderer asks bolder). */
#fern-toc {
  font-family: var(--font-chrome);
}

#fern-toc div.text-sm.font-medium {
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-right: -0.08em;
}

#fern-toc a {
  font-size: 1rem;
}

#fern-toc a.font-bold,
#fern-toc a.font-semibold,
#fern-toc a[aria-current] {
  font-weight: 500;
}

/* Lockup label (`logo.right-text`) — the breadcrumb's eyebrow register
   -------------------------------------------------------------------
   The renderer ships this as Domaine 1.5rem/300 in the accent color; only
   the color is kept. Everything else drops to the tracked-caps Futura of
   `.fern-breadcrumb-item`, so the label reads as chrome beside the mark
   rather than as a second wordmark competing with it.
   The two-line break is set by width, not markup: the label is one text
   node the renderer owns, so `max-width` is the only lever. 5.5em (66px at
   this size) clears `HELP &` and `GUIDES` individually but not the full
   string, which puts the greedy break after the ampersand. It is expressed
   in `em` so it tracks the font-size rather than pinning to one px value. */
#fern-header .fern-logo-text {
  display: inline-block;
  max-width: 5.5em;
  margin-left: 0.75rem;
  margin-right: -0.08em;
  font-family: var(--font-chrome);
  font-size: 0.6875rem;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: left;
  white-space: normal;
}

@media (max-width: 639px) {

  #fern-header .flex:has(> .fern-header-logo-container) {
    gap: 0.5rem;
  }

  #fern-header [data-fern-logo] {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }

  #fern-header [data-fern-logo] img {
    width: auto !important;
    height: 22px !important;
  }

  #fern-header .fern-header-logo-container {
    margin-right: 4px;
  }

  #fern-header .fern-logo-text {
    box-sizing: border-box;
    width: 100%;
    max-width: none;
    margin: 0;
    /* Brand wordmark starts at x=2175.3980317 of 9248; compensate final tracking. */
    padding-left: calc(23.5229% + 2.25px);
    letter-spacing: 2.25px;
    text-align: center;
    white-space: nowrap;
  }

  #fern-header #fern-search-button > div:has(> kbd) {
    display: none;
  }

}

/* Search — app `#uig-text-empty` material register
   ------------------------------------------------
   The renderer exposes search as a button, but it occupies the app text
   input's role in the sidebar. Keep Fern's centered button content while
   porting the input's shell, edge sheen, warm lift, and focus ring — at 40px
   rather than the app input's 48px, the height that lines the control up with
   the sheet's top edge across the desktop breakpoints. */
#fern-search-button {
  height: 40px;
  /* Asymmetric by design: the leading icon keeps the input's 14px inset, but
     the trailing key caps are 20px in a 40px shell, so a 10px right pad is
     what makes the last cap equidistant from the top, bottom, and right. */
  padding: 0 10px 0 14px;
  gap: 8px;
  border: 1px solid rgb(var(--c-white-rgb) / 0.56) !important;
  border-radius: 8px;
  background:
    radial-gradient(140% 90% at 50% -35%, rgb(var(--c-white-rgb) / 0.6) 0%, rgb(var(--c-white-rgb) / 0.24) 38%, transparent 68%),
    linear-gradient(180deg, rgb(var(--c-white-rgb) / 0.24) 0%, transparent 55%),
    rgb(251 250 246 / 0.82);
  box-shadow:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.48),
    inset 0 -1px 0 rgb(45 41 38 / 0.035),
    0 0 0 1px rgb(228 224 219 / 0.42),
    0 1px 2px rgb(45 41 38 / 0.045),
    0 8px 18px -16px rgb(45 41 38 / 0.22);
  color: #78716b;
  font-family: var(--font-chrome);
  font-size: 0.90625rem;
  font-weight: 400;
  transition: background 0.15s ease-out, border-color 0.15s ease-out, box-shadow 0.15s ease-out;
}

/* Key label — Cmd/Ctrl+K, paired with `search-hotkey.js`.
   The renderer prints a literal `/` into a single `kbd.fern-kbd`; the
   accelerator is added by the script, which cannot relabel the element
   without writing into renderer-owned markup. Rebuild the label here
   instead: the `kbd` becomes a bare flex track (its own chip chrome moves
   onto the children), `font-size: 0` collapses the real `/` text node, and
   the element's two pseudo-elements become the two key caps — the only way
   to get a second box without adding markup.
   Every rule hangs off the `data-hotkey-modifier` flag the script stamps on
   `<html>`, so a script that never runs leaves the stock `/` untouched: the
   label cannot advertise a binding that is not installed.
   The caps are square at rest (`min-width` = `height`); `Ctrl` simply
   outgrows the minimum, and because the renderer's wrapper carries `ml-auto`
   the extra width is taken leftward, holding the right edge fixed. */
[data-hotkey-modifier] #fern-search-button .fern-kbd {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 0;
  border: none;
  background: none;
  font-size: 0;
}

[data-hotkey-modifier] #fern-search-button .fern-kbd::before,
[data-hotkey-modifier] #fern-search-button .fern-kbd::after {
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  height: 20px;
  min-width: 20px;
  padding-inline: 5px;
  border: 1px solid var(--grayscale-a6);
  border-radius: calc(var(--radius) * 1.5);
  /* Sandstone, NOT `--grayscale-surface` — that token is white at 80%, which
     over the field composites to #FEFEFD and makes the caps brighter than the
     control holding them. Sandstone sits just under it (#F5F4EF against the
     button's ~#FAF9F5), the same step a table header takes from its card
     (`--grayscale-a2` over `--card-background` composites to #F5F4EF exactly).
     The light value is the base and dark overrides below, rather than the
     reverse: one declaration wins per mode, with no specificity contest. */
  background-color: var(--background);
  color: var(--grayscale-a12);
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 400;
  line-height: 1;
}

/* U+2318 is absent from Söhne and resolves through the stack to a system
   face — which is safe precisely because this branch only ever renders on
   Apple platforms, where that glyph is guaranteed. */
[data-hotkey-modifier='command'] #fern-search-button .fern-kbd::before {
  content: '\2318';
}

[data-hotkey-modifier='control'] #fern-search-button .fern-kbd::before {
  content: 'Ctrl';
}

[data-hotkey-modifier] #fern-search-button .fern-kbd::after {
  content: 'K';
}

/* Dark keeps the stock surface — a dark alpha there, already below its field. */
.dark [data-hotkey-modifier] #fern-search-button .fern-kbd::before,
.dark [data-hotkey-modifier] #fern-search-button .fern-kbd::after {
  background-color: var(--grayscale-surface);
}

/* Top-align the control with the sheet. The desktop sidebar stacks the search
   row under `pt-2` on its column (8px) plus `mt-3 lg:mt-2` on the row itself
   (8px at lg), landing the button 16px below the main content box while the
   sheet's top edge sits at 2px. Zero the column's top padding and restate the
   row's margin at that 2px, so both tops resolve to the same line. Scoped by
   `[data-viewport='desktop']` rather than a pixel media query: that attribute
   is exactly the condition under which this sidebar (and this stack) renders,
   so the override cannot drift out of step with Fern's own `lg` breakpoint. */
#fern-sidebar[data-viewport='desktop'] > .flex.flex-col {
  padding-top: 0;
}

#fern-sidebar[data-viewport='desktop'] > .flex.flex-col > .flex.flex-row:has(> #fern-search-button) {
  margin-top: 2px;
}

#fern-search-button:hover {
  border-color: rgb(var(--c-white-rgb) / 0.68) !important;
  background:
    radial-gradient(145% 95% at 50% -35%, rgb(var(--c-white-rgb) / 0.68) 0%, rgb(var(--c-white-rgb) / 0.28) 40%, transparent 70%),
    rgb(251 250 246 / 0.9);
  box-shadow:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.56),
    inset 0 -1px 0 rgb(45 41 38 / 0.035),
    0 0 0 1px rgb(228 224 219 / 0.52),
    0 2px 4px rgb(45 41 38 / 0.055),
    0 10px 20px -17px rgb(45 41 38 / 0.25);
}

#fern-search-button:focus-visible {
  border-color: rgb(122 79 103 / 0.76) !important;
  background:
    radial-gradient(140% 90% at 50% -35%, rgb(var(--c-white-rgb) / 0.7) 0%, rgb(var(--c-white-rgb) / 0.28) 42%, transparent 70%),
    rgb(251 250 246 / 0.92);
  box-shadow:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.62),
    inset 0 -1px 0 rgb(45 41 38 / 0.025),
    0 0 0 3px rgb(164 139 156 / 0.34),
    0 6px 14px -12px rgb(45 41 38 / 0.22);
  color: #6f0c4a;
  outline: none;
}

/* TENTATIVE — operator-supplied recipe, not yet a derived standard. It
   inverts the light sheen (ground-colored top inset, deeper bottom insets
   picking up `--card-background`) instead of the white-alpha lift, and is
   the only dark surface carrying it. Tune deliberately before trusting the
   numbers; FLAG THE OPERATOR before extending this recipe to any other
   element — it is not yet the portal's dark elevation language. */
.dark #fern-search-button {
  border-color: rgb(var(--c-white-rgb) / 0.14) !important;
  background: var(--c-surface-emphasis);
  box-shadow:
    inset 0 1px 0 rgb(39 7 31 / 0.2),
    inset 0 -1px 0 rgb(39 7 31 / 0.5),
    inset 0 -2px 0 rgb(85 59 78 / 0.2),
    0 1px 2px rgb(45 41 38 / 0.045),
    0 8px 18px -16px rgb(45 41 38 / 0.22);
  color: var(--accent-11);
}

/* Hover derives from the rest recipe above, not from the old white-alpha
   lift. The top inset stays pinned at its rest value: brightening it read as
   a hard light seam across the top edge rather than as elevation. The change
   is carried by the surface and the lower insets instead — the bottom edge
   deepens and the drop spreads, so the control lifts without re-lighting. */
.dark #fern-search-button:hover {
  border-color: rgb(var(--c-white-rgb) / 0.22) !important;
  background: color-mix(in srgb, var(--c-surface-emphasis), var(--c-foreground) 4%);
  box-shadow:
    inset 0 1px 0 rgb(39 7 31 / 0.2),
    inset 0 -1px 0 rgb(39 7 31 / 0.55),
    inset 0 -2px 0 rgb(85 59 78 / 0.28),
    0 1px 2px rgb(45 41 38 / 0.06),
    0 10px 22px -16px rgb(45 41 38 / 0.3);
}

.dark #fern-search-button:focus-visible {
  border-color: var(--accent-8) !important;
  background: color-mix(in srgb, var(--c-surface-emphasis), var(--c-foreground) 4%);
  box-shadow: 0 0 0 3px rgb(210 173 210 / 0.28);
  color: var(--accent-12);
}

/* The Sheet
   ---------
   Light: exact app `.c-card` surface, border, radius, and four-layer
   warm lift. The sheet is the portal's one card instance, so the recipe
   stays literal instead of importing the app's SCSS token system. */
/* Geometry: the renderer sizes the sheet
   `height: calc(100vh - var(--header-height-real) - 12px)` under the default
   `box-sizing: content-box`, with `margin: 0 12px 12px 0`. Two consequences,
   both fixed here rather than papered over with a blanket `margin: 2px`
   (which would also have collapsed the intended 12px right/bottom gutter):
     · the top and left borders sat flush under the header and against the
       sidebar, so the sheet read as edgeless;
     · content-box left the 1px top+bottom borders OUTSIDE that height, so the
       document ran exactly 2px past 100vh — a whole-page scrollbar nested
       around the sheet's own, and 2px of overscroll that clipped the top
       border.
   `border-box` pulls the borders back inside the declared height; the 2px top
   margin (which reveals the border and lines the sheet's top edge up with the
   sidebar search control) is then subtracted from that height, so the column
   totals exactly 100vh: 64 header + 2 + (100vh - 64 - 14) + 12 bottom. */
.canvas-wrapper {
  --c-toc-height: 0px;
  --c-toc-track-height: var(--c-toc-height);
  --c-toc-trigger: var(--background);
  --c-toc-panel: var(--card-background);
  box-sizing: border-box !important;
  margin-top: 2px !important;
  margin-left: 2px !important;
  height: calc(100vh - var(--header-height-real) - 14px) !important;
  height: calc(100dvh - var(--header-height-real) - 14px) !important;
  scroll-padding-top: calc(var(--c-toc-height) + 1rem) !important;
  background: var(--c-sheet) !important;
  border: 1px solid rgb(var(--c-white-rgb) / 0.45) !important;
  border-radius: 12px !important;
  box-shadow:
    0 -1px 2px rgb(45 41 38 / 0.03),
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.55),
    0 1px 2px rgb(45 41 38 / 0.06),
    0 14px 34px -24px rgb(45 41 38 / 0.13);
}

@media (max-width: 1023px) {

  .canvas-wrapper {
    margin-inline: 6px !important;
    min-width: 0;
  }

}

/* Fern hides this bar at 80rem and omits it for fewer than two anchors.
   The measured variable can be zero after a desktop resize; 41px is the
   renderer's single-line trigger height, including its bottom border. */
@media (width < 80rem) {

  .canvas-wrapper:has(.toc-mobile-bar) {
    --c-toc-height: max(41px, var(--mobile-toc-height, 41px));
  }

}

/* Dark: flat fill + hairline, no elevation — web dark doctrine says
   depth is atmospheric, never box-shadow. */
.dark .canvas-wrapper {
  border-color: var(--border) !important;
  box-shadow: none;
}

/* Keep Fern's scroll root: its anchor/progress code targets `.canvas-wrapper`.
   Standard properties are the native fallback; non-auto values override the
   WebKit pseudo-elements, so the custom lane must reset both explicitly. */
.canvas-wrapper {
  scrollbar-width: thin;
  scrollbar-color: var(--grayscale-a6) transparent;
}

@supports selector(::-webkit-scrollbar) {

  .canvas-wrapper {
    scrollbar-width: auto;
    scrollbar-color: auto;
  }

  .canvas-wrapper::-webkit-scrollbar {
    width: 12px;
    height: 12px;
  }

  .canvas-wrapper::-webkit-scrollbar-track,
  .canvas-wrapper::-webkit-scrollbar-corner {
    background: transparent;
  }

  .canvas-wrapper::-webkit-scrollbar-track:vertical {
    margin-top: calc(var(--c-toc-track-height) + 4px);
    margin-bottom: 4px;
  }

  /* Paint the bar's surface and separator across the reserved scrollbar
     gutter, which lies outside the content's paintable scrollport. */
  @media (width < 80rem) {

    .canvas-wrapper:has(.toc-mobile-bar)::-webkit-scrollbar:vertical {
      background: linear-gradient(to bottom,
        var(--c-toc-trigger) calc(var(--c-toc-height) - 1px),
        var(--border) calc(var(--c-toc-height) - 1px) var(--c-toc-height),
        transparent var(--c-toc-height));
    }
  
}

  .canvas-wrapper::-webkit-scrollbar-thumb {
    border: 4px solid transparent;
    border-radius: 999px;
    background: var(--grayscale-a6);
    background-clip: content-box;
  }

  .canvas-wrapper::-webkit-scrollbar-thumb:hover {
    background: var(--grayscale-a8);
    background-clip: content-box;
  }
.canvas-wrapper::-webkit-scrollbar-thumb:focus-visible {
    background: var(--grayscale-a8);
    background-clip: content-box;
  }

}

/* A filtered ancestor becomes a backdrop root: blur the two sibling
   surfaces independently so the open panel can sample the article below. */
.canvas-wrapper .toc-mobile-bar {
  border-bottom: 0;
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.canvas-wrapper .toc-mobile-bar > div > button {
  padding-left: 12px;
  padding-right: 19px;
  border-bottom: 1px solid var(--border);
  border-radius: 11px 11px 0 0;
  background: var(--c-toc-trigger);
}

/* Match the header's 16px → 24px gutter change. The right inset includes
   the 12px scrollbar gutter now covered by the full-width button. */
@media (min-width: 48rem) {

  .canvas-wrapper .toc-mobile-bar > div > button {
    padding-left: 20px;
    padding-right: 27px;
  }

}

.canvas-wrapper .toc-mobile-bar > div > button:hover {
  background-image: linear-gradient(var(--grayscale-a2), var(--grayscale-a2));
}
.canvas-wrapper .toc-mobile-bar > div > button:focus-visible {
  background-image: linear-gradient(var(--grayscale-a2), var(--grayscale-a2));
}

.canvas-wrapper .toc-mobile-bar .fern-collapsible {
  background: var(--c-toc-panel);
}

.dark .canvas-wrapper {
  --c-toc-trigger: var(--c-surface-nested);
  --c-toc-panel: var(--c-surface-nested);
}

/* The measured fixed surface escapes the scrollport clip, keeping its hover
   and hit area full-width. The sticky placeholder remains Fern's anchor. */
@media (width < 80rem) {

  [data-toc-layout='ready'] .canvas-wrapper {
    --c-toc-track-height: var(--c-toc-covered-height);
  }

  [data-toc-layout='ready'] .toc-mobile-bar {
    height: var(--c-toc-button-height);
  }

  [data-toc-layout='ready'] .toc-mobile-bar > div {
    position: fixed;
    top: var(--c-toc-top);
    left: var(--c-toc-left);
    width: var(--c-toc-width);
  }

  [data-toc-layout='ready'] .toc-mobile-bar .fern-scroll-area {
    max-height: var(--c-toc-panel-max-height);
  }

  [data-toc-layout='ready'] .canvas-wrapper:has(.toc-mobile-bar)::-webkit-scrollbar:vertical {
    background: transparent;
  }

}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {

  .canvas-wrapper {
    --c-toc-trigger: color-mix(in srgb, var(--background) 70%, transparent);
    --c-toc-panel: color-mix(in srgb, var(--card-background) 84%, transparent);
  }

  .dark .canvas-wrapper {
    --c-toc-trigger: color-mix(in srgb, var(--c-surface-nested) 70%, transparent);
    --c-toc-panel: color-mix(in srgb, var(--c-surface-nested) 84%, transparent);
  }

  .canvas-wrapper .toc-mobile-bar > div > button,
  .canvas-wrapper .toc-mobile-bar .fern-collapsible {
    -webkit-backdrop-filter: blur(var(--blur-lg, 16px));
    backdrop-filter: blur(var(--blur-lg, 16px));
  }

}

/* Fern derives off-brand green/cyan accents beside the pinned solids.
   Keep its low-step alpha weights but use Curate lilac; high steps take
   the pinned solids, as in light mode. Neutral veils use Tyrian-50. */
.dark {
  --accent-contrast: var(--c-sheet);
  --accent-a1: rgb(210 173 210 / 0.045);
  --accent-a2: rgb(210 173 210 / 0.066);
  --accent-a3: rgb(210 173 210 / 0.094);
  --accent-a4: rgb(210 173 210 / 0.122);
  --accent-a5: rgb(210 173 210 / 0.147);
  --accent-a6: rgb(210 173 210 / 0.192);
  --accent-a7: rgb(210 173 210 / 0.283);
  --accent-a8: rgb(210 173 210 / 0.392);
  --accent-a9: var(--accent-9);
  --accent-a10: var(--accent-10);
  --accent-a11: var(--accent-11);
  --accent-a12: var(--accent-12);
  --grayscale-a1: rgb(var(--c-white-rgb) / 0.015);
  --grayscale-a2: rgb(var(--c-white-rgb) / 0.035);
  --grayscale-a3: rgb(var(--c-white-rgb) / 0.078);
  --grayscale-a4: rgb(var(--c-white-rgb) / 0.113);
  --grayscale-a5: rgb(var(--c-white-rgb) / 0.148);
  --grayscale-a6: rgb(var(--c-white-rgb) / 0.191);
  --grayscale-a7: rgb(var(--c-white-rgb) / 0.252);
  --grayscale-a8: rgb(var(--c-white-rgb) / 0.386);
  --grayscale-a9: rgb(var(--c-white-rgb) / 0.447);
  --grayscale-a10: rgb(var(--c-white-rgb) / 0.499);
  --grayscale-a11: rgb(var(--c-white-rgb) / 0.718);
  --grayscale-a12: rgb(var(--c-white-rgb) / 0.937);
}

/* Light alpha scale — the fuchsia at its source.
   The pinned `accent-1…12` solids in `docs.yml` are already brand-tone; the
   faint pink surfaces (sidebar active pill, tertiary hovers) come from the
   scale Fern DERIVES beside them, which is not the brand plum at all but a
   vivid display-p3 magenta — `--accent-a3` resolves to
   `p3(0.733 0.008 0.522 / 0.103)`, and `--accent-a1` is not even in the
   family (a pale blue, `p3(0.867 0.831 1 / 0.125)`). Over the sheet that a3
   composites to ~#F3DAE7, the faint fuchsia.
   Re-derive every step from the brand values in sRGB, keeping Fern's own
   alpha weights so each step lands where the renderer expects it. The same
   weight against the true accent gives #6F0C4A at 0.103 over #FBFAF6 =
   #EDE1E4 — the warm brand mauve, on the nose. Steps 1–8 are the tint band
   and take the interactive plum; 9–12 are effectively opaque, so they take
   the solid steps already pinned in `docs.yml` (10 brightens on hover, 12 is
   App Tyrian) rather than drifting to a lightened plum. */
/* Body ink: the renderer paints prose straight from `--color-black` #2A2A2A
   (`body,html{color:var(--color-black)}`, `.text-body`) — `--color-body` is
   only an alias it derives from that, so overriding the alias never reached
   the text (measured 2026-09-06: prose still rendered #2A2A2A). Pin
   `--color-black` itself to the App ink (#2D2926) so the prose sits in the
   same family as the surfaces under it; `--color-body` follows. Light only
   — dark paints prose from `--color-white`. */
:root:not(.dark) {
  --color-black: #2d2926;
  --color-body: #2d2926;
  --accent-a1: rgb(111 12 74 / 0.125);
  --accent-a2: rgb(111 12 74 / 0.041);
  --accent-a3: rgb(111 12 74 / 0.103);
  --accent-a4: rgb(111 12 74 / 0.16);
  --accent-a5: rgb(111 12 74 / 0.218);
  --accent-a6: rgb(111 12 74 / 0.283);
  --accent-a7: rgb(111 12 74 / 0.365);
  --accent-a8: rgb(111 12 74 / 0.468);
  --accent-a9: rgb(111 12 74 / 0.906);
  --accent-a10: rgb(133 23 94 / 0.82);
  --accent-a11: rgb(111 12 74 / 0.734);
  --accent-a12: rgb(77 8 52 / 0.927);
}

/* Content gutter: the hover anchor chip is a left-side Radix tooltip
   (24px + offset), so the content column needs ≥3rem of sheet-side
   breathing room or the chip straddles the sheet border — the same
   role as legal's `.c-doc` clamp padding. */
.fern-layout-guide,
.fern-layout-overview,
.fern-layout-reference {
  padding-inline: clamp(2.5rem, 4vw, 3.25rem) !important;
}

@media (max-width: 639px) {

  .fern-layout-guide,
  .fern-layout-overview,
  .fern-layout-reference {
    padding-inline: 20px !important;
  }

}

/* Keep Fern's configured article width, capped at both the available column
   and the reading measure. A fixed cap alone overrides `max-w-full` and
   allows the configured width to overflow narrow columns. */
.fern-layout-guide article {
  max-width: min(100%, 48rem);
}

/* Anchor jumps: heading targets carried `scroll-margin-top: 0` under
   the 64px fixed header (verified live) — jumped-to headings landed
   underneath it. */
article [id] {
  scroll-margin-top: calc(var(--header-height, 64px) + 1rem);
}

.canvas-wrapper article [id] {
  scroll-margin-top: 0;
}

/* Icons
   -----
   FA Pro glyphs may paint outside the 512-unit artboard (wine-glass
   reaches 544): the renderer leaves `overflow: hidden`, clipping feet
   and ascenders. FA's own kit CSS ships overflow visible. */
svg[data-icon] {
  overflow: visible;
}

/* Callouts
   --------
   Inline code inside a callout keeps the intent's text color and takes
   a tonal fill mixed from it, instead of the page accent on cream. The
   chip's "border" is a Tailwind ring (box-shadow), tone-matched too. */
.fern-callout code {
  color: inherit;
  background-color: color-mix(in srgb, currentColor 9%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, currentColor 22%, transparent);
}

/* The Launch intent derives from lilac alphas in dark and reads grey;
   pin it to the tyrian register so it keeps the light mode's plum tone. */
.dark .fern-callout[data-intent='launch'] {
  --c-callout-border: var(--accent-8);
  background-color: var(--accent-4);
}

/* Buttons — app `.c-btn` register
   -------------------------------
   Geometry is shared by MDX buttons and the three reader-control roles.
   Filled/default + helpful Yes/No = secondary; minimal + Copy Page +
   theme picker = tertiary. The selectors are renderer internals and must
   be rechecked after a `fern-api` bump. */
article .fern-button.filled,
article .fern-button.minimal,
.fern-page-actions > button,
.fern-layout-footer-toolbar .flex.gap-2 > button,
button[aria-haspopup='menu']:has(> svg:is(.lucide-monitor, .lucide-sun, .lucide-moon)) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 38px;
  padding: 8px 24px;
  gap: 8px;
  border-radius: 9999px;
  font-family: var(--font-chrome);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1;
  transition:
    background-color 0.25s ease,
    border-color 0.25s ease,
    color 0.25s ease,
    box-shadow 0.25s ease,
    transform 0.25s ease;
}

.fern-header-navbar-links > button[aria-haspopup='menu']:has(> svg:is(.lucide-monitor, .lucide-sun, .lucide-moon)) {
  width: 38px;
  min-width: 38px;
  padding: 0;
  border-radius: 50%;
}

article .fern-button.filled,
.fern-layout-footer-toolbar .flex.gap-2 > button {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background-color: rgb(251 250 246 / 0.78);
  color: #6f0c4a;
  border: 1px solid rgb(var(--c-white-rgb) / 0.45);
  box-shadow:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.35),
    0 1px 2px rgb(45 41 38 / 0.06),
    0 4px 12px -4px rgb(45 41 38 / 0.1);
}

article .fern-button.filled::before,
.fern-layout-footer-toolbar .flex.gap-2 > button::before {
  content: '';
  position: absolute;
  inset: 1px;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  background:
    radial-gradient(var(--c-white) 0%, rgb(251 250 246 / 0.2) 100%),
    linear-gradient(160deg, rgb(45 41 38 / 0.04), transparent 90%);
  opacity: 0.9;
}

article .fern-button.filled:hover,
.fern-layout-footer-toolbar .flex.gap-2 > button:hover {
  background-color: rgb(251 250 246 / 0.9);
  color: #6f0c4a;
  border-color: rgb(var(--c-white-rgb) / 0.68);
  box-shadow:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.56),
    inset 0 -1px 0 rgb(45 41 38 / 0.035),
    0 0 0 1px rgb(228 224 219 / 0.52),
    0 2px 4px rgb(45 41 38 / 0.055),
    0 10px 20px -17px rgb(45 41 38 / 0.25);
}
article .fern-button.filled:focus-visible {
  background-color: rgb(251 250 246 / 0.9);
  color: #6f0c4a;
  border-color: rgb(var(--c-white-rgb) / 0.68);
  box-shadow:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.56),
    inset 0 -1px 0 rgb(45 41 38 / 0.035),
    0 0 0 1px rgb(228 224 219 / 0.52),
    0 2px 4px rgb(45 41 38 / 0.055),
    0 10px 20px -17px rgb(45 41 38 / 0.25);
}

article .fern-button.filled:active,
.fern-layout-footer-toolbar .flex.gap-2 > button:active {
  background-color: rgb(251 250 246 / 0.92);
  color: #6f0c4a;
  border-color: rgb(var(--c-white-rgb) / 0.5);
  box-shadow:
    inset 0 1px 2px rgb(var(--c-white-rgb) / 0.3),
    0 1px 2px rgb(45 41 38 / 0.06);
}

article .fern-button.minimal,
.fern-page-actions > button,
button[aria-haspopup='menu']:has(> svg:is(.lucide-monitor, .lucide-sun, .lucide-moon)) {
  border: none;
  background-color: transparent;
  box-shadow: none;
  color: #6f0c4a;
}

article .fern-button.minimal:hover,
.fern-page-actions > button:hover,
button[aria-haspopup='menu']:has(> svg:is(.lucide-monitor, .lucide-sun, .lucide-moon)):hover {
  background-color: rgb(111 12 74 / 0.1);
  backdrop-filter: blur(4px);
  color: #6f0c4a;
}
article .fern-button.minimal:focus-visible {
  background-color: rgb(111 12 74 / 0.1);
  backdrop-filter: blur(4px);
  color: #6f0c4a;
}

article .fern-button.minimal:active,
.fern-page-actions > button:active,
button[aria-haspopup='menu']:has(> svg:is(.lucide-monitor, .lucide-sun, .lucide-moon)):is(:active, [data-state='open']) {
  background-color: rgb(111 12 74 / 0.15);
  backdrop-filter: blur(4px);
  color: #6f0c4a;
}

article .fern-button {
  margin: 0 2px 6px 0;
}

article .fern-button:focus-visible,
.fern-page-actions > button:focus-visible,
.fern-layout-footer-toolbar .flex.gap-2 > button:focus-visible,
button[aria-haspopup='menu']:has(> svg:is(.lucide-monitor, .lucide-sun, .lucide-moon)):focus-visible {
  box-shadow: 0 0 0 2px rgb(111 12 74 / 0.55);
  outline: none;
}

/* The label span truncates (`overflow: hidden`) at line-height 1, which
   crops Söhne descenders — open the leading, keep the truncation. */
article .fern-button .fern-button-text {
  line-height: 1.35;
}

/* Trailing indicator (external-link / arrow) — the app `.c-btn__arrow`
   register: a 10px whisper with the 2px hover nudge, not a 16px glyph
   shouting beside the label. Leading icons keep the stock 16px. */
article .fern-button.filled .fern-button-content > svg:last-child:not(:first-child) {
  width: 0.625rem;
  height: 0.625rem;
  margin-left: 2px;
  margin-right: -5px;
  transition: transform 0.25s ease;
}

article .fern-button.filled:hover .fern-button-content > svg:last-child:not(:first-child) {
  transform: translateX(2px);
}
article .fern-button.filled:focus-within .fern-button-content > svg:last-child:not(:first-child) {
  transform: translateX(2px);
}

/* Badges — Futura at the app `.c-badge` register (500, xs-half). Fern's
   default palette is retained for now (recorded as an open item). */
article .fern-docs-badge {
  font-family: var(--font-chrome);
  font-weight: 500;
}

article .fern-docs-badge.large {
  font-size: 0.84375rem;
}

/* Compact icon labels sit on the prose baseline, independent of block badges. */
.fern-prose :is(p, li, td) .fern-docs-badge:has(.fern-mdx-icon) {
  padding: 0 3px 0 2.5px;
  margin: 0 1px;
  height: 1.375rem;
  position: relative;
  top: 2px;
}

.fern-prose :is(p, li, td) .fern-docs-badge .fern-mdx-icon:not(.c-required-asterisk, .c-detail-level, .c-feature-included, .c-feature-not-included) {
  width: 0.875rem !important;
  height: 0.875rem !important;
}

/* Descriptive cells may wrap; the first column reserves each UI label's width.
   Fern's native table scroll area contains tables wider than the reader sheet. */
.fern-prose td .fern-docs-badge:has(.fern-mdx-icon) {
  white-space: normal;
  height: auto;
  min-height: 1.375rem;
}

.fern-prose td:first-child:has(.fern-docs-badge) {
  width: 1%;
}

.fern-prose td:first-child .fern-docs-badge {
  white-space: nowrap;
}

.fern-prose table:has(td:first-child .fern-docs-badge) :is(th, td):last-child {
  min-width: 14rem;
}

.fern-prose table:has(td:first-child .fern-docs-badge):has(th:nth-child(3)) :is(th, td):nth-child(2) {
  min-width: 8rem;
}

.fern-prose td .fern-docs-badge .fern-mdx-icon {
  flex-shrink: 0;
}

/* <Compare> against renderer internals. The component's own chrome lives in
   fern/compare.css; only these selectors name Fern's DOM, so only these live
   here. The compact badge calibration above is scoped to `p, li, td` and a
   Compare label is a flex span, so it is restated — without the 2px baseline
   nudge, which the flex row already centers (and which a paragraph wrapper
   would otherwise reapply). */
.fern-prose .c-compare .fern-docs-badge:has(.fern-mdx-icon) {
  padding: 0 3px 0 2.5px;
  margin: 0 1px;
  height: 1.375rem;
  top: 0;
  white-space: normal;
}

.fern-prose .c-compare .fern-docs-badge .fern-mdx-icon {
  width: 0.875rem !important;
  height: 0.875rem !important;
  flex-shrink: 0;
}

/* State and column glyphs take their ink from the cell, so one authored
   <Icon> serves every state without a per-state asset. */
.fern-prose .c-compare .c-compare__mark .fern-mdx-icon {
  width: 0.8125rem !important;
  height: 0.8125rem !important;
  margin: 0;
  color: inherit;
}

/* A value row's glyphs are its whole content, with no word beside them to
   carry the reading; the heads keep the smaller size because theirs sits
   above a word. */
.fern-prose .c-compare .c-compare__row:not(.c-compare__row--head) .c-compare__mark .fern-mdx-icon {
  width: 0.875rem !important;
  height: 0.875rem !important;
}


/* The anchor owns link ink and focus; the badge retains its accent outline. */
.fern-prose .fern-mdx-link .fern-docs-badge[data-intent='launch'] {
  color: inherit;
}

.fern-prose .fern-mdx-link:has(.fern-docs-badge[data-intent='launch']):focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
  border-radius: 4px;
}

/* Reader-facing device labels use App badge hues, with darker orange ink for
   small text. Their scoped rule also clears Fern's default info grayscale filter.
   Dark surfaces are Help-owned, derived from the same source pairs. */
.c-guide-device--mobile {
  --c-guide-device-ink: #0f766e;
  --c-guide-device-ground: #ddf4f2;
}

.c-guide-device--wide {
  --c-guide-device-ink: color-mix(in srgb, #ef6c00 65%, #2d2926);
  --c-guide-device-ground: #fff3e0;
}

.dark .c-guide-device--mobile {
  --c-guide-device-ink: #ddf4f2;
  --c-guide-device-ground: color-mix(in srgb, #0f766e 25%, var(--c-sheet));
}

.dark .c-guide-device--wide {
  --c-guide-device-ink: #fff3e0;
  --c-guide-device-ground: color-mix(in srgb, #ef6c00 20%, var(--c-sheet));
}

/* Status and device badges are one treatment — soft fill, no border, no
   shadow — differing only in the hue their wrapper sets, so they share a
   rule rather than repeating one. Alignment is deliberately absent: every
   inline badge carrying an icon is already seated by the shared rule above,
   and the `vertical-align: middle` these once restated landed on top of that
   nudge and pushed both a few pixels low. */
.fern-prose :is(.c-guide-status, .c-guide-device) .fern-docs-badge {
  color: var(--c-guide-device-ink);
  background: var(--c-guide-device-ground);
  border: 0;
  box-shadow: none;
  filter: none;
  white-space: nowrap;
}

/* These two carry a 12px icon where every other badge carries 14px, and an
   inline-block takes its baseline from its last line box — so the smaller
   glyph lands the whole badge a pixel below where the shared `top: 2px`
   leaves a launch or info badge. Measured on the served page: launch and
   info sit 0.75px under the text centre, these sat 1.75px. One pixel back. */
.fern-prose :is(p, li, td) :is(.c-guide-status, .c-guide-device) .fern-docs-badge {
  top: 1px;
}

/* A control in this help site rather than in Curate. The same neutral badge
   with a dotted outline: the reader is being pointed at something on the page
   in front of them, not sent to find it in the App. Dotted rather than dashed
   so it cannot be mistaken for the `n hidden` break marker in a comparison
   table, which is dashed at a smaller size. The color derives from the badge's
   own ink, so it follows both themes without a second pair of values. */
.fern-prose .c-guide-help .fern-docs-badge {
  border-style: dotted;
  border-color: color-mix(in srgb, currentColor 38%, transparent);
}

.fern-prose .c-guide-help--dashed .fern-docs-badge {
  border-style: dashed;
}

/* Status labels share the device contract; keep meaningful text beside icons. */
.c-guide-status--new {
  --c-guide-device-ink: #2e7d32;
  --c-guide-device-ground: #e8f5e9;
}

.c-guide-status--preview {
  --c-guide-device-ink: #1565c0;
  --c-guide-device-ground: #e3f2fd;
}

.c-guide-status--guest {
  --c-guide-device-ink: #c62828;
  --c-guide-device-ground: #ffebee;
}

.dark .c-guide-status--new {
  --c-guide-device-ink: #d7efda;
  --c-guide-device-ground: color-mix(in srgb, #2e7d32 25%, var(--c-sheet));
}

.dark .c-guide-status--preview {
  --c-guide-device-ink: #d7e8fc;
  --c-guide-device-ground: color-mix(in srgb, #1565c0 25%, var(--c-sheet));
}

.dark .c-guide-status--guest {
  --c-guide-device-ink: #ffcdd2;
  --c-guide-device-ground: color-mix(in srgb, #c62828 25%, var(--c-sheet));
}

.fern-prose :is(.c-guide-status, .c-guide-device) .fern-docs-badge .fern-mdx-icon:not(.c-detail-level) {
  --fa-icon-dark: currentColor;
  color: inherit;
  width: 0.75rem !important;
  height: 0.75rem !important;
}

.fern-prose :is(h2, h3, h4) :is(.c-guide-status, .c-guide-device) .fern-docs-badge {
  position: relative;
  top: -2px;
}

.c-guide-sensory {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  font-size: 0.875rem;
  line-height: 0.65;
  vertical-align: middle;
}

.c-guide-sensory--point {
  flex-direction: row;
  gap: 0.1rem;
  line-height: 1;
}

/* Illustrative four-part coverage examples. The label states the quantity;
   the actual builder and Library count their own fields and categories. */
.c-guide-coverage {
  --c-guide-coverage-fill: #85175e;
  --c-guide-coverage-empty: #e4e0db;
  --c-guide-coverage-amount: 50%;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.dark .c-guide-coverage {
  --c-guide-coverage-fill: #d2add2;
  --c-guide-coverage-empty: #60475b;
}

.c-guide-coverage::before {
  content: '';
  flex-shrink: 0;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: conic-gradient(var(--c-guide-coverage-fill) var(--c-guide-coverage-amount), var(--c-guide-coverage-empty) 0);
  mask-image: radial-gradient(transparent 60%, #000 62%), repeating-conic-gradient(#000 0deg 85deg, transparent 85deg 90deg);
  mask-composite: intersect;
}

.c-guide-coverage--empty {
  --c-guide-coverage-amount: 0%;
}

.c-guide-coverage--full {
  --c-guide-coverage-amount: 100%;
}

.c-guide-coverage--flaw::before {
  background: conic-gradient(#ee000b 0% 25%, var(--c-guide-coverage-fill) 25% 50%, var(--c-guide-coverage-empty) 50%);
}

.c-guide-coverage--bar::before {
  width: 4rem;
  height: 4px;
  border-radius: 2px;
  background: linear-gradient(to right, var(--c-guide-coverage-fill) var(--c-guide-coverage-amount), var(--c-guide-coverage-empty) 0);
  mask-image: repeating-linear-gradient(to right, #000 0 14px, transparent 14px 16px);
}

/* Swatch text and separators remain in the MDX for assistive technology and
   the mirror. Only this compact visual reference hides its redundant labels. */
.c-guide-palette {
  display: flex;
  flex-wrap: wrap;
  gap: 0.875rem 1rem;
  margin-block: 1rem;
}

.c-guide-palette-group {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.c-guide-palette-label {
  font-size: 0.8125rem;
  line-height: 1.4;
}

.c-guide-palette-chips {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0;
}

.c-guide-swatch {
  display: inline-block;
  width: 2rem;
  height: 2rem;
  border-radius: 0.375rem;
  background: var(--c-guide-swatch-fill);
  box-shadow: inset 0 0 0 1px rgb(45 41 38 / 0.18);
  font-size: 0;
  color: transparent;
  vertical-align: middle;
}

.c-guide-palette-separator {
  display: none;
}

/* App var.js color references; note-panel-views.js renders the first and last
   values as a two-stop radial gradient. Wine colors stay identical in both themes. */
.c-guide-swatch--101-1 {
  --c-guide-swatch-fill: radial-gradient(#f3f1da, #fdfbec);
}

.c-guide-swatch--101-2 {
  --c-guide-swatch-fill: radial-gradient(#ebe3b4, #fcfae3);
}

.c-guide-swatch--101-3 {
  --c-guide-swatch-fill: radial-gradient(#e3df98, #efecc1);
}

.c-guide-swatch--102-1 {
  --c-guide-swatch-fill: radial-gradient(#f4f3b3, #f4f5d5);
}

.c-guide-swatch--102-2 {
  --c-guide-swatch-fill: radial-gradient(#f4ec7f, #f7f5ba);
}

.c-guide-swatch--102-3 {
  --c-guide-swatch-fill: radial-gradient(#f0db4c, #f8ee72);
}

.c-guide-swatch--103-1 {
  --c-guide-swatch-fill: radial-gradient(#eddc8e, #f3efcc);
}

.c-guide-swatch--103-2 {
  --c-guide-swatch-fill: radial-gradient(#f2dc76, #f3eab3);
}

.c-guide-swatch--103-3 {
  --c-guide-swatch-fill: radial-gradient(#f1ca53, #f6db82);
}

.c-guide-swatch--104-1 {
  --c-guide-swatch-fill: radial-gradient(#cb962e, #eab042);
}

.c-guide-swatch--104-2 {
  --c-guide-swatch-fill: radial-gradient(#a75b27, #de9d37);
}

.c-guide-swatch--104-3 {
  --c-guide-swatch-fill: radial-gradient(#1a100e, #905126);
}

.c-guide-swatch--105-1 {
  --c-guide-swatch-fill: radial-gradient(#f6a635, #fcce6c);
}

.c-guide-swatch--105-2 {
  --c-guide-swatch-fill: radial-gradient(#f08221, #f7bc56);
}

.c-guide-swatch--105-3 {
  --c-guide-swatch-fill: radial-gradient(#cb5d2a, #f19832);
}

.c-guide-swatch--106-1 {
  --c-guide-swatch-fill: radial-gradient(#e2ac7e, #f3c8a5);
}

.c-guide-swatch--106-2 {
  --c-guide-swatch-fill: radial-gradient(#eb7930, #fab687);
}

.c-guide-swatch--106-3 {
  --c-guide-swatch-fill: radial-gradient(#d64a27, #ed985f);
}

.c-guide-swatch--107-1 {
  --c-guide-swatch-fill: radial-gradient(#f2aa9b, #f3cbc1);
}

.c-guide-swatch--107-2 {
  --c-guide-swatch-fill: radial-gradient(#ef6e51, #f3a99c);
}

.c-guide-swatch--107-3 {
  --c-guide-swatch-fill: radial-gradient(#e75232, #f2967f);
}

.c-guide-swatch--108-1 {
  --c-guide-swatch-fill: radial-gradient(#efa9a9, #f6cfd0);
}

.c-guide-swatch--108-2 {
  --c-guide-swatch-fill: radial-gradient(#ed6071, #f09ea4);
}

.c-guide-swatch--108-3 {
  --c-guide-swatch-fill: radial-gradient(#cb223f, #f59ca2);
}

.c-guide-swatch--109-1 {
  --c-guide-swatch-fill: radial-gradient(#630e21, #8f1a37);
}

.c-guide-swatch--109-2 {
  --c-guide-swatch-fill: radial-gradient(#271016, #8d1b35);
}

.c-guide-swatch--109-3 {
  --c-guide-swatch-fill: radial-gradient(#0f090b, #621825);
}

.c-guide-swatch--110-1 {
  --c-guide-swatch-fill: radial-gradient(#64102a, #9c1b44);
}

.c-guide-swatch--110-2 {
  --c-guide-swatch-fill: radial-gradient(#331821, #5a1931);
}

.c-guide-swatch--110-3 {
  --c-guide-swatch-fill: radial-gradient(#09070a, #361422);
}

.c-guide-swatch--111-1 {
  --c-guide-swatch-fill: radial-gradient(#9b1e22, #c02626);
}

.c-guide-swatch--111-2 {
  --c-guide-swatch-fill: radial-gradient(#701212, #ac2529);
}

.c-guide-swatch--111-3 {
  --c-guide-swatch-fill: radial-gradient(#3c1615, #7e1c19);
}

.c-guide-swatch--112-1 {
  --c-guide-swatch-fill: radial-gradient(#962e21, #ac4326);
}

.c-guide-swatch--112-2 {
  --c-guide-swatch-fill: radial-gradient(#732719, #9f3d24);
}

.c-guide-swatch--112-3 {
  --c-guide-swatch-fill: radial-gradient(#4a1b13, #962c1f);
}

.c-guide-swatch--121 {
  --c-guide-swatch-fill: radial-gradient(#dddad6, #e3e0dd);
}

.c-guide-swatch--122 {
  --c-guide-swatch-fill: radial-gradient(#4b9737, #73ae63);
}

.c-guide-swatch--123 {
  --c-guide-swatch-fill: radial-gradient(#eb7930, #fab687);
}

.c-guide-swatch--124 {
  --c-guide-swatch-fill: radial-gradient(#f1ca53, #f3efcc);
}

.c-guide-swatch--125 {
  --c-guide-swatch-fill: radial-gradient(#3c2716, #aa5e28);
}

.c-guide-swatch--126 {
  --c-guide-swatch-fill: radial-gradient(#69007c, #970075);
}

.c-guide-swatch--127 {
  --c-guide-swatch-fill: radial-gradient(#79154c, #bd2077);
}

.c-guide-swatch--128 {
  --c-guide-swatch-fill: radial-gradient(#630e03, #8f1a05);
}

.c-guide-swatch--129 {
  --c-guide-swatch-fill: radial-gradient(#f68040, #f9aa7f);
}

.c-guide-swatch--130 {
  --c-guide-swatch-fill: radial-gradient(#9b1e22, #c02626);
}

.c-guide-swatch--131 {
  --c-guide-swatch-fill: radial-gradient(#64222c, #892e3c);
}

.c-guide-swatch--132 {
  --c-guide-swatch-fill: radial-gradient(#962e03, #ac4326);
}


article .fern-button.filled.primary {
  background-color: #6f0c4a;
  color: var(--c-white);
  border-color: rgb(var(--c-white-rgb) / 0.18);
  box-shadow:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.12),
    0 1px 2px rgb(45 41 38 / 0.06),
    0 4px 12px -4px rgb(45 41 38 / 0.1);
}

article .fern-button.filled.primary::before,
article .fern-button.filled.danger::before {
  background: none;
}

article .fern-button.filled.primary:hover {
  background-color: #912e6e;
  color: var(--c-white);
  border-color: rgb(var(--c-white-rgb) / 0.25);
  box-shadow:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.15),
    0 1px 2px rgb(45 41 38 / 0.08),
    0 6px 16px -4px rgb(45 41 38 / 0.13);
}
article .fern-button.filled.primary:focus-visible {
  background-color: #912e6e;
  color: var(--c-white);
  border-color: rgb(var(--c-white-rgb) / 0.25);
  box-shadow:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.15),
    0 1px 2px rgb(45 41 38 / 0.08),
    0 6px 16px -4px rgb(45 41 38 / 0.13);
}

article .fern-button.filled.danger {
  background-color: #c0392b;
  color: var(--c-white);
  border-color: rgb(249 235 234 / 0.18);
  box-shadow:
    inset 0 1px 0 rgb(249 235 234 / 0.12),
    0 1px 2px rgb(45 41 38 / 0.06),
    0 4px 12px -4px rgb(45 41 38 / 0.1);
}

article .fern-button.filled.danger:hover {
  background-color: #a93226;
  color: var(--c-white);
  border-color: rgb(249 235 234 / 0.25);
}
article .fern-button.filled.danger:focus-visible {
  background-color: #a93226;
  color: var(--c-white);
  border-color: rgb(249 235 234 / 0.25);
}

/* Dark: primary rides the accent solid (lilac on dark text), secondary
   becomes a translucent chip, and tertiary uses the lilac alpha scale. */
.dark article .fern-button.filled,
.dark .fern-layout-footer-toolbar .flex.gap-2 > button {
  background-color: rgb(var(--c-white-rgb) / 0.08);
  color: var(--accent-11);
  border-color: rgb(var(--c-white-rgb) / 0.14);
  box-shadow:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.12),
    0 1px 2px rgb(0 0 0 / 0.25),
    0 4px 12px -4px rgb(0 0 0 / 0.35);
}

.dark article .fern-button.filled::before,
.dark .fern-layout-footer-toolbar .flex.gap-2 > button::before {
  background:
    radial-gradient(rgb(var(--c-white-rgb) / 0.08) 0%, transparent 100%),
    linear-gradient(160deg, rgb(var(--c-white-rgb) / 0.03), transparent 90%);
}

/* Secondary hovers use the same Tyrian-50 veil as the other dark controls.
   This Help treatment is independent of the light-only App contract. */
.dark article .fern-button.filled:hover,
.dark .fern-layout-footer-toolbar .flex.gap-2 > button:hover {
  background-color: var(--grayscale-a5);
  border-color: rgb(var(--c-white-rgb) / 0.3);
  box-shadow:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.15),
    0 1px 2px rgb(0 0 0 / 0.3),
    0 6px 16px -4px rgb(0 0 0 / 0.45);
}
.dark article .fern-button.filled:focus-visible {
  background-color: var(--grayscale-a5);
  border-color: rgb(var(--c-white-rgb) / 0.3);
  box-shadow:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.15),
    0 1px 2px rgb(0 0 0 / 0.3),
    0 6px 16px -4px rgb(0 0 0 / 0.45);
}

.dark article .fern-button.minimal,
.dark .fern-page-actions > button,
.dark button[aria-haspopup='menu']:has(> svg:is(.lucide-monitor, .lucide-sun, .lucide-moon)) {
  color: var(--accent-11);
}

.dark article .fern-button.minimal:hover,
.dark .fern-page-actions > button:hover,
.dark button[aria-haspopup='menu']:has(> svg:is(.lucide-monitor, .lucide-sun, .lucide-moon)):hover {
  background-color: var(--accent-a3);
  color: var(--accent-12);
}
.dark article .fern-button.minimal:focus-visible {
  background-color: var(--accent-a3);
  color: var(--accent-12);
}

.dark article .fern-button.minimal:active,
.dark .fern-page-actions > button:active,
.dark button[aria-haspopup='menu']:has(> svg:is(.lucide-monitor, .lucide-sun, .lucide-moon)):is(:active, [data-state='open']) {
  background-color: var(--accent-a4);
  color: var(--accent-12);
}

.dark article .fern-button:focus-visible,
.dark .fern-page-actions > button:focus-visible,
.dark .fern-layout-footer-toolbar .flex.gap-2 > button:focus-visible,
.dark button[aria-haspopup='menu']:has(> svg:is(.lucide-monitor, .lucide-sun, .lucide-moon)):focus-visible {
  box-shadow: 0 0 0 2px rgb(210 173 210 / 0.55);
}

.dark article .fern-button.filled.primary {
  background-color: var(--accent-9);
  color: var(--accent-contrast);
  border-color: rgb(var(--c-white-rgb) / 0.28);
  box-shadow:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.12),
    0 1px 2px rgb(0 0 0 / 0.25),
    0 4px 12px -4px rgb(0 0 0 / 0.35);
}

.dark article .fern-button.filled.primary:hover {
  background-color: var(--accent-10);
  color: var(--accent-contrast);
  border-color: rgb(var(--c-white-rgb) / 0.4);
  box-shadow:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.15),
    0 1px 2px rgb(0 0 0 / 0.3),
    0 6px 16px -4px rgb(0 0 0 / 0.45);
}
.dark article .fern-button.filled.primary:focus-visible {
  background-color: var(--accent-10);
  color: var(--accent-contrast);
  border-color: rgb(var(--c-white-rgb) / 0.4);
  box-shadow:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.15),
    0 1px 2px rgb(0 0 0 / 0.3),
    0 6px 16px -4px rgb(0 0 0 / 0.45);
}

.dark article .fern-button.filled.danger {
  background-color: #c0392b;
  color: var(--c-white);
  border-color: rgb(249 235 234 / 0.22);
  box-shadow:
    inset 0 1px 0 rgb(249 235 234 / 0.12),
    0 1px 2px rgb(0 0 0 / 0.25),
    0 4px 12px -4px rgb(0 0 0 / 0.35);
}

.dark article .fern-button.filled.danger:hover {
  background-color: #a93226;
  border-color: rgb(249 235 234 / 0.3);
}
.dark article .fern-button.filled.danger:focus-visible {
  background-color: #a93226;
  border-color: rgb(249 235 234 / 0.3);
}

/* Overview/reference pages use the full column; guides use the article's configured
   width and responsive cap rather than Fern's independent footer measure. */
#fern-docs .fern-layout-footer {
  width: 100%;
  max-width: 100%;
  margin-inline: 0;
}

#fern-docs .fern-layout-guide .fern-layout-footer {
  width: var(--content-width, 40rem);
  max-width: min(100%, 48rem);
  margin-inline: auto;
}

.fern-footer-nav :is(.fern-footer-prev, .fern-footer-next) > span > span {
  display: block;
}

/* Helpful-feedback footer
   -----------------------
   The renderer lays the prompt and its Yes/No pair out as one left-justified
   wrapping row (`flex flex-wrap items-center justify-start gap-4`). Turn that
   row into a centered column so the question sits on its own line above the
   buttons, which keep their own row via the inner `flex gap-2` — untouched
   here. The `:has()` qualifier pins the selector to the wrapper that actually
   holds the button pair, so a future sibling row in the same toolbar (Edit
   this page, footer nav) is not swept up by the generic utility classes.
   Centering the column's contents is not enough on its own: the row sits
   inside two class-less wrapper divs, so the toolbar child that actually
   contains the button pair is also made a centering flex parent. Reaching it
   through `:has()` keeps any sibling toolbar row (footer nav) unaffected.
   `flex: 1 1 100%` is the part that actually centers it. The toolbar is only
   a column below 40rem; at every larger width it is a flex ROW carrying
   `justify-content: space-between`, so this wrapper is otherwise a
   content-width item pinned to the start — centering inside a box that hugs
   its own contents moves nothing. Claiming the full line first gives the
   centering something to act on. */
.fern-layout-footer-toolbar > div:has(.flex.gap-2 > button) {
  display: flex;
  flex: 1 1 100%;
  justify-content: center;
}

.fern-layout-footer-toolbar .flex.flex-wrap.items-center:has(> .flex.gap-2) {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 0.75rem;
}

/* Tabs (MDX component) — app `.c-tabs.nav-tabs` register
   -------------------------------------------------------
   Tab titles are h6 elements: give them the chrome face, as in the
   app itself (the global heading rules would set Domaine). The stock 2px `::before`
   indicator sits at bottom -1px inside the `fern-x-overflow` scroll
   container and gets clipped — replaced by the app's gradient
   border-image underline, which stays inside the tab's own box. */
h6[role='tab'] {
  font-family: var(--font-chrome);
  font-size: 1rem;
  font-weight: 400;
  letter-spacing: normal;
  padding: 10px 15px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h6[role='tab']:hover:not([data-state='active']) {
  color: var(--accent-11);
  border-bottom: 1px dotted var(--accent);
}
h6[role='tab']:focus-visible:not([data-state='active']) {
  color: var(--accent-11);
  border-bottom: 1px dotted var(--accent);
}

h6[role='tab'][data-state='active'] {
  border-bottom: 1px solid;
  border-image: linear-gradient(to right, var(--border), var(--accent) 20%, var(--accent) 80%, var(--border)) 1;
}

h6[role='tab'][data-state='active']::before {
  content: none;
}

/* App tab rhythm: `.c-tabs__link` pads 10px 15px (underline runs wider
   than the label) with the `--collapsing` variant's 0.45rem box gap —
   wide tap targets, narrow seams. The 1px padding/margin pair extends
   the scroll container's paint box so the tabs' `-mb-px` bottom borders
   are not clipped at its edge — without it the active underline never
   renders. */
.fern-x-overflow:has(> h6[role='tab']) {
  gap: 0.45rem;
  padding-bottom: 1px;
  margin-bottom: -1px;
}

/* Accordions
   ----------
   Trim the prose margins at the top and bottom of the content well
   (the wrapper already carries its own padding). */
.fern-accordion-item [role='region'] > div > :first-child {
  margin-top: 0;
}

.fern-accordion-item [role='region'] > div > :last-child {
  margin-bottom: 0;
}

/* A code block closing the well keeps 20px on all three sides
   (the well pads 12px bottom + 20px inline). */
.fern-accordion-item [role='region'] > div > .fern-code-block:last-child {
  margin-bottom: 8px;
}

/* Tooltips — App register in light; inverse lilac in dark
   ------------------------------------------------------------ */
.fern-mdx-tooltip-content {
  background: var(--c-tooltip-background);
  color: var(--c-tooltip-foreground);
  border: none;
  border-radius: 10px;
  box-shadow: 0 4px 14px rgb(0 0 0 / 0.25);
  padding: 6px 10px 8px;
  font-size: 0.8125rem;
  line-height: 1.45;
}

/* Radix portals contain the accessible tooltip as a direct hidden child.
   Scope the visible shell, not that hidden copy or every popover/menu. */
.dark [data-radix-popper-content-wrapper] > [data-state]:has(> [role='tooltip']) {
  --color-body: var(--c-tooltip-foreground);
  --color-white: var(--c-tooltip-foreground);
  --accent: var(--c-tooltip-foreground);
  --accent-11: var(--c-tooltip-foreground);
  --accent-12: var(--c-tooltip-foreground);
  --grayscale-a11: color-mix(in srgb, var(--c-tooltip-foreground) 80%, transparent);
  --grayscale-a12: var(--c-tooltip-foreground);
  background: var(--c-tooltip-background);
  color: var(--c-tooltip-foreground);
  border-color: var(--c-tooltip-background);
  border-radius: 10px;
}

.dark [data-radix-popper-content-wrapper] .fern-anchor {
  background: var(--c-tooltip-background);
  color: var(--c-tooltip-foreground);
}

/* Fern colors the nested chip and copied SVG independently of the anchor. */
.dark [data-radix-popper-content-wrapper] .fern-anchor-icon {
  background: var(--c-tooltip-background);
  border-color: var(--c-tooltip-background);
}

.dark [data-radix-popper-content-wrapper] .fern-anchor-icon,
.dark [data-radix-popper-content-wrapper] .fern-anchor-icon > svg {
  color: var(--c-tooltip-foreground);
}

.dark [role='menu'] {
  background: var(--c-surface-nested);
}

.fern-mdx-tooltip-trigger {
  --tooltip-underline-color: var(--accent-8);
  --tooltip-underline-hover-color: var(--accent);
  text-decoration-style: dotted !important;
  text-underline-offset: 2.5px;
  text-decoration-skip-ink: auto;
}

.fern-mdx-tooltip-trigger:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Lilac-derived dotted underlines wash out on the tyrian surfaces */
.dark .fern-mdx-tooltip-trigger {
  --tooltip-underline-color: color-mix(in srgb, var(--accent) 60%, transparent);
}

/* Prose links share the native-underline approach, pulled tighter */
.fern-mdx-link {
  text-underline-offset: 2px;
}

/* Cards — app `.c-option-block` register
   --------------------------------------- */
article .fern-card.interactive {
  border: 2px solid var(--border);
  border-radius: 12px;
  background: var(--card-background);
  box-shadow: none;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

article .fern-card.interactive:hover {
  border-color: #c4b0bd;
  background: #f8f6f3;
}
article .fern-card.interactive:focus-visible {
  border-color: #c4b0bd;
  background: #f8f6f3;
}

/* The bolded card title deepens to Tyrian on hover (dark: accent-12
   is the light lilac text tier — same rule serves both modes). */
article .fern-card.interactive:hover .font-semibold {
  color: var(--accent-12);
}
article .fern-card.interactive:focus-within .font-semibold {
  color: var(--accent-12);
}

.dark article .fern-card.interactive:hover {
  border-color: var(--accent-7);
  background: var(--c-surface-emphasis);
}
.dark article .fern-card.interactive:focus-visible {
  border-color: var(--accent-7);
  background: var(--c-surface-emphasis);
}

.dark article .fern-card {
  background: var(--c-surface-nested);
}

/* Table bodies carry 30% of their header's shading over the same surface. */
.fern-table {
  --c-table-header: var(--grayscale-a2);
}

.dark .fern-table {
  --c-table-header: var(--c-surface-nested);
}

.fern-table thead th {
  background: var(--c-table-header);
}

.fern-table tbody td,
.fern-table tbody th {
  background: color-mix(in srgb, var(--c-table-header) 30%, transparent);
}

/* Accordions & Frames share Fern's lavender-tinted card shadow, which
   reads as glow on both grounds — swap for the tooltip register's
   geometry (soft black-based drop; warm ink in light). Interactive
   cards are excluded: they are deliberately flat per `.c-option-block`. */
article .fern-card:not(.interactive) {
  box-shadow: 0 4px 14px rgb(45 41 38 / 0.08);
}

.dark article .fern-card:not(.interactive) {
  box-shadow: 0 4px 14px rgb(0 0 0 / 0.25);
}

/* Steps — the rail must start behind the first numeral, so the
   container's full-height `border-left` becomes a gradient strip
   offset past the indicator's top edge; its tail fades over a fixed
   48px run so a long last step keeps the rail for most of its height
   without an abrupt stop. */
.fern-steps {
  border-left-color: transparent !important;
  background: linear-gradient(to bottom, var(--border) calc(100% - 48px), transparent) no-repeat left 8px / 1px calc(100% - 8px);
  background-origin: border-box;
}

/* Prompt
   ------
   `.fern-prompt` is `not-prose`, so it gets no flow margins at all;
   restore the article rhythm (siblings collapse to one gap). */
.fern-prompt {
  margin-block: 1.25rem;
}

/* Reader guide icons use Fern’s native Font Awesome light glyphs. */
/* The house group for Q/S/A squares: `white-space: nowrap` is the whole point
   of it, and is why an inline square binds to the level it names. A non-
   breaking space cannot do that job alone — it binds itself to the word, and
   the break opportunity sits between the square's replaced box and the space
   (observed on the served page: the A square ended one line and `Advanced`
   opened the next). The 0.3em lead is a heading gesture, so it lives with the
   heading rule rather than on the group. */
.c-detail-levels {
  display: inline-block;
  white-space: nowrap;
}

.fern-prose :is(h2, h3, h4) .c-detail-levels {
  position: relative;
  top: 2px;
  margin-left: 0.3em;
}

/* The rule above nudges the hint *group*; a bare square carries no group,
   so in a heading or a table header it keeps the glyph's own box and sits
   about 2px above the text's optical center. Same correction, same 2px. */
.fern-prose :is(h2, h3, h4) > .c-detail-level {
  position: relative;
  top: 2px;
}

/* A header cell's own line-height seats the square a touch higher still. */
.fern-prose th .c-detail-level {
  position: relative;
  top: 2.5px;
}

.c-detail-level {
  opacity: 1;
}

.c-detail-level--inactive {
  opacity: 0.3;
}

.c-feature-included {
  color: #16a34a;
}

.dark .c-feature-included {
  color: #4ade80;
}

.c-feature-not-included {
  color: #8b8790;
}

.dark .c-feature-not-included {
  --fa-icon-dark: var(--grayscale-a10);
  color: var(--fa-icon-dark);
}

.fern-prose td .c-detail-level {
  position: relative;
  top: 1.5px;
}

/* Keep short option names with their identifying glyph in table legends. */
.fern-prose td:has(> .c-guide-option-icon) {
  white-space: nowrap;
}

/* The helper limits decoration to text, leaving edge icons and their spaces
   undecorated. The final word + external indicator is one wrapping unit. */
.fern-prose .fern-mdx-link.c-icon-link {
  --c-link-underline: 1px;
  text-decoration-line: none;
}

.fern-prose .fern-mdx-link.c-icon-link:hover {
  --c-link-underline: 2px;
}
.fern-prose .fern-mdx-link.c-icon-link:focus-visible {
  --c-link-underline: 2px;
}

.c-icon-link .c-link-text {
  text-decoration-line: underline;
  text-decoration-color: inherit;
  text-decoration-thickness: var(--c-link-underline);
  text-underline-offset: 2px;
}

.c-link-tail {
  white-space: nowrap;
}

.c-app-link-head {
  white-space: nowrap;
}

.c-app-link-mark {
  display: inline-block;
  width: 0.875em;
  height: 0.875em;
  margin-right: 0.25em;
  vertical-align: -0.125em;
  background: url('https://static.curate.software/wine/brand/treatments/tonal/logomark--8e5377.svg') center / contain no-repeat;
}

.dark .c-app-link-mark {
  background-image: url('https://static.curate.software/wine/brand/treatments/tonal/logomark--ccafd0.svg');
}

.fern-prose .fern-mdx-link.c-app-link .external-link-icon {
  display: none;
}

.fern-prose .fern-mdx-link.c-app-link.c-icon-link:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
  border-radius: 2px;
}

.fern-prose .fern-mdx-link :is(.fern-mdx-icon, .external-link-icon) {
  --fa-icon-dark: currentColor;
  color: inherit;
}

/* Inline <Icon> (Fern's `.fern-mdx-icon`) renders ~1.5px high against the
   surrounding text baseline by default (verified live,
   help.wine.curate.dev). Scoped to prose paragraphs/list items so
   heading-embedded guide icons (`c-guide-icon`, calibrated against the much
   larger heading type — the guide icon convention above) are untouched. */
.fern-prose :is(p, li) .fern-mdx-icon {
  margin: 0 0.125em;
  vertical-align: -0.125em;
}

/* Override Fern's fixed inline dimensions and dark icon foreground while
   preserving the guide icons and required marker's semantic calibration. */
.fern-prose :is(p, li) .fern-mdx-icon:not(.c-required-asterisk, .c-detail-level, .c-feature-included, .c-feature-not-included) {
  --fa-icon-dark: currentColor;
  color: inherit;
  width: 0.9375rem !important;
  height: 0.9375rem !important;
}

/* Required-field marker beside inline label prose (Your First Tasting Note,
   Wine Details). Unmapped on the Intercom mirror per AUTHORING.md §3.3 —
   degrades to `[interactive]`; the "red asterisk" text callout beside it
   carries the meaning until icons get a general mirror treatment.
   `!important` on width/height: Fern's <Icon> writes its own inline
   `style="width:16px;height:16px"` on the svg, and only `!important` in an
   external stylesheet beats a plain inline style. Matching text height
   alone is not enough either — the FA `asterisk` glyph fills nearly its
   full 512-unit viewBox, so even at 1em it reads much heavier than a typed
   `*`; 0.5em is the actual visual match. Deliberately superscript, not
   baseline, so `!important` on vertical-align too, overriding the prose
   default above. */
.c-required-asterisk {
  color: #c0392b;
  font-size: 0.75em;
  width: 0.625em !important;
  height: 0.625em !important;
  vertical-align: 0.25em !important;
}

/* Descriptor lists inside a comparison table cell (Choosing a Detail
   Level's aroma ladder). Scoped to cells that actually hold one, so the
   corpus-wide table and prose-list defaults are untouched: Fern sizes a
   prose `li` against the 16px reading measure, which reads a step large
   against a 14px table row, and gives it the paragraph rhythm a table
   cell does not want. `:has()` is the only way to reach the `td` — a
   Markdown table cell takes no class of its own. The size lands on the
   list as well as the item because `padding-left` is the marker-to-text
   distance and its `em` resolves against the list — sized on the item
   alone, the text shrinks to the row while the gutter stays at the
   reading measure. Top alignment matters because the three cells in a
   row hold different numbers of items. */
.fern-prose td .c-cell-list {
  margin: 0;
  font-size: inherit;
  padding-left: 1.05em;
}

.fern-prose td .c-cell-list li {
  font-size: inherit;
  margin: 0;
}

.fern-prose td:has(> .c-cell-list) {
  vertical-align: top;
}

/* ==========================
   Diagram tokens — the `curate` diagram-design skin as CSS
   ==========================
   Inline SVG diagrams carry only `.dd-*` classes; every color and face is
   resolved here, once, in both themes (Fern toggles `.dark` on <html>).
   Values mirror `Curate/brand/tokens/diagram-design.profile.md` (the
   canonical profile) — change them there first, then here.

   `--dd-paper` is the SHEET the diagram sits on — the `.canvas-wrapper`
   in `styles.css` (`--c-sheet` in both themes) — never the body background behind the sidebar.
   Masks fill it, so a diagram sits on the sheet with no slab of its own;
   if the sheet color moves, this moves with it. Standards CSS only. */

.dd-diagram {
  --dd-paper:        var(--c-sheet);          /* App surface-card */
  --dd-paper-2:      var(--c-surface-nested);  /* App surface-recessed */
  --dd-ink:          #4c4845;                 /* App ink @ 85% over the sheet — 8.6:1, reads as ink not black */
  --dd-muted:        #6b6864;                 /* App ink @ 70% — 5.3:1 */
  --dd-soft:         #6d6966;                 /* App ink @ 69% — AA on both paper and node fills */
  --dd-rule:         rgb(45 41 38 / 0.12);
  --dd-rule-solid:   #e4e0db;
  --dd-accent:       #6f0c4a;                 /* interactive Tyrian */
  --dd-accent-tint:  rgb(111 12 74 / 0.08);
  --dd-accent-a20:   rgb(111 12 74 / 0.20);
  --dd-link:         #704d75;
  --dd-ink-a02:      rgb(45 41 38 / 0.02);
  --dd-ink-a03:      rgb(45 41 38 / 0.03);
  --dd-ink-a12:      rgb(45 41 38 / 0.12);
  --dd-ink-a20:      rgb(45 41 38 / 0.20);
  --dd-ink-a25:      rgb(45 41 38 / 0.25);
  --dd-ink-a30:      rgb(45 41 38 / 0.30);
  --dd-ink-a50:      rgb(45 41 38 / 0.50);
  --dd-font-title:   var(--font-heading);
  --dd-font-name:    var(--font-body);
  --dd-font-label:   var(--font-chrome);
  --dd-font-mono:    'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
  margin: 1.5rem 0;
  -webkit-font-smoothing: antialiased;
}

.dark .dd-diagram {
  --dd-ink:          #d1c9cb;                 /* Rich Cream @ 80% over the sheet — 11.4:1 */
  --dd-muted:        #a699a0;                 /* @ 60% — 6.8:1 */
  --dd-soft:         #91818b;                 /* @ 50% — 5.0:1 */
  --dd-rule:         rgb(251 250 246 / 0.12);
  --dd-rule-solid:   #4f314f;                 /* tyrian-700 */
  --dd-accent:       #d2add2;                 /* tyrian-400 lilac */
  --dd-accent-tint:  rgb(210 173 210 / 0.10);
  --dd-accent-a20:   rgb(210 173 210 / 0.22);
  --dd-link:         #e0cae0;
  --dd-ink-a02:      rgb(251 250 246 / 0.025);
  --dd-ink-a03:      rgb(251 250 246 / 0.04);
  --dd-ink-a12:      rgb(251 250 246 / 0.12);
  --dd-ink-a20:      rgb(251 250 246 / 0.22);
  --dd-ink-a25:      rgb(251 250 246 / 0.20);
  --dd-ink-a30:      rgb(251 250 246 / 0.30);
  --dd-ink-a50:      rgb(251 250 246 / 0.50);
}

/* A diagram is authored at the 640px content lane and scales with it; strokes
   stay 1 CSS px at any scale instead of thinning as the figure shrinks. */
.dd-diagram line,
.dd-diagram path,
.dd-diagram rect,
.dd-diagram polygon,
.dd-diagram circle  { vector-effect: non-scaling-stroke; }

/* Fills */
.dd-diagram .dd-f-paper       { fill: var(--dd-paper); }
.dd-diagram .dd-f-paper2      { fill: var(--dd-paper-2); }
.dd-diagram .dd-f-ink         { fill: var(--dd-ink); }
.dd-diagram .dd-f-muted       { fill: var(--dd-muted); }
.dd-diagram .dd-f-accent      { fill: var(--dd-accent); }
.dd-diagram .dd-f-accent-tint { fill: var(--dd-accent-tint); }
.dd-diagram .dd-f-accent-a20  { fill: var(--dd-accent-a20); }
.dd-diagram .dd-f-ink-a02     { fill: var(--dd-ink-a02); }
.dd-diagram .dd-f-ink-a03     { fill: var(--dd-ink-a03); }
.dd-diagram .dd-f-ink-a12     { fill: var(--dd-ink-a12); }
.dd-diagram .dd-f-none        { fill: none; }

/* Strokes (width set per element) */
.dd-diagram .dd-s-ink         { stroke: var(--dd-ink); }
.dd-diagram .dd-s-muted       { stroke: var(--dd-muted); }
.dd-diagram .dd-s-accent      { stroke: var(--dd-accent); }
.dd-diagram .dd-s-rule        { stroke: var(--dd-rule); }
.dd-diagram .dd-s-ink-a20     { stroke: var(--dd-ink-a20); }
.dd-diagram .dd-s-ink-a25     { stroke: var(--dd-ink-a25); }
.dd-diagram .dd-s-ink-a30     { stroke: var(--dd-ink-a30); }
.dd-diagram .dd-s-ink-a50     { stroke: var(--dd-ink-a50); }

/* Connectors — heads are open chevrons (the Curate default): a stroked path in
   the connector's own color, never a filled triangle. */
.dd-diagram .dd-head          { fill: none; stroke-width: 1.2; stroke-linecap: round; stroke-linejoin: round; }
.dd-diagram .dd-head-accent   { fill: none; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.dd-diagram .dd-arrow         { fill: none; stroke: var(--dd-muted);  stroke-width: 1.2; }
.dd-diagram .dd-arrow-accent  { fill: none; stroke: var(--dd-accent); stroke-width: 1.4; }
.dd-diagram .dd-hairline      { fill: none; stroke: var(--dd-rule);   stroke-width: 0.8; }

/* Text roles — the portal ramp (authored for the 640px lane, rendered ~1:1):
   Söhne carries the body; Futura PT is the all-caps register only. */
.dd-diagram text              { font-family: var(--dd-font-name); font-kerning: normal; }
.dd-diagram .dd-name          { font-size: 12px;  font-weight: 500; fill: var(--dd-ink); }
.dd-diagram .dd-name-lg       { font-size: 15px;  font-weight: 500; fill: var(--dd-ink); letter-spacing: -0.005em; }
.dd-diagram .dd-sub           { font-size: 10px;  font-weight: 400; fill: var(--dd-muted); }
.dd-diagram .dd-legend        { font-size: 10px;  font-weight: 400; fill: var(--dd-muted); }
.dd-diagram .dd-callout-sm    { font-size: 10px;  font-weight: 400; font-style: italic; fill: var(--dd-muted); }
.dd-diagram .dd-node-title    { font-size: 11px;  font-weight: 500; fill: var(--dd-ink); }
.dd-diagram .dd-node-sub      { font-size: 8px;   font-weight: 400; fill: var(--dd-muted); }
.dd-diagram .dd-node-tool     { font-size: 8px;   font-weight: 400; fill: var(--dd-soft); }
.dd-diagram .dd-chip-num      { font-size: 9px;   font-weight: 500; fill: var(--dd-ink); }
.dd-diagram .dd-role          { font-size: 7px;   font-weight: 600; fill: var(--dd-ink); }
.dd-diagram .dd-eyebrow,
.dd-diagram .dd-eyebrow-sm,
.dd-diagram .dd-arrow-label,
.dd-diagram .dd-lane-label,
.dd-diagram .dd-step-label    { font-family: var(--dd-font-label); font-weight: 500; text-transform: uppercase; fill: var(--dd-muted); }
.dd-diagram .dd-eyebrow       { font-size: 8px; letter-spacing: 0.18em; }
.dd-diagram .dd-eyebrow-sm    { font-size: 7px; letter-spacing: 0.12em; }
.dd-diagram .dd-arrow-label   { font-size: 8px; letter-spacing: 0.08em; }
.dd-diagram .dd-lane-label    { font-size: 8px; letter-spacing: 0.08em; }
.dd-diagram .dd-step-label    { font-size: 7px; letter-spacing: 0.12em; }

/* Text color modifiers — after the roles so they win */
.dd-diagram .dd-t-ink         { fill: var(--dd-ink); }
.dd-diagram .dd-t-muted       { fill: var(--dd-muted); }
.dd-diagram .dd-t-accent      { fill: var(--dd-accent); }

/* ==========================
   Figure chrome — <Frame>, <Diagram>, <Screenshot> (fern/components/*.tsx)
   ==========================
   The shared chrome of the three custom figure components: the framed
   figure, the zoom layer they all open, and the frameless screenshot.
   Every color is set for both themes (Fern toggles `.dark` on <html>).
   Values sit on the same sheet the diagrams are keyed to — `.canvas-wrapper`,
   `--c-sheet` — and the nested ground uses `--c-surface-nested`, shared with
   the diagram nodes (`--dd-paper-2`). Standards CSS only; nothing
   here targets the renderer's DOM. */

/* Tokens
   ------
   One block per theme, as `compare.css` does it: a literal appears once,
   where it can be read against its neighbors. The zoom layer is portaled to
   <body> and inherits nothing from the figure, so it carries the same block.
   Surfaces and roles that already exist portal-wide (`--c-sheet`,
   `--c-surface-nested`, `--background`, `--card-background`, `--c-focus-ring`)
   are consumed rather than re-pinned — if the palette moves, this moves with
   it, and the focus ring stays the same ring the form controls draw. */
.c-figure,
.c-shot,
.c-zoom {
  --c-figure-ground:      var(--c-surface-nested);
  --c-figure-rule:        #e4e0db;                  /* docs.yml `border`, light */
  --c-figure-ink:         #615b54;                  /* App ink @ 70% over the sheet */
  --c-figure-radius:      12px;                     /* the App card radius */
  --c-zoom-veil:          color-mix(in srgb, var(--background) 72%, transparent);
  --c-zoom-stage-shadow:  0 24px 64px -24px rgb(45 41 38 / 0.35);
  --c-zoom-close-ground:  color-mix(in srgb, var(--card-background) 90%, transparent);
  --c-zoom-close-rule:    rgb(var(--c-white-rgb) / 0.5);
  --c-zoom-close-ink:     #6f0c4a;                  /* docs.yml `accent-primary`, light */
  /* Read by `shadowFilter()` in Screenshot.tsx, which builds the drop-shadow
     inline — no rule in this sheet consumes it. Warm ink in light; dark keeps
     depth atmospheric, so it becomes a plain black at higher alpha. */
  --c-shot-shadow-color:  rgb(45 41 38 / 0.22);
  /* Must stay in lockstep with `CORNER_RADIUS` in Screenshot.tsx, which rounds
     the untorn corners of the clip polygon to the same value. */
  --c-shot-radius:        4px;
}
.dark .c-figure,
.dark .c-shot,
.dark .c-zoom {
  --c-figure-rule:        #4f314f;                  /* tyrian-700 */
  --c-figure-ink:         #a699a0;
  --c-zoom-veil:          color-mix(in srgb, var(--background) 78%, transparent);
  --c-zoom-stage-shadow:  none;
  --c-zoom-close-ground:  rgb(var(--c-white-rgb) / 0.1);
  --c-zoom-close-rule:    rgb(var(--c-white-rgb) / 0.18);
  --c-zoom-close-ink:     #d2add2;                  /* tyrian-400 lilac */
  --c-shot-shadow-color:  rgb(0 0 0 / 0.45);
}

/* Framed figure
   ------------- */
.c-figure {
  margin: 1.75rem 0;
}
.c-figure__trigger {
  display: block;
  width: 100%;
  padding: 1rem;
  border: 1px solid var(--c-figure-rule);
  border-radius: var(--c-figure-radius);
  background: var(--c-figure-ground);
  cursor: zoom-in;
  text-align: left;
  font: inherit;
  color: inherit;
}
.c-figure__trigger--static {
  cursor: default;
}
.c-figure__trigger:focus-visible {
  outline: 2px solid var(--c-focus-ring);
  outline-offset: 2px;
}
.c-figure--sheet .c-figure__trigger {
  background: transparent;
}
.c-figure--diagram .c-figure__trigger {
  padding: 1rem 1rem 0.5rem;
}

/* A hosted diagram is fetched and injected, so it is ordinary markup in the
   document and `diagrams.css` reaches it. Until it lands, a placeholder holds
   the figure's space at the authored viewBox ratio. */
.c-figure__svg,
.c-figure__placeholder {
  display: block;
  width: 100%;
}
.c-figure__placeholder {
  background: var(--c-surface-nested);
  border-radius: 6px;
}
.c-figure--sheet .c-figure__placeholder {
  background: var(--c-figure-ground);
}

/* An image inside the frame fills its width; Fern's own zoom wrapper is kept
   off with `noZoom` on the image (a renderer-internal selector for that
   wrapper does not belong in this sheet). */
.c-figure__trigger > img,
.c-figure__image {
  display: block;
  width: 100%;
  height: auto;
  margin: 0;
}
.c-figure__trigger .dd-diagram {
  margin: 0;
}

.c-figure__caption {
  margin: 0.5rem 0.25rem 0;
  font-family: var(--font-body);
  font-size: 0.875rem;
  line-height: 1.45;
  color: var(--c-figure-ink);
}

/* Zoom layer
   ----------
   Portaled to <body>, so it is outside the renderer's `main` stacking
   context and any filtered ancestor. It begins below the fixed header
   (`--header-height-real` is the renderer's variable), so the header stays
   visible and usable and the stage centers in the area beneath it. */
.c-zoom {
  position: fixed;
  top: var(--header-height-real, 64px);
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: 2rem 3rem 3rem;
  background: var(--c-zoom-veil);
  -webkit-backdrop-filter: blur(8px) saturate(0.9);
  backdrop-filter: blur(8px) saturate(0.9);
  cursor: zoom-out;
}
/* The stage inherits `zoom-out` from the layer: a click anywhere in the layer,
   the enlarged figure included, closes it. */
.c-zoom__stage {
  width: min(1200px, 100%);
  max-height: 100%;
  overflow: auto;
  overscroll-behavior: contain;
  padding: 2rem;
  border-radius: var(--c-figure-radius);
  background: var(--c-sheet);
  border: 1px solid var(--c-figure-rule);
  box-shadow: var(--c-zoom-stage-shadow);
}
.c-zoom__stage > img,
.c-zoom__stage .c-figure__image {
  display: block;
  width: 100%;
  height: auto;
  margin: 0;
}
.c-zoom__stage .dd-diagram {
  margin: 0;
}
.c-zoom__close {
  position: fixed;
  top: calc(var(--header-height-real, 64px) + 1rem);
  right: 1rem;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid var(--c-zoom-close-rule);
  background: var(--c-zoom-close-ground);
  color: var(--c-zoom-close-ink);
  font: 400 22px/1 var(--font-body);
  cursor: pointer;
}
.c-zoom__close:focus-visible {
  outline: 2px solid var(--c-focus-ring);
  outline-offset: 2px;
}

/* Narrow viewports: the inline figure already fills the lane, so the zoom
   layer renders it at twice the lane and lets the stage pan (the layer's
   click-to-close ignores a drag). */
@media (max-width: 1023px) {

  .c-zoom {
    padding: 1rem;
  }
  .c-zoom__stage {
    padding: 1rem;
  }
  .c-zoom__stage > .dd-diagram,
  .c-zoom__stage > img,
  .c-zoom__stage > .c-figure__image,
  .c-zoom__stage > .c-shot__lift {
    width: 1280px;
    max-width: none;
  }

}

/* Screenshot (frameless)
   ----------------------
   No border, no ground: the capture sits on the sheet as a cut sheet of
   paper. The clip polygon and the drop-shadow direction are computed by the
   component from its edges; the shadow color is the one token that changes
   with the theme. */
.c-shot {
  margin: 1.75rem 0;
}
.c-shot__trigger {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: zoom-in;
  text-align: left;
  font: inherit;
  color: inherit;
}
.c-shot__trigger:focus-visible {
  outline: 2px solid var(--c-focus-ring);
  outline-offset: 4px;
}
.c-shot__lift {
  display: block;
  width: 100%;
}
.c-shot__image {
  display: block;
  width: 100%;
  height: auto;
  margin: 0;
  border-radius: var(--c-shot-radius);
}
.c-shot__placeholder {
  display: block;
  width: 100%;
  background: var(--c-surface-nested);
}
.c-shot .c-figure__caption {
  margin-top: 0.75rem;
}

/* In the zoom layer a screenshot floats on the blurred ground with its edge
   intact — no sheet card around it. */
.c-zoom--shot .c-zoom__stage {
  width: auto;
  max-width: min(1200px, 100%);
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}
.c-zoom--shot .c-shot__lift {
  margin: 0 auto;
}

/* Authoring failure
   -----------------
   Same treatment as `.c-compare--invalid`: a broken figure has to look
   broken, or the notice reads as an ordinary caption and is scrolled past.
   `.c-shot--invalid` is the whole figure (the capture never renders);
   `.c-figure__notice` sits inside a frame that is otherwise intact. */
.c-shot--invalid,
.c-figure__notice {
  display: block;
  padding: 0.75rem 1rem;
  border: 1px dashed var(--c-figure-rule);
  border-radius: 6px;
  color: var(--c-figure-ink);
  font-size: 0.875rem;
}
.c-shot--invalid .c-figure__caption {
  margin: 0;
  font-size: inherit;
}

/* ==========================
   Comparison table — <Compare> (fern/components/Compare.tsx)
   ==========================
   A grid with table semantics: one label column carrying a drawn tree, then
   one equal-width cell column per thing being compared. Neither Söhne nor
   Fern's icon set has usable box-drawing glyphs, so the connectors are drawn
   here — a tee and an elbow, aligned off one slot width, never a left border
   per level. Every horizontal position derives from the slot tokens below, so
   no level is nudged by hand. `--c-compare-slot` is the indent per level, set
   to one glyph width: a child's label lands inside the span of its parent's
   own icon, near enough to read as belonging to it, and the connector still
   has six pixels of tick to be drawn with. The caret occupies a slot of the
   same width for the same reason the rails do — at any other width its centre
   drifts off the vertical its own children hang from.

   `minmax(0, 1fr)` on the label column is load-bearing: the zero minimum is
   what keeps an intrinsically wide label (a badge that will not wrap) from
   pushing the grid past the reading sheet. Standards CSS only; nothing here
   targets the renderer's DOM. */

.c-compare {
  --c-compare-slot: 0.875rem;
  --c-compare-elbow: 0.125rem;
  --c-compare-column: 6.25rem;
  --c-compare-type: 2.75rem;
  --c-compare-row: 2.125rem;
  --c-compare-control-row: 1.3125rem;
  --c-compare-control-gap: 0.1875rem;
  --c-compare-rail: rgb(45 41 38 / 0.18);
  --c-compare-ink: rgb(45 41 38 / 0.55);
  --c-compare-hover: rgb(45 41 38 / 0.035);
  --c-compare-hairline: rgb(45 41 38 / 0.1);
  --c-compare-on: #16a34a;
  --c-compare-type-ink: var(--accent-11, #6f0c4a);
  margin: 1.5rem 0;
  overflow-x: auto;
}

.dark .c-compare {
  --c-compare-rail: rgb(255 255 255 / 0.16);
  --c-compare-ink: rgb(255 255 255 / 0.5);
  --c-compare-hover: rgb(255 255 255 / 0.04);
  --c-compare-hairline: rgb(255 255 255 / 0.09);
  --c-compare-on: #4ade80;
  --c-compare-type-ink: var(--accent-11, #e3b8d6);
}

/* MDX wraps a row's authored content in a paragraph when the block reads as
   one; the row is the layout, so the paragraph contributes no flow. */
.c-compare p {
  margin: 0;
}

/* Controls
   -------- */
/* The two stacks face each other: view controls on the left, the state key on
   the right in the opposite order, so "Expand all" sits across from
   "Included" and the pair reads as one block rather than two strays. */
.c-compare__controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  margin-bottom: 0.875rem;
}

/* The controls are `.c-checkbox` rows in a `.c-check-group` (forms.css); all
   this adds is the fieldset's own reset and the shared row box. Nothing here
   restates a colour, a size, or a control — the App's register is the whole
   point of adopting the recipe. */
.c-compare .c-compare__views {
  margin: 0;
  padding: 0;
  border: 0;
  gap: var(--c-compare-control-gap);
}

.c-compare__views-legend,
.c-compare .c-compare__legend-head {
  padding: 0;
  margin: 0 0 0.125rem;
  font-family: var(--font-chrome);
  font-size: 0.6875rem;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--c-compare-ink);
}

/* The view rows and the key rows share a row box, so the two stacks line up
   pair for pair across the gap rather than drifting on their own leading.
   The control's own alignment is left to `.c-checkbox`, which centres it on
   the first line box rather than on a wrapped label's middle. */
.c-compare .c-compare__view,
.c-compare__legend-item {
  min-height: var(--c-compare-control-row);
}

.c-compare__legend-item {
  align-items: center;
}

/* The key mirrors the view stack: its own heading, then its rows in the
   opposite order, so "All expanded" sits across from "Included". */
.c-compare__key {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.c-compare__legend {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--c-compare-control-gap);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Doubly scoped on purpose: these are list items inside the prose, and
   `.fern-prose li` would otherwise win the size with its extra element. The
   register is the portal's eyebrow — Futura at the accent size and tracked.
   No negative margin to swallow the trailing tracking, as elsewhere: these are
   flex items, and a margin narrower than the border box leaves the widest of
   them hanging past the column the rest of the row is measured against. */
.c-compare .c-compare__legend-item {
  display: flex;
  gap: 0.4375rem;
  margin: 0;
  font-family: var(--font-chrome);
  font-size: 0.71875rem;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--c-compare-ink);
}

/* Grid
   ---- */
.c-compare__grid {
  min-width: 0;
}

.c-compare__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) repeat(var(--c-compare-columns, 3), var(--c-compare-column));
  align-items: stretch;
}

/* The type column sits between the labels and the comparison: what the field
   holds, before how much of it each level gets. */
.c-compare__grid[data-typed='true'] .c-compare__row {
  grid-template-columns: minmax(0, 1fr) var(--c-compare-type) repeat(var(--c-compare-columns, 3), var(--c-compare-column));
}

.c-compare__type {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.1875rem;
  min-height: var(--c-compare-row);
  padding: 0.1875rem 0.25rem;
}

/* Tyrian rather than the warm neutral the rails use: these are content, not
   chrome, and at this size a neutral reads as switched off. Still a step below
   the states, which are the answer the column exists to give. */
.c-compare__row:not(.c-compare__row--head) .c-compare__type {
  color: var(--c-compare-type-ink);
}

/* Structure, not content — a section or subsection glyph says where you are,
   and should not be read at the volume of a field's own answer. */
.c-compare__mark[data-muted='true'] {
  opacity: 0.3;
}

.c-compare__row:not(.c-compare__row--head):hover {
  background: var(--c-compare-hover);
}
.c-compare__row:not(.c-compare__row--head):focus-visible {
  background: var(--c-compare-hover);
}

.c-compare__row--head {
  border-bottom: 1px solid var(--c-compare-hairline);
}

/* A section opens with a hairline, so the tree reads in blocks rather than as
   one undifferentiated run. The first one is redundant under the head rule. */
.c-compare__row[data-depth='0'] ~ .c-compare__row[data-depth='0'] {
  border-top: 1px solid var(--c-compare-hairline);
}

/* `display: grid` above outranks the UA's `[hidden] { display: none }`, so a
   collapsed or filtered row would otherwise stay on screen. */
.c-compare__row[hidden] {
  display: none;
}

.c-compare__label {
  display: flex;
  align-items: center;
  min-width: 0;
  min-height: var(--c-compare-row);
  padding: 0.1875rem 0.75rem 0.1875rem 0;
  overflow-wrap: anywhere;
}

/* Badges are inline-flex boxes, so on a prose line they sit on the baseline
   rather than on the line's middle — 1.5px above the axis the connector and
   caret beside them use. A flex line centres the boxes themselves. The gap
   restores the word spacing that flex strips from the ` · ` between a pair. */
.c-compare__text {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0 0.125rem;
  min-width: 0;
}

.c-compare__text > p {
  display: contents;
}

/* A linked badge sits inside an anchor, which would otherwise reintroduce the
   baseline the flex line above just took away. */
.c-compare__text a {
  display: flex;
  align-items: center;
}

/* The whole label opens the row, so it takes the pointer — but a badge that is
   already a link keeps its own. */
.c-compare__label[data-toggle='true'] {
  cursor: pointer;
}

.c-compare__label[data-toggle='true'] a {
  cursor: pointer;
}

.c-compare__row--head .c-compare__label,
.c-compare__row[data-depth='0'] .c-compare__label {
  font-weight: 500;
}

/* The heads read as a table's heads — Söhne at the corpus table size, not the
   chrome register the legend uses; the column words must not wrap, so the
   column token above is sized for the longest of them. */
.c-compare__row--head .c-compare__label,
.c-compare__row--head .c-compare__type,
.c-compare__row--head .c-compare__cell {
  font-size: 0.875rem;
  font-weight: 600;
  white-space: nowrap;
}

/* Each head stacks its glyph over its word, so the column reads as one mark
   rather than a pair racing the cell's width. */
.c-compare__row--head .c-compare__type,
.c-compare__row--head .c-compare__cell {
  flex-direction: column;
  gap: 0.1875rem;
  padding-top: 0.375rem;
  padding-bottom: 0.375rem;
}

/* Tree connectors
   --------------- */
.c-compare__gutter {
  display: flex;
  align-self: stretch;
  flex: 0 0 auto;
}

.c-compare__rail,
.c-compare__joint {
  position: relative;
  flex: 0 0 auto;
  width: var(--c-compare-slot);
}

/* An ancestor's rail continues only while that ancestor still has a following
   visible sibling — the component recomputes it against the visible set, so a
   filtered or collapsed branch never leaves a rail running to nothing. */
.c-compare__rail[data-on='true']::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  border-left: 1px solid var(--c-compare-rail);
}

.c-compare__joint::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  border-left: 1px solid var(--c-compare-rail);
}

/* The tick starts one pixel clear of the vertical rather than on it: both
   strokes are translucent, and where they overlapped the two alphas composited
   into a single brighter pixel at every junction. */
.c-compare__joint::after {
  content: '';
  position: absolute;
  left: calc(50% + 1px);
  right: 0;
  top: 50%;
  border-top: 1px solid var(--c-compare-rail);
}

/* The last child turns the corner instead of running on: the vertical stops a
   hair past the tick so its rounded bottom border lands on exactly the pixels
   the tick occupies, and the tick starts after the radius. */
.c-compare__row[data-last='true'] .c-compare__joint::before {
  bottom: auto;
  height: calc(50% + 1px);
  width: var(--c-compare-elbow);
  border-bottom: 1px solid var(--c-compare-rail);
  border-bottom-left-radius: var(--c-compare-elbow);
}

.c-compare__row[data-last='true'] .c-compare__joint::after {
  left: calc(50% + var(--c-compare-elbow));
}

/* Caret
   ----- */
/* Narrow but full-height: the slot is sized to sit the label against the
   tick, and the row's height is what keeps the control worth aiming at. */
.c-compare__caret {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  flex: 0 0 auto;
  width: var(--c-compare-slot);
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 3px;
  background: none;
  color: var(--c-compare-ink);
  cursor: pointer;
  transition: color 150ms ease;
}

/* The chevron turns, not the button — rotating a box taller than it is wide
   would swing its hit area out over the label. */
.c-compare__caret::before {
  content: '';
  width: 0.3125rem;
  height: 0.3125rem;
  margin-left: -1px;
  border-top: 1.5px solid currentColor;
  border-right: 1.5px solid currentColor;
  transform: rotate(45deg);
  transition: transform 150ms ease;
}

.c-compare__caret[aria-expanded='true']::before {
  transform: rotate(135deg);
}

/* The caret answers the cell that triggers it. Hovering a state column
   highlights the row but leaves the caret alone: clicking there opens
   nothing, and a control that lights up for a dead click is a lie. */
.c-compare__label[data-toggle='true']:hover .c-compare__caret,
.c-compare__caret:focus-visible {
  color: var(--accent-11, #6f0c4a);
}
.c-compare__label[data-toggle='true']:focus-within .c-compare__caret {
  color: var(--accent-11, #6f0c4a);
}

.c-compare__caret:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 1px;
}

/* A leaf reserves the caret's width so every label at a depth starts on the
   same x; the slot is empty, not a disabled control. */
.c-compare__caret--leaf {
  cursor: default;
}

.c-compare__caret--leaf::before {
  content: none;
}

@media (prefers-reduced-motion: reduce) {

  .c-compare__caret,
  .c-compare__caret::before {
    transition: none;
  }

}

/* Break rows
   ----------- */
/* Under the filter a branch can hold rows the filter kept out. Rather than
   pretend they are not there, the branch ends in a break — half a row high,
   no glyphs, the count and a way back to them. The axis-break reading is the
   point: the tree continues, it is just not all drawn. */
.c-compare__row--break .c-compare__label {
  grid-column: 1 / -1;
  min-height: 1.125rem;
  padding-top: 0;
  padding-bottom: 0;
}

.c-compare__reveal {
  margin: 0;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  padding: 0 0.375rem;
  border: 1px dashed var(--c-compare-rail);
  border-radius: 999px;
  background: none;
  color: var(--c-compare-ink);
  font-family: var(--font-chrome);
  font-size: 0.6875rem;
  font-weight: 500;
  line-height: 1.0625rem;
  cursor: pointer;
  transition: color 150ms ease, border-color 150ms ease;
}

.c-compare__reveal:hover {
  color: var(--accent-11, #6f0c4a);
  border-color: var(--accent-11, #6f0c4a);
}

.c-compare__reveal:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 1px;
}

/* Cells
   ----- */
.c-compare__cell {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.3125rem;
  min-height: var(--c-compare-row);
  padding: 0.1875rem 0.25rem;
}

.c-compare__mark {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
}

/* All three states are one ink at one weight — the glyph carries the reading,
   not a second hue. An empty circle at full strength competes with the filled
   ones for attention it does not deserve, so absence is dimmed rather than
   greyed: still legibly the same family, plainly the lesser answer. */
.c-compare__mark[data-state] {
  color: var(--c-compare-on);
}

.c-compare__mark[data-state='none'] {
  opacity: 0.3;
}

.c-compare__column-label {
  min-width: 0;
}

/* Narrow viewports: the column heads are lettered squares, so the word beside
   each one is redundant before it is unaffordable. */
@media (max-width: 639px) {

  .c-compare {
    --c-compare-type: 2.25rem;
    --c-compare-column: 2.75rem;
    --c-compare-slot: 0.625rem;
  }

  .c-compare__column-label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

}

/* Authoring failure
   ----------------- */
.c-compare--invalid {
  padding: 0.75rem 1rem;
  border: 1px dashed var(--c-compare-rail);
  border-radius: 6px;
  color: var(--c-compare-ink);
  font-size: 0.875rem;
}

/* ==========================
   Form controls — .c-checkbox, .c-radio
   ==========================
   A distillation of the App's `.m-checkbox` / `.m-radio` (Metronic base plus
   `curate/forms/_checkboxes.scss`), not a port of it. The App's construction
   absolutely positions an empty trailing `<span>` behind a `padding-left` on
   the label, because Metronic could not style the input itself; here the input
   IS the control (`appearance: none`), so the label is an ordinary flex row —
   control, optional icon, words. An icon between the box and the text is then
   just the next flex child: no wrapper, no reserved gutter, no negative
   margin. That is what `.c-table-sorts__option` and the `#modal-somm-config`
   check lists build by hand in the App, arrived at natively here.

   Light values are the App's own numbers (`app/dist/app.bundle.css`: the 18px
   control, `#6f0c4a` fill, `#85175e` hover, both choice-control shadow
   stacks); keep them in lockstep when the App moves. Dark is Help's own,
   derived from the dark button recipe in `styles.css` — a translucent white
   chip at rest, the accent solid when checked — since the App has no dark
   register to port. The App's danger intent is deliberately not carried over.

   Selectors are depth-agnostic on purpose: MDX wraps a label's contents, or a
   group's rows, in a paragraph depending on how the block is written, and the
   component must not depend on which. Standards CSS only; nothing here
   targets the renderer's DOM. */

.c-checkbox,
.c-radio {
  /* Geometry */
  --c-check-size: 1.125rem;        /* App 18px control */
  --c-check-gap: 0.5rem;
  --c-check-icon: 0.875rem;
  --c-check-leading: 1.45;         /* App label leading. The control and the
                                      icon center on the FIRST line box, so a
                                      label that wraps does not drag them into
                                      the middle of its own paragraph. */

  /* Ink and fill — light */
  --c-check-bg: rgb(251 250 246 / 0.82);          /* App surface-card #fbfaf6 */
  --c-check-bg-hover: rgb(251 250 246 / 0.9);
  --c-check-border: rgb(209 205 199 / 0.82);      /* App neutral-300 #d1cdc7 */
  --c-check-border-hover: rgb(133 23 94 / 0.82);  /* App interactive-hover */
  --c-check-fill: var(--accent-9, #6f0c4a);
  --c-check-fill-hover: var(--accent-10, #85175e);
  --c-check-mark: #ffffff;
  --c-check-accent: var(--accent-11, #6f0c4a);    /* checked / hovered icon ink */

  /* The tick cannot read a custom property — an SVG data URI has no access to
     the cascade — so the checkmark is a per-theme image, while the radio's
     dot, being a gradient, takes the color variable directly. */
  --c-check-mark-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='square' d='M3.3 8 6.4 11.1 12.7 4.8'/%3E%3C/svg%3E");
  --c-check-dot-image: radial-gradient(circle at 50% 50%, var(--c-check-mark) 0 0.1875rem, transparent calc(0.1875rem + 0.5px));

  /* The rest sheen sits on the unchecked fill; the gloss is the veil the App
     paints from a `::before` over a checked control on hover. */
  --c-check-sheen: linear-gradient(180deg, rgb(255 255 255 / 0.34) 0%, rgb(255 255 255 / 0.12) 52%, transparent 100%);
  --c-check-sheen-hover: linear-gradient(180deg, rgb(255 255 255 / 0.42) 0%, rgb(255 255 255 / 0.16) 54%, transparent 100%);
  --c-check-gloss: linear-gradient(180deg, rgb(255 255 255 / 0.16) 0%, rgb(255 255 255 / 0.06) 52%, transparent 100%);

  --c-check-shadow:
    inset 0 0.75px 0 rgb(255 255 255 / 0.64),
    inset 0 -0.75px 0 rgb(45 41 38 / 0.03),
    0 1px 0 rgb(255 255 255 / 0.85),
    0 4px 6px -2px rgb(45 41 38 / 0.07);
  --c-check-shadow-checked:
    inset 0 0.75px 0 rgb(255 255 255 / 0.36),
    inset 0 -0.75px 0 rgb(45 41 38 / 0.08),
    0 1px 0 rgb(255 255 255 / 0.95),
    0 4px 6px -2px rgb(45 41 38 / 0.12);
  /* The portal's focus ring, shared with buttons and figures, rather than the
     App's border-100 ring — the portal already has one answer here. Only the
     shape is local: the color is `--c-focus-ring` in `styles.css`, so this
     needs no dark override and cannot drift from the ring the figure triggers
     draw (it had, at 0.55 against their 0.7, until 2026-09-11). */
  --c-check-ring: 0 0 0 2px var(--c-focus-ring);

  display: inline-flex;
  align-items: flex-start;
  gap: var(--c-check-gap);
  margin: 0;
  font-family: var(--font-chrome);
  font-size: 0.875rem;
  font-weight: 400;
  line-height: var(--c-check-leading);
  cursor: pointer;
}

/* Dark derives from the dark button chip: a translucent white fill on the
   sheet, the accent solid when checked. The edge is carried above the
   button's 0.14 — an 18px control has a fraction of a button's perimeter to
   say "control" with. */
.dark :is(.c-checkbox, .c-radio) {
  --c-check-bg: rgb(var(--c-white-rgb) / 0.08);
  --c-check-bg-hover: rgb(var(--c-white-rgb) / 0.14);
  --c-check-border: rgb(var(--c-white-rgb) / 0.2);
  --c-check-border-hover: color-mix(in srgb, var(--accent-9, #d2add2) 55%, transparent);
  --c-check-mark: #4d0834;         /* App Tyrian on lilac — 7.7:1 */
  --c-check-mark-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%234d0834' stroke-width='2' stroke-linecap='square' d='M3.3 8 6.4 11.1 12.7 4.8'/%3E%3C/svg%3E");
  --c-check-sheen: linear-gradient(180deg, rgb(var(--c-white-rgb) / 0.1) 0%, rgb(var(--c-white-rgb) / 0.04) 52%, transparent 100%);
  --c-check-sheen-hover: linear-gradient(180deg, rgb(var(--c-white-rgb) / 0.14) 0%, rgb(var(--c-white-rgb) / 0.05) 54%, transparent 100%);
  --c-check-gloss: linear-gradient(180deg, rgb(var(--c-white-rgb) / 0.12) 0%, rgb(var(--c-white-rgb) / 0.04) 52%, transparent 100%);
  --c-check-shadow:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.12),
    0 1px 2px rgb(0 0 0 / 0.25),
    0 4px 12px -4px rgb(0 0 0 / 0.35);
  --c-check-shadow-checked:
    inset 0 1px 0 rgb(var(--c-white-rgb) / 0.15),
    0 1px 2px rgb(0 0 0 / 0.3),
    0 4px 12px -4px rgb(0 0 0 / 0.45);
}

/* Control
   ------- */
.c-checkbox input[type='checkbox'],
.c-radio input[type='radio'] {
  --c-check-elevation: var(--c-check-shadow);
  appearance: none;
  flex: none;
  width: var(--c-check-size);
  height: var(--c-check-size);
  margin: calc((var(--c-check-leading) * 1em - var(--c-check-size)) / 2) 0 0;
  padding: 0;
  border: 1px solid var(--c-check-border);
  background-color: var(--c-check-bg);
  background-image: var(--c-check-sheen);
  background-repeat: no-repeat;
  box-shadow: var(--c-check-elevation);
  font: inherit;
  cursor: inherit;
  transition:
    background-color 0.15s ease,
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}

.c-checkbox input[type='checkbox'] {
  border-radius: 3px;
}

.c-radio input[type='radio'] {
  border-radius: 50%;
}

.c-checkbox:hover input[type='checkbox']:not(:disabled, :checked),
.c-radio:hover input[type='radio']:not(:disabled, :checked) {
  border-color: var(--c-check-border-hover);
  background-color: var(--c-check-bg-hover);
  background-image: var(--c-check-sheen-hover);
}
.c-checkbox:focus-within input[type='checkbox']:not(:disabled, :checked),
.c-radio:focus-within input[type='radio']:not(:disabled, :checked) {
  border-color: var(--c-check-border-hover);
  background-color: var(--c-check-bg-hover);
  background-image: var(--c-check-sheen-hover);
}

.c-checkbox input[type='checkbox']:checked,
.c-radio input[type='radio']:checked {
  --c-check-elevation: var(--c-check-shadow-checked);
  border-color: transparent;
  background-color: var(--c-check-fill);
}

.c-checkbox input[type='checkbox']:checked {
  background-image: var(--c-check-mark-image);
}

.c-radio input[type='radio']:checked {
  background-image: var(--c-check-dot-image);
}

.c-checkbox:hover input[type='checkbox']:checked:not(:disabled),
.c-radio:hover input[type='radio']:checked:not(:disabled) {
  background-color: var(--c-check-fill-hover);
}
.c-checkbox:focus-within input[type='checkbox']:checked:not(:disabled),
.c-radio:focus-within input[type='radio']:checked:not(:disabled) {
  background-color: var(--c-check-fill-hover);
}

.c-checkbox:hover input[type='checkbox']:checked:not(:disabled) {
  background-image: var(--c-check-mark-image), var(--c-check-gloss);
}
.c-checkbox:focus-within input[type='checkbox']:checked:not(:disabled) {
  background-image: var(--c-check-mark-image), var(--c-check-gloss);
}

.c-radio:hover input[type='radio']:checked:not(:disabled) {
  background-image: var(--c-check-dot-image), var(--c-check-gloss);
}
.c-radio:focus-within input[type='radio']:checked:not(:disabled) {
  background-image: var(--c-check-dot-image), var(--c-check-gloss);
}

/* One rule serves both states: the resting elevation travels in a variable,
   so the ring is never written twice. */
.c-checkbox input[type='checkbox']:focus-visible,
.c-radio input[type='radio']:focus-visible {
  box-shadow: var(--c-check-ring), var(--c-check-elevation);
  outline: 2px solid transparent;  /* the ring is a shadow — forced colors
                                      repaints this outline in its place. */
  outline-offset: 2px;
}

:is(.c-checkbox, .c-radio):has(input:disabled) {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Icon slot
   --------- */
/* The icon is the element immediately after the control — any Fern `<Icon>`,
   or a `c-guide-icon-stack` holding the App's base-plus-overlay glyphs. Being
   adjacent to the input is the whole contract: no class, and no chance of
   catching the glyphs nested inside a stack. It takes the accent once the
   control is on, as the App's `.c-inline-check__icon` does. */
:is(.c-checkbox, .c-radio) input + :is(svg, .c-guide-icon-stack) {
  flex: none;
  width: var(--c-check-icon) !important;
  height: var(--c-check-icon) !important;
  margin: calc((var(--c-check-leading) * 1em - var(--c-check-icon)) / 2) 0 0;
  color: inherit;
  transition: color 0.15s ease;
}

:is(.c-checkbox, .c-radio) input + .c-guide-icon-stack > svg {
  width: 100% !important;
  height: 100% !important;
}

:is(.c-checkbox, .c-radio):hover:has(input:not(:disabled)) input + :is(svg, .c-guide-icon-stack),
:is(.c-checkbox, .c-radio):has(input:checked) input + :is(svg, .c-guide-icon-stack) {
  color: var(--c-check-accent);
}
:is(.c-checkbox, .c-radio):focus-within:has(input:not(:disabled)) input + :is(svg, .c-guide-icon-stack) {
  color: var(--c-check-accent);
}

/* A dependent control sits under the words it depends on rather than under
   its parent's box: the indent is the gutter the parent's control occupies. */
.c-checkbox--nested,
.c-radio--nested {
  margin-left: calc(var(--c-check-size) + var(--c-check-gap));
}

/* Groups
   ------ */
/* Vertical is the default rhythm (the App leaves 6px between adjacent
   labels); the inline modifier is its `.m-checkbox-inline` row, wrapping. */
.c-check-group {
  display: flex;
  flex-direction: column;
  align-items: flex-start;   /* rows keep their intrinsic width, so the hover
                                and click target is the label, not the sheet. */
  gap: 0.375rem;
  margin: 1rem 0;
}

.c-check-group--inline {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 0.375rem 0.9375rem;
}

/* MDX wraps a group's rows — or a label's contents — in a paragraph, one for
   the block or one per row depending on the blank lines around them. The
   paragraph is never the layout, so it hands its children straight through. */
.c-check-group > p,
:is(.c-checkbox, .c-radio) > p {
  display: contents;
}

/* Forced colors strips every background, which would leave an `appearance:
   none` control invisible. Hand it back to the platform. */
@media (forced-colors: active) {

  .c-checkbox input[type='checkbox'],
  .c-radio input[type='radio'] {
    appearance: auto;
  }

}

/* ==========================
   Chips — .c-chip, the aroma palette, .c-guide-category
   ==========================
   A distillation of the **Web** chip (`web/css/curate.css` 4798–4977, 5827–5929)
   rather than the App's. Both draw the same object, but the App's is an
   interactive control — a `<label>` wrapping a chip inside a
   `.c-chip-check-group`, with hidden inputs, `:checked` cascades, hover washes
   and focus rings. Web renders the same chip as static page furniture, which is
   what a documentation page needs: a picture of a control, never a control
   (`AUTHORING.md` §6). Everything interactive is therefore absent by intent —
   no hover, no focus, no inputs — as are the App's `--glass`, `--person`,
   `__remove`, `--vintage`, `--wrappable` and boolean registers, and Web's
   `.split` and `backdrop-filter` (a no-op over an opaque sheet).

   Both themes are real product truth rather than one invented register, which
   is a happy accident of where Web lives:

     light  Sandstone #faf9f5   App `_chips.scss`  — the hues opaque
     dark   Tyrian    #27071f   Web `curate.css`   — the same hues at 0.85

   Web's canvas IS this portal's dark sheet, and its RGB triplets ARE the App's
   hexes (black fruit #a02f43 = rgba(160,47,67); floral #6f3d97 =
   rgba(111,61,151)) — only the alpha differs, and it differs because the ground
   does. So `AUTHORING.md` §6.5's "keep these colors unchanged between themes"
   holds exactly: one literal per hue, composited twice. Web's own per-id well
   values were read and deliberately not carried as a second set (`PORTAL` §7).

   The palette lives here because two components consume it — the chip and the
   category dot — so the dot moved here with it rather than leaving the hues
   split across two sheets. Standards CSS only; nothing here targets the
   renderer's DOM. */

/* Aroma palette
   -------------
   One rule per aroma category, keyed by the App's `data-descriptor-subclass`
   id, feeding both consumers through the role pair they already shared.
   `--c-chip-ink` is read by the chip alone and is deliberately unset for every
   aroma hue: the App draws them all in white — `_chips.scss` says so in as many
   words, "white text … Applied to all aroma classes" — and carries the pale ones
   on the label shadow below, not on darker ink. Its `c-chip--dark-text` modifier
   is not the counter-example it looks like: `func.js` pushes that only from the
   `case 'color':` branch, for a wine-color capsule whose contrast is computed at
   runtime, and never for an aroma. The hook stays for that case; the dot never
   reads it. This diverges from a 3:1 text floor on four hues (citrus 2.09, tree
   fruit 1.88, yeast 1.87, lees 2.65) and matches the product instead. */
.c-guide-category--10,
.c-chip--10 {
  --c-guide-aroma:       #6f3d97;
  --c-guide-aroma-shade: #5f2e86;
}

.c-guide-category--20,
.c-chip--20 {
  --c-guide-aroma:       #87c44b;
  --c-guide-aroma-shade: #639f29;
}

.c-guide-category--21,
.c-chip--21 {
  --c-guide-aroma:       #a9ca38;
  --c-guide-aroma-shade: #9ab73c;
}

.c-guide-category--22,
.c-chip--22 {
  --c-guide-aroma:       #e97124;
  --c-guide-aroma-shade: #cc6528;
}

.c-guide-category--30,
.c-chip--30 {
  --c-guide-aroma:       #e93226;
  --c-guide-aroma-shade: #ce2a28;
}

.c-guide-category--31,
.c-chip--31 {
  --c-guide-aroma:       #a02f43;
  --c-guide-aroma-shade: #7a091d;
}

.c-guide-category--32,
.c-chip--32 {
  --c-guide-aroma:       #40449a;
  --c-guide-aroma-shade: #30378a;
}

.c-guide-category--33,
.c-chip--33 {
  --c-guide-aroma:       #c7608f;
  --c-guide-aroma-shade: #a13a69;
}

.c-guide-category--40,
.c-chip--40 {
  --c-guide-aroma:       #4f7942;
  --c-guide-aroma-shade: #29531c;
}

.c-guide-category--41,
.c-chip--41 {
  --c-guide-aroma:       #1b8b3f;
  --c-guide-aroma-shade: #006519;
}

.c-guide-category--50,
.c-chip--50 {
  --c-guide-aroma:       #17a049;
  --c-guide-aroma-shade: #138c45;
}

.c-guide-category--51,
.c-chip--51 {
  --c-guide-aroma:       #778899;
  --c-guide-aroma-shade: #516273;
}

.c-guide-category--60,
.c-chip--60 {
  --c-guide-aroma:       #c3c34b;
  --c-guide-aroma-shade: #9d9d25;
}

.c-guide-category--61,
.c-chip--61 {
  --c-guide-aroma:       #a3a436;
  --c-guide-aroma-shade: #7e7e32;
}

.c-guide-category--70,
.c-chip--70 {
  --c-guide-aroma:       #a0722a;
  --c-guide-aroma-shade: #795722;
}

.c-guide-category--80,
.c-chip--80 {
  --c-guide-aroma:       #1271a8;
  --c-guide-aroma-shade: #15649b;
}

.c-guide-category--90,
.c-chip--90 {
  --c-guide-aroma:       #555555;
  --c-guide-aroma-shade: #474747;
}

/* Category dot
   ------------
   The name of an aroma category beside the App's two-tone dot. Moved here from
   `styles.css` with the palette it reads; the markup on the reader pages is
   unchanged, because the selector came with it. */
.c-guide-category {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  white-space: nowrap;
}

/* App `_dots.scss` pairs: the bright upper-left triangle ends at 92% of each
   edge, equivalent to a 46% diagonal gradient stop inside the circular mask. */
.c-guide-category::before {
  content: '';
  width: 0.875rem;
  height: 0.875rem;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--c-guide-aroma) 46%, var(--c-guide-aroma-shade) 46%);
  flex-shrink: 0;
}

/* Chip
   ----
   Filled is the resting register, as it is in Web: a chip with no aroma class
   falls back to the house tyrian rather than becoming a different component.
   `--colorless` below is the opt-out, and carries the App's warm recessed base
   for the chips that hold no category at all. */
.c-chip {
  /* Geometry — Web's numbers, which are the App's but for the icon well: 32px
     against 30px, so the disc meets the chip's own edge instead of insetting. */
  --c-chip-height: 32px;
  --c-chip-radius: 16px;
  --c-chip-well: 32px;
  --c-chip-glyph: 1rem;
  --c-chip-overlap: -9px;

  /* Fill and ink. The aroma roles are read through a fallback rather than a
     modifier: a hue class sets them, and a chip without one resolves to the
     house pair. */
  --c-chip-fill: var(--c-guide-aroma, #553355);
  --c-chip-well-fill: var(--c-guide-aroma-shade, #472645);
  --c-chip-label: var(--c-chip-ink, #ffffff);
  --c-chip-shade: 0 0 4.5px rgb(0 0 0 / 0.2);

  /* The bevels the App and Web both paint: a lit top edge, a shadowed bottom
     with a second lit hairline under it, each faded out across the chip by a
     mask so the light reads as a curve rather than a line. */
  --c-chip-lip: inset 0 0.75px 0 rgb(255 255 255 / 0.22);
  --c-chip-bevel-top: inset -0.5px 1px 0 rgb(255 255 255 / 0.22);
  --c-chip-bevel-bottom: inset 0 -1px 0 rgb(0 0 0 / 0.14), inset -0.5px -1.5px 0 rgb(255 255 255 / 0.18);
  --c-chip-bevel-well: inset 0 -0.5px 0 rgb(0 0 0 / 0.14), inset 0 -1px 0 rgb(255 255 255 / 0.18);
  --c-chip-well-lip: inset 0 0.75px 0 rgb(255 255 255 / 0.25);

  /* The indicator cannot use the App's `\f00c`: that is a Font Awesome ligature
     and the portal loads no Kit. An SVG data URI draws the same tick, and like
     the form controls' it cannot read a custom property, so the ink is baked. */
  --c-chip-tick: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='square' d='M3.3 8 6.4 11.1 12.7 4.8'/%3E%3C/svg%3E");
  --c-chip-flag: #db020b;

  display: inline-flex;
  align-items: center;
  height: var(--c-chip-height);
  margin: 0 0.25rem 0.25rem 0;
  padding: 0 12px 0 8px;
  border: 0;
  border-radius: var(--c-chip-radius);
  background-color: var(--c-chip-fill);
  box-shadow: var(--c-chip-lip);
  color: var(--c-chip-label);
  font-family: var(--font-chrome);
  font-size: 0.90625rem;
  line-height: 1;
  white-space: nowrap;
  text-shadow: var(--c-chip-shade);
  vertical-align: middle;
  position: relative;
  overflow: visible;
}

/* Dark reproduces Web's composite from the same literal: the hue at 0.85 over
   the sheet it was drawn for, with a heavier text shadow for the darker ground
   (Web's own 7px). The well goes further back than the chip so the disc still
   reads as recessed once both are translucent. */
.dark .c-chip {
  --c-chip-fill: color-mix(in srgb, var(--c-guide-aroma, #553355) 85%, transparent);
  --c-chip-well-fill: color-mix(in srgb, var(--c-guide-aroma-shade, #472645) 70%, transparent);
  --c-chip-shade: 0 0 7px rgb(16 16 16 / 0.4);
}

/* Icon well
   ---------
   A wrapper, not the icon itself: the disc's inner bevel is a pseudo-element,
   and an `<svg>` — which is what Fern's `<Icon>` renders for a glyph name —
   cannot host one. The disc overlaps the chip's left edge, so it needs a
   stacking order above the chip's own bevels. */
.c-chip__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: var(--c-chip-well);
  height: var(--c-chip-well);
  margin: 0 5px 0 var(--c-chip-overlap);
  border-radius: var(--c-chip-radius);
  background-color: var(--c-chip-well-fill);
  box-shadow: var(--c-chip-well-lip);
  position: relative;
  z-index: 1;
}

/* Whatever the well is given is sized to the well — matched structurally, as
   its only child, rather than by the renderer's icon class, so this sheet keeps
   its lane. Two things have to lose for that to hold: Fern writes
   `style="width:16px;height:16px"` on the icon, and `styles.css` forces
   0.9375rem on every icon inside a prose paragraph but NOT inside a table cell,
   so the same chip rendered 15px in one and 16px in the other until this rule
   outranked it. `!important` alone cannot settle it — both declarations carry
   it and the prose rule is the more specific — so the class is doubled to win
   on specificity, the device `typography.css` uses with `:root:root`. */
.c-chip.c-chip .c-chip__icon.c-chip__icon > * {
  width: var(--c-chip-glyph) !important;
  height: var(--c-chip-glyph) !important;
  margin: 0 !important;
  color: inherit;
  vertical-align: baseline;
}

.c-chip__icon::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: var(--c-chip-bevel-well);
  transform: rotate(30deg);
  mask-image: linear-gradient(to top, #000 0%, transparent 30%);
  pointer-events: none;
}

/* Bevels
   ------
   Inset one half-pixel from each edge so the lit hairline sits inside the
   border radius rather than on it. */
.c-chip::before,
.c-chip::after {
  content: '';
  position: absolute;
  right: 0.5px;
  width: calc(100% - 1px);
  height: 100%;
  border-radius: inherit;
  pointer-events: none;
}

.c-chip::before {
  top: 0.5px;
  box-shadow: var(--c-chip-bevel-top);
  mask-image: linear-gradient(to bottom, #000 0%, transparent 30%);
}

.c-chip::after {
  bottom: 0;
  box-shadow: var(--c-chip-bevel-bottom);
  mask-image: linear-gradient(to top, #000 0%, transparent 30%);
}

/* Colorless
   ---------
   The App's unfilled base — a chip holding no aroma category. Warm recessed
   ground, a real border, body ink, and no bevels, because there is no saturated
   fill for them to curve. */
.c-chip--colorless {
  --c-chip-fill: var(--c-surface-nested);
  --c-chip-well-fill: rgb(255 255 255 / 0.35);
  --c-chip-label: var(--c-foreground);
  --c-chip-shade: none;

  border: 1px solid var(--border);
}

/* `--c-chip-shade` is re-cleared here, not inherited from the rule above: the
   dark register sets it at `.dark .c-chip`, which outranks a bare
   `.c-chip--colorless`, and a dark glow behind near-white ink is exactly wrong. */
.dark .c-chip--colorless {
  --c-chip-fill: rgb(var(--c-white-rgb) / 0.08);
  --c-chip-well-fill: rgb(var(--c-white-rgb) / 0.1);
  --c-chip-shade: none;
}

.c-chip--colorless::before,
.c-chip--colorless::after,
.c-chip--colorless .c-chip__icon::after {
  display: none;
}

/* Sizes
   -----
   The App's two smaller steps. The well and its overlap shrink with the chip;
   everything else is inherited. */
.c-chip--sm {
  --c-chip-height: 28px;
  --c-chip-well: 26px;
  --c-chip-glyph: 0.875rem;
  --c-chip-overlap: -6px;

  padding: 0 10px 0 6px;
  font-size: 0.84375rem;
}

.c-chip--xs {
  --c-chip-height: 24px;
  --c-chip-well: 22px;
  --c-chip-glyph: 0.75rem;
  --c-chip-overlap: -5px;

  padding: 0 8px 0 5px;
  font-size: 0.78125rem;
}

/* Mini
   ----
   The datatable's icon-only pill: the chip itself disappears and the well
   becomes the whole object, its two tones pulled to the middle quartiles so the
   gradient stays vivid at 32px instead of running to either endpoint. */
.c-chip--mini {
  width: var(--c-chip-height);
  padding: 0;
  border: 0;
  border-radius: 50%;
  background-color: transparent;
  box-shadow: none;
  justify-content: center;
}

.c-chip--mini .c-chip__icon {
  margin: 0;
  background-image: linear-gradient(
    135deg,
    color-mix(in srgb, var(--c-guide-aroma) 25%, var(--c-guide-aroma-shade)) 0%,
    color-mix(in srgb, var(--c-guide-aroma) 75%, var(--c-guide-aroma-shade)) 100%
  );
}

.c-chip--mini::before,
.c-chip--mini::after {
  display: none;
}

/* No icon
   -------
   Without a well to overlap, the left padding matches the right. */
.c-chip--no-icon {
  padding-left: 12px;
}

/* Checkable
   ---------
   A selectable option. The squared upper-right corner is the affordance the App
   shows before anything is selected; the indicator arrives with `--checked`.
   Both are drawn, never wired: a reader page must not carry a control that does
   nothing, so there is no input here and nothing to click. */
.c-chip--checkable {
  padding-right: 20px;
  border-top-right-radius: 4px;
}

.c-chip__indicator {
  position: absolute;
  top: 0;
  right: 0;
  width: 16px;
  height: 16px;
  border-radius: 4px;
  background-color: transparent;
  pointer-events: none;
}

.c-chip--checked .c-chip__indicator {
  background-color: var(--c-chip-flag);
  background-image: var(--c-chip-tick);
  background-repeat: no-repeat;
  background-position: center;
  background-size: 12px 12px;
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.32);
}

/* Adjective
   ---------
   A qualifier the reader can open. The App's dotted underline, lightened over a
   filled chip so it reads as a hint rather than a rule. */
.c-chip__adjective {
  text-decoration: 1px underline dotted;
  text-underline-offset: 2px;
}

.c-chip:not(.c-chip--colorless) .c-chip__adjective {
  text-decoration-color: rgb(255 255 255 / 0.4);
}

/* Forced colors drops every background, which would leave the well and the
   indicator as empty holes. Give them borders to survive on. */
@media (forced-colors: active) {

  .c-chip,
  .c-chip__icon {
    border: 1px solid currentColor;
  }

  .c-chip--checked .c-chip__indicator {
    border: 1px solid currentColor;
    background-color: Highlight;
  }

}
