/* The document viewport: the one element a KPress document scrolls inside.
   It is the `@container kpress-doc` query container. The standalone page shell
   sets it on `kpress-page-main`; an embedding host sets the same class/attribute
   on its own scroll pane. This is what lets the TOC react to the document's real
   width.

   CRITICAL: the viewport must NOT be a containing block for `position: fixed`
   descendants — no transform/filter/perspective/backdrop-filter here. A
   transformed ancestor makes fixed descendants behave like `position: absolute`,
   and absolutely-positioned children of a scroller move with the scrolled
   content: every piece of floating UI (TOC toggle/drawer/backdrop, settings
   menu) would sit at the top of the *document* and scroll away exactly when it
   should appear. The fixed containing block lives one level up, on the
   non-scrolling `.kpress-frame`. */
.kpress-viewport {
  block-size: 100dvh;
  overflow-y: auto;
  container: kpress-doc / inline-size;
  /* In-document hash navigation (TOC and section links) is native browser
     navigation; the glide lives here so it also honors the reduced-motion
     override below. */
  scroll-behavior: smooth;
}

/* The document frame: a non-scrolling wrapper of the viewport that pins the
   floating UI. `transform` is the universally-honored trigger that makes it the
   containing block for `position: fixed` descendants; because the frame does not
   scroll, the floating UI stays pinned to its box while the viewport's content
   scrolls beneath it. Standalone, the page shell marks `<body>` (whose box is
   exactly the window). An embedding host puts this class/attribute on a
   non-scrolling wrapper of its scroll pane so the floating UI pins to the pane
   instead of escaping over the host's own chrome; a host that omits it gets
   window-pinned floating UI. */
.kpress-frame {
  transform: translateZ(0);
}

/* The standalone page scroller carries the document background/text so the
   whole window is themed (the embedded host owns its own pane background, so
   this targets the standalone-only `.kpress-page-main`, not `.kpress-viewport`). */
.kpress-page-main {
  background: var(--kpress-doc-bg);
  color: var(--kpress-doc-text);
  padding-inline: var(--kpress-page-margin-inline);
  padding-block-start: var(--kpress-page-margin-block-start);
}

/* Standalone pages on phones: the 2rem gutter is a third of the padding stack;
   narrow it so the reading column keeps its width. */
@media (max-width: 767px) {
  .kpress-page-main {
    --kpress-page-margin-inline: 0.5rem;
  }
}

/* ─────────────────────────────────────────────────────────────────
   Document layout + Table of Contents: the responsive system.

   READ THIS BEFORE TOUCHING THE TOC OR TABLE WIDTHS — the pieces are
   coupled and the failure modes are non-obvious.

   DOM (emitted by format/render.py):
     article.kpress-doc                       reading-measure cap #1
       div.kpress-doc-layout.kpress-content-with-toc   cap #2 + TOC grid
         nav.kpress-toc                        the TOC (sidebar OR drawer)
         div.kpress-prose.kpress-long-text     the article body

   TWO elements carry the reading-measure cap and BOTH centre via
   margin:auto (in document.css): `.kpress-doc` (max-width measure + 2rem)
   and the inner `.kpress-doc-layout` (max-width = measure). Plain single-
   column reading wants both caps. Any layout that needs the full pane must
   uncap BOTH — uncapping only the article leaves `.kpress-doc-layout`
   centred at the measure, which reads as a large left margin with the
   grid tracks spilling off its right edge.

   Everything responsive keys off `@container kpress-doc` — the width of the
   scroll pane (`.kpress-viewport`), NOT the window — so it is correct both
   standalone and embedded in a host pane narrower than the window. Three
   mutually exclusive bands, each defined once below:

     >= 75rem   WIDE     TOC is a sticky left sidebar. Uncaps both caps;
                         grid is `15rem 53rem`, left-aligned (justify-
                         content: start) so the reading column is a constant
                         48rem and all extra width is one right-hand margin.
     48-75rem   TABLET   Single column; TOC is a fixed drawer + toggle.
     < 48rem    MOBILE   Single column; drawer; tighter type.

   TABLE INVARIANT: only tables marked `data-kpress-table-scale="wide"`
   (stamped by the renderer / tables.js past the TABLE_WIDE_MIN_* cutoff)
   ever leave the reading column; unmarked tables cap at the column in
   every band. The base wide rule (further down) is a column-centred
   full-bleed — left:50% + translateX(-50%), width keyed off 100cqw so it
   caps at the kpress-doc pane, never the window. That centred bleed is
   only right for a centred single column (with or without a pane
   narrower than the window). Bands that left-align the column (the
   wide-band TOC grid) or want internal scrolling instead MUST neutralise
   it (left:0; transform:none; a left-anchored width) AT OR ABOVE THE
   ATTRIBUTE SELECTOR'S SPECIFICITY (list the
   [data-kpress-table-scale="wide"] variant in the reset) or wide tables
   centre on the column and overhang the layout. All three bands carry
   that reset today; if you add a band, add the reset too.
   ───────────────────────────────────────────────────────────────── */
.kpress-content-with-toc {
  position: relative;
}

.kpress-content-with-toc.has-toc,
.kpress-content-with-toc:has(.kpress-toc) {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

.kpress-long-text {
  background: var(--kpress-doc-bg);
  margin-inline: auto;
  max-width: min(100%, 48rem);
  padding: 1rem 1.5rem;
}

@media (min-width: 768px) {
  .kpress-long-text {
    padding-inline: 4rem;
  }
}

/* Content card: the reading column rendered as a bordered sheet floating
   over the page — textpress's long-text card (hairline + soft shadow at md+;
   narrow screens stay full-bleed, same as textpress). The geometry is
   ALREADY the card's (.kpress-long-text's 48rem cap and md 4rem inline
   padding above are kash's max-w-3xl + md:px-16), so this adds chrome only —
   no layout-affecting properties, which keeps the coupled TOC/table width
   system untouched. Render-time switch: RenderOptions.content_card /
   `format.content_card` stamps data-kpress-card on the article ("on" is the
   default); embedding hosts stamp the same attribute on the fragment wrapper
   themselves. Chrome tokens: --kpress-card-border / --kpress-card-shadow
   (style-tokens.css). */
@media (min-width: 768px) {
  .kpress[data-kpress-card="on"] .kpress-long-text {
    border: var(--kpress-card-border);
    box-shadow: var(--kpress-card-shadow);
    /* Breathing room around the text: vertical only here (inline padding is
       the band system's business — 4rem single-column, 2.5rem in the wide
       TOC track — so the card never touches the coupled width math). */
    padding-block: 2.5rem 3rem;
  }

  /* Breathing room below the card before the page (or footer) ends. On the
     article so it composes with .kpress-doc's own padding; vertical only. */
  .kpress-doc[data-kpress-card="on"] {
    padding-block-end: 6rem;
  }
}

.kpress-header-row {
  align-items: center;
  display: flex;
}

.kpress-header-grow {
  flex: 1 1 auto;
  margin-inline-start: 0.5rem;
}

.kpress-header-actions {
  align-items: center;
  display: flex;
  gap: 0.5rem;
  margin-inline-start: auto;
}

.kpress-page-spacer {
  margin-top: 1.5rem;
}

/* Settings menu: a gear button that opens a popover of segmented icon
   choosers (theme today; more can be added). Ported from the original host
   app's settings control, re-tokenized onto KPress document tokens so it
   themes with the document. The wrapper's `aria-expanded` drives menu visibility. */
.kpress-settings {
  inset-block-start: var(--kpress-settings-inset-block);
  inset-inline-end: var(--kpress-settings-inset-inline);
  position: fixed;
  z-index: 250;
}

.kpress-settings-btn {
  align-items: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--kpress-radius-sm);
  color: var(--kpress-doc-muted);
  cursor: pointer;
  display: inline-flex;
  height: 28px;
  justify-content: center;
  padding: 4px;
  transition:
    color var(--kpress-transition-fast),
    background var(--kpress-transition-fast);
  width: 28px;
}

