/* ==========================================================================
   Kanonik theme layer for MkDocs Material. Per ADR-0016.

   This file RETOKENISES Material onto the locked v2 evergreen system. It
   does not restyle Material's components and must not grow into a rewrite:
   every value below is one of the `--kn`-equivalent tokens already defined
   in kanonik-v2.css, mapped onto the `--md-*` custom property Material
   already uses for that role. If a rule here starts describing layout
   rather than colour/type, it belongs in Material's own config instead.

   Source of truth for the values: kanonik-v2.css :root.
   ========================================================================== */

/* --- Self-hosted faces -----------------------------------------------------
   Material's `font: false` (mkdocs.yml) removes its Google Fonts link. These
   declarations point at the SAME /fonts/*.woff2 the marketing site already
   ships, so the KB adds no new bytes and needs no third-party font origin -
   the production CSP is `font-src 'self'` and would block a CDN.
   Paths are absolute: the KB is served from /docs/<section>/<page>/, so a
   relative URL would resolve against the page, not the site root.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/inter-latin-wght-normal.woff2") format("woff2-variations");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/ibm-plex-mono-latin-500-normal.woff2") format("woff2");
}

/* --- The v2 tokens, verbatim ---------------------------------------------- */
:root {
  --kn-background: #eef1ed;
  --kn-surface: #ffffff;
  --kn-surface-2: #e4e9e2;
  --kn-cream: #f5f6f2;

  --kn-ink: #0e1a17;
  --kn-ink-soft: #3a4642;
  --kn-ink-mute: #606a65;

  --kn-evergreen: #0a3d34;
  --kn-evergreen-deep: #062822;
  --kn-mint: #8fcaa3;
  --kn-mint-soft: #cbe6d3;

  --kn-signal: #b55333;
  --kn-line: #d3d8d0;

  --kn-font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
  --kn-font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* --- Map onto Material's roles -------------------------------------------- */
:root,
[data-md-color-scheme="default"] {
  --md-default-bg-color: var(--kn-background);
  --md-default-fg-color: var(--kn-ink);
  --md-default-fg-color--light: var(--kn-ink-soft);
  --md-default-fg-color--lighter: var(--kn-ink-mute);
  --md-default-fg-color--lightest: var(--kn-line);

  --md-primary-fg-color: var(--kn-evergreen);
  --md-primary-fg-color--light: #14574a;
  --md-primary-fg-color--dark: var(--kn-evergreen-deep);
  --md-primary-bg-color: var(--kn-cream);
  --md-primary-bg-color--light: var(--kn-mint-soft);

  --md-accent-fg-color: var(--kn-evergreen);
  --md-accent-fg-color--transparent: rgb(10 61 52 / 0.1);
  --md-accent-bg-color: var(--kn-cream);

  --md-typeset-color: var(--kn-ink);
  --md-typeset-a-color: var(--kn-evergreen);

  --md-code-bg-color: var(--kn-cream);
  --md-code-fg-color: var(--kn-ink);

  --md-footer-bg-color: var(--kn-evergreen-deep);
  --md-footer-bg-color--dark: #041d18;
  --md-footer-fg-color: var(--kn-cream);

  --md-text-font: var(--kn-font-sans);
  --md-code-font: var(--kn-font-mono);

  /* Material sizes its shadows for a card-heavy Google aesthetic. The v2
     system is flatter: hairline rules, almost no elevation. */
  --md-shadow-z1: 0 1px 2px rgb(6 40 34 / 0.06);
  --md-shadow-z2: 0 2px 8px rgb(6 40 34 / 0.08);
  --md-shadow-z3: 0 6px 20px rgb(6 40 34 / 0.10);
}

/* --- Type ----------------------------------------------------------------
   The v2 system sets headings at weight 600 with tight tracking. Material's
   default is 300/400, which reads noticeably lighter than every other page
   on the site - this is the single most visible "bolted-on subsite" tell.
   -------------------------------------------------------------------------- */
.md-typeset h1,
.md-typeset h2,
.md-typeset h3,
.md-typeset h4 {
  color: var(--kn-ink);
  font-weight: 600;
  letter-spacing: -0.02em;
}
/* Sizes mirror the marketing doc pages (.doc .prose in kanonik-v2.css):
   17px prose, a 28px h2, and an h1 that goes fluid below 640px so a long
   title does not eat three lines on a phone. Material's own scale is a
   step larger throughout, which reads as a different product. */
.md-typeset h1 {
  font-size: clamp(1.6rem, 7vw, 1.85rem);
  line-height: 1.12;
  letter-spacing: -0.03em;
  margin-bottom: 0.6em;
}
.md-typeset h2 {
  margin-top: 2em;
  font-size: 1.3rem;
  line-height: 1.2;
}
.md-typeset h3 {
  font-size: 1.05rem;
  line-height: 1.25;
}
.md-typeset {
  font-size: 0.78rem;
  line-height: 1.65;
}

/* Measure. Material's grid is 61rem wide, which at this size runs ~85
   characters - far past comfortable reading. The marketing pages cap prose
   at 760px (`.doc .prose > *`); match that, while letting tables, code and
   admonitions use the full width they need. */
.md-typeset > p,
.md-typeset > ul,
.md-typeset > ol,
.md-typeset > h1,
.md-typeset > h2,
.md-typeset > h3,
.md-typeset > h4,
.md-typeset > blockquote {
  max-width: 42rem;
}
/* Prose links are ALWAYS underlined, matching `.doc main a[href]:not(.btn)`
   in kanonik-v2.css:713. Not cosmetic: colour alone fails WCAG 1.4.1 (axe
   `link-in-text-block`) because evergreen against ink does not reach 3:1,
   so an underline is the required non-colour cue. Excludes Material's own
   chrome, which is navigation rather than running text. */
.md-typeset a:not(.md-button):not(.headerlink):not(.md-content__button) {
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}

/* Mono labels carry the same uppercase tracking as the site's .kicker. */
.md-nav__title {
  font-family: var(--kn-font-mono);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--kn-ink-mute);
}