.kpress-settings-btn:hover,
.kpress-settings[aria-expanded="true"] .kpress-settings-btn {
  background: var(--color-hover-bg);
  color: var(--kpress-doc-text);
}

.kpress-settings-btn:focus-visible {
  outline: 3px solid var(--color-primary-light);
  outline-offset: 2px;
}

.kpress-settings-btn svg {
  height: 16px;
  width: 16px;
}

.kpress-settings-menu {
  display: none;
  inset-block-start: calc(100% + 4px);
  inset-inline-end: 0;
  position: absolute;
}

.kpress-settings[aria-expanded="true"] .kpress-settings-menu {
  display: flex;
}

.kpress-menu {
  background: var(--kpress-doc-bg);
  border: 1px solid var(--kpress-doc-border);
  border-radius: var(--kpress-radius-sm);
  box-shadow:
    0 4px 6px -1px oklch(0.00% 0 0 / 0.1),
    0 2px 4px -1px oklch(0.00% 0 0 / 0.06);
  flex-direction: column;
  min-width: 124px;
  padding: 4px;
  z-index: 300;
}

.kpress-menu-chooser {
  display: flex;
  gap: 2px;
}

.kpress-menu-select {
  background: var(--kpress-doc-bg);
  border: 1px solid var(--kpress-doc-border);
  border-radius: var(--kpress-radius-sm);
  color: var(--kpress-doc-text);
  font-family: var(--kpress-font-sans);
  font-size: var(--kpress-font-size-tiny);
  padding: 4px 6px;
  width: 100%;
}

/* Stacked chooser groups read as one menu; give successive groups a little
   separation. The native select (font-set chooser) inherits document tokens.
   These adjacency selectors come after the base `.kpress-menu-select` above so
   specificity ascends in source order (biome noDescendingSpecificity). */
.kpress-menu-chooser + .kpress-menu-chooser,
.kpress-menu-chooser + .kpress-menu-select,
.kpress-menu-select + .kpress-menu-chooser {
  margin-top: 4px;
}

.kpress-menu-seg {
  align-items: center;
  background: transparent;
  border: 0;
  border-radius: var(--kpress-radius-sm);
  color: var(--kpress-doc-muted);
  cursor: pointer;
  display: flex;
  flex: 1;
  height: 30px;
  justify-content: center;
  min-width: 34px;
  padding: 0;
  transition:
    color var(--kpress-transition-fast),
    background var(--kpress-transition-fast);
}

.kpress-menu-seg:hover,
.kpress-menu-seg:focus-visible {
  background: var(--color-hover-bg);
  color: var(--kpress-doc-text);
  outline: none;
}

.kpress-menu-seg[aria-checked="true"] {
  background: var(--color-bg-selected);
  color: var(--kpress-doc-link);
}

.kpress-menu-seg svg {
  height: 16px;
  width: 16px;
}

.kpress-toc {
  border: 1px solid var(--kpress-doc-border);
  color: var(--kpress-doc-muted);
  font-family: var(--kpress-font-sans);
  font-feature-settings: var(--kpress-font-features-sans);
  font-size: var(--kpress-font-size-smaller);
  font-variant-numeric: tabular-nums;
  margin: 0 0 1.5rem;
  padding: 0.5rem 0.7rem 1rem 1.2rem;
}

.kpress-toc ol {
  line-height: 1.2;
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
}

.kpress-toc a {
  border-left: 2px solid transparent;
  color: inherit;
  display: block;
  padding-block: 0.2rem;
  text-decoration: none;
  /* Only the hover/active properties. Never `all`: a late-applied stylesheet
     (slow or failed sheet, host style injection) must snap into place, not
     visibly animate every property. */
  transition:
    color var(--kpress-transition-fast),
    background-color var(--kpress-transition-fast),
    border-color var(--kpress-transition-fast);
}

/* Hover and active both shift the text to the secondary tone; the colored
   left indicator (plus the selected background) is what marks the active
   section. The 2px transparent border above keeps text from shifting when
   active. */
.kpress-toc a:hover {
  background-color: var(--color-hover-bg);
  color: var(--color-secondary);
  text-decoration: none;
}

.kpress-toc a[data-active="true"],
.kpress-toc a.active {
  background-color: var(--color-bg-selected);
  border-left-color: var(--kpress-doc-link);
  color: var(--color-secondary);
  text-decoration: none;
}

/* Each entry indents by heading level. The padding sits on the link (the
   element carrying the active border-left bar) so the bar pins to the
   container edge while the text indents away from it; the -1em hanging
   indent keeps wrapped lines aligned under the first. Deeper levels indent
   further and lighten in weight, echoing the document's heading hierarchy. */
.kpress-toc-level-1 > a,
.kpress-toc-level-2 > a,
.kpress-toc-level-3 > a,
.kpress-toc-level-4 > a,
.kpress-toc-level-5 > a,
.kpress-toc-level-6 > a {
  text-indent: -1em;
}

/* Two-level weight hierarchy, matching textpress (toc-h2=550 medium, toc-h3=370
   light). kpress normalizes TOC levels to structural tree depths, so the top
   content level is level-1 (typically the document's h2): it gets medium;
   everything deeper gets light. (textpress keys the same two weights off raw
   h2/h3.) */
.kpress-toc-level-1 > a {
  font-weight: var(--kpress-font-weight-sans-medium);
  letter-spacing: 0.007em;
}

.kpress-toc-level-2 > a,
.kpress-toc-level-3 > a,
.kpress-toc-level-4 > a,
.kpress-toc-level-5 > a,
.kpress-toc-level-6 > a {
  font-weight: var(--kpress-font-weight-sans-light);
}

.kpress-toc-level-1 > a {
  padding-left: 1.3rem;
}

.kpress-toc-level-2 > a {
  padding-left: 2rem;
}

.kpress-toc-level-3 > a {
  padding-left: 2.7rem;
}

.kpress-toc-level-4 > a {
  padding-left: 3.4rem;
}

.kpress-toc-level-5 > a {
  padding-left: 4.1rem;
}

.kpress-toc-level-6 > a {
  padding-left: 4.8rem;
}

/* Floating TOC control (32px button, 20px icon — a step larger than the
   settings gear so it reads as the document's primary navigation affordance).
   It floats over the narrow band's tightened text gutter, so instead of the
   gear's transparent-until-hover chrome it always carries a translucent
   document-background fill: where it slightly overlaps a long line, both the
   icon and the text beneath stay readable, in light and dark themes alike
   (the fill follows --kpress-doc-bg). */
.kpress-toc-toggle {
  align-items: center;
  background: color-mix(in srgb, var(--kpress-doc-bg) 80%, transparent);
  border: 1px solid transparent;
  border-radius: var(--kpress-radius-sm);
  color: var(--kpress-doc-muted);
  cursor: pointer;
  display: inline-flex;
  font: inherit;
  height: 32px;
  justify-content: center;
  padding: 4px;
  transition:
    color var(--kpress-transition-fast),
    background-color var(--kpress-transition-fast);
  width: 32px;
}

.kpress-toc-toggle:hover {
  background-color: var(--color-hover-bg);
  color: var(--kpress-doc-text);
}

.kpress-toc-toggle-icon {
  display: block;
  height: 20px;
  width: 20px;
}

.kpress-toc-title {
  border-bottom: 1px solid var(--kpress-doc-border);
  border-left: none;
  font-size: var(--kpress-caps-label-size);
  font-variant-caps: var(--kpress-caps-variant);
  font-weight: var(--kpress-font-weight-sans-medium);
  letter-spacing: var(--kpress-caps-spacing);
  line-height: var(--kpress-caps-heading-line-height);
  padding-left: 0.3rem;
  text-transform: var(--kpress-caps-transform);
}

/* Collapsible-TOC chrome (server-rendered only when toc_collapse_depth is
   set and the document has deeper entries; toc.js owns the state). The
   header row moves the title's underline onto the full row so the TOC reads
   the same with and without the expand-all button flush right of
   "Contents". */
.kpress-toc-header {
  align-items: center;
  border-bottom: 1px solid var(--kpress-doc-border);
  display: flex;
  gap: 0.3rem;
  justify-content: space-between;
}

.kpress-toc-header .kpress-toc-title {
  border-bottom: none;
  flex: 1 1 auto;
}

/* Deliberately quiet control: no border or fill, colored like the Contents
   label it sits beside (the muted TOC tone), darkening slightly on hover.
   The chevrons glyph pair keeps it minimal — a small disclosure hint, not a
   chrome button. */
.kpress-toc-expand-all {
  align-items: center;
  background: transparent;
  border: none;
  border-radius: var(--kpress-radius-sm);
  color: inherit;
  cursor: pointer;
  display: inline-flex;
  flex: none;
  height: 18px;
  justify-content: center;
  opacity: 0.55;
  padding: 2px;
  transition:
    color var(--kpress-transition-fast),
    opacity var(--kpress-transition-fast);
  width: 18px;
}

.kpress-toc-expand-all:hover {
  background-color: var(--color-hover-bg);
  color: var(--kpress-doc-text);
  opacity: 1;
}

.kpress-toc-expand-all-icon {
  display: block;
  height: 12px;
  width: 12px;
}

/* Both state icons are server-rendered; aria-expanded picks the visible one
   (unfold while collapsed, fold while expanded) so the behavior only flips
   the attribute, never the markup. */
.kpress-toc-expand-all[aria-expanded="true"] .kpress-toc-expand-all-icon:first-of-type,
.kpress-toc-expand-all[aria-expanded="false"] .kpress-toc-expand-all-icon:last-of-type {
  display: none;
}

/* Collapsed entries animate closed rather than display:none (which cannot
   transition): each row eases its block-size and opacity to zero with the
   standard motion tokens, and visibility drops the hidden links from the
   tab order when the transition ends. Scoped to collapse-enabled navs so
   documents without the feature keep today's exact row styling. The
   :where() keeps the ancestor scope at zero specificity so the global
   prefers-reduced-motion block (`.kpress [class]`, later in this file) still
   outranks the transition and suppresses the motion. */
:where(.kpress-toc[data-kpress-toc-collapse-depth]) .toc-list > li {
  max-block-size: 5rem;
  overflow: hidden;
  transition:
    max-block-size var(--kpress-transition-med),
    opacity var(--kpress-transition-med),
    visibility var(--kpress-transition-med);
}

:where(.kpress-toc[data-kpress-toc-collapse-depth]) .toc-list > li.kpress-toc-collapsed {
  max-block-size: 0;
  opacity: 0;
  visibility: hidden;
}

/* `position: fixed` resolves against the non-scrolling `.kpress-frame` (the
   containing block for fixed descendants), so `inset: 0` covers the document
   frame — the whole window standalone, just the pane when embedded. */
.kpress-toc-backdrop {
  background-color: oklch(0.00% 0 0 / 0.5);
  display: none;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  position: fixed;
  transition:
    opacity var(--kpress-transition-fade),
    visibility var(--kpress-transition-fade);
  visibility: hidden;
  z-index: 199;
}

.kpress-toc-backdrop.kpress-visible {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
}

.kpress-footnotes {
  border-top: 1px solid var(--kpress-doc-border);
  color: var(--kpress-doc-muted);
  font-family: var(--kpress-font-footnote);
  font-size: 0.9em;
  margin-top: 2rem;
  padding-top: 1rem;
}

.kpress-footnote-ref a,
.kpress-footnote-backref {
  background-color: var(--color-bg-meta-solid);
  border-radius: var(--kpress-radius-md);
  color: var(--color-hint-strong);
  font-family: var(--kpress-font-sans);
  font-feature-settings: var(--kpress-font-features-sans);
  font-style: normal;
  font-weight: 600;
  margin-right: 0.15rem;
  padding: 0 0.15rem;
  text-decoration: none;
  /* Hover properties only, never `all` (late-applied styles must not animate). */
  transition:
    color var(--kpress-transition-fast),
    background-color var(--kpress-transition-fast);
}

/* `a.…backref` qualifier: the generic `.kpress a:hover` underline is specificity
   (0,2,1); a bare `.kpress-footnote-backref:hover` is only (0,2,0) and loses, so the
   ↑ back-link would underline on hover. Adding the `a` type wins it back. */
.kpress-footnote-ref a:hover,
.kpress a.kpress-footnote-backref:hover {
  background-color: var(--color-hover-bg);
  color: var(--color-primary-light);
  text-decoration: none;
}

.kpress-tooltip {
  background: var(--color-bg-meta-solid);
  border: 1px solid var(--color-hint-gentle);
  border-left: 2px solid var(--kpress-doc-link);
  border-radius: var(--kpress-radius-none);
  box-shadow:
    0 4px 6px -1px oklch(0.00% 0 0 / 0.1),
    0 2px 4px -1px oklch(0.00% 0 0 / 0.06);
  color: var(--kpress-doc-text);
  font-family: var(--kpress-font-sans);
  font-feature-settings: var(--kpress-font-features-sans);
  font-size: var(--kpress-font-size-small);
  font-weight: 400;
  hyphens: auto;
  line-height: 1.4;
  max-width: min(20rem, calc(100vw - 2rem));
  min-width: 8rem;
  opacity: 0;
  overflow-wrap: break-word;
  padding: 0.5rem 0.75rem;
  pointer-events: none;
  position: fixed;
  transition:
    opacity 0.6s ease-in-out,
    visibility 0.6s ease-in-out;
  visibility: hidden;
  white-space: normal;
  width: max-content;
  word-break: normal;
  z-index: 1000;
}

.kpress-tooltip.kpress-tooltip-visible {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
}

/* Section-preview tooltips navigate to their target on tap/click
   (tooltips.js); the pointer signals it. Footnote popovers stay plain — only
   the links inside them navigate. */
.kpress-tooltip:not(.kpress-tooltip-footnote) {
  cursor: pointer;
}

/* No edge arrow on tooltips (textpress has none; the bare popover reads cleaner).
   The per-position `::after` border-color rules below are inert while this is hidden. */
.kpress-tooltip::after {
  display: none;
}

.kpress-tooltip a {
  color: var(--kpress-doc-link);
  cursor: pointer;
  overflow-wrap: break-word;
  pointer-events: auto;
  text-decoration: underline;
  transition: color var(--kpress-transition-med);
}

.kpress-tooltip a:hover {
  color: var(--color-primary-light);
  text-decoration: underline;
}

.kpress-tooltip code,
.kpress-tooltip pre {
  font-size: 0.9em;
  overflow-wrap: break-word;
  white-space: normal;
  word-break: break-all;
}

.kpress-tooltip p,
.kpress-tooltip span,
.kpress-tooltip div {
  overflow-wrap: break-word;
  word-break: normal;
}

.kpress-tooltip-footnote {
  font-family: var(--kpress-font-footnote);
  line-height: 1.5;
  max-width: min(25rem, calc(100vw - 2rem));
  min-width: 12rem;
  text-align: left;
}

.kpress-tooltip-bottom::after {
  border-bottom-color: var(--kpress-doc-border);
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
}

.kpress-tooltip-bottom-right::after {
  border-bottom-color: var(--kpress-doc-border);
  bottom: 100%;
  left: 1rem;
}

.kpress-tooltip-bottom-left::after {
  border-bottom-color: var(--kpress-doc-border);
  bottom: 100%;
  right: 1rem;
}

.kpress-tooltip-top::after {
  border-top-color: var(--kpress-doc-border);
  left: 50%;
  top: 100%;
  transform: translateX(-50%);
}

.kpress-tooltip-top-right::after {
  border-top-color: var(--kpress-doc-border);
  left: 1rem;
  top: 100%;
}

.kpress-tooltip-top-left::after {
  border-top-color: var(--kpress-doc-border);
  right: 1rem;
  top: 100%;
}