/* --- Chrome --------------------------------------------------------------- */
.md-header {
  background-color: var(--kn-evergreen-deep);
  box-shadow: none;
  border-bottom: 1px solid rgb(255 255 255 / 0.1);
}
.md-tabs {
  background-color: var(--kn-evergreen-deep);
}
.md-search__form {
  border-radius: 6px;
  background-color: rgb(255 255 255 / 0.12);
}
.md-search__form:hover {
  background-color: rgb(255 255 255 / 0.18);
}
.md-search__input::placeholder {
  color: rgb(245 246 242 / 0.7);
}

/* Content sits on white against the cream page, matching the site's cards. */
.md-main__inner {
  margin-top: 1.5rem;
}
.md-content {
  background-color: var(--kn-surface);
  border: 1px solid var(--kn-line);
  border-radius: 8px;
}
.md-content__inner {
  padding: 1.2rem 1.6rem 2.4rem;
  margin-bottom: 0;
}

/* Sidebars are plain text on the page background, no card. */
.md-sidebar {
  background: transparent;
}
.md-nav__link--active,
.md-nav__link:focus,
.md-nav__link:hover {
  color: var(--kn-evergreen);
}

/* Tables: the site scrolls wide content inside its own container so the page
   never scrolls sideways on a phone. Material already wraps tables in a
   scroll container; this only aligns the border and header treatment. */
.md-typeset table:not([class]) {
  border: 1px solid var(--kn-line);
  border-radius: 8px;
  font-size: 0.72rem;
}
.md-typeset table:not([class]) th {
  background-color: var(--kn-cream);
  font-family: var(--kn-font-mono);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--kn-ink-mute);
}