.kpress-tooltip-left::after {
  border-left-color: var(--kpress-doc-border);
  left: 100%;
  top: 50%;
  transform: translateY(-50%);
}

.kpress-tooltip-right::after {
  border-right-color: var(--kpress-doc-border);
  right: 100%;
  top: 50%;
  transform: translateY(-50%);
}

.kpress-tooltip-wide-right {
  box-shadow:
    0 8px 25px -3px oklch(0.00% 0 0 / 0.15),
    0 4px 6px -2px oklch(0.00% 0 0 / 0.05);
  max-width: 24rem;
}

.kpress-tooltip-wide-right::after {
  border-right-color: var(--kpress-doc-border);
  right: 100%;
  top: 50%;
  transform: translateY(-50%);
}

.kpress-tooltip-mobile-bottom {
  box-shadow: 0 -4px 16px oklch(0.00% 0 0 / 0.18);
  box-sizing: border-box;
  max-width: none;
  padding: 0.75rem 1rem;
  text-align: left;
}

.kpress-tooltip-mobile-bottom::after {
  display: none;
}

.kpress-footnote-nav {
  float: right;
  margin-inline-start: 0.5rem;
}

.kpress-tooltip .kpress-footnote-nav-link {
  text-decoration: none;
}

.kpress-tooltip .kpress-footnote-nav-link:hover {
  text-decoration: none;
}

/* Tables: only tables marked wide (data-kpress-table-scale="wide", stamped by
   the renderer/tables.js when a table is large on both axes — see
   TABLE_WIDE_MIN_* in format/markdown.py) get the wide presentation. Smaller
   tables keep the reading-column width in every band; content wider than the
   wrap still scrolls internally. The base wide rule below is the
   column-centred, pane-capped full bleed for a centred single column;
   container bands neutralise it where the column is not centred or the
   bleed is unwanted (see the layout comment above). */
.kpress-table-wrap {
  background-color: var(--kpress-doc-bg);
  box-sizing: border-box;
  margin: 2rem 0;
  overflow-x: auto;
  overflow-y: hidden;
  position: relative;
  scrollbar-color: var(--color-scrollbar) transparent;
  scrollbar-width: thin;
  width: 100%;
}

.kpress-table-wrap[data-kpress-table-scale="wide"] {
  left: 50%;
  transform: translateX(-50%);
  /* 100cqw, not 100vw: the bleed is capped at the kpress-doc pane, so a
     no-TOC document embedded in a pane narrower than the window stays inside
     the pane (without a query container, cqw falls back to vw — the
     standalone window-width case, where they are equal). */
  width: min(calc(100cqw - 2rem), max(100%, var(--kpress-measure)));
}

.kpress-table {
  border: 1px solid var(--color-border-hint);
  border-collapse: collapse;
  font-family: var(--kpress-font-table);
  font-feature-settings: var(--kpress-font-features-sans);
  font-size: var(--kpress-font-size-small);
  line-height: 1.3;
  min-width: 100%;
  width: auto;
  word-break: break-word;
}

.kpress-table th,
.kpress-table td {
  max-width: 40rem;
  min-width: 6rem;
  padding: 0.3rem 0.6rem;
  text-align: start;
  vertical-align: top;
}

.kpress-table th {
  background-color: var(--color-bg-alt-solid);
  border-bottom: 1px solid var(--color-border-hint);
  font-size: var(--kpress-caps-label-size);
  font-variant-caps: var(--kpress-caps-variant);
  font-weight: var(--kpress-font-weight-sans-bold);
  /* Header labels hyphenate rather than inherit the table's break-word
     letter-level wrapping: a narrow column shows "Capitali-zation" over more
     lines, never an unhyphenated mid-word cut. overflow-wrap stays as the
     last resort for strings hyphenation cannot split (needs a `lang` on the
     document/host root to pick a hyphenation dictionary). */
  hyphens: auto;
  letter-spacing: var(--kpress-caps-spacing);
  line-height: var(--kpress-caps-heading-line-height);
  overflow-wrap: break-word;
  text-align: center;
  text-transform: var(--kpress-caps-transform);
  word-break: normal;
}

.kpress-table tbody tr:nth-child(even) {
  background-color: var(--color-bg-alt-solid);
}

.kpress-table [data-kpress-numeric="true"] {
  font-variant-numeric: tabular-nums;
  text-align: end;
}

/* Task-list checkboxes: one clean box (no extra prose bullet), drawn with the
   shared Lucide `square` / `square-check` glyphs via a mask. Unchecked is a dimmer
   gray empty box; checked is a darker box with a check. The disabled <input> stays
   for its accessible checked/unchecked state. */
.kpress-prose ul > li.kpress-task::before {
  content: none;
}

.kpress-task {
  list-style: none;
}

.kpress-task input[type="checkbox"] {
  appearance: none;
  background-color: var(--kpress-doc-muted);
  block-size: var(--kpress-checkbox-size);
  cursor: default;
  inline-size: var(--kpress-checkbox-size);
  margin-inline-end: 0.4rem;
  mask:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='18' height='18' x='3' y='3' rx='2'/%3E%3C/svg%3E")
    center / contain no-repeat;
  vertical-align: -0.15em;
}

.kpress-task input[type="checkbox"]:checked {
  background-color: var(--kpress-doc-text);
  mask:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='18' height='18' x='3' y='3' rx='2' stroke-width='2'/%3E%3Cpath d='m7 12.5 3.5 3.5 6.5-7' stroke-width='2.5'/%3E%3C/svg%3E")
    center / contain no-repeat;
}

.kpress-code-scroll {
  overflow-x: auto;
}

/* Minimal scrollbar on the remaining doc scroll surfaces (the main viewport
   keeps the OS scrollbar; tables/code/tabs set theirs inline). */
.kpress-code-scroll,
.kpress-math-display,
.kpress-diagram-source,
.kpress-diagram-rendered {
  scrollbar-color: var(--color-scrollbar) transparent;
  scrollbar-width: thin;
}

.kpress-code:has(.kpress-code-copy) {
  position: relative;
}

/* Icon-only copy control, revealed on hover/focus of the code block
   (host-app parity). The label lives in aria-label/title, never as text. */
.kpress-code-copy {
  align-items: center;
  background: var(--kpress-doc-bg);
  border: 1px solid var(--kpress-doc-border);
  border-radius: var(--kpress-radius-sm);
  color: var(--kpress-doc-muted);
  cursor: pointer;
  display: flex;
  inset-block-start: 0.4rem;
  inset-inline-end: 0.4rem;
  justify-content: center;
  opacity: 0;
  padding: 0.3rem;
  position: absolute;
  transition:
    background-color var(--kpress-transition-fast),
    border-color var(--kpress-transition-fast),
    color var(--kpress-transition-fast),
    opacity var(--kpress-transition-fast);
  z-index: 1;
}

.kpress-code-copy svg {
  block-size: 15px;
  display: block;
  inline-size: 15px;
}

.kpress-code:hover .kpress-code-copy,
.kpress-code:focus-within .kpress-code-copy,
.kpress-code-copy:focus-visible {
  opacity: 1;
}

.kpress-code-copy:hover {
  background: var(--color-hover-bg);
  color: var(--kpress-doc-text);
}

.kpress-code-copy:focus-visible {
  outline: 3px solid var(--kpress-doc-link);
  outline-offset: 2px;
}

.kpress-code-copy[data-kpress-copy-state="copied"] {
  background: color-mix(in srgb, var(--color-success) 12%, transparent);
  border-color: var(--color-success);
  color: var(--color-success);
  opacity: 1;
}

.kpress-code-copy[data-kpress-copy-state="error"] {
  background: color-mix(in srgb, var(--kpress-doc-danger) 12%, transparent);
  border-color: var(--kpress-doc-danger);
  color: var(--kpress-doc-danger);
  opacity: 1;
}

.kpress-math {
  font-family: var(--kpress-font-prose);
  line-height: 1.4;
}

.kpress-math math {
  color: inherit;
  font-size: 1.02em;
}

.kpress-math-inline {
  display: inline-block;
  max-width: 100%;
  /* Let KaTeX's / the MathML fallback's own baseline seat on the text baseline;
     the previous -0.1em nudge dropped inline math ~half an x-height too low. */
  vertical-align: baseline;
}

.kpress-math-display {
  display: block;
  margin-block: 1rem;
  overflow-x: auto;
  padding-block: 0.25rem;
  scrollbar-color: var(--color-scrollbar) transparent;
  scrollbar-width: thin;
  text-align: center;
}

.kpress-math-display math {
  display: inline-block;
  max-width: 100%;
}

/* KaTeX progressive enhancement: the semantic MathML renders by default and
   as the no-JS fallback; the TeX source node stays hidden until KaTeX
   replaces it. Once rendered, KaTeX is shown and the MathML is kept in the
   accessibility tree only. */
.kpress-math-render {
  display: none;
}

.kpress-math[data-kpress-math-rendered="true"] .kpress-math-render {
  display: inline;
}

.kpress-math-display[data-kpress-math-rendered="true"] .kpress-math-render {
  display: block;
}

.kpress-math[data-kpress-math-rendered="true"] .kpress-math-semantic {
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

.kpress-math[data-kpress-math-error="true"] {
  background: color-mix(in srgb, var(--kpress-doc-danger) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--kpress-doc-danger) 45%, transparent);
  border-radius: var(--kpress-radius-sm);
  color: var(--kpress-doc-danger);
  font-family: var(--kpress-font-mono);
  font-size: var(--kpress-font-size-mono);
  padding: 0.05rem 0.25rem;
}

.kpress-diagram {
  margin: 1.5rem 0;
}

.kpress-diagram svg {
  display: block;
  height: auto;
  margin-inline: auto;
  max-width: 100%;
}

.kpress-svg-diagram,
.kpress-mermaid {
  background: var(--kpress-doc-bg);
  border: 1px solid var(--kpress-doc-border);
  padding: 1rem;
}

.kpress-diagram-source {
  margin: 0;
  overflow-x: auto;
  scrollbar-color: var(--color-scrollbar) transparent;
  scrollbar-width: thin;
  white-space: pre;
}

.kpress-diagram-rendered {
  overflow-x: auto;
  scrollbar-color: var(--color-scrollbar) transparent;
  scrollbar-width: thin;
}

.kpress-diagram[data-kpress-diagram-status="rendered"] .kpress-diagram-source[hidden] {
  display: none;
}

.kpress-diagram[data-kpress-diagram-status="error"] {
  border-color: color-mix(in srgb, var(--kpress-doc-danger) 45%, var(--kpress-doc-border));
}

.kpress-video-popover[hidden] {
  display: none;
}

/* Tabs: all panels share one grid cell so the container sizes to the TALLEST
   panel and does not jump when switching tabs; capped at ~half a page with
   internal scroll. Inactive panels stay in layout (for sizing) but are hidden
   from view and from the a11y / focus order. */
.kpress-tabs {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  margin: 1.5rem 0;
}

.kpress-tab-list,
.kpress-tabs [role="tablist"] {
  align-items: flex-end;
  border-bottom: 1px solid var(--kpress-doc-border);
  display: flex;
  gap: 0.25rem;
  grid-column: 1;
  grid-row: 1;
  overflow-x: auto;
  scrollbar-color: var(--color-scrollbar) transparent;
  scrollbar-width: thin;
}

.kpress-tab-panel {
  grid-column: 1;
  grid-row: 2;
  max-block-size: 50vh;
  overflow-y: auto;
  padding-block: 1rem;
  scrollbar-color: var(--color-scrollbar) transparent;
  scrollbar-width: thin;
}

.kpress-tab-panel[hidden] {
  display: block;
  visibility: hidden;
}

.kpress .highlight {
  border-radius: var(--kpress-radius-lg);
  padding: 0 0.5rem;
}

.kpress .citation {
  border-radius: var(--kpress-radius-sm);
  color: var(--color-secondary);
  display: inline-block;
  font-family: var(--kpress-font-sans);
  font-feature-settings: var(--kpress-font-features-sans);
  height: 1.3rem;
  padding: 0 0.4rem;
  transition:
    background-color var(--kpress-transition-med),
    color var(--kpress-transition-med);
}

.kpress .citation::before {
  content: "[";
}

.kpress .citation::after {
  content: "]";
}

.kpress .citation:hover {
  background-color: var(--color-hover-bg);
  color: var(--color-primary);
}

.kpress .debug {
  color: var(--color-hint);
  font-family: var(--kpress-font-sans);
  font-feature-settings: var(--kpress-font-features-sans);
  font-size: var(--kpress-font-size-tiny);
  font-weight: 400;
}

.kpress .hero h1 {
  font-family: var(--kpress-font-sans);
  font-feature-settings: var(--kpress-font-features-sans);
  font-size: 1.6rem;
  font-weight: var(--kpress-font-weight-sans-medium);
  letter-spacing: 0.03em;
  line-height: 1.05;
  margin-block: 1rem 0;
  text-transform: uppercase;
}

.kpress .hero h1 i {
  font-family: var(--kpress-font-prose);
  font-size: 1.5rem;
  font-style: italic;
  letter-spacing: 0;
  text-transform: none;
}

.kpress .subtitle {
  font-family: var(--kpress-font-prose);
  font-size: var(--kpress-font-size-normal);
  font-style: italic;
}

.kpress .boxed-text {
  /* The deliberate ink rule (kash border-hairline), not the faint doc border:
     a box the author drew should read as drawn. */
  border: 1px solid var(--kpress-doc-border-hairline);
  margin: 1rem 0;
  padding: 0 1rem;
}

.kpress .shaded-text {
  background-color: var(--kpress-doc-code-bg);
}

/* A sans-serif region: front matter, hero blocks, and other UI-voiced passages
   switch from the serif reading face to the sans stack. */
.kpress .sans-text {
  font-family: var(--kpress-font-sans);
  font-feature-settings: var(--kpress-font-features-sans);
}

.kpress .sans-text p {
  margin-block: 0.8rem;
}

.kpress .sans-text h1 {
  font-family: var(--kpress-font-sans);
  font-feature-settings: var(--kpress-font-features-sans);
  font-size: 1.75rem;
  font-weight: 380;
  margin-block: 1rem 1.2rem;
}

.kpress .sans-text h2 {
  font-family: var(--kpress-font-sans);
  font-feature-settings: var(--kpress-font-features-sans);
  font-size: 1.25rem;
  font-weight: 440;
  margin-block: 1rem 0.8rem;
}

.kpress .centered-headers h1,
.kpress .centered-headers h2,
.kpress .centered-headers h3 {
  text-align: center;
}

.kpress .justify p {
  text-align: justify;
  text-align-last: left;
}

.kpress .description {
  color: var(--color-secondary);
  font-family: var(--kpress-font-sans);
  font-feature-settings: var(--kpress-font-features-sans);
  font-size: var(--kpress-font-size-small);
  margin: 2rem 0;
}

.kpress .key-claims,
.kpress .summary,
.kpress .concepts {
  font-family: var(--kpress-font-sans);
  font-feature-settings: var(--kpress-font-features-sans);
  font-size: var(--kpress-font-size-small);
  margin: 1rem 0;
  padding: 1rem;
}

.kpress .key-claims,
.kpress .concepts {
  border: 1px solid var(--color-hint-gentle);
}

.kpress .key-claims::before,
.kpress .summary::before,
.kpress .concepts::before {
  display: block;
  font-family: var(--kpress-font-sans);
  font-feature-settings: var(--kpress-font-features-sans);
  font-size: calc(1.2rem * var(--kpress-caps-heading-size-multiplier));
  font-variant-caps: var(--kpress-caps-variant);
  font-weight: var(--kpress-font-weight-sans-medium);
  letter-spacing: var(--kpress-caps-spacing);
  line-height: var(--kpress-caps-heading-line-height);
  margin-bottom: 0.5rem;
  text-align: center;
  text-transform: var(--kpress-caps-transform);
}