/* Admonitions in the house palette rather than Material's blue/orange. */
.md-typeset .admonition,
.md-typeset details {
  border-left-width: 3px;
  border-radius: 0 8px 8px 0;
  box-shadow: none;
  border-color: var(--kn-line);
  font-size: 0.76rem;
}
.md-typeset .admonition.note,
.md-typeset details.note {
  border-left-color: var(--kn-evergreen);
}
.md-typeset .note > .admonition-title,
.md-typeset .note > summary {
  background-color: var(--kn-mint-soft);
}
.md-typeset .note > .admonition-title::before,
.md-typeset .note > summary::before {
  background-color: var(--kn-evergreen);
}
.md-typeset .admonition.warning,
.md-typeset details.warning {
  border-left-color: var(--kn-signal);
}

/* Code blocks pick up the cream surface instead of Material's grey. */
.md-typeset pre > code {
  border-radius: 6px;
}
.md-typeset code {
  border-radius: 4px;
  border: 1px solid var(--kn-line);
  padding: 1px 5px;
  font-size: 0.85em;
}
.md-typeset pre > code {
  border: 1px solid var(--kn-line);
}

/* --- Accessibility --------------------------------------------------------
   The site floor is WCAG 2.2 AA plus a 44px touch target on coarse pointers
   (stricter than AA's 24px). Material's nav links and search controls sit
   under that on a phone.
   -------------------------------------------------------------------------- */
:focus-visible {
  outline: 2px solid var(--kn-evergreen);
  outline-offset: 2px;
}

/* WCAG 2.2 AA 2.5.8 Target Size (Minimum) is 24x24 CSS px and applies to
   EVERY pointer type, not just touch. Material's sidebar links render about
   18px tall, which axe flags as `target-size`. The 44px block below covers
   coarse pointers; this covers the mouse-driven case that AA still requires. */
/* NOT .headerlink. It is the inline permalink glyph inside a heading, and
   display:flex turned it into a full-width block that took its own line under
   every heading and lit up as a wide band on hover. Inline targets whose
   position is set by the surrounding text are exempt from 2.5.8 anyway, the
   same exception that covers prose links. */
.md-nav__link,
.md-footer__link {
  min-height: 24px;
  display: flex;
  align-items: center;
}
.md-nav__link .md-ellipsis {
  min-height: 24px;
  display: flex;
  align-items: center;
}

@media (pointer: coarse) {
  .md-nav__link,
  .md-footer__link,
  .md-typeset .md-button {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
  .md-header__button,
  .md-search__icon {
    min-height: 44px;
    min-width: 44px;
  }
}

/* Wide content must scroll inside its own container, never the page. */
.md-typeset .md-typeset__table,
.md-typeset pre {
  max-width: 100%;
  overflow-x: auto;
}

/* On a phone, wrap commands instead of scrolling them.
   A horizontally scrolling <code> is a scrollable region, and WCAG requires
   those to be keyboard-focusable (axe `scrollable-region-focusable`); Material
   does not add tabindex here. Wrapping removes the scroll region entirely
   rather than papering over it, and for a one-line shell command it is the
   better phone experience anyway - the reader sees the whole command instead
   of swiping through it. The hanging indent keeps a wrapped continuation
   visually distinct from a genuine second line. */
/* Applies at every width, not just phones: Firefox and WebKit still reported
   a scrollable code box at 1280 where Chromium did not, so a breakpoint-scoped
   fix passed one engine and failed two. The content column is ~42rem and the
   commands here are single lines, so wrapping everywhere costs nothing. */
.md-typeset pre > code {
    white-space: pre-wrap;
    /* `anywhere`, not `break-word`: the long token here is a URL placeholder
       with no break opportunity, and engines disagree about whether
       break-word may split it. */
    overflow-wrap: anywhere;
    word-break: break-word;
    /* Kill the scroll container outright. Wrapping alone leaves
       `overflow: auto` in place, and any engine that still reports a
       scrollable box re-triggers axe `scrollable-region-focusable`. With no
       overflow and no auto, there is no region to make focusable. */
  overflow: visible;
  padding-left: 2.2em;
  text-indent: -1.4em;
}