.kpress .key-claims::before {
  content: "Key Claims";
}

.kpress .summary::before {
  content: "Summary";
}

.kpress .concepts {
  column-count: 3;
  column-gap: 2rem;
  font-weight: var(--kpress-font-weight-sans-bold);
  padding-top: 3.5rem;
  position: relative;
}

.kpress .concepts::before {
  content: "Concepts";
  left: 50%;
  position: absolute;
  top: 1rem;
  transform: translateX(-50%);
  width: 100%;
}

.kpress .claim {
  font-family: var(--kpress-font-sans);
  font-feature-settings: var(--kpress-font-features-sans);
  font-weight: var(--kpress-font-weight-sans-bold);
  margin: 0.7rem 0 0.7rem 1.8rem;
  position: relative;
}

.kpress .claim::before {
  content: "\25AA\FE0E";
  font-size: var(--kpress-bullet-size);
  left: -0.85rem;
  position: absolute;
  top: 0.1rem;
}

.kpress .full-text {
  margin: 1rem 0;
}

.kpress .annotated-para {
  align-items: flex-start;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}

.kpress .annotated-para .para-caption {
  align-self: center;
  border-right: 2px solid var(--color-hint);
  color: var(--color-secondary);
  font-family: var(--kpress-font-sans);
  font-feature-settings: var(--kpress-font-features-sans);
  font-size: var(--kpress-font-size-smaller);
  margin: 0.5rem 1rem 0.5rem 0;
  max-height: 15rem;
  order: 0;
  overflow-y: auto;
  padding-right: 0.5rem;
  scrollbar-color: var(--color-hint-gentle) transparent;
  scrollbar-width: thin;
  width: 20%;
}

.kpress .annotated-para .para {
  order: 1;
  width: 80%;
}

.kpress .frame-capture {
  border: 1px solid var(--color-hint);
  border-radius: var(--kpress-radius-lg);
  display: block;
  margin: 1rem auto;
  max-width: 225px;
}

.kpress .video-gallery {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}

.kpress .video-item {
  background-color: var(--kpress-doc-bg);
  border: 1px solid var(--kpress-doc-border);
  border-radius: var(--kpress-radius-lg);
  padding: 1rem;
}

/* Inline YouTube player. The server emits a safe placeholder (no iframe, so
   sanitized + hashed output stay network-free); video-popover.js swaps in this
   responsive 16:9 frame on load. */
.kpress-video {
  margin: 1.5rem 0;
}

.kpress-video-embed {
  aspect-ratio: 16 / 9;
  border: 0;
  border-radius: var(--kpress-radius-sm);
  display: block;
  width: 100%;
}

.kpress .kpress-video-placeholder {
  align-items: center;
  aspect-ratio: 16 / 9;
  background:
    linear-gradient(135deg, oklch(0.00% 0 0 / 0.72), oklch(0.00% 0 0 / 0.42)), var(--color-primary);
  border: 1px solid var(--kpress-doc-border);
  border-radius: var(--kpress-radius-none);
  color: oklch(100.00% 0 0);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  font-family: var(--kpress-font-sans);
  font-feature-settings: var(--kpress-font-features-sans);
  gap: 0.75rem;
  justify-content: center;
  min-height: 12rem;
  padding: 1rem;
  text-align: center;
  width: 100%;
}

.kpress .kpress-video-placeholder:focus-visible {
  outline: 3px solid var(--kpress-doc-link);
  outline-offset: 3px;
}

.kpress .kpress-video-placeholder-action {
  align-items: center;
  background: oklch(100.00% 0 0 / 0.92);
  border-radius: var(--kpress-radius-pill);
  color: oklch(17.76% 0 0);
  display: inline-flex;
  font-size: var(--kpress-font-size-small);
  font-weight: 700;
  height: 3rem;
  justify-content: center;
  line-height: 1;
  width: 3rem;
}

.kpress .kpress-video-placeholder-title {
  font-size: var(--kpress-font-size-small);
  font-weight: 700;
}

.kpress-video-popover iframe {
  aspect-ratio: 16 / 9;
  border: 0;
  width: 100%;
}

.kpress .video-item iframe {
  border: 0;
  border-radius: var(--kpress-radius-lg);
  height: 200px;
  width: 100%;
}

.kpress .tab-button,
.kpress-tab-button {
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  color: var(--color-secondary);
  cursor: pointer;
  flex: 1 1 auto;
  font-family: var(--kpress-font-sans);
  font-feature-settings: var(--kpress-font-features-sans);
  font-size: var(--kpress-caps-label-size);
  font-variant-caps: var(--kpress-caps-variant);
  font-weight: 600;
  letter-spacing: var(--kpress-caps-spacing);
  line-height: 1.2;
  max-width: 10rem;
  min-width: 5rem;
  outline: none;
  padding: 0 0.5rem;
  text-align: center;
  text-transform: var(--kpress-caps-transform);
}

.kpress-tab-button:focus-visible {
  outline: 3px solid var(--kpress-doc-link);
  outline-offset: 2px;
}

.kpress .tab-button-active,
.kpress-tab-button[aria-selected="true"] {
  border-color: var(--color-primary-light);
  color: var(--color-primary);
}

.kpress .tab-button-inactive,
.kpress-tab-button[aria-selected="false"] {
  border-color: transparent;
  color: var(--color-secondary);
}

.kpress .tab-button-inactive:hover,
.kpress-tab-button[aria-selected="false"]:hover {
  border-color: var(--color-hover);
  color: var(--color-primary);
}

.hidden {
  display: none;
}

.kpress .hidden {
  display: none;
}

.kpress-video-backdrop {
  background-color: oklch(0.00% 0 0 / 0.5);
  inset: 0;
  opacity: 0;
  pointer-events: none;
  position: fixed;
  transition:
    opacity var(--kpress-transition-fade),
    visibility var(--kpress-transition-fade);
  visibility: hidden;
  z-index: 199;
}

.kpress-video-backdrop.kpress-visible {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
}

.kpress-video-popover {
  background: var(--kpress-doc-bg);
  border: 1px solid var(--kpress-doc-border);
  color: var(--kpress-doc-text);
  display: flex;
  flex-direction: column;
  left: 1rem;
  max-height: calc(100dvh - 2rem);
  overflow: hidden;
  position: fixed;
  top: 1rem;
  width: min(44rem, calc(100dvw - 2rem));
  z-index: 200;
}

.kpress-video-popover.kpress-maximized {
  bottom: 1rem;
  right: 1rem;
  width: auto;
}

.kpress-video-header {
  align-items: center;
  display: flex;
  gap: 0.5rem;
  justify-content: space-between;
  padding: 0.5rem 0.6rem 0.5rem 0.85rem;
}

/* Icon-only close (Lucide `x`), not a text button. */
.kpress-video-header [data-kpress-video-close] {
  align-items: center;
  background: transparent;
  border: 0;
  border-radius: var(--kpress-radius-sm);
  color: var(--kpress-doc-muted);
  cursor: pointer;
  display: flex;
  justify-content: center;
  padding: 0.25rem;
  transition:
    background var(--kpress-transition-fast),
    color var(--kpress-transition-fast);
}

.kpress-video-header [data-kpress-video-close]:hover,
.kpress-video-header [data-kpress-video-close]:focus-visible {
  background: var(--color-hover-bg);
  color: var(--kpress-doc-text);
}

.kpress-video-header [data-kpress-video-close] svg {
  block-size: 18px;
  display: block;
  inline-size: 18px;
}

/* Heading step-up band: from 64rem the H2-H4 section headings take their
   larger sizes; narrow and medium panes keep the tighter defaults from
   style-tokens.css. Deliberately one notch below the 75rem TOC band so the
   heading step is not swallowed by that layout reflow, and deliberately
   headings ONLY: body text stays 1rem at every width (kash parity — kash
   bumps prose above 1rem only for print). */
@container kpress-doc (min-width: 64rem) {
  .kpress {
    --kpress-font-size-h2: 1.4rem;
    --kpress-font-size-h3: 1.2rem;
    --kpress-font-size-h4: 1.2rem;
  }
}

/* Wide document: TOC is a sticky sidebar. Widths track the document viewport
   via `cqw` (not the window), so this is correct standalone and embedded. */
@container kpress-doc (min-width: 75rem) {
  body.kpress-video-open .kpress-toc,
  .kpress-viewport.kpress-video-open .kpress-toc {
    display: none;
  }

  /* The TOC sidebar needs the full document width. Both the article
     (`.kpress-doc`, max-width 76ch+2rem) AND the inner grid wrapper
     (`.kpress-doc-layout`, max-width 76ch) are otherwise capped at the
     single-column reading measure and centred via margin:auto — so left
     in place the two-column grid is crushed into ~600px and shoved toward
     the centre/right (a left margin on the TOC, the fixed tracks spilling
     past the cap to the right). Uncap both so the sidebar + content span
     the pane, left-aligned. */
  .kpress-doc:has(.kpress-toc),
  .kpress-doc-layout:has(.kpress-toc) {
    margin-inline: 0;
    max-width: none;
  }

  /* BOTH columns are fixed widths, and the pair is left-aligned with
     justify-content. Neither track contains a pane-coupled term (no cqw/vw, no
     1fr), so the content column is a hard constant 48rem at every pane width.
     The earlier `clamp(.., 15cqw, ..)` TOC column grew with the pane and, under
     a fixed 68rem group cap, ate into the 1fr content column -- so the text got
     narrower the wider you dragged. Fixed tracks remove that coupling entirely;
     left-aligning pins the TOC + content to the start so all extra pane width
     becomes a single trailing margin -- no empty band to the left of the TOC. */
  .kpress-content-with-toc.has-toc,
  .kpress-content-with-toc:has(.kpress-toc) {
    align-items: start;
    column-gap: 3rem;
    grid-template-columns: 15rem 53rem;
    justify-content: start;
    min-height: 100dvh;
  }

  /* The content track is 53rem = the 48rem reading measure + 2×2.5rem inset.
     The base md rule pads .kpress-long-text by 4rem inline (kash's md:px-16,
     meant to inset text from the screen edge in a full-width single-column
     view). Here the column is already inset by the 3rem TOC gap and a large
     symmetric outer margin, so we trim that padding back to 2.5rem (enough
     inner margin for the content-card chrome to breathe); with the widened
     track the *text* lands at the full 48rem measure (border-box), not the
     40rem it shrank to under 4rem padding. The 75rem band floor still fits:
     15 + 3 + 53 = 71rem + the 2×2rem page gutters = 75rem exactly. */
  /* The site header/footer rows follow the same geometry as the doc grid: with a
     TOC the grid left-anchors inside .kpress-doc (1rem doc pad + 15rem track +
     3rem gap) and .kpress-long-text pads 2.5rem, so the reading text's inline
     start sits at 21.5rem. A centered header would drift off that column as the
     pane widens; align its content instead. Only the inline centering is
     cancelled: the footer keeps its block gap above. */
  .kpress-page-main:has(.kpress-toc) .kpress-site-header,
  .kpress-page-main:has(.kpress-toc) .kpress-site-footer {
    margin-inline: 0;
    max-width: none;
    padding-inline-start: 21.5rem;
  }

  .kpress-content-with-toc .kpress-long-text {
    grid-column: 2;
    margin: 0;
    max-width: none;
    padding-inline: 2.5rem;
  }

  .kpress-toc {
    align-self: start;
    grid-column: 1;
    margin: 0;
    max-height: calc(100vh - 4rem);
    overflow-y: auto;
    position: sticky;
    scrollbar-color: var(--kpress-doc-border) transparent;
    scrollbar-width: thin;
    top: 2rem;
    width: auto;
  }

  .kpress-toc::-webkit-scrollbar {
    width: 2px;
  }

  .kpress-toc::-webkit-scrollbar-track {
    background: transparent;
  }

  .kpress-toc::-webkit-scrollbar-thumb {
    background: var(--kpress-doc-border);
    border-radius: var(--kpress-radius-sm);
  }

  .kpress-toc-toggle,
  .kpress-toc-backdrop {
    display: none;
  }

  /* Tables marked wide bleed rightward into the trailing margin instead of
     scrolling inside the reading column. The grid is 15rem TOC + 3rem gap +
     53rem column (left-aligned), and `.kpress-long-text` insets 2.5rem, so the
     table's left edge sits 20.5rem from the pane's left; cap the width at the
     pane's right edge (a matching 2.5rem inset → `100cqw - 23rem`). Unmarked
     tables cap at the reading column (`max-width: 100%`) and scroll internally;
     wide-marked ones grow to their content and scroll internally only once
     they pass the pane edge. `100cqw` is the pane, so the table never centres
     on / spills past the window. */
  .kpress-content-with-toc.has-toc .kpress-table-wrap,
  .kpress-content-with-toc:has(.kpress-toc) .kpress-table-wrap {
    left: 0;
    margin-inline: 0;
    max-width: 100%;
    min-width: 100%;
    transform: none;
    width: max-content;
  }

  .kpress-content-with-toc.has-toc .kpress-table-wrap[data-kpress-table-scale="wide"],
  .kpress-content-with-toc:has(.kpress-toc) .kpress-table-wrap[data-kpress-table-scale="wide"] {
    max-width: calc(100cqw - 23rem);
  }

  .kpress-content-with-toc.has-toc .kpress-table,
  .kpress-content-with-toc:has(.kpress-toc) .kpress-table {
    max-width: none;
    width: 100%;
  }
}

/* Narrow document: TOC collapses to a floating list-icon button that fades in
   once toc.js detects the reader has scrolled past the first section; clicking
   it slides a fixed drawer (with backdrop) over the prose. Fixed positioning
   resolves against the non-scrolling `.kpress-frame`, so the drawer covers the
   document pane, not the browser window. */
@container kpress-doc (max-width: 74.99rem) {
  .kpress-toc-toggle {
    left: 0.75rem;
    opacity: 0;
    position: fixed;
    top: 1rem;
    transition:
      opacity var(--kpress-transition-fade),
      visibility var(--kpress-transition-fade),
      color var(--kpress-transition-fast),
      background-color var(--kpress-transition-fast);
    visibility: hidden;
    z-index: 201;
  }

  .kpress-toc-toggle.show-toggle {
    opacity: 1;
    visibility: visible;
  }

  /* The floating toggle lives in the pane's top-left gutter (fixed against
     the frame), so the document must keep an inline gutter at least as wide
     as the toggle's footprint (0.75rem inset + 32px button + breathing
     room) or prose slides under the control — both at mid widths, where the
     centered column's left edge moves inside the footprint, and on phones,
     where the 1rem base padding leaves the first characters covered. Hosts
     that add their own pane inset shrink the reservation through the
     clearance variable (their inset already contributes to the gutter). */
  .kpress-doc {
    padding-inline: max(1rem, var(--kpress-toc-toggle-clearance));
  }

  .kpress-toc-backdrop {
    display: block;
  }

  .kpress-toc {
    -webkit-overflow-scrolling: touch;
    background: var(--kpress-doc-code-bg);
    color: var(--color-secondary);
    left: 1rem;
    /* dvh, not vh: on phones 100vh includes the area behind the collapsing
       browser chrome, which pushed the drawer's bottom below the visible
       viewport and trapped the last entries. The extra block-end padding
       gives the list scroll room past its final entry so it is always
       comfortably reachable. */
    max-height: calc(100dvh - 6rem);
    opacity: 0;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-block-end: 2.5rem;
    pointer-events: none;
    position: fixed;
    top: 4rem;
    touch-action: pan-y;
    transform: translateY(-0.5rem);
    transition:
      opacity var(--kpress-transition-fade),
      transform var(--kpress-transition-fade),
      visibility var(--kpress-transition-fade);
    visibility: hidden;
    width: calc(100cqw - 2rem);
    z-index: 200;
  }

  .kpress-toc a {
    color: var(--color-secondary);
  }

  .kpress-toc a:hover {
    color: var(--kpress-doc-text);
  }

  .kpress-toc a[data-active="true"],
  .kpress-toc a.active {
    color: var(--kpress-doc-text);
  }

  .kpress-toc-title {
    font-size: var(--kpress-caps-label-size);
  }

  /* In the drawer the expand-all control returns to a comfortable touch
     size; the extra-small sizing is for the wide sidebar, where it sits
     beside the small-caps Contents label. */
  .kpress-toc-expand-all {
    height: 20px;
    width: 20px;
  }

  .kpress-toc-expand-all-icon {
    height: 14px;
    width: 14px;
  }

  .kpress-toc ol {
    font-size: var(--kpress-font-size-small);
  }

  .kpress-toc.kpress-mobile-visible {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
    visibility: visible;
  }

  .kpress .annotated-para {
    display: block;
  }

  .kpress .annotated-para .para,
  .kpress .annotated-para .para-caption {
    width: auto;
  }

  /* Tablet band (48–75rem): the wide (>=75rem) and mobile (<48rem) blocks
     both neutralize the base wide-table full-bleed (left:50% +
     translateX(-50%) centred on the viewport), but this band did not — so
     the centred bleed leaked through. Embedded in a host pane narrower than
     the window, that centres the table on the window and spills it past the
     pane on both sides. Anchor it to the prose column and scroll internally,
     matching the other two breakpoints. (The attribute variant is listed so
     this reset also out-specifies the base wide-table bleed rule.) */
  .kpress-table-wrap,
  .kpress-table-wrap[data-kpress-table-scale="wide"] {
    left: 0;
    margin-inline: 0;
    max-width: 100%;
    transform: none;
    width: 100%;
  }

  .kpress-table {
    max-width: none;
    width: 100%;
  }
}

@container kpress-doc (max-width: 47.99rem) {
  /* Narrow screens get a tighter frame: the wide-screen gutters stack up to several
     rem per side, which is dead space on a phone (kash used 1.5rem total). The doc
     and long-text pads shrink here; the standalone page gutter shrinks in the
     media rule by .kpress-page-main below. The floating TOC toggle is present in
     this whole band, so the shrink must still respect its clearance reservation
     (this rule ties with the clearance rule above and wins by order). */
  .kpress-doc {
    /* The two phone gutters are held in variables so the wide-table
       edge-bleed below can extend across exactly this inset. The stray-wide-
       content clip guard lives HERE (not on .kpress-long-text): the doc's
       padding box ends at the pane edge, so wide tables may bleed across the
       gutters and are clipped only at the pane, never at the text margin.
       Unlike the mid-width band above, the phone band does NOT reserve the
       floating-toggle clearance: on a phone every rem of gutter is reading
       width, and the toggle's translucent document-background fill keeps the
       control and any text it slightly overlaps legible (design review
       decision — see the toggle's own comment). */
    --kpress-doc-gutter: 0.5rem;
    overflow-x: hidden;
    padding-inline: var(--kpress-doc-gutter);
  }

  .kpress-long-text {
    --kpress-prose-gutter: 0.75rem;
    max-width: 100%;
    padding-inline: var(--kpress-prose-gutter);
  }

  /* The wide 4rem pull-in reads as wasted width on a phone. */
  .kpress blockquote {
    margin-inline: 0.75rem 1rem;
  }

  /* Shallower list indents on narrow screens (kash parity). */
  .kpress-prose ul,
  .kpress-prose ol,
  .kpress .concepts ul {
    margin-left: 1rem;
  }

  /* Three columns are unreadable at phone width. */
  .kpress .concepts {
    column-count: 1;
  }

  /* Any table too wide for the phone column keeps its left edge on the text
     column but bleeds rightward across the phone gutters to the pane edge, so
     the scroll region is cut off at the screen, not at the text's right
     margin (the screen-edge cut also signals scrollability). This
     deliberately ignores the wide mark: on a phone the mark decides nothing —
     `max-content` under the pane-edge cap means small tables sit at the
     column width and only overflowing ones grow. The gutter variables are the
     two inline pads above; the doc-level clip guard keeps any rounding
     overflow at the pane edge. */
  .kpress-table-wrap,
  .kpress-table-wrap[data-kpress-table-scale="wide"] {
    left: 0;
    margin-inline: 0;
    max-width: calc(100% + var(--kpress-doc-gutter, 0.5rem) + var(--kpress-prose-gutter, 0.75rem));
    min-width: 100%;
    transform: none;
    width: max-content;
  }

  .kpress-table {
    font-size: var(--kpress-font-size-smaller);
    max-width: none;
    min-width: 100%;
    width: auto;
  }

  .kpress-table code,
  .kpress-table pre {
    font-size: var(--kpress-font-size-mono-small);
  }
}

@media (max-width: 1199px) {
  body.kpress-video-open {
    overflow: hidden;
    position: fixed;
    touch-action: none;
    width: 100%;
  }

  .kpress-viewport.kpress-video-open {
    overflow: hidden;
    touch-action: none;
  }
}

@media (min-width: 1200px) {
  .kpress-tooltip-wide-right {
    max-width: 22rem;
    min-width: 16rem;
  }

  .kpress-tooltip-footnote.kpress-tooltip-wide-right {
    max-width: 24rem;
    min-width: 18rem;
  }
}

@media (min-width: 1600px) {
  .kpress-tooltip-wide-right {
    max-width: 28rem;
    min-width: 20rem;
  }

  .kpress-tooltip-footnote.kpress-tooltip-wide-right {
    max-width: 30rem;
    min-width: 22rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .kpress [class],
  .kpress [class]::before,
  .kpress [class]::after,
  .kpress summary,
  .kpress summary::before,
  .kpress details::details-content,
  .kpress-toc-backdrop,
  .kpress-video-backdrop,
  /* The viewport pane sits above .kpress, so the smooth hash-navigation
     glide needs its own reduced-motion opt-out. */
  .kpress-viewport {
    animation-duration: 0.01ms;
    animation-iteration-count: 1;
    scroll-behavior: auto;
    transition-duration: 0.01ms;
  }
}

/* Site chrome slots. The header/footer content is site-owned raw HTML (page
   chrome slots); these wrappers only align it with the document column and
   hand it the document's sans typography and theme tokens. KPress never
   styles the slot's inner markup. */
.kpress-site-header,
.kpress-site-footer {
  box-sizing: border-box;
  color: var(--kpress-doc-text);
  font-family: var(--kpress-font-sans);
  font-size: var(--kpress-font-size-small);
  margin: 0 auto;
  max-width: var(--kpress-measure);
  padding: 0.75rem 1.5rem;
  width: 100%;
}

.kpress-site-header {
  border-bottom: 1px solid var(--kpress-doc-border);
}

.kpress-site-footer {
  border-top: 1px solid var(--kpress-doc-border);
  color: var(--kpress-doc-muted);
  margin-top: 2rem;
}

/* Slot <-> reading-column alignment in the md single-column state: from 48rem
   container width .kpress-long-text pads 4rem inline (kash's md:px-16), so the
   slot content must pad the same or header/footer chrome sits 2.5rem off the
   text's inline edge. Below 48rem both sides land at 1.5rem (long-text 1rem +
   .kpress-doc 0.5rem); at >=75rem the docked-TOC rule re-anchors
   padding-inline-start at the reading column, overriding this by specificity. */
@container kpress-doc (min-width: 48rem) {
  .kpress-site-header,
  .kpress-site-footer {
    padding-inline: 4rem;
  }
}

.kpress-site-header a,
.kpress-site-footer a {
  color: var(--kpress-doc-link);
  text-decoration: none;
}

.kpress-site-header a:hover,
.kpress-site-footer a:hover {
  text-decoration: underline;
}
